vfs: check userland buffers before reading them.
[haiku.git] / src / kits / app / ServerLink.cpp
blob05ac10546531c3d8d19327b6041428c00ce0f148
1 /*
2 * Copyright 2001-2009, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Pahtz <pahtz@yahoo.com.au>
7 * Axel Dörfler, axeld@pinc-software.de
8 */
11 /*! Class for low-overhead port-based messaging */
14 #include <ServerLink.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <new>
20 #include <Gradient.h>
21 #include <GradientLinear.h>
22 #include <GradientRadial.h>
23 #include <GradientRadialFocus.h>
24 #include <GradientDiamond.h>
25 #include <GradientConic.h>
26 #include <Region.h>
27 #include <Shape.h>
28 #include <StackOrHeapArray.h>
30 #include <ServerProtocol.h>
33 //#define TRACE_SERVER_LINK_GRADIENTS
34 #ifdef TRACE_SERVER_LINK_GRADIENTS
35 # include <OS.h>
36 # define GTRACE(x) debug_printf x
37 #else
38 # define GTRACE(x) ;
39 #endif
42 namespace BPrivate {
45 ServerLink::ServerLink()
50 ServerLink::~ServerLink()
55 void
56 ServerLink::SetTo(port_id sender, port_id receiver)
58 fSender->SetPort(sender);
59 fReceiver->SetPort(receiver);
63 status_t
64 ServerLink::ReadRegion(BRegion* region)
66 fReceiver->Read(&region->fCount, sizeof(int32));
67 if (region->fCount > 0) {
68 fReceiver->Read(&region->fBounds, sizeof(clipping_rect));
69 if (!region->_SetSize(region->fCount))
70 return B_NO_MEMORY;
71 return fReceiver->Read(region->fData,
72 region->fCount * sizeof(clipping_rect));
75 return fReceiver->Read(&region->fBounds, sizeof(clipping_rect));
79 status_t
80 ServerLink::AttachRegion(const BRegion& region)
82 fSender->Attach(&region.fCount, sizeof(int32));
83 if (region.fCount > 0) {
84 fSender->Attach(&region.fBounds, sizeof(clipping_rect));
85 return fSender->Attach(region.fData,
86 region.fCount * sizeof(clipping_rect));
89 return fSender->Attach(&region.fBounds, sizeof(clipping_rect));
93 status_t
94 ServerLink::ReadShape(BShape* shape)
96 int32 opCount, ptCount;
97 fReceiver->Read(&opCount, sizeof(int32));
98 fReceiver->Read(&ptCount, sizeof(int32));
100 BStackOrHeapArray<uint32, 64> opList(opCount);
101 if (opCount > 0)
102 fReceiver->Read(opList, opCount * sizeof(uint32));
104 BStackOrHeapArray<BPoint, 64> ptList(ptCount);
105 if (ptCount > 0)
106 fReceiver->Read(ptList, ptCount * sizeof(BPoint));
108 shape->SetData(opCount, ptCount, opList, ptList);
109 return B_OK;
113 status_t
114 ServerLink::AttachShape(BShape& shape)
116 int32 opCount, ptCount;
117 uint32* opList;
118 BPoint* ptList;
120 shape.GetData(&opCount, &ptCount, &opList, &ptList);
122 fSender->Attach(&opCount, sizeof(int32));
123 fSender->Attach(&ptCount, sizeof(int32));
124 if (opCount > 0)
125 fSender->Attach(opList, opCount * sizeof(uint32));
126 if (ptCount > 0)
127 fSender->Attach(ptList, ptCount * sizeof(BPoint));
128 return B_OK;
132 status_t
133 ServerLink::ReadGradient(BGradient** _gradient)
135 GTRACE(("ServerLink::ReadGradient\n"));
136 return fReceiver->ReadGradient(_gradient);
140 status_t
141 ServerLink::AttachGradient(const BGradient& gradient)
143 GTRACE(("ServerLink::AttachGradient\n"));
144 BGradient::Type gradientType = gradient.GetType();
145 int32 stopCount = gradient.CountColorStops();
146 GTRACE(("ServerLink::AttachGradient> color stop count == %d\n",
147 (int)stopCount));
148 fSender->Attach(&gradientType, sizeof(BGradient::Type));
149 fSender->Attach(&stopCount, sizeof(int32));
150 if (stopCount > 0) {
151 for (int i = 0; i < stopCount; i++) {
152 fSender->Attach(gradient.ColorStopAtFast(i),
153 sizeof(BGradient::ColorStop));
157 switch (gradientType) {
158 case BGradient::TYPE_LINEAR:
160 GTRACE(("ServerLink::AttachGradient> type == TYPE_LINEAR\n"));
161 const BGradientLinear* linear = (BGradientLinear*)&gradient;
162 fSender->Attach(linear->Start());
163 fSender->Attach(linear->End());
164 break;
166 case BGradient::TYPE_RADIAL:
168 GTRACE(("ServerLink::AttachGradient> type == TYPE_RADIAL\n"));
169 const BGradientRadial* radial = (BGradientRadial*)&gradient;
170 BPoint center = radial->Center();
171 float radius = radial->Radius();
172 fSender->Attach(&center, sizeof(BPoint));
173 fSender->Attach(&radius, sizeof(float));
174 break;
176 case BGradient::TYPE_RADIAL_FOCUS:
178 GTRACE(("ServerLink::AttachGradient> type == TYPE_RADIAL_FOCUS\n"));
179 const BGradientRadialFocus* radialFocus
180 = (BGradientRadialFocus*)&gradient;
181 BPoint center = radialFocus->Center();
182 BPoint focal = radialFocus->Focal();
183 float radius = radialFocus->Radius();
184 fSender->Attach(&center, sizeof(BPoint));
185 fSender->Attach(&focal, sizeof(BPoint));
186 fSender->Attach(&radius, sizeof(float));
187 break;
189 case BGradient::TYPE_DIAMOND:
191 GTRACE(("ServerLink::AttachGradient> type == TYPE_DIAMOND\n"));
192 const BGradientDiamond* diamond = (BGradientDiamond*)&gradient;
193 BPoint center = diamond->Center();
194 fSender->Attach(&center, sizeof(BPoint));
195 break;
197 case BGradient::TYPE_CONIC:
199 GTRACE(("ServerLink::AttachGradient> type == TYPE_CONIC\n"));
200 const BGradientConic* conic = (BGradientConic*)&gradient;
201 BPoint center = conic->Center();
202 float angle = conic->Angle();
203 fSender->Attach(&center, sizeof(BPoint));
204 fSender->Attach(&angle, sizeof(float));
205 break;
207 case BGradient::TYPE_NONE:
209 GTRACE(("ServerLink::AttachGradient> type == TYPE_NONE\n"));
210 break;
213 return B_OK;
217 status_t
218 ServerLink::FlushWithReply(int32& code)
220 status_t status = Flush(B_INFINITE_TIMEOUT, true);
221 if (status < B_OK)
222 return status;
224 return GetNextMessage(code);
228 } // namespace BPrivate