1// RequestFlattener.cpp 2 3#include <ByteOrder.h> 4 5#include "RequestFlattener.h" 6 7// Writer 8 9// constructor 10Writer::Writer() 11{ 12} 13 14// destructor 15Writer::~Writer() 16{ 17} 18 19// Pad 20status_t 21Writer::Pad(int32 size) 22{ 23 if (size <= 0) 24 return B_OK; 25 26 if (size > 8) 27 return B_BAD_VALUE; 28 29 char buffer[8]; 30 return Write(buffer, size); 31} 32 33 34// DataIOWriter 35 36// constructor 37DataIOWriter::DataIOWriter(BDataIO* dataIO) 38 : Writer(), 39 fDataIO(dataIO) 40{ 41} 42 43// destructor 44DataIOWriter::~DataIOWriter() 45{ 46} 47 48// Write 49status_t 50DataIOWriter::Write(const void* buffer, int32 size) 51{ 52 ssize_t bytesWritten = fDataIO->Write(buffer, size); 53 if (bytesWritten < 0) 54 return bytesWritten; 55 if (bytesWritten != size) 56 return B_ERROR; 57 return B_OK; 58} 59 60 61// DummyWriter 62 63// constructor 64DummyWriter::DummyWriter() 65{ 66} 67 68// destructor 69DummyWriter::~DummyWriter() 70{ 71} 72 73// Write 74status_t 75DummyWriter::Write(const void* buffer, int32 size) 76{ 77 return B_OK; 78} 79 80 81// RequestFlattener 82 83// constructor 84RequestFlattener::RequestFlattener(Writer* writer) 85 : RequestMemberVisitor(), 86 fWriter(writer), 87 fStatus(B_OK), 88 fBytesWritten(0) 89{ 90} 91 92// GetStatus 93status_t 94RequestFlattener::GetStatus() const 95{ 96 return fStatus; 97} 98 99// GetBytesWritten 100int32 101RequestFlattener::GetBytesWritten() const 102{ 103 return fBytesWritten; 104} 105 106// Visit 107void 108RequestFlattener::Visit(RequestMember* member, bool& data) 109{ 110 uint8 netData = (data ? ~0 : 0); 111 Write(&netData, 1); 112} 113 114// Visit 115void 116RequestFlattener::Visit(RequestMember* member, int8& data) 117{ 118 Write(&data, 1); 119} 120 121// Visit 122void 123RequestFlattener::Visit(RequestMember* member, uint8& data) 124{ 125 Write(&data, 1); 126} 127 128// Visit 129void 130RequestFlattener::Visit(RequestMember* member, int16& data) 131{ 132 int16 netData = B_HOST_TO_BENDIAN_INT16(data); 133 Write(&netData, 2); 134} 135 136// Visit 137void 138RequestFlattener::Visit(RequestMember* member, uint16& data) 139{ 140 uint16 netData = B_HOST_TO_BENDIAN_INT16(data); 141 Write(&netData, 2); 142} 143 144// Visit 145void 146RequestFlattener::Visit(RequestMember* member, int32& data) 147{ 148 int32 netData = B_HOST_TO_BENDIAN_INT32(data); 149 Write(&netData, 4); 150} 151 152// Visit 153void 154RequestFlattener::Visit(RequestMember* member, uint32& data) 155{ 156 uint32 netData = B_HOST_TO_BENDIAN_INT32(data); 157 Write(&netData, 4); 158} 159 160// Visit 161void 162RequestFlattener::Visit(RequestMember* member, int64& data) 163{ 164 int64 netData = B_HOST_TO_BENDIAN_INT64(data); 165 Write(&netData, 8); 166} 167 168// Visit 169void 170RequestFlattener::Visit(RequestMember* member, uint64& data) 171{ 172 uint64 netData = B_HOST_TO_BENDIAN_INT64(data); 173 Write(&netData, 8); 174} 175 176// Visit 177void 178RequestFlattener::Visit(RequestMember* member, Data& data) 179{ 180 WriteData(data.address, data.size); 181} 182 183// Visit 184void 185RequestFlattener::Visit(RequestMember* member, StringData& data) 186{ 187 WriteData(data.address, data.size); 188} 189 190// Visit 191void 192RequestFlattener::Visit(RequestMember* member, RequestMember& subMember) 193{ 194 subMember.ShowAround(this); 195} 196 197// Visit 198void 199RequestFlattener::Visit(RequestMember* member, 200 FlattenableRequestMember& subMember) 201{ 202 if (fStatus != B_OK) 203 return; 204 205 status_t status = subMember.Flatten(this); 206 if (fStatus == B_OK) 207 fStatus = status; 208} 209 210 211// Write 212status_t 213RequestFlattener::Write(const void* buffer, int32 size) 214{ 215 if (fStatus != B_OK) 216 return fStatus; 217 218 fStatus = fWriter->Write(buffer, size); 219 if (fStatus == B_OK) 220 fBytesWritten += size; 221 222 return fStatus; 223} 224 225// Align 226status_t 227RequestFlattener::Align(int32 align) 228{ 229 if (fStatus != B_OK) 230 return fStatus; 231 232 if (align > 1) { 233 int32 newBytesWritten = fBytesWritten; 234 if (!(align & 0x3)) 235 newBytesWritten = (fBytesWritten + 3) & ~0x3; 236 else if (!(align & 0x1)) 237 newBytesWritten = (fBytesWritten + 1) & ~0x1; 238 239 if (newBytesWritten > fBytesWritten) { 240 fStatus = fWriter->Pad(newBytesWritten - fBytesWritten); 241 if (fStatus == B_OK) 242 fBytesWritten = newBytesWritten; 243 } 244 } 245 246 return fStatus; 247} 248 249// WriteBool 250status_t 251RequestFlattener::WriteBool(bool data) 252{ 253 return Write(&data, 1); 254} 255 256// WriteInt32 257status_t 258RequestFlattener::WriteInt32(int32 data) 259{ 260 int32 netData = B_HOST_TO_BENDIAN_INT32(data); 261 return Write(&netData, 4); 262} 263 264// WriteData 265status_t 266RequestFlattener::WriteData(const void* buffer, int32 size) 267{ 268 if ((!buffer && size > 0) || size < 0) 269 return B_BAD_VALUE; 270 271 int32 netData = B_HOST_TO_BENDIAN_INT32(size); 272 Write(&netData, 4); 273 return Write(buffer, size); 274} 275 276// WriteString 277status_t 278RequestFlattener::WriteString(const char* string) 279{ 280 int32 size = (string ? strlen(string) + 1 : 0); 281 return WriteData(string, size); 282} 283 284