Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
posh.cpp
Go to the documentation of this file.
1 
8 #include "posh.h"
9 
10 #if !defined POSH_NO_FLOAT
11 # define POSH_FLOAT_STRING "enabled"
12 #else
13 # define POSH_FLOAT_STRING "disabled"
14 #endif
15 
16 #if defined POSH_64BIT_INTEGER
17 # define POSH_64BIT_INTEGER_STRING "yes"
18 #else
19 # define POSH_64BIT_INTEGER_STRING "no"
20 #endif
21 
22 #if defined POSH_64BIT_POINTER
23 # define POSH_POINTER_STRING "64-bits"
24 #else
25 # define POSH_POINTER_STRING "32-bits"
26 #endif
27 
28 #if defined POSH_LITTLE_ENDIAN
29 # define IS_BIG_ENDIAN 0
30 
31 # define NATIVE16 POSH_LittleU16
32 # define NATIVE32 POSH_LittleU32
33 # define NATIVE64 POSH_LittleU64
34 # define FOREIGN16 POSH_BigU16
35 # define FOREIGN32 POSH_BigU32
36 # define FOREIGN64 POSH_BigU64
37 #else
38 # define IS_BIG_ENDIAN 1
39 
40 # define NATIVE16 POSH_BigU16
41 # define NATIVE32 POSH_BigU32
42 # define NATIVE64 POSH_BigU64
43 # define FOREIGN16 POSH_LittleU16
44 # define FOREIGN32 POSH_LittleU32
45 # define FOREIGN64 POSH_LittleU64
46 #endif
47 
48 static
49 int s_testBigEndian( void )
50 {
51  union
52  {
53  posh_byte_t c[4];
54  posh_u32_t i;
55  }
56  u;
57 
58  u.i = 1;
59  if (u.c[0] == 1)
60  return 0;
61  return 1;
62 }
63 
64 static
65 const char * s_testSerialization( void )
66 {
67  posh_byte_t serbuf[8];
68  posh_u16_t tmp16;
69  posh_u32_t tmp32;
70 
71  /* 16-bit serialization */
72  POSH_WriteU16ToLittle( serbuf, 0xABCD );
73  if ( ( tmp16 = POSH_ReadU16FromLittle( serbuf ) ) != 0xABCD )
74  return "*ERROR: failed little-endian 16-bit serialization test";
75  POSH_WriteU16ToBig( serbuf, 0xABCD );
76  if ( ( tmp16 = POSH_ReadU16FromBig( serbuf ) ) != 0xABCD )
77  return "*ERROR: failed big-endian 16-bit serialization test";
78  /* 32-bit serialization */
79  POSH_WriteU32ToLittle( serbuf, 0xABCD1234L );
80  if ( ( tmp32 = POSH_ReadU32FromLittle( serbuf ) ) != 0xABCD1234 )
81  return "*ERROR: failed little-endian 32-bit serialization test";
82  POSH_WriteU32ToBig( serbuf, 0xABCD1234L );
83  if ( ( tmp32 = POSH_ReadU32FromBig( serbuf ) ) != 0xABCD1234 )
84  return "*ERROR: failed big-endian 32-bit serialization test";
85 #if defined POSH_64BIT_INTEGER
86  {
87 #define REF64 POSH_U64( 0xFEDCBA9876543210 )
88 
89  posh_u64_t tmp64;
90 
91  POSH_WriteU64ToLittle( serbuf, REF64 );
92  if ( ( tmp64 = POSH_ReadU64FromLittle( serbuf ) ) != REF64 )
93  return "*ERROR: failed little-endian 64-bit serialization test";
94  POSH_WriteU64ToBig( serbuf, REF64 );
95  if ( ( tmp64 = POSH_ReadU64FromBig( serbuf ) ) != REF64 )
96  return "*ERROR: failed big-endian 64-bit serialization test";
97  }
98 #endif
99 
100  return 0;
101 }
102 
103 #if !defined POSH_NO_FLOAT
104 static
105 const char * s_testFloatingPoint( void )
106 {
107  float fRef = 10.0f/30.0f;
108  double dRef = 10.0/30.0;
109  posh_byte_t dbuf[8];
110  float fTmp;
111  double dTmp;
112 
114  if (fTmp != fRef)
115  return "*ERROR: POSH little endian floating point conversion failed. Please report this to poshlib@poshlib.org!\n";
116  fTmp = POSH_FloatFromBigBits( POSH_BigFloatBits( fRef ) );
117  if (fTmp != fRef)
118  return "*ERROR: POSH big endian floating point conversion failed. Please report this to poshlib@poshlib.org!\n";
119  POSH_DoubleBits( dRef, dbuf );
120 
121  dTmp = POSH_DoubleFromBits( dbuf );
122  if (dTmp != dRef)
123  return
124  "*ERROR: POSH double precision floating point serialization failed. Please report this to poshlib@poshlib.org!\n";
125  return 0;
126 }
127 #endif /* !defined POSH_NO_FLOAT */
128 
129 static
130 const char * s_testEndianess( void )
131 {
132  /* check endianess */
134  return
135  "*ERROR: POSH compile time endianess does not match run-time endianess verification. Please report this to poshlib@poshlib.org!\n";
136  /* make sure our endian swap routines work */
137  if ( (NATIVE32( 0x11223344L ) != 0x11223344L)
138  || (FOREIGN32( 0x11223344L ) != 0x44332211L)
139  || (NATIVE16( 0x1234 ) != 0x1234)
140  || (FOREIGN16( 0x1234 ) != 0x3412) )
141  return "*ERROR: POSH endianess macro selection failed. Please report this to poshlib@poshlib.org!\n";
142  /* test serialization routines */
143 
144  return 0;
145 }
146 
159 const char * POSH_GetArchString( void )
160 {
161  const char *err;
162  const char *s = "OS:.............." POSH_OS_STRING "\n"
163  "CPU:............." POSH_CPU_STRING "\n"
164  "endian:.........." POSH_ENDIAN_STRING "\n"
165  "ptr size:........" POSH_POINTER_STRING "\n"
166  "64-bit ints......" POSH_64BIT_INTEGER_STRING "\n"
167  "floating point..." POSH_FLOAT_STRING "\n";
168 
169  /* test endianess */
170  err = s_testEndianess();
171  if (err != 0)
172  return err;
173  /* test serialization */
174  err = s_testSerialization();
175  if (err != 0)
176  return err;
177 #if !defined POSH_NO_FLOAT
178  /* check that our floating point support is correct */
179  err = s_testFloatingPoint();
180  if (err != 0)
181  return err;
182 #endif
183 
184  return s;
185 }
186 
187 /*
188  * ---------------------------------------------------------------------------
189  * BYTE SWAPPING SUPPORT
190  * ---------------------------------------------------------------------------
191  */
199 {
200  posh_u16_t swapped;
201 
202  swapped = v<<8;
203  swapped |= v>>8;
204 
205  return swapped;
206 }
207 
218 {
219  return (posh_s16_t) POSH_SwapU16( v );
220 }
221 
229 {
230  posh_u32_t swapped;
231 
232  swapped = (v&0xFF)<<24;
233  swapped |= (v&0xFF00)<<8;
234  swapped |= (v>>8)&0xFF00;
235  swapped |= (v>>24);
236 
237  return swapped;
238 }
239 
250 {
251  return (posh_s32_t) POSH_SwapU32( (posh_u32_t) v );
252 }
253 
254 #if defined POSH_64BIT_INTEGER
255 
262 posh_u64_t POSH_SwapU64( posh_u64_t v )
263 {
264  posh_byte_t tmp;
265  union
266  {
267  posh_byte_t bytes[8];
268  posh_u64_t u64;
269  }
270  u;
271 
272  u.u64 = v;
273 
274  tmp = u.bytes[0];
275  u.bytes[0] = u.bytes[7];
276  u.bytes[7] = tmp;
277  tmp = u.bytes[1];
278  u.bytes[1] = u.bytes[6];
279  u.bytes[6] = tmp;
280  tmp = u.bytes[2];
281  u.bytes[2] = u.bytes[5];
282  u.bytes[5] = tmp;
283  tmp = u.bytes[3];
284  u.bytes[3] = u.bytes[4];
285  u.bytes[4] = tmp;
286 
287  return u.u64;
288 }
289 
297 posh_s64_t POSH_SwapS64( posh_s64_t v )
298 {
299  return (posh_s64_t) POSH_SwapU64( (posh_u64_t) v );
300 }
301 
302 #endif /* defined POSH_64BIT_INTEGER */
303 
304 /*
305  * ---------------------------------------------------------------------------
306  * IN-MEMORY SERIALIZATION
307  * ---------------------------------------------------------------------------
308  */
309 
319 {
320  posh_u16_t *p16 = (posh_u16_t*) dst;
321 
322  *p16 = POSH_LittleU16( value );
323 
324  return p16+2;
325 }
326 
337 {
338  return (posh_s16_t*) POSH_WriteU16ToLittle( dst, (posh_u16_t) value );
339 }
340 
350 {
351  posh_u32_t *p32 = (posh_u32_t*) dst;
352 
353  *p32 = POSH_LittleU32( value );
354 
355  return p32+4;
356 }
357 
368 {
369  return (posh_s32_t*) POSH_WriteU32ToLittle( dst, (posh_u32_t) value );
370 }
371 
381 {
382  posh_u16_t *p16 = (posh_u16_t*) dst;
383 
384  *p16 = POSH_BigU16( value );
385 
386  return p16+2;
387 }
388 
399 {
400  return (posh_s16_t*) POSH_WriteU16ToBig( dst, (posh_u16_t) value );
401 }
402 
412 {
413  posh_u32_t *p32 = (posh_u32_t*) dst;
414 
415  *p32 = POSH_BigU32( value );
416 
417  return p32+4;
418 }
419 
430 {
431  return (posh_s32_t*) POSH_WriteU32ToBig( dst, (posh_u32_t) value );
432 }
433 
434 #if defined POSH_64BIT_INTEGER
435 
444 posh_u64_t * POSH_WriteU64ToLittle( void *dst, posh_u64_t value )
445 {
446  posh_u64_t *p64 = (posh_u64_t*) dst;
447 
448  *p64 = POSH_LittleU64( value );
449 
450  return p64+8;
451 }
452 
462 posh_s64_t * POSH_WriteS64ToLittle( void *dst, posh_s64_t value )
463 {
464  return (posh_s64_t*) POSH_WriteU64ToLittle( dst, (posh_u64_t) value );
465 }
466 
476 posh_u64_t * POSH_WriteU64ToBig( void *dst, posh_u64_t value )
477 {
478  posh_u64_t *p64 = (posh_u64_t*) dst;
479 
480  *p64 = POSH_BigU64( value );
481 
482  return p64+8;
483 }
484 
494 posh_s64_t * POSH_WriteS64ToBig( void *dst, posh_s64_t value )
495 {
496  return (posh_s64_t*) POSH_WriteU64ToBig( dst, (posh_s64_t) value );
497 }
498 
499 #endif /* POSH_64BIT_INTEGER */
500 
501 /*
502  * ---------------------------------------------------------------------------
503  * IN-MEMORY DESERIALIZATION
504  * ---------------------------------------------------------------------------
505  */
506 
513 {
514  return POSH_LittleU16( (*(const posh_u16_t*) src) );
515 }
516 
523 {
524  return POSH_LittleS16( (*(const posh_s16_t*) src) );
525 }
526 
533 {
534  return POSH_LittleU32( (*(const posh_u32_t*) src) );
535 }
536 
543 {
544  return POSH_LittleS32( (*(const posh_s32_t*) src) );
545 }
546 
552 posh_u16_t POSH_ReadU16FromBig( const void *src )
553 {
554  return POSH_BigU16( (*(const posh_u16_t*) src) );
555 }
556 
562 posh_s16_t POSH_ReadS16FromBig( const void *src )
563 {
564  return POSH_BigS16( (*(const posh_s16_t*) src) );
565 }
566 
572 posh_u32_t POSH_ReadU32FromBig( const void *src )
573 {
574  return POSH_BigU32( (*(const posh_u32_t*) src) );
575 }
576 
582 posh_s32_t POSH_ReadS32FromBig( const void *src )
583 {
584  return POSH_BigS32( (*(const posh_s32_t*) src) );
585 }
586 
587 #if defined POSH_64BIT_INTEGER
588 
594 posh_u64_t POSH_ReadU64FromLittle( const void *src )
595 {
596  return POSH_LittleU64( (*(const posh_u64_t*) src) );
597 }
598 
604 posh_s64_t POSH_ReadS64FromLittle( const void *src )
605 {
606  return POSH_LittleS64( (*(const posh_s64_t*) src) );
607 }
608 
614 posh_u64_t POSH_ReadU64FromBig( const void *src )
615 {
616  return POSH_BigU64( (*(const posh_u64_t*) src) );
617 }
618 
624 posh_s64_t POSH_ReadS64FromBig( const void *src )
625 {
626  return POSH_BigS64( (*(const posh_s64_t*) src) );
627 }
628 
629 #endif /* POSH_64BIT_INTEGER */
630 
631 /*
632  * ---------------------------------------------------------------------------
633  * FLOATING POINT SUPPORT
634  * ---------------------------------------------------------------------------
635  */
636 
637 #if !defined POSH_NO_FLOAT
638 
646 {
647  union
648  {
649  float f32;
650  posh_u32_t u32;
651  }
652  u;
653 
654  u.f32 = f;
655 
656 #if defined POSH_LITTLE_ENDIAN
657  return u.u32;
658 
659 #else
660  return POSH_SwapU32( u.u32 );
661 #endif
662 }
663 
672 {
673  union
674  {
675  float f32;
676  posh_u32_t u32;
677  }
678  u;
679 
680  u.f32 = f;
681 
682 #if defined POSH_LITTLE_ENDIAN
683  return POSH_SwapU32( u.u32 );
684 
685 #else
686  return u.u32;
687 #endif
688 }
689 
698 void POSH_DoubleBits( double d, posh_byte_t dst[8] )
699 {
700  union
701  {
702  double d64;
703  posh_byte_t bytes[8];
704  }
705  u;
706 
707  u.d64 = d;
708 
709 #if defined POSH_LITTLE_ENDIAN
710  dst[0] = u.bytes[0];
711  dst[1] = u.bytes[1];
712  dst[2] = u.bytes[2];
713  dst[3] = u.bytes[3];
714  dst[4] = u.bytes[4];
715  dst[5] = u.bytes[5];
716  dst[6] = u.bytes[6];
717  dst[7] = u.bytes[7];
718 #else
719  dst[0] = u.bytes[7];
720  dst[1] = u.bytes[6];
721  dst[2] = u.bytes[5];
722  dst[3] = u.bytes[4];
723  dst[4] = u.bytes[3];
724  dst[5] = u.bytes[2];
725  dst[6] = u.bytes[1];
726  dst[7] = u.bytes[0];
727 #endif
728 }
729 
742 double POSH_DoubleFromBits( const posh_byte_t src[8] )
743 {
744  union
745  {
746  double d64;
747  posh_byte_t bytes[8];
748  }
749  u;
750 
751 #if defined POSH_LITTLE_ENDIAN
752  u.bytes[0] = src[0];
753  u.bytes[1] = src[1];
754  u.bytes[2] = src[2];
755  u.bytes[3] = src[3];
756  u.bytes[4] = src[4];
757  u.bytes[5] = src[5];
758  u.bytes[6] = src[6];
759  u.bytes[7] = src[7];
760 #else
761  u.bytes[0] = src[7];
762  u.bytes[1] = src[6];
763  u.bytes[2] = src[5];
764  u.bytes[3] = src[4];
765  u.bytes[4] = src[3];
766  u.bytes[5] = src[2];
767  u.bytes[6] = src[1];
768  u.bytes[7] = src[0];
769 #endif
770 
771  return u.d64;
772 }
773 
784 {
785  union
786  {
787  float f32;
788  posh_u32_t u32;
789  }
790  u;
791 
792  u.u32 = bits;
793 #if defined POSH_BIG_ENDIAN
794  u.u32 = POSH_SwapU32( u.u32 );
795 #endif
796 
797  return u.f32;
798 }
799 
810 {
811  union
812  {
813  float f32;
814  posh_u32_t u32;
815  }
816  u;
817 
818  u.u32 = bits;
819 #if defined POSH_LITTLE_ENDIAN
820  u.u32 = POSH_SwapU32( u.u32 );
821 #endif
822 
823  return u.f32;
824 }
825 
826 #endif /* !defined POSH_NO_FLOAT */
827