]> rtime.felk.cvut.cz Git - orte.git/blob - orte/liborte/cdr.c
37411b5de346ce90949b035962913a82b8b1bd6a
[orte.git] / orte / liborte / cdr.c
1 /*
2  *  $Id: cdr.c,v 0.0.0.1                2004/11/26
3  *
4  *  DEBUG:  section 5                   CDR codeing
5  *
6  *  -------------------------------------------------------------------  
7  *                                ORTE                                 
8  *                      Open Real-Time Ethernet                       
9  *                                                                    
10  *                      Copyright (C) 2001-2006                       
11  *  Department of Control Engineering FEE CTU Prague, Czech Republic  
12  *                      http://dce.felk.cvut.cz                       
13  *                      http://www.ocera.org                          
14  *                                                                    
15  *  Author:              Petr Smolik    petr.smolik@wo.cz             
16  *  Advisor:             Pavel Pisa                                   
17  *  Project Responsible: Zdenek Hanzalek                              
18  *  --------------------------------------------------------------------
19  *
20  *  This program is free software; you can redistribute it and/or modify
21  *  it under the terms of the GNU General Public License as published by
22  *  the Free Software Foundation; either version 2 of the License, or
23  *  (at your option) any later version.
24  *
25  *  This program is distributed in the hope that it will be useful,
26  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
27  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  *  GNU General Public License for more details.
29  *
30  *  This module maintains a hash table of key/value pairs.
31  *  Keys can be strings of any size, or numbers up to size
32  *  unsigned long (HASHKEYTYPE).
33  *  Values should be a pointer to some data you wish to store.
34  *
35  *  Original of source was from ORBit: A CORBA v2.2 ORB
36  *
37  */
38
39 #include "orte_all.h"
40
41 #define CDR_GROW_AMOUNT 128
42
43 CORBA_boolean 
44 CDR_buffer_init(CDR_Codec *codec, const unsigned int size)
45 {
46
47         if(codec->release_buffer) {
48                 FREE(codec->buffer);
49         }
50
51         codec->buffer=(CORBA_octet *)MALLOC(size);
52         codec->buf_len=size;
53         codec->wptr_max=size;
54         codec->rptr=codec->wptr=0;
55         codec->release_buffer=CORBA_TRUE;
56
57         return CORBA_TRUE;
58 }
59
60 /*
61 CORBA_boolean 
62 CDR_buffer_grow(CDR_Codec *codec, const unsigned int growth)
63 {
64         unsigned int real_growth,quot;
65
66         if(codec->release_buffer) {
67                 quot = growth / CDR_GROW_AMOUNT;
68                 real_growth=CDR_GROW_AMOUNT * (quot+1);
69                 
70                 codec->buffer=(CORBA_octet *)REALLOC(codec->buffer,
71                                                      codec->buf_len
72                                                      +real_growth);
73         }
74
75         return CORBA_TRUE;
76 }
77 */
78 CORBA_boolean 
79 CDR_buffer_puts(CDR_Codec *codec, const void *data, const unsigned int len)
80 {
81         if(codec->wptr+len > codec->wptr_max) {
82                 return CORBA_FALSE; 
83         }
84
85         memcpy(&codec->buffer[codec->wptr], data, len);
86         codec->wptr+=len;
87
88         return CORBA_TRUE;
89 }
90
91 CORBA_boolean 
92 CDR_buffer_gets(CDR_Codec *codec, void *dest, const unsigned int len)
93 {
94         if(codec->rptr+len > codec->buf_len) {
95                 return CORBA_FALSE; 
96         }
97
98         memcpy(dest, &codec->buffer[codec->rptr], len);
99         codec->rptr+=len;
100
101         return CORBA_TRUE;
102 }
103
104 CORBA_boolean 
105 CDR_buffer_put(CDR_Codec *codec, void *datum)
106 {
107         if(codec->wptr+1 > codec->wptr_max) {
108                 return(CORBA_FALSE);
109         }
110
111         codec->buffer[codec->wptr++]=*(unsigned char *)datum;
112         return CORBA_TRUE;
113 }
114
115 CORBA_boolean 
116 CDR_buffer_get(CDR_Codec *codec, void *dest)
117 {
118         if(codec->rptr+1 > codec->buf_len) {
119                 return(CORBA_FALSE);
120         }
121
122         *(CORBA_octet *)dest=codec->buffer[codec->rptr++];
123         return CORBA_TRUE;
124 }
125
126 #define CDR_buffer_put2(codec, datum) CDR_buffer_putn(codec, datum, 2)
127 #define CDR_buffer_put4(codec, datum) CDR_buffer_putn(codec, datum, 4)
128 #define CDR_buffer_put8(codec, datum) CDR_buffer_putn(codec, datum, 8)
129 #define CDR_buffer_put16(codec, datum) CDR_buffer_putn(codec, datum, 16)
130 #define CDR_buffer_get2(codec, dest) CDR_buffer_getn(codec, dest, 2)
131 #define CDR_buffer_get4(codec, dest) CDR_buffer_getn(codec, dest, 4)
132 #define CDR_buffer_get8(codec, dest) CDR_buffer_getn(codec, dest, 8)
133 #define CDR_buffer_get16(codec, dest) CDR_buffer_getn(codec, dest, 16)
134
135 static CORBA_boolean
136 CDR_buffer_getn(CDR_Codec *codec, void *dest, int bsize)
137 {
138         codec->rptr = (unsigned long)ALIGN_ADDRESS(codec->rptr, bsize);
139         if(codec->host_endian==codec->data_endian)
140                 memcpy(dest, codec->buffer + codec->rptr, bsize);
141         else
142                 rtps_byteswap(dest, codec->buffer + codec->rptr, bsize);
143         codec->rptr += bsize;
144
145         return CORBA_TRUE;
146 }
147
148 static CORBA_boolean
149 CDR_buffer_putn(CDR_Codec *codec, void *datum, int bsize)
150 {
151         unsigned long forward,i;
152         
153         forward = (unsigned long)ALIGN_ADDRESS(codec->wptr, bsize);
154         if (forward+bsize > codec->wptr_max) {
155                 return CORBA_FALSE;
156         }       
157
158         i = codec->wptr;
159         while(forward > i)
160                 codec->buffer[i++] = '\0';
161
162         codec->wptr = forward;
163         if(codec->host_endian==codec->data_endian)
164                 memcpy(codec->buffer + codec->wptr, datum, bsize);
165         else
166                 rtps_byteswap(codec->buffer + codec->wptr, datum, bsize);
167         codec->wptr += bsize;
168
169         return CORBA_TRUE;
170 }
171
172 #define CDR_swap2(d,s) rtps_byteswap((d), (s), 2)
173 #define CDR_swap4(d,s) rtps_byteswap((d), (s), 4)
174 #define CDR_swap8(d,s) rtps_byteswap((d), (s), 8)
175 #define CDR_swap16(d,s) rtps_byteswap((d), (s), 16)
176
177 inline CORBA_boolean 
178 CDR_put_short(CDR_Codec *codec, CORBA_short s)
179 {
180         return CDR_buffer_put2(codec, &s);
181 }
182
183 inline CORBA_boolean 
184 CDR_get_short(CDR_Codec *codec, CORBA_short *s)
185 {
186         return CDR_buffer_get2(codec, s);
187 }
188
189 inline CORBA_boolean 
190 CDR_put_ushort(CDR_Codec *codec, CORBA_unsigned_short us)
191 {
192         return CDR_buffer_put2(codec, &us);
193 }
194
195 inline CORBA_boolean 
196 CDR_get_ushort(CDR_Codec *codec, CORBA_unsigned_short *us)
197 {
198         return CDR_buffer_get2(codec, us);
199 }
200
201 inline CORBA_boolean 
202 CDR_put_long(CDR_Codec *codec, CORBA_long l)
203 {
204         return CDR_buffer_put4(codec, &l);
205 }
206
207 inline CORBA_boolean 
208 CDR_get_long(CDR_Codec *codec, CORBA_long *l)
209 {
210         return CDR_buffer_get4(codec, l);
211 }
212
213 inline CORBA_boolean 
214 CDR_put_ulong(CDR_Codec *codec, CORBA_unsigned_long ul)
215 {
216         return CDR_buffer_put4(codec, &ul);
217 }
218
219 inline CORBA_boolean 
220 CDR_get_ulong(CDR_Codec *codec, CORBA_unsigned_long *ul)
221 {
222         return CDR_buffer_get4(codec, ul);
223 }
224
225 #ifdef HAVE_CORBA_LONG_LONG
226 inline CORBA_boolean 
227 CDR_get_long_long(CDR_Codec *codec, CORBA_long_long *ul)
228 {
229         return CDR_buffer_get8(codec, ul);
230 }
231
232 inline CORBA_boolean 
233 CDR_put_long_long(CDR_Codec *codec, CORBA_long_long ll)
234 {
235         return CDR_buffer_put8(codec, &ll);
236 }
237
238 inline CORBA_boolean 
239 CDR_put_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long ll)
240 {
241         return CDR_buffer_put8(codec, &ll);
242 }
243
244 inline CORBA_boolean 
245 CDR_get_ulong_long(CDR_Codec *codec, CORBA_unsigned_long_long *ull)
246 {
247         return CDR_buffer_get8(codec, ull);
248 }
249 #endif
250
251 inline CORBA_boolean 
252 CDR_put_float(CDR_Codec *codec, CORBA_float f)
253 {
254         return CDR_buffer_put4(codec, &f);
255 }
256
257 inline CORBA_boolean 
258 CDR_get_float(CDR_Codec *codec, CORBA_float *f)
259 {
260         return CDR_buffer_get4(codec, f);
261 }
262
263 inline CORBA_boolean 
264 CDR_put_double(CDR_Codec *codec, CORBA_double d)
265 {
266         return CDR_buffer_put8(codec, &d);
267 }
268
269 inline CORBA_boolean 
270 CDR_get_double(CDR_Codec *codec, CORBA_double *d)
271 {
272         return CDR_buffer_get8(codec, d);
273 }
274
275 inline CORBA_boolean 
276 CDR_put_long_double(CDR_Codec *codec, CORBA_long_double ld)
277 {
278         return CDR_buffer_put16(codec, &ld);
279 }
280
281 inline CORBA_boolean 
282 CDR_put_octet(CDR_Codec *codec, CORBA_octet datum)
283 {
284         return CDR_buffer_put(codec, &datum);
285 }
286
287 inline CORBA_boolean 
288 CDR_get_octet(CDR_Codec *codec, CORBA_octet *datum)
289 {
290         return(CDR_buffer_get(codec, datum));
291 }
292
293 inline CORBA_boolean 
294 CDR_put_octets(CDR_Codec *codec, void *data, unsigned long len)
295 {
296         return CDR_buffer_puts(codec, data, len);
297 }
298
299 inline CORBA_boolean 
300 CDR_put_char(CDR_Codec *codec, CORBA_char c)
301 {
302         return CDR_buffer_put(codec, &c);
303 }
304
305 inline CORBA_boolean 
306 CDR_get_char(CDR_Codec *codec, CORBA_char *c)
307 {
308         return CDR_buffer_get(codec, c);
309 }
310
311 inline CORBA_boolean 
312 CDR_put_boolean(CDR_Codec *codec, CORBA_boolean datum)
313 {
314         datum = datum&&1;
315         return CDR_buffer_put(codec, &datum);
316 }
317
318 inline CORBA_boolean 
319 CDR_get_boolean(CDR_Codec *codec, CORBA_boolean *b)
320 {
321         return CDR_buffer_get(codec, b);
322 }
323
324 CORBA_boolean 
325 CDR_put_string(CDR_Codec *codec, const char *str)
326 {
327         unsigned int len;
328
329         len=strlen(str)+1;
330
331         if (CDR_put_ulong(codec, len)==CORBA_FALSE) return -1;
332         return CDR_buffer_puts(codec, str, len);
333 }
334
335 CORBA_boolean 
336 CDR_get_string_static(CDR_Codec *codec,CORBA_char **str)
337 {
338         CORBA_unsigned_long len;
339
340         if(CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
341                 return CORBA_FALSE;
342
343         if((codec->rptr + len) > codec->buf_len)
344                 return CORBA_FALSE;
345
346         *str = ((CORBA_char *)codec->buffer) + codec->rptr;
347
348         codec->rptr += len;
349
350         return CORBA_TRUE;
351 }
352
353 CORBA_boolean 
354 CDR_get_string(CDR_Codec *codec, CORBA_char **str)
355 {
356         CORBA_unsigned_long len;
357
358         if(CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
359                 return(CORBA_FALSE);
360
361         if(len==0)
362                 return(CORBA_FALSE);
363
364         *str=MALLOC(len);
365
366         if(CDR_buffer_gets(codec, *str, len)==CORBA_FALSE) {
367                 FREE(*str);
368                 return(CORBA_FALSE);
369         }
370
371         if((*str)[len-1]!='\0') {
372                 (*str)[len-1]='\0';
373         }
374
375         return(CORBA_TRUE);
376 }
377
378 CORBA_boolean 
379 CDR_get_string_buff(CDR_Codec *codec, CORBA_char *str)
380 {
381         CORBA_unsigned_long len;
382
383         if(CDR_get_ulong(codec, (CORBA_unsigned_long *)&len)==CORBA_FALSE)
384                 return(CORBA_FALSE);
385
386         if(len==0)
387                 return(CORBA_FALSE);
388
389         if(CDR_buffer_gets(codec, str, len)==CORBA_FALSE) {
390                 return(CORBA_FALSE);
391         }
392
393         if(str[len-1]!='\0') {
394                 str[len-1]='\0';
395         }
396
397         return(CORBA_TRUE);
398 }
399
400 CORBA_boolean 
401 CDR_get_seq_begin(CDR_Codec *codec, CORBA_unsigned_long *ul)
402 {
403         return(CDR_get_ulong(codec, (CORBA_unsigned_long *)ul));
404 }
405
406 CDR_Codec *
407 CDR_codec_init_static(CDR_Codec *codec)
408 {
409         memset(codec, 0, sizeof(CDR_Codec));
410
411         codec->host_endian = FLAG_ENDIANNESS;
412
413         return codec;
414 }
415
416 CDR_Codec *
417 CDR_codec_init(void)
418 {
419         CDR_Codec *c;
420
421         c=MALLOC(sizeof(CDR_Codec));
422         CDR_codec_init_static(c);
423
424         return(c);
425 }
426
427 void 
428 CDR_codec_release_buffer(CDR_Codec *codec)
429 {
430         if(codec->release_buffer)
431                 FREE(codec->buffer);
432 }
433
434
435 void 
436 CDR_codec_free(CDR_Codec *codec)
437 {
438         CDR_codec_release_buffer(codec);
439         FREE(codec);
440 }