vfs: check userland buffers before reading them.
[haiku.git] / src / apps / cortex / support / MultiInvoker.cpp
blob0344bb2345460bdd6e2be6c23000ff98a176ab9d
1 /*
2 * Copyright 1999, Be Incorporated.
3 * Copyright (c) 1999-2000, Eric Moon.
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions, and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
28 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ////////////////////////////////////////////////////////////
34 // MultiInvoker.cpp
35 // ----------------
36 // Implements the MultiInvoker class.
39 #include <Messenger.h>
40 #include "MultiInvoker.h"
42 MultiInvoker::MultiInvoker()
44 m_message = 0;
45 m_timeout = B_INFINITE_TIMEOUT;
46 m_replyHandler = 0;
49 MultiInvoker::MultiInvoker(const MultiInvoker& src)
51 Clone(src);
54 MultiInvoker::~MultiInvoker()
56 Clear();
59 MultiInvoker& MultiInvoker::operator=(const MultiInvoker& src)
61 if (this != &src) {
62 Clear();
63 Clone(src);
65 return *this;
68 void MultiInvoker::Clear()
70 delete m_message;
71 int32 i=CountTargets();
72 while (--i >=0) {
73 RemoveTarget(i);
77 void MultiInvoker::Clone(const MultiInvoker& src)
79 m_message = new BMessage(*src.Message());
80 int32 len=src.CountTargets();
81 for (int32 i=0; i<len; i++) {
82 AddTarget(src.TargetAt(i));
84 m_timeout = src.Timeout();
85 m_replyHandler = src.HandlerForReply();
88 void MultiInvoker::SetMessage(BMessage* message)
90 delete m_message;
91 m_message = message;
94 BMessage* MultiInvoker::Message() const
96 return m_message;
99 uint32 MultiInvoker::Command() const
101 return (m_message) ? m_message->what : 0;
104 status_t MultiInvoker::AddTarget(const BHandler* h, const BLooper* loop)
106 status_t err;
107 BMessenger* msgr = new BMessenger(h, loop, &err);
108 if (err == B_OK)
109 m_messengers.AddItem(msgr);
110 else
111 delete msgr;
112 return err;
115 status_t MultiInvoker::AddTarget(BMessenger* msgr)
117 if (msgr) {
118 m_messengers.AddItem(msgr);
119 return B_OK;
120 } else {
121 return B_BAD_VALUE;
125 void MultiInvoker::RemoveTarget(const BHandler* h)
127 int32 i = IndexOfTarget(h);
128 if (i >= 0)
129 RemoveTarget(i);
132 void MultiInvoker::RemoveTarget(int32 index)
134 BMessenger* msgr = static_cast<BMessenger*>
135 (m_messengers.RemoveItem(index));
136 delete msgr;
139 int32 MultiInvoker::IndexOfTarget(const BHandler* h) const
141 int32 len = CountTargets();
142 for (int32 i=0; i<len; i++) {
143 BMessenger* msgr = MessengerAt(i);
144 if (msgr && msgr->Target(0) == h) {
145 return i;
148 return -1;
151 int32 MultiInvoker::CountTargets() const
153 return m_messengers.CountItems();
156 BHandler* MultiInvoker::TargetAt(int32 index, BLooper** looper) const
158 BMessenger* msgr = MessengerAt(index);
159 if (msgr) {
160 return msgr->Target(looper);
161 } else {
162 if (looper) *looper = 0;
163 return 0;
167 BMessenger* MultiInvoker::MessengerAt(int32 index) const
169 return static_cast<BMessenger*>
170 (m_messengers.ItemAt(index));
173 bool MultiInvoker::IsTargetLocal(int32 index) const
175 BMessenger* msgr = MessengerAt(index);
176 return (msgr) ? msgr->IsTargetLocal() : false;
179 void MultiInvoker::SetTimeout(bigtime_t timeout)
181 m_timeout = timeout;
184 bigtime_t MultiInvoker::Timeout() const
186 return m_timeout;
189 void MultiInvoker::SetHandlerForReply(BHandler* h)
191 m_replyHandler = h;
194 BHandler* MultiInvoker::HandlerForReply() const
196 return m_replyHandler;
199 status_t MultiInvoker::Invoke(BMessage* msg)
201 BMessage* sendMsg = (msg) ? msg : m_message;
202 if (! sendMsg)
203 return B_BAD_VALUE;
205 status_t err, finalResult=B_OK;
206 BMessage replyMsg;
207 int32 len = CountTargets();
208 for (int32 i=0; i<len; i++) {
209 BMessenger* msgr = MessengerAt(i);
210 if (msgr) {
211 err = msgr->SendMessage(sendMsg,
212 HandlerForReply(), m_timeout);
213 if (err != B_OK) finalResult = err;
216 return finalResult;