blob: 1f9e57ac8be0d3c29635afe6dded46b06baa029f [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Mark Slee7e9eea42007-09-10 21:00:23 +000020#import "TBinaryProtocol.h"
Jens Geyer56e5b9b2015-10-09 22:01:55 +020021#import "TProtocolError.h"
Mark Slee7e9eea42007-09-10 21:00:23 +000022
Mark Slee7e9eea42007-09-10 21:00:23 +000023
Jens Geyer56e5b9b2015-10-09 22:01:55 +020024static SInt32 VERSION_1 = 0x80010000;
25static SInt32 VERSION_MASK = 0xffff0000;
Roger Meier6b616012015-03-01 12:32:50 +010026
Roger Meier6b616012015-03-01 12:32:50 +010027
Jens Geyer56e5b9b2015-10-09 22:01:55 +020028static TBinaryProtocolFactory *gSharedFactory = nil;
Mark Slee7e9eea42007-09-10 21:00:23 +000029
Mark Slee77575e62007-09-24 19:24:53 +000030
David Reiss0c90f6f2008-02-06 22:18:40 +000031@implementation TBinaryProtocolFactory
Mark Slee77575e62007-09-24 19:24:53 +000032
Jens Geyer56e5b9b2015-10-09 22:01:55 +020033+(TBinaryProtocolFactory *) sharedFactory
34{
Mark Slee77575e62007-09-24 19:24:53 +000035 if (gSharedFactory == nil) {
36 gSharedFactory = [[TBinaryProtocolFactory alloc] init];
37 }
David Reiss0c90f6f2008-02-06 22:18:40 +000038
Mark Slee77575e62007-09-24 19:24:53 +000039 return gSharedFactory;
40}
41
Jens Geyer56e5b9b2015-10-09 22:01:55 +020042-(NSString *) protocolName
43{
44 return @"binary";
45}
46
47-(TBinaryProtocol *) newProtocolOnTransport:(id <TTransport>)transport
48{
49 return [[TBinaryProtocol alloc] initWithTransport:transport];
Mark Slee77575e62007-09-24 19:24:53 +000050}
51
52@end
53
54
Jens Geyer56e5b9b2015-10-09 22:01:55 +020055@interface TBinaryProtocol ()
56
57@property(strong, nonatomic) id <TTransport> transport;
58
59@property(assign, nonatomic) BOOL strictRead;
60@property(assign, nonatomic) BOOL strictWrite;
61
62@property(strong, nonatomic) NSString *currentMessageName;
63@property(strong, nonatomic) NSString *currentFieldName;
64
65@end
66
Mark Slee77575e62007-09-24 19:24:53 +000067
Mark Slee7e9eea42007-09-10 21:00:23 +000068@implementation TBinaryProtocol
69
Jens Geyer56e5b9b2015-10-09 22:01:55 +020070-(id) initWithTransport:(id <TTransport>)aTransport
Mark Slee7e9eea42007-09-10 21:00:23 +000071{
Jens Geyer56e5b9b2015-10-09 22:01:55 +020072 return [self initWithTransport:aTransport strictRead:NO strictWrite:YES];
Mark Slee7e9eea42007-09-10 21:00:23 +000073}
74
Jens Geyer56e5b9b2015-10-09 22:01:55 +020075-(id) initWithTransport:(id <TTransport>)transport
76 strictRead:(BOOL)strictRead
77 strictWrite:(BOOL)strictWrite
Mark Slee7e9eea42007-09-10 21:00:23 +000078{
79 self = [super init];
Jens Geyer56e5b9b2015-10-09 22:01:55 +020080 if (self) {
81 _transport = transport;
82 _strictRead = strictRead;
83 _strictWrite = strictWrite;
84 }
Mark Slee7e9eea42007-09-10 21:00:23 +000085 return self;
86}
87
Jens Geyer56e5b9b2015-10-09 22:01:55 +020088-(id <TTransport>) transport
Mark Slee84406052007-11-20 01:39:25 +000089{
Jens Geyer56e5b9b2015-10-09 22:01:55 +020090 return _transport;
Mark Slee84406052007-11-20 01:39:25 +000091}
92
Jens Geyer56e5b9b2015-10-09 22:01:55 +020093-(NSString *) readStringBody:(int)size error:(NSError **)error
Mark Slee84406052007-11-20 01:39:25 +000094{
Jens Geyer56e5b9b2015-10-09 22:01:55 +020095 NSMutableData *data = [NSMutableData dataWithLength:size];
96 if (!data) {
97 PROTOCOL_ERROR(nil, Unknown, @"Unable to allocate %d bytes", size);
Andrew McGeachie061722b2009-07-23 18:12:18 +000098 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +020099
100 if (![_transport readAll:data.mutableBytes offset:0 length:size error:error]) {
101 PROTOCOL_TRANSPORT_ERROR(nil, error, @"Transport read failed");
102 }
103
104 return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Mark Slee7e9eea42007-09-10 21:00:23 +0000105}
106
107
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200108-(BOOL) readMessageBeginReturningName:(NSString **)name
109 type:(SInt32 *)type
110 sequenceID:(SInt32 *)sequenceID
111 error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000112{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200113 SInt32 size;
114 if (![self readI32:&size error:error]) {
115 return NO;
116 }
117 ;
118
Mark Slee7e9eea42007-09-10 21:00:23 +0000119 if (size < 0) {
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200120 int version = size & VERSION_MASK;
Mark Slee7e9eea42007-09-10 21:00:23 +0000121 if (version != VERSION_1) {
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200122 PROTOCOL_ERROR(NO, BadVersion, @"Bad message version");
Mark Slee7e9eea42007-09-10 21:00:23 +0000123 }
124 if (type != NULL) {
Roger Meierff951bd2013-03-22 22:12:19 +0100125 *type = size & 0x00FF;
Mark Slee7e9eea42007-09-10 21:00:23 +0000126 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200127 NSString *messageName;
128 if (![self readString:&messageName error:error]) {
129 return NO;
130 }
131 if (name != nil) {
132 *name = messageName;
133 }
134 }
135 else {
136
137 if (_strictRead) {
138 PROTOCOL_ERROR(NO, InvalidData, @"Missing message version, old client?");
139 }
140
141 if (_messageSizeLimit > 0 && size > _messageSizeLimit) {
142 PROTOCOL_ERROR(NO, SizeLimit, @"Message exceeeds size limit of %d", (int)size);
143 }
144
145 NSString *messageName = [self readStringBody:size error:error];
146 if (!messageName) {
147 return NO;
148 }
149
Mark Slee7e9eea42007-09-10 21:00:23 +0000150 if (name != NULL) {
151 *name = messageName;
152 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200153
154 UInt8 messageType;
155 if (![self readByte:&messageType error:error]) {
156 return NO;
Mark Slee7e9eea42007-09-10 21:00:23 +0000157 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200158
Mark Slee7e9eea42007-09-10 21:00:23 +0000159 if (type != NULL) {
160 *type = messageType;
161 }
Mark Slee7e9eea42007-09-10 21:00:23 +0000162 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200163
164 SInt32 seqID;
165 if (![self readI32:&seqID error:error]) {
166 return NO;
167 }
168 if (sequenceID != NULL) {
169 *sequenceID = seqID;
170 }
171
172 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000173}
174
175
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200176-(BOOL) readMessageEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000177{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200178 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000179}
180
181
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200182-(BOOL) readStructBeginReturningName:(NSString *__autoreleasing *)name error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000183{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200184 return YES;
185}
186
187
188-(BOOL) readStructEnd:(NSError *__autoreleasing *)error
189{
190 return YES;
191}
192
193
194-(BOOL) readFieldBeginReturningName:(NSString *__autoreleasing *)name
195 type:(SInt32 *)fieldType
196 fieldID:(SInt32 *)fieldID
197 error:(NSError *__autoreleasing *)error
198{
199 if (name != nil) {
Mark Slee7e9eea42007-09-10 21:00:23 +0000200 *name = nil;
201 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200202
203 UInt8 ft;
204 if (![self readByte:&ft error:error]) {
205 return NO;
206 }
Mark Slee7e9eea42007-09-10 21:00:23 +0000207 if (fieldType != NULL) {
208 *fieldType = ft;
David Reiss0c90f6f2008-02-06 22:18:40 +0000209 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200210 if (ft != TTypeSTOP) {
211 SInt16 fid;
212 if (![self readI16:&fid error:error]) {
213 return NO;
214 }
Mark Slee7e9eea42007-09-10 21:00:23 +0000215 if (fieldID != NULL) {
216 *fieldID = fid;
217 }
218 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200219 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000220}
221
222
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200223-(BOOL) readFieldEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000224{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200225 return YES;
226}
227
228
229-(BOOL) readString:(NSString *__autoreleasing *)value error:(NSError *__autoreleasing *)error
230{
231 SInt32 size;
232 if (![self readI32:&size error:error]) {
233 return NO;
234 }
235
236 NSString *string = [self readStringBody:size error:error];
237 if (!string) {
238 return NO;
239 }
240
241 *value = string;
242
243 return YES;
244}
245
246
247-(BOOL) readBool:(BOOL *)value error:(NSError *__autoreleasing *)error
248{
249 UInt8 byte;
250 if (![self readByte:&byte error:error]) {
251 return NO;
252 }
253
254 *value = byte == 1;
255
256 return YES;
257}
258
259
260-(BOOL) readByte:(UInt8 *)value error:(NSError *__autoreleasing *)error
261{
262 UInt8 buff[1];
263 if (![_transport readAll:buff offset:0 length:1 error:error]) {
264 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
265 }
266
267 *value = buff[0];
268
269 return YES;
270}
271
272
273-(BOOL) readI16:(SInt16 *)value error:(NSError *__autoreleasing *)error
274{
275 UInt8 buff[2];
276 if (![_transport readAll:buff offset:0 length:2 error:error]) {
277 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
278 }
279
280 *value =
281 ((SInt16)(buff[0] & 0xff) << 8) |
282 ((SInt16)(buff[1] & 0xff));
283
284 return YES;
285}
286
287
288-(BOOL) readI32:(SInt32 *)value error:(NSError *__autoreleasing *)error
289{
290 UInt8 i32rd[4];
291 if (![_transport readAll:i32rd offset:0 length:4 error:error]) {
292 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
293 }
294
295 *value =
Mark Slee7e9eea42007-09-10 21:00:23 +0000296 ((i32rd[0] & 0xff) << 24) |
297 ((i32rd[1] & 0xff) << 16) |
298 ((i32rd[2] & 0xff) << 8) |
299 ((i32rd[3] & 0xff));
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200300
301 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000302}
303
304
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200305-(BOOL) readI64:(SInt64 *)value error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000306{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200307 UInt8 buff[8];
308 if (![_transport readAll:buff offset:0 length:8 error:error]) {
309 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
310 }
311
312 *value =
313 ((SInt64)(buff[0] & 0xff) << 56) |
314 ((SInt64)(buff[1] & 0xff) << 48) |
315 ((SInt64)(buff[2] & 0xff) << 40) |
316 ((SInt64)(buff[3] & 0xff) << 32) |
317 ((SInt64)(buff[4] & 0xff) << 24) |
318 ((SInt64)(buff[5] & 0xff) << 16) |
319 ((SInt64)(buff[6] & 0xff) << 8) |
320 ((SInt64)(buff[7] & 0xff));
321
322 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000323}
324
325
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200326-(BOOL) readDouble:(double *)value error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000327{
328 // FIXME - will this get us into trouble on PowerPC?
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200329 return [self readI64:(SInt64 *)value error:error];
Mark Slee7e9eea42007-09-10 21:00:23 +0000330}
331
332
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200333-(BOOL) readBinary:(NSData *__autoreleasing *)value error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000334{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200335 SInt32 size;
336 if (![self readI32:&size error:error]) {
337 return NO;
Mark Slee7e9eea42007-09-10 21:00:23 +0000338 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200339
340 NSMutableData *data = [NSMutableData dataWithLength:size];
341 if (!data) {
342 PROTOCOL_ERROR(NO, Unknown, @"Unable to allocate %d bytes", (int)size);
343 }
344
345 if (![_transport readAll:data.mutableBytes offset:0 length:size error:error]) {
346 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport read failed");
347 }
348
349 *value = data;
350
351 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000352}
353
354
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200355-(BOOL) readMapBeginReturningKeyType:(SInt32 *)keyType
356 valueType:(SInt32 *)valueType
357 size:(SInt32 *)size
358 error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000359{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200360 UInt8 kt;
361 if (![self readByte:&kt error:error]) {
362 return NO;
363 }
364
365 UInt8 vt;
366 if (![self readByte:&vt error:error]) {
367 return NO;
368 }
369
370 SInt32 s;
371 if (![self readI32:&s error:error]) {
372 return NO;
373 }
374
Mark Slee7e9eea42007-09-10 21:00:23 +0000375 if (keyType != NULL) {
376 *keyType = kt;
377 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200378
Mark Slee7e9eea42007-09-10 21:00:23 +0000379 if (valueType != NULL) {
380 *valueType = vt;
381 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200382
Mark Slee7e9eea42007-09-10 21:00:23 +0000383 if (size != NULL) {
384 *size = s;
385 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200386
387 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000388}
389
Mark Slee7e9eea42007-09-10 21:00:23 +0000390
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200391-(BOOL) readMapEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000392{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200393 return YES;
394}
395
396
397-(BOOL) readSetBeginReturningElementType:(SInt32 *)elementType
398 size:(SInt32 *)size
399 error:(NSError *__autoreleasing *)error
400{
401 UInt8 et;
402 if (![self readByte:&et error:error]) {
403 return NO;
404 }
405
406 SInt32 s;
407 if (![self readI32:&s error:error]) {
408 return NO;
409 }
410
Mark Slee7e9eea42007-09-10 21:00:23 +0000411 if (elementType != NULL) {
412 *elementType = et;
413 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200414
Mark Slee7e9eea42007-09-10 21:00:23 +0000415 if (size != NULL) {
416 *size = s;
417 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200418
419 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000420}
421
422
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200423-(BOOL) readSetEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000424{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200425 return YES;
426}
427
428
429-(BOOL) readListBeginReturningElementType:(SInt32 *)elementType
430 size:(SInt32 *)size
431 error:(NSError *__autoreleasing *)error
432{
433 UInt8 et;
434 if (![self readByte:&et error:error]) {
435 return NO;
436 }
437
438 SInt32 s;
439 if (![self readI32:&s error:error]) {
440 return NO;
441 }
442
Mark Slee7e9eea42007-09-10 21:00:23 +0000443 if (elementType != NULL) {
444 *elementType = et;
445 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200446
Mark Slee7e9eea42007-09-10 21:00:23 +0000447 if (size != NULL) {
448 *size = s;
449 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200450
451 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000452}
453
454
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200455-(BOOL) readListEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000456{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200457 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000458}
459
460
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200461
462-(BOOL) writeMessageBeginWithName:(NSString *)name
463 type:(SInt32)messageType
464 sequenceID:(SInt32)sequenceID
465 error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000466{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200467 if (_strictWrite) {
468
469 int version = VERSION_1 | messageType;
470
471 if (![self writeI32:version error:error]) {
472 return NO;
473 }
474
475 if (![self writeString:name error:error]) {
476 return NO;
477 }
478
479 if (![self writeI32:sequenceID error:error]) {
480 return NO;
481 }
Mark Slee7e9eea42007-09-10 21:00:23 +0000482 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200483 else {
484
485 if (![self writeString:name error:error]) {
486 return NO;
487 }
488
489 if (![self writeByte:messageType error:error]) {
490 return NO;
491 }
492
493 if (![self writeI32:sequenceID error:error]) {
494 return NO;
495 }
496 }
497
498 _currentMessageName = name;
499
500 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000501}
502
503
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200504-(BOOL) writeMessageEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000505{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200506 _currentMessageName = nil;
507 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000508}
509
510
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200511-(BOOL) writeStructBeginWithName:(NSString *)name
512 error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000513{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200514 return YES;
515}
516
517
518-(BOOL) writeStructEnd:(NSError *__autoreleasing *)error
519{
520 return YES;
521}
522
523
524-(BOOL) writeFieldBeginWithName:(NSString *)name
525 type:(SInt32)fieldType
526 fieldID:(SInt32)fieldID
527 error:(NSError *__autoreleasing *)error
528{
529 if (![self writeByte:fieldType error:error]) {
530 return NO;
531 }
532
533 if (![self writeI16:fieldID error:error]) {
534 return NO;
535 }
536
537 return YES;
538}
539
540
541-(BOOL) writeBool:(BOOL)value error:(NSError *__autoreleasing *)error
542{
543 return [self writeByte:(value ? 1 : 0) error:error];
544}
545
546
547-(BOOL) writeByte:(UInt8)value error:(NSError *__autoreleasing *)error
548{
549 if (![_transport write:&value offset:0 length:1 error:error]) {
550 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
551 }
552 return YES;
553}
554
555
556-(BOOL) writeI16:(short)value error:(NSError *__autoreleasing *)error
557{
558 UInt8 buff[2];
559 buff[0] = 0xff & (value >> 8);
560 buff[1] = 0xff & value;
561
562 if (![_transport write:buff offset:0 length:2 error:error]) {
563 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
564 }
565
566 return YES;
567}
568
569
570-(BOOL) writeI32:(SInt32)value error:(NSError *__autoreleasing *)error
571{
572 UInt8 buff[4];
Mark Slee7e9eea42007-09-10 21:00:23 +0000573 buff[0] = 0xFF & (value >> 24);
574 buff[1] = 0xFF & (value >> 16);
575 buff[2] = 0xFF & (value >> 8);
576 buff[3] = 0xFF & value;
Mark Slee7e9eea42007-09-10 21:00:23 +0000577
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200578 if (![_transport write:buff offset:0 length:4 error:error]) {
579 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
580 }
581
582 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000583}
584
585
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200586-(BOOL) writeI64:(SInt64)value error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000587{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200588 UInt8 buff[8];
Mark Slee7e9eea42007-09-10 21:00:23 +0000589 buff[0] = 0xFF & (value >> 56);
590 buff[1] = 0xFF & (value >> 48);
591 buff[2] = 0xFF & (value >> 40);
592 buff[3] = 0xFF & (value >> 32);
593 buff[4] = 0xFF & (value >> 24);
594 buff[5] = 0xFF & (value >> 16);
595 buff[6] = 0xFF & (value >> 8);
596 buff[7] = 0xFF & value;
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200597
598 if (![_transport write:buff offset:0 length:8 error:error]) {
599 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
600 }
601
602 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000603}
604
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200605
606-(BOOL) writeDouble:(double)value error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000607{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200608 // FIXME - will this get us in trouble on PowerPC?
609 if (![self writeI64:*(SInt64 *)&value error:error]) {
610 return NO;
611 }
612
613 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000614}
615
Mark Sleeaa3c5a82007-09-19 21:12:52 +0000616
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200617-(BOOL) writeString:(NSString *)value error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000618{
Mark Sleeaa3c5a82007-09-19 21:12:52 +0000619 if (value != nil) {
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200620
621 const char *utf8Bytes = [value UTF8String];
622
623 SInt32 length = (SInt32)strlen(utf8Bytes);
624 if (![self writeI32:length error:error]) {
625 return NO;
626 }
627
628 if (![_transport write:(UInt8 *)utf8Bytes offset:0 length:(int)length error:error]) {
629 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
630 }
631
632 }
633 else {
634
Mark Slee77575e62007-09-24 19:24:53 +0000635 // instead of crashing when we get null, let's write out a zero
636 // length string
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200637 if (![self writeI32:0 error:error]) {
638 return NO;
639 }
640
Mark Sleeaa3c5a82007-09-19 21:12:52 +0000641 }
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200642
643 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000644}
645
646
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200647-(BOOL) writeBinary:(NSData *)data error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000648{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200649 if (![self writeI32:(SInt32)data.length error:error]) {
650 return NO;
651 }
Mark Slee7e9eea42007-09-10 21:00:23 +0000652
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200653 if (![_transport write:data.bytes offset:0 length:(UInt32)data.length error:error]) {
654 PROTOCOL_TRANSPORT_ERROR(NO, error, @"Transport write failed");
655 }
656
657 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000658}
659
660
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200661-(BOOL) writeFieldStop:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000662{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200663 if (![self writeByte:TTypeSTOP error:error]) {
664 return NO;
665 }
666
667 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000668}
669
Mark Slee7e9eea42007-09-10 21:00:23 +0000670
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200671-(BOOL) writeFieldEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000672{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200673 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000674}
675
Mark Slee7e9eea42007-09-10 21:00:23 +0000676
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200677-(BOOL) writeMapBeginWithKeyType:(SInt32)keyType
678 valueType:(SInt32)valueType
679 size:(SInt32)size
680 error:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000681{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200682 if (![self writeByte:keyType error:error]) {
683 return NO;
684 }
685 if (![self writeByte:valueType error:error]) {
686 return NO;
687 }
688 if (![self writeI32:(int)size error:error]) {
689 return NO;
690 }
691 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000692}
693
Mark Slee7e9eea42007-09-10 21:00:23 +0000694
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200695-(BOOL) writeMapEnd:(NSError *__autoreleasing *)error
Mark Slee7e9eea42007-09-10 21:00:23 +0000696{
Jens Geyer56e5b9b2015-10-09 22:01:55 +0200697 return YES;
698}
699
700
701-(BOOL) writeSetBeginWithElementType:(SInt32)elementType
702 size:(SInt32)size
703 error:(NSError *__autoreleasing *)error
704{
705 if (![self writeByte:elementType error:error]) {
706 return NO;
707 }
708 if (![self writeI32:size error:error]) {
709 return NO;
710 }
711 return YES;
712}
713
714
715-(BOOL) writeSetEnd:(NSError *__autoreleasing *)error
716{
717 return YES;
718}
719
720
721-(BOOL) writeListBeginWithElementType:(SInt32)elementType
722 size:(SInt32)size
723 error:(NSError *__autoreleasing *)error
724{
725 if (![self writeByte:elementType error:error]) {
726 return NO;
727 }
728 if (![self writeI32:size error:error]) {
729 return NO;
730 }
731 return YES;
732}
733
734
735-(BOOL) writeListEnd:(NSError *__autoreleasing *)error
736{
737 return YES;
Mark Slee7e9eea42007-09-10 21:00:23 +0000738}
739
740@end