~ubuntu-branches/ubuntu/trusty/ruby-ferret/trusty

1 by Antonio Terceiro
Import upstream version 0.11.6
1
/*
2
LICENSE:
3
4
Copyright (c) 2004, Brian Hook
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
    * Redistributions of source code must retain the above copyright
12
      notice, this list of conditions and the following disclaimer.
13
14
    * Redistributions in binary form must reproduce the above
15
      copyright notice, this list of conditions and the following
16
      disclaimer in the documentation and/or other materials provided
17
      with the distribution.
18
19
    * The names of this package'ss contributors contributors may not
20
      be used to endorse or promote products derived from this
21
      software without specific prior written permission.
22
23
24
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
*/
36
/** 
37
 @file    posh.c
38
 @author  Brian Hook
39
 @date    2002
40
 @brief   Portable Open Source Harness primary source file
41
*/
42
#include "posh.h"
43
44
#if !defined FORCE_DOXYGEN
45
46
#if !defined POSH_NO_FLOAT
47
#  define POSH_FLOAT_STRING "enabled"
48
#else
49
#  define POSH_FLOAT_STRING "disabled"
50
#endif
51
52
#if defined POSH_64BIT_INTEGER
53
#  define POSH_64BIT_INTEGER_STRING "yes"
54
#else
55
#  define POSH_64BIT_INTEGER_STRING "no"
56
#endif
57
58
#if defined POSH_64BIT_POINTER
59
#  define POSH_POINTER_STRING "64-bits"
60
#else
61
#  define POSH_POINTER_STRING "32-bits"
62
#endif
63
64
#if defined POSH_LITTLE_ENDIAN
65
#  define IS_BIG_ENDIAN    0
66
67
#  define NATIVE16  POSH_LittleU16
68
#  define NATIVE32  POSH_LittleU32
69
#  define NATIVE64  POSH_LittleU64
70
#  define FOREIGN16 POSH_BigU16
71
#  define FOREIGN32 POSH_BigU32
72
#  define FOREIGN64 POSH_BigU64
73
#else
74
#  define IS_BIG_ENDIAN    1
75
76
#  define NATIVE16  POSH_BigU16
77
#  define NATIVE32  POSH_BigU32
78
#  define NATIVE64  POSH_BigU64
79
#  define FOREIGN16 POSH_LittleU16
80
#  define FOREIGN32 POSH_LittleU32
81
#  define FOREIGN64 POSH_LittleU64
82
#endif /* POSH_LITTLE_ENDIAN */
83
84
static 
85
int 
86
s_testBigEndian( void )
87
{
88
   union 
89
   {
90
      posh_byte_t c[ 4 ];
91
      posh_u32_t  i;
92
   } u;
93
94
   u.i= 1;
95
96
   if ( u.c[ 0 ] == 1 )
97
   {
98
      return 0;
99
   }
100
   return 1;
101
}
102
103
static
104
const char *
105
s_testSerialization( void )
106
{
107
   posh_byte_t serbuf[ 8 ];
108
   posh_u16_t  tmp16;
109
   posh_u32_t  tmp32;
110
111
   /* 16-bit serialization */
112
   POSH_WriteU16ToLittle( serbuf, 0xABCD );
113
   if ( ( tmp16 = POSH_ReadU16FromLittle( serbuf ) ) != 0xABCD )
114
   {
115
      return "*ERROR: failed little-endian 16-bit serialization test";
116
   }
117
118
   POSH_WriteU16ToBig( serbuf, 0xABCD );
119
   if ( ( tmp16 = POSH_ReadU16FromBig( serbuf ) ) != 0xABCD )
120
   {
121
      return "*ERROR: failed big-endian 16-bit serialization test";
122
   }
123
124
   /* 32-bit serialization */
125
   POSH_WriteU32ToLittle( serbuf, 0xABCD1234L );
126
   if ( ( tmp32 = POSH_ReadU32FromLittle( serbuf ) ) != 0xABCD1234 )
127
   {
128
      return "*ERROR: failed little-endian 32-bit serialization test";
129
   }
130
131
   POSH_WriteU32ToBig( serbuf, 0xABCD1234L );
132
   if ( ( tmp32 = POSH_ReadU32FromBig( serbuf ) ) != 0xABCD1234 )
133
   {
134
      return "*ERROR: failed big-endian 32-bit serialization test";
135
   }
136
137
#if defined POSH_64BIT_INTEGER
138
   {
139
#define REF64 POSH_U64(0xFEDCBA9876543210)
140
141
      posh_u64_t tmp64;
142
143
      POSH_WriteU64ToLittle( serbuf, REF64 );
144
145
      if ( ( tmp64 = POSH_ReadU64FromLittle( serbuf ) ) != REF64 )
146
      {
147
         return "*ERROR: failed little-endian 64-bit serialization test";
148
      }
149
150
      POSH_WriteU64ToBig( serbuf, REF64 );
151
152
      if ( ( tmp64 = POSH_ReadU64FromBig( serbuf ) ) != REF64 )
153
      {
154
         return "*ERROR: failed big-endian 64-bit serialization test";
155
      }
156
   }
157
#endif
158
159
   return 0;
160
}
161
162
#if !defined POSH_NO_FLOAT
163
static
164
const char *
165
s_testFloatingPoint( void )
166
{
167
   float fRef = 10.0f/30.0f;
168
   double dRef = 10.0/30.0;
169
   posh_byte_t dbuf[ 8 ];
170
   float fTmp;
171
   double dTmp;
172
173
   fTmp = POSH_FloatFromLittleBits( POSH_LittleFloatBits( fRef ) );
174
175
   if ( fTmp != fRef )
176
   {
177
      return "*ERROR: POSH little endian floating point conversion failed.  Please report this to poshlib@poshlib.org!\n";
178
   }
179
180
   fTmp = POSH_FloatFromBigBits( POSH_BigFloatBits( fRef ) );
181
   if ( fTmp != fRef )
182
   {
183
      return "*ERROR: POSH big endian floating point conversion failed.  Please report this to poshlib@poshlib.org!\n";
184
   }
185
186
   POSH_DoubleBits( dRef, dbuf );
187
188
   dTmp = POSH_DoubleFromBits( dbuf );
189
190
   if ( dTmp != dRef )
191
   {
192
      return "*ERROR: POSH double precision floating point serialization failed.  Please report this to poshlib@poshlib.org!\n";
193
   }
194
195
   return 0;
196
}
197
#endif /* !defined POSH_NO_FLOAT */
198
199
static
200
const char *
201
s_testEndianess( void )
202
{
203
   /* check endianess */
204
   if ( s_testBigEndian() != IS_BIG_ENDIAN )
205
   {
206
      return "*ERROR: POSH compile time endianess does not match run-time endianess verification.  Please report this to poshlib@poshlib.org!\n";
207
   }
208
209
   /* make sure our endian swap routines work */
210
   if ( ( NATIVE32( 0x11223344L ) != 0x11223344L ) || 
211
        ( FOREIGN32( 0x11223344L ) != 0x44332211L ) ||
212
        ( NATIVE16( 0x1234 ) != 0x1234 ) ||
213
        ( FOREIGN16( 0x1234 ) != 0x3412 ) )
214
   {
215
      return "*ERROR: POSH endianess macro selection failed.  Please report this to poshlib@poshlib.org!\n";
216
   }
217
218
   /* test serialization routines */
219
220
   return 0;
221
}
222
#endif /* !defined FORCE_DOXYGEN */
223
224
/**
225
  Returns a string describing this platform's basic attributes.  
226
227
  POSH_GetArchString() reports on an architecture's statically determined
228
  attributes.  In addition, it will perform run-time verification checks
229
  to make sure the various platform specific functions work.  If an error
230
  occurs, please contact me at poshlib@poshlib.org so we can try to resolve
231
  what the specific failure case is.
232
  @returns a string describing this platform on success, or a string in the 
233
           form "*ERROR: [text]" on failure.  You can simply check to see if
234
           the first character returned is '*' to verify an error condition.
235
*/
236
const char *
237
POSH_GetArchString( void )
238
{
239
   const char *err;
240
   const char *s = "OS:.............."POSH_OS_STRING"\n"
241
                   "CPU:............."POSH_CPU_STRING"\n"
242
                   "endian:.........."POSH_ENDIAN_STRING"\n"
243
                   "ptr size:........"POSH_POINTER_STRING"\n"
244
                   "64-bit ints......"POSH_64BIT_INTEGER_STRING"\n"
245
                   "floating point..."POSH_FLOAT_STRING"\n"
246
                   "compiler........."POSH_COMPILER_STRING"\n";
247
248
   /* test endianess */
249
   err = s_testEndianess();
250
251
   if ( err != 0 )
252
   {
253
      return err;
254
   }
255
256
   /* test serialization */
257
   err = s_testSerialization();
258
259
   if ( err != 0 )
260
   {
261
      return err;
262
   }
263
264
#if !defined POSH_NO_FLOAT
265
   /* check that our floating point support is correct */
266
   err = s_testFloatingPoint();
267
268
   if ( err != 0 )
269
   {
270
      return err;
271
   }
272
273
#endif
274
275
   return s;
276
}
277
278
/* ---------------------------------------------------------------------------*/
279
/*                           BYTE SWAPPING SUPPORT                            */
280
/* ---------------------------------------------------------------------------*/
281
/** 
282
 * Byte swaps a 16-bit unsigned value
283
 *
284
   @ingroup ByteSwapFunctions
285
   @param v [in] unsigned 16-bit input value to swap
286
   @returns a byte swapped version of v
287
 */
288
posh_u16_t
289
POSH_SwapU16( posh_u16_t v )
290
{
291
   posh_u16_t swapped;
292
293
   swapped  = v << 8;
294
   swapped |= v >> 8;
295
296
   return swapped;
297
}
298
299
/** 
300
 * Byte swaps a 16-bit signed value
301
 *
302
   @ingroup ByteSwapFunctions
303
   @param v [in] signed 16-bit input value to swap
304
   @returns a byte swapped version of v
305
   @remarks This just calls back to the unsigned version, since byte swapping 
306
            is independent of sign.  However, we still provide this function to
307
            avoid signed/unsigned mismatch compiler warnings.
308
 */
309
posh_i16_t
310
POSH_SwapI16( posh_i16_t v )
311
{
312
   return ( posh_i16_t ) POSH_SwapU16( v );
313
}
314
315
/** 
316
 * Byte swaps a 32-bit unsigned value
317
 *
318
   @ingroup ByteSwapFunctions
319
   @param v [in] unsigned 32-bit input value to swap
320
   @returns a byte swapped version of v
321
 */
322
posh_u32_t
323
POSH_SwapU32( posh_u32_t v )
324
{
325
   posh_u32_t swapped;
326
327
   swapped  = ( v & 0xFF ) << 24;
328
   swapped |= ( v & 0xFF00 ) << 8;
329
   swapped |= ( v >> 8 ) & 0xFF00;
330
   swapped |= ( v >> 24 );
331
332
   return swapped;
333
}
334
335
/** 
336
 * Byte swaps a 32-bit signed value
337
 *
338
   @ingroup ByteSwapFunctions
339
   @param v [in] signed 32-bit input value to swap
340
   @returns a byte swapped version of v
341
   @remarks This just calls back to the unsigned version, since byte swapping 
342
            is independent of sign.  However, we still provide this function to
343
            avoid signed/unsigned mismatch compiler warnings.
344
 */
345
posh_i32_t
346
POSH_SwapI32( posh_i32_t v )
347
{
348
   return ( posh_i32_t ) POSH_SwapU32( ( posh_u32_t ) v );
349
}
350
351
#if defined POSH_64BIT_INTEGER
352
/**
353
 * Byte swaps a 64-bit unsigned value
354
355
   @param v [in] a 64-bit input value to swap
356
   @ingroup SixtyFourBit
357
   @returns a byte swapped version of v
358
*/
359
posh_u64_t 
360
POSH_SwapU64( posh_u64_t v )
361
{
362
   posh_byte_t tmp;
363
   union {
364
      posh_byte_t bytes[ 8 ];
365
      posh_u64_t  u64;
366
   } u;
367
368
   u.u64 = v;
369
370
   tmp = u.bytes[ 0 ]; u.bytes[ 0 ] = u.bytes[ 7 ]; u.bytes[ 7 ] = tmp;
371
   tmp = u.bytes[ 1 ]; u.bytes[ 1 ] = u.bytes[ 6 ]; u.bytes[ 6 ] = tmp;
372
   tmp = u.bytes[ 2 ]; u.bytes[ 2 ] = u.bytes[ 5 ]; u.bytes[ 5 ] = tmp;
373
   tmp = u.bytes[ 3 ]; u.bytes[ 3 ] = u.bytes[ 4 ]; u.bytes[ 4 ] = tmp;
374
375
   return u.u64;
376
}
377
378
/**
379
 * Byte swaps a 64-bit signed value
380
381
   @param v [in] a 64-bit input value to swap
382
   @ingroup SixtyFourBit
383
   @returns a byte swapped version of v
384
*/
385
posh_i64_t 
386
POSH_SwapI64( posh_i64_t v )
387
{
388
   return ( posh_i64_t ) POSH_SwapU64( ( posh_u64_t ) v );
389
}
390
391
#endif /* defined POSH_64BIT_INTEGER */
392
393
/* ---------------------------------------------------------------------------*/
394
/*                           IN-MEMORY SERIALIZATION                          */
395
/* ---------------------------------------------------------------------------*/
396
397
/**
398
 * Writes an unsigned 16-bit value to a little endian buffer
399
400
 @ingroup MemoryBuffer
401
 @param dst [out] pointer to the destination buffer, may not be NULL.  Alignment doesn't matter.
402
 @param value [in] host-endian unsigned 16-bit value
403
 @returns a pointer to the location two bytes after dst
404
 @remarks does no validation of the inputs
405
*/
406
posh_u16_t *
407
POSH_WriteU16ToLittle( void *dst, posh_u16_t value )
408
{
409
   posh_u16_t  *p16 = ( posh_u16_t * ) dst;
410
   posh_byte_t *p   = ( posh_byte_t * ) dst;
411
412
   p[ 0 ] = value & 0xFF;
413
   p[ 1 ] = ( value & 0xFF00) >> 8;
414
415
   return p16 + 1;
416
}
417
418
/**
419
 * Writes a signed 16-bit value to a little endian buffer
420
421
 @ingroup MemoryBuffer
422
 @param dst [out] pointer to the destination buffer, may not be NULL
423
 @param value [in] host-endian signed 16-bit value
424
 @returns a pointer to the location two bytes after dst
425
 @remarks does no validation of the inputs.  This simply calls
426
          POSH_WriteU16ToLittle() with appropriate casting.
427
*/
428
posh_i16_t *
429
POSH_WriteI16ToLittle( void *dst, posh_i16_t value )
430
{
431
   return ( posh_i16_t * ) POSH_WriteU16ToLittle( dst, ( posh_u16_t ) value );
432
}
433
434
/**
435
 * Writes an unsigned 32-bit value to a little endian buffer
436
437
 @ingroup MemoryBuffer
438
 @param dst [out] pointer to the destination buffer, may not be NULL
439
 @param value [in] host-endian signed 32-bit value
440
 @returns a pointer to the location four bytes after dst
441
 @remarks does no validation of the inputs.
442
*/
443
posh_u32_t *
444
POSH_WriteU32ToLittle( void *dst, posh_u32_t value )
445
{
446
   posh_u32_t  *p32   = ( posh_u32_t * ) dst;
447
   posh_byte_t *p     = ( posh_byte_t * ) dst;
448
449
   p[ 0 ] = ( value & 0xFF );
450
   p[ 1 ] = ( value & 0xFF00 ) >> 8;
451
   p[ 2 ] = ( value & 0xFF0000 ) >> 16;
452
   p[ 3 ] = ( value & 0xFF000000 ) >> 24;
453
454
   return p32 + 1;
455
}
456
457
/**
458
 * Writes a signed 32-bit value to a little endian buffer
459
460
 @ingroup MemoryBuffer
461
 @param dst [out] pointer to the destination buffer, may not be NULL
462
 @param value [in] host-endian signed 32-bit value
463
 @returns a pointer to the location four bytes after dst
464
 @remarks does no validation of the inputs.  This simply calls
465
          POSH_WriteU32ToLittle() with appropriate casting.
466
*/
467
posh_i32_t *
468
POSH_WriteI32ToLittle( void *dst, posh_i32_t value )
469
{
470
   return ( posh_i32_t * ) POSH_WriteU32ToLittle( dst, ( posh_u32_t ) value );
471
}
472
473
/**
474
 * Writes an unsigned 16-bit value to a big endian buffer
475
476
 @ingroup MemoryBuffer
477
 @param dst [out] pointer to the destination buffer, may not be NULL
478
 @param value [in] host-endian unsigned 16-bit value
479
 @returns a pointer to the location two bytes after dst
480
 @remarks does no validation of the inputs
481
*/
482
posh_u16_t *
483
POSH_WriteU16ToBig( void *dst, posh_u16_t value )
484
{
485
   posh_u16_t *p16 = ( posh_u16_t * ) dst;
486
   posh_byte_t *p  = ( posh_byte_t * ) dst;
487
488
   p[ 1 ] = ( value & 0xFF );
489
   p[ 0 ] = ( value & 0xFF00 ) >> 8;
490
491
   return p16 + 1;
492
}
493
494
/**
495
 * Writes a signed 16-bit value to a big endian buffer
496
497
 @ingroup MemoryBuffer
498
 @param dst [out] pointer to the destination buffer, may not be NULL
499
 @param value [in] host-endian signed 16-bit value
500
 @returns a pointer to the location two bytes after dst
501
 @remarks does no validation of the inputs.  This simply calls
502
          POSH_WriteU16ToLittle() with appropriate casting.
503
*/
504
posh_i16_t *
505
POSH_WriteI16ToBig( void *dst, posh_i16_t value )
506
{
507
   return ( posh_i16_t * ) POSH_WriteU16ToBig( dst, ( posh_u16_t ) value );
508
}
509
510
/**
511
 * Writes an unsigned 32-bit value to a big endian buffer
512
513
 @ingroup MemoryBuffer
514
 @param dst [out] pointer to the destination buffer, may not be NULL
515
 @param value [in] host-endian unsigned 32-bit value
516
 @returns a pointer to the location four bytes after dst
517
 @remarks does no validation of the inputs.
518
*/
519
posh_u32_t *
520
POSH_WriteU32ToBig( void *dst, posh_u32_t value )
521
{
522
   posh_u32_t *p32 = ( posh_u32_t * ) dst;
523
   posh_byte_t *p  = ( posh_byte_t * ) dst;
524
525
   p[ 3 ] = ( value & 0xFF );
526
   p[ 2 ] = ( value & 0xFF00 ) >> 8;
527
   p[ 1 ] = ( value & 0xFF0000 ) >> 16;
528
   p[ 0 ] = ( value & 0xFF000000 ) >> 24;
529
530
   return p32 + 1;
531
}
532
533
/**
534
 * Writes a signed 32-bit value to a big endian buffer
535
536
 @ingroup MemoryBuffer
537
 @param dst [out] pointer to the destination buffer, may not be NULL
538
 @param value [in] host-endian signed 32-bit value
539
 @returns a pointer to the location four bytes after dst
540
 @remarks does no validation of the inputs.  This simply calls
541
          POSH_WriteU32ToBig() with appropriate casting.
542
*/
543
posh_i32_t *
544
POSH_WriteI32ToBig( void *dst, posh_i32_t value )
545
{
546
   return ( posh_i32_t * ) POSH_WriteU32ToBig( dst, ( posh_u32_t ) value );
547
}
548
549
#if defined POSH_64BIT_INTEGER
550
/**
551
 * Writes an unsigned 64-bit value to a little-endian buffer
552
553
 @ingroup SixtyFourBit
554
 @param dst [out] pointer to the destination buffer, may not be NULL
555
 @param value [in] host-endian unsigned 64-bit value
556
 @returns a pointer to the location eight bytes after dst
557
 @remarks does no validation of the inputs.
558
*/
559
posh_u64_t *
560
POSH_WriteU64ToLittle( void *dst, posh_u64_t value )
561
{
562
   posh_u64_t *p64 = ( posh_u64_t * ) dst;
563
   posh_byte_t *p  = ( posh_byte_t * ) dst;
564
   int i;
565
566
   for ( i = 0; i < 8; i++, value >>= 8 )
567
   {
568
       p[ i ] = ( posh_byte_t ) ( value & 0xFF );
569
   }
570
571
   return p64 + 1;
572
}
573
574
/**
575
 * Writes a signed 64-bit value to a little-endian buffer
576
577
 @ingroup SixtyFourBit
578
 @param dst [out] pointer to the destination buffer, may not be NULL
579
 @param value [in] host-endian unsigned 64-bit value
580
 @returns a pointer to the location eight bytes after dst
581
 @remarks does no validation of the inputs.
582
*/
583
posh_i64_t *
584
POSH_WriteI64ToLittle( void *dst, posh_i64_t value )
585
{
586
   return ( posh_i64_t * ) POSH_WriteU64ToLittle( dst, ( posh_u64_t ) value );
587
}
588
589
/**
590
 * Writes an unsigned 64-bit value to a big-endian buffer
591
592
 @ingroup SixtyFourBit
593
 @param dst [out] pointer to the destination buffer, may not be NULL
594
 @param value [in] host-endian unsigned 64-bit value
595
 @returns a pointer to the location eight bytes after dst
596
 @remarks does no validation of the inputs.
597
*/
598
posh_u64_t *
599
POSH_WriteU64ToBig( void *dst, posh_u64_t value )
600
{
601
   posh_u64_t *p64 = ( posh_u64_t * ) dst;
602
   posh_byte_t *p  = ( posh_byte_t * ) dst;
603
   int i;
604
605
   for ( i = 0; i < 8; i++, value >>= 8 )
606
   {
607
       p[ 7-i ] = ( posh_byte_t ) ( value & 0xFF );
608
   }
609
610
   return p64 + 8;
611
}
612
613
/**
614
 * Writes a signed 64-bit value to a big-endian buffer
615
616
 @ingroup SixtyFourBit
617
 @param dst [out] pointer to the destination buffer, may not be NULL
618
 @param value [in] host-endian signed 64-bit value
619
 @returns a pointer to the location eight bytes after dst
620
 @remarks does no validation of the inputs.
621
*/
622
posh_i64_t *
623
POSH_WriteI64ToBig( void *dst, posh_i64_t value )
624
{
625
   return ( posh_i64_t * ) POSH_WriteU64ToBig( dst, ( posh_u64_t ) value );
626
}
627
628
#endif /* POSH_64BIT_INTEGER */
629
630
/* ---------------------------------------------------------------------------*/
631
/*                         IN-MEMORY DESERIALIZATION                          */
632
/* ---------------------------------------------------------------------------*/
633
634
/** 
635
 * Reads an unsigned 16-bit value from a little-endian buffer
636
 @ingroup MemoryBuffer
637
 @param src [in] source buffer
638
 @returns host-endian unsigned 16-bit value
639
*/
640
posh_u16_t  
641
POSH_ReadU16FromLittle( const void *src )
642
{
643
    posh_u16_t   v = 0;
644
    posh_byte_t *p = ( posh_byte_t * ) src;
645
646
    v |= p[ 0 ];
647
    v |= ( ( posh_u16_t ) p[ 1 ] ) << 8;
648
649
    return v;
650
}
651
652
/** 
653
 * Reads a signed 16-bit value from a little-endian buffer
654
 @ingroup MemoryBuffer
655
 @param src [in] source buffer
656
 @returns host-endian signed 16-bit value
657
*/
658
posh_i16_t  
659
POSH_ReadI16FromLittle( const void *src )
660
{
661
   return ( posh_i16_t ) POSH_ReadU16FromLittle( src );
662
}
663
664
/** 
665
 * Reads an unsigned 32-bit value from a little-endian buffer
666
 @ingroup MemoryBuffer
667
 @param src [in] source buffer
668
 @returns host-endian unsigned 32-bit value
669
*/
670
posh_u32_t  
671
POSH_ReadU32FromLittle( const void *src )
672
{
673
    posh_u32_t v = 0;
674
    posh_byte_t *p = ( posh_byte_t * ) src;
675
676
    v |= p[ 0 ];
677
    v |= ( ( posh_u32_t ) p[ 1 ] ) << 8;
678
    v |= ( ( posh_u32_t ) p[ 2 ] ) << 16;
679
    v |= ( ( posh_u32_t ) p[ 3 ] ) << 24;
680
681
    return v;
682
}
683
684
/** 
685
 * Reads a signed 32-bit value from a little-endian buffer
686
 @ingroup MemoryBuffer
687
 @param src [in] source buffer
688
 @returns host-endian signed 32-bit value
689
*/
690
posh_i32_t  
691
POSH_ReadI32FromLittle( const void *src )
692
{
693
   return ( posh_i32_t ) POSH_ReadU32FromLittle( src );
694
}
695
696
697
/** 
698
 * Reads an unsigned 16-bit value from a big-endian buffer
699
 @ingroup MemoryBuffer
700
 @param src [in] source buffer
701
 @returns host-endian unsigned 16-bit value
702
*/
703
posh_u16_t  
704
POSH_ReadU16FromBig( const void *src )
705
{
706
    posh_u16_t   v = 0;
707
    posh_byte_t *p = ( posh_byte_t * ) src;
708
709
    v |= p[ 1 ];
710
    v |= ( ( posh_u16_t ) p[ 0 ] ) << 8;
711
712
    return v;
713
}
714
715
/** 
716
 * Reads a signed 16-bit value from a big-endian buffer
717
 @ingroup MemoryBuffer
718
 @param src [in] source buffer
719
 @returns host-endian signed 16-bit value
720
*/
721
posh_i16_t  
722
POSH_ReadI16FromBig( const void *src )
723
{
724
   return ( posh_i16_t ) POSH_ReadU16FromBig( src );
725
}
726
727
/** 
728
 * Reads an unsigned 32-bit value from a big-endian buffer
729
 @ingroup MemoryBuffer
730
 @param src [in] source buffer
731
 @returns host-endian unsigned 32-bit value
732
*/
733
posh_u32_t  
734
POSH_ReadU32FromBig( const void *src )
735
{
736
    posh_u32_t   v = 0;
737
    posh_byte_t *p = ( posh_byte_t * ) src;
738
739
    v |= p[ 3 ];
740
    v |= ( ( posh_u32_t ) p[ 2 ] ) << 8;
741
    v |= ( ( posh_u32_t ) p[ 1 ] ) << 16;
742
    v |= ( ( posh_u32_t ) p[ 0 ] ) << 24;
743
744
    return v;
745
}
746
747
/** 
748
 * Reads a signed 32-bit value from a big-endian buffer
749
 @ingroup MemoryBuffer
750
 @param src [in] source buffer
751
 @returns host-endian signed 32-bit value
752
*/
753
posh_i32_t  
754
POSH_ReadI32FromBig( const void *src )
755
{
756
   return POSH_BigI32( (*(const posh_i32_t*)src ) );
757
}
758
759
#if defined POSH_64BIT_INTEGER
760
761
/** 
762
 * Reads an unsigned 64-bit value from a little-endian buffer
763
 @param src [in] source buffer
764
 @returns host-endian unsigned 32-bit value
765
*/
766
posh_u64_t  
767
POSH_ReadU64FromLittle( const void *src )
768
{
769
    posh_u64_t v = 0;
770
    posh_byte_t *p = ( posh_byte_t * ) src;
771
    int i;
772
773
    for ( i = 0; i < 8; i++ )
774
    {
775
        v |= ( ( posh_u64_t ) p[ i ] ) << (i*8);
776
    }
777
778
    return v;
779
}
780
781
/** 
782
 * Reads a signed 64-bit value from a little-endian buffer
783
 @param src [in] source buffer
784
 @returns host-endian signed 32-bit value
785
*/
786
posh_i64_t  
787
POSH_ReadI64FromLittle( const void *src )
788
{
789
   return ( posh_i64_t ) POSH_ReadU64FromLittle( src );
790
}
791
792
/** 
793
 * Reads an unsigned 64-bit value from a big-endian buffer
794
 @param src [in] source buffer
795
 @returns host-endian unsigned 32-bit value
796
*/
797
posh_u64_t
798
POSH_ReadU64FromBig( const void *src )
799
{
800
    posh_u64_t v = 0;
801
    posh_byte_t *p = ( posh_byte_t * ) src;
802
    int i;
803
804
    for ( i = 0; i < 8; i++ )
805
    {
806
        v |= ( ( posh_u64_t ) p[ 7-i ] ) << (i*8);
807
    }
808
809
    return v;
810
}
811
812
/** 
813
 * Reads an signed 64-bit value from a big-endian buffer
814
 @param src [in] source buffer
815
 @returns host-endian signed 32-bit value
816
*/
817
posh_i64_t
818
POSH_ReadI64FromBig( const void *src )
819
{
820
   return ( posh_i64_t ) POSH_ReadU64FromBig( src );
821
}
822
823
#endif /* POSH_64BIT_INTEGER */
824
825
/* ---------------------------------------------------------------------------*/
826
/*                           FLOATING POINT SUPPORT                           */
827
/* ---------------------------------------------------------------------------*/
828
829
#if !defined POSH_NO_FLOAT
830
831
/** @ingroup FloatingPoint
832
    @param[in] f floating point value
833
    @returns a little-endian bit representation of f
834
 */
835
posh_u32_t
836
POSH_LittleFloatBits( float f )
837
{
838
   union
839
   {
840
      float f32;
841
      posh_u32_t u32;
842
   } u;
843
844
   u.f32 = f;
845
846
   return POSH_LittleU32( u.u32 );
847
}
848
849
/** 
850
 * Extracts raw big-endian bits from a 32-bit floating point value
851
 *
852
   @ingroup FloatingPoint
853
   @param   f [in] floating point value
854
   @returns a big-endian bit representation of f
855
 */
856
posh_u32_t
857
POSH_BigFloatBits( float f )
858
{
859
   union
860
   {
861
      float f32;
862
      posh_u32_t u32;
863
   } u;
864
865
   u.f32 = f;
866
867
   return POSH_BigU32( u.u32 );
868
}
869
870
/** 
871
 * Extracts raw, little-endian bit representation from a 64-bit double.
872
 *
873
   @param d [in] 64-bit double precision value
874
   @param dst [out] 8-byte storage buffer
875
   @ingroup FloatingPoint
876
   @returns the raw bits used to represent the value 'd', in the form dst[0]=LSB
877
 */
878
void
879
POSH_DoubleBits( double d, posh_byte_t dst[ 8 ] )
880
{
881
   union
882
   {
883
      double d64;
884
      posh_byte_t bytes[ 8 ];
885
   } u;
886
887
   u.d64 = d;
888
889
#if defined POSH_LITTLE_ENDIAN
890
   dst[ 0 ] = u.bytes[ 0 ];
891
   dst[ 1 ] = u.bytes[ 1 ];
892
   dst[ 2 ] = u.bytes[ 2 ];
893
   dst[ 3 ] = u.bytes[ 3 ];
894
   dst[ 4 ] = u.bytes[ 4 ];
895
   dst[ 5 ] = u.bytes[ 5 ];
896
   dst[ 6 ] = u.bytes[ 6 ];
897
   dst[ 7 ] = u.bytes[ 7 ];
898
#else
899
   dst[ 0 ] = u.bytes[ 7 ];
900
   dst[ 1 ] = u.bytes[ 6 ];
901
   dst[ 2 ] = u.bytes[ 5 ];
902
   dst[ 3 ] = u.bytes[ 4 ];
903
   dst[ 4 ] = u.bytes[ 3 ];
904
   dst[ 5 ] = u.bytes[ 2 ];
905
   dst[ 6 ] = u.bytes[ 1 ];
906
   dst[ 7 ] = u.bytes[ 0 ];
907
#endif
908
}
909
910
/** 
911
 * Creates a double-precision, 64-bit floating point value from a set of raw, 
912
 * little-endian bits
913
914
   @ingroup FloatingPoint
915
   @param src [in] little-endian byte representation of 64-bit double precision 
916
                  floating point value
917
   @returns double precision floating point representation of the raw bits
918
   @remarks No error checking is performed, so there are no guarantees that the 
919
            result is a valid number, nor is there any check to ensure that src is 
920
            non-NULL.  BE CAREFUL USING THIS.
921
 */
922
double
923
POSH_DoubleFromBits( const posh_byte_t src[ 8 ] )
924
{
925
   union
926
   {
927
      double d64;
928
      posh_byte_t bytes[ 8 ];
929
   } u;
930
931
#if defined POSH_LITTLE_ENDIAN
932
   u.bytes[ 0 ] = src[ 0 ];
933
   u.bytes[ 1 ] = src[ 1 ];
934
   u.bytes[ 2 ] = src[ 2 ];
935
   u.bytes[ 3 ] = src[ 3 ];
936
   u.bytes[ 4 ] = src[ 4 ];
937
   u.bytes[ 5 ] = src[ 5 ];
938
   u.bytes[ 6 ] = src[ 6 ];
939
   u.bytes[ 7 ] = src[ 7 ];
940
#else
941
   u.bytes[ 0 ] = src[ 7 ];
942
   u.bytes[ 1 ] = src[ 6 ];
943
   u.bytes[ 2 ] = src[ 5 ];
944
   u.bytes[ 3 ] = src[ 4 ];
945
   u.bytes[ 4 ] = src[ 3 ];
946
   u.bytes[ 5 ] = src[ 2 ];
947
   u.bytes[ 6 ] = src[ 1 ];
948
   u.bytes[ 7 ] = src[ 0 ];
949
#endif
950
951
   return u.d64;
952
}
953
954
/** 
955
 * Creates a floating point number from little endian bits
956
 *
957
   @ingroup FloatingPoint
958
   @param   bits [in] raw floating point bits in little-endian form
959
   @returns a floating point number based on the given bit representation
960
   @remarks No error checking is performed, so there are no guarantees that the 
961
            result is a valid number.  BE CAREFUL USING THIS.
962
 */
963
float       
964
POSH_FloatFromLittleBits( posh_u32_t bits )
965
{
966
   union
967
   {
968
      float f32;
969
      posh_u32_t u32;
970
   } u;
971
972
   u.u32 = bits;
973
#if defined POSH_BIG_ENDIAN
974
   u.u32 = POSH_SwapU32( u.u32 );
975
#endif
976
977
   return u.f32;
978
}
979
980
/** 
981
 * Creates a floating point number from big-endian bits
982
 *
983
   @ingroup FloatingPoint
984
   @param   bits [in] raw floating point bits in big-endian form
985
   @returns a floating point number based on the given bit representation
986
   @remarks No error checking is performed, so there are no guarantees that the 
987
            result is a valid number.  BE CAREFUL USING THIS.
988
 */
989
float
990
POSH_FloatFromBigBits( posh_u32_t bits )
991
{
992
   union
993
   {
994
      float f32;
995
      posh_u32_t u32;
996
   } u;
997
998
   u.u32 = bits;
999
#if defined POSH_LITTLE_ENDIAN
1000
   u.u32 = POSH_SwapU32( u.u32 );
1001
#endif
1002
1003
   return u.f32;
1004
}
1005
1006
#endif /* !defined POSH_NO_FLOAT */