2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 # include <sys/types.h>
28 # if HAVE_SYS_SOCKET_H
29 # include <sys/socket.h>
31 # if HAVE_NETINET_IN_H
32 # include <netinet/in.h>
34 # include <arpa/inet.h>
38 #include "NGStream+serialization.h"
41 # include <objc/objc-class.h>
44 @implementation NGStream(serialization)
48 - (void)serializeChar:(char)_value {
49 NGStreamSerializeObjC(self, &_value, @encode(char), nil);
51 - (void)serializeShort:(short)_value {
52 NGStreamSerializeObjC(self, &_value, @encode(short), nil);
54 - (void)serializeInt:(int)_value {
55 NGStreamSerializeObjC(self, &_value, @encode(int), nil);
57 - (void)serializeLong:(long)_value {
58 NGStreamSerializeObjC(self, &_value, @encode(long), nil);
61 - (void)serializeFloat:(float)_value {
62 NGStreamSerializeObjC(self, &_value, @encode(float), nil);
64 - (void)serializeDouble:(double)_value {
65 NGStreamSerializeObjC(self, &_value, @encode(double), nil);
67 - (void)serializeLongLong:(long long)_value {
68 NGStreamSerializeObjC(self, &_value, @encode(long long), nil);
71 - (void)serializeCString:(const char *)_value {
72 NGStreamSerializeObjC(self, &_value, @encode(char *), nil);
76 - (void)serializeDataAt:(const void*)_value ofObjCType:(const char*)_type
77 context:(id<NSObjCTypeSerializationCallBack>)_callback
79 NGStreamSerializeObjC(self, _value, _type, _callback);
85 - (char)deserializeChar {
87 NGStreamDeserializeObjC(self, &c, @encode(char), nil);
90 - (short)deserializeShort {
92 NGStreamDeserializeObjC(self, &s, @encode(short), nil);
95 - (int)deserializeInt {
97 NGStreamDeserializeObjC(self, &i, @encode(int), nil);
100 - (long)deserializeLong {
102 NGStreamDeserializeObjC(self, &l, @encode(long), nil);
105 - (float)deserializeFloat {
107 NGStreamDeserializeObjC(self, &f, @encode(float), nil);
111 - (double)deserializeDouble {
113 NGStreamDeserializeObjC(self, &d, @encode(double), nil);
116 - (long long)deserializeLongLong {
118 NGStreamDeserializeObjC(self, &l, @encode(long long), nil);
122 - (char *)deserializeCString {
124 NGStreamDeserializeObjC(self, &result, @encode(char *), nil);
129 - (void)deserializeDataAt:(void *)_value ofObjCType:(const char *)_type
130 context:(id<NSObjCTypeSerializationCallBack>)_callback
132 NGStreamDeserializeObjC(self, _value, _type, _callback);
138 void NGStreamSerializeObjC(id<NGStream> self,
139 const void *_value, const char *_type,
141 id<NSObjCTypeSerializationCallBack> _callback
150 [_callback serializeObjectAt:(id *)_value
152 intoData:(NSMutableData *)self];
156 const char *cstr = *(char **)_value;
157 int len = cstr ? (int)strlen(cstr) : -1;
159 NGStreamSerializeObjC(self, &len, @encode(int), _callback);
161 [self safeWriteBytes:cstr count:len];
167 int i, offset, itemSize, count;
169 count = atoi(_type + 1); // skip '[' and get dimension
171 while (isdigit((int)*++_type)) ; // skip '[' and dimension
172 itemSize = objc_sizeof_type(_type);
174 for (i = offset = 0; i < count; i++, offset += itemSize)
175 NGStreamSerializeObjC(self, (char *)_value + offset, _type, _callback);
182 while ((*_type != _C_STRUCT_E) && (*_type++ != '=')) ; // skip '<name>='
185 NGStreamSerializeObjC(self, (char *)_value + offset, _type, _callback);
187 offset += objc_sizeof_type(_type);
188 _type = objc_skip_typespec(_type);
190 if (*_type != _C_STRUCT_E) {
191 int align, remainder;
193 align = objc_alignof_type(_type);
194 if ((remainder = offset % align))
195 offset += align - remainder;
197 else // done with structure
204 NGStreamSerializeObjC(self, *(char **)_value, _type + 1, _callback);
209 [self safeWriteBytes:_value count:1];
214 short netValue = htons(*(short *)_value);
215 [self safeWriteBytes:&netValue count:2];
221 int netValue = htonl(*(int *)_value);
222 [self safeWriteBytes:&netValue count:4];
228 long netValue = htonl(*(long *)_value);
229 [self safeWriteBytes:&netValue count:sizeof(long)];
238 fc.value = *(float *)_value;
239 fc.ul = htonl(fc.ul);
240 [self safeWriteBytes:&fc count:sizeof(unsigned long)];
244 [self safeWriteBytes:_value count:8];
249 NSCAssert1(0, @"unsupported C type %s ..", _type);
254 void NGStreamDeserializeObjC(id<NGStream> self,
255 void *_value, const char *_type,
257 id<NSObjCTypeSerializationCallBack> _callback
263 if ((_value == NULL) || (_type == NULL))
269 [_callback deserializeObjectAt:(id *)_value
271 fromData:(NSData *)self
275 case _C_CHARPTR: { // malloced C-string
278 NGStreamDeserializeObjC(self, &len, @encode(int), _callback);
280 if (len == -1) // NULL-string
281 *(char **)_value = NULL;
285 #if NeXT_Foundation_LIBRARY
286 result = NSZoneMalloc(NULL, len + 1);
288 result = NSZoneMallocAtomic(NULL, len + 1);
292 if (len > 0) [self safeReadBytes:result count:len];
293 *(char **)_value = result;
299 int i, offset, itemSize, count;
301 count = atoi(_type + 1); // skip '[' and get dimension
303 while (isdigit((int)*++_type)) ; // skip '[' and dimension
304 itemSize = objc_sizeof_type(_type);
306 for (i = offset = 0; i < count; i++, offset += itemSize)
307 NGStreamDeserializeObjC(self, (char *)_value + offset, _type, _callback);
315 while ((*_type != _C_STRUCT_E) && (*_type++ != '=')) ; // skip '<name>='
318 NGStreamDeserializeObjC(self, (char *)_value + offset, _type, _callback);
320 offset += objc_sizeof_type(_type);
321 _type = objc_skip_typespec(_type);
323 if (*_type != _C_STRUCT_E) {
324 int align, remainder;
326 align = objc_alignof_type(_type);
327 if ((remainder = offset % align))
328 offset += align - remainder;
330 else // done with structure
337 // skip '^', type of the value the ptr points to
340 result = NSZoneMalloc(NULL, objc_sizeof_type(_type + 1));
342 NGStreamDeserializeObjC(self, result, _type + 1, _callback);
344 *(char **)_value = result;
352 [self safeReadBytes:_value count:1];
357 [self safeReadBytes:_value count:2];
358 *(short *)_value = ntohs(*(short *)_value);
363 [self safeReadBytes:_value count:4];
364 *(int *)_value = ntohl(*(int *)_value);
369 [self safeReadBytes:_value count:4];
370 *(long *)_value = ntohl(*(long *)_value);
374 [self safeReadBytes:_value count:4];
375 *(long *)_value = ntohl(*(long *)_value);
379 [self safeReadBytes:_value count:8];
384 NSLog(@"unsupported C type %s ..", _type);
389 void __link_NGStream_serialization(void) {
390 __link_NGStream_serialization();