home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Found / ODUtils / FlipEnd.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-17  |  4.0 KB  |  176 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        FlipEnd.cpp
  3.  
  4.     Contains:    routines to manipulate endianness of memory
  5.  
  6.     Owned by:    David McCusker
  7.  
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     
  11. */
  12.  
  13. #ifndef _FLIPEND_
  14. #include "FlipEnd.h"
  15. #endif
  16.  
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20.  
  21. /*=========================================================================*/
  22. /* ODUShort endianness flipping */
  23. /*=========================================================================*/
  24.  
  25. ODUShort ODFlipShort(ODUShort n)
  26.     /* n is a single 2-byte int; return it with flipped endianness */
  27. {
  28.     /* note it is unorthodox, but legal, to modify stack arguments */
  29.     register ODUShort* p = &n;
  30.  
  31.     char c = *(char*) p;
  32.     *(char*) p = ((char*) p)[1]; 
  33.     ((char*) p)[1] = c;
  34.  
  35.     return *p;
  36. }
  37.  
  38. void ODFlipShortArray(register ODUShort* n, unsigned long count)
  39.     /* n points to count 2-byte ints; flip each int's endianness */
  40. {
  41.     register char c;
  42.     ODUShort* end = n + count; /* one past the end */
  43.     
  44.     --n;
  45.     while (++n < end)
  46.     {
  47.         c = *(char*) n;
  48.         *(char*) n = ((char*) n)[1]; 
  49.         ((char*) n)[1] = c;
  50.     }
  51. }
  52.  
  53. /*=========================================================================*/
  54. /* ODULong endianness flipping */
  55. /*=========================================================================*/
  56.  
  57. ODULong ODFlipLong(ODULong n)
  58.     /* n is a single 4-byte int; return it with flipped endianness */
  59. {
  60.     /* note it is unorthodox, but legal, to modify stack arguments */
  61.     register ODULong* p = &n;
  62.  
  63.     register char c = *(char*) p;
  64.     *(char*) p = ((char*) p)[3]; 
  65.     ((char*) p)[3] = c; 
  66.     
  67.     c = ((char*) p)[1];
  68.     ((char*) p)[1]= ((char*) p)[2]; 
  69.     ((char*) p)[2] = c; 
  70.     
  71.     return *p;
  72. }
  73.  
  74. void ODFlipLongArray(register ODULong* n, unsigned long count)
  75.     /* n points to count 4-byte ints; flip each int's endianness */
  76. {
  77.     register char c;
  78.     ODULong* end = n + count; /* one past the end */
  79.     
  80.     --n;
  81.     while (++n < end)
  82.     {
  83.         c = *(char*) n;
  84.         *(char*) n = ((char*) n)[3]; 
  85.         ((char*) n)[3] = c; 
  86.         
  87.         c = ((char*) n)[1];
  88.         ((char*) n)[1]= ((char*) n)[2]; 
  89.         ((char*) n)[2] = c; 
  90.     }
  91. }
  92.  
  93. /*=========================================================================*/
  94. /* structure endianness flipping */
  95. /*=========================================================================*/
  96.  
  97. void ODFlipStruct(void* structure, const short* groups)
  98.     /* Invert the endianness of the contents of memory in structure
  99.      * according to the layout described by groups, which should
  100.      * be a zero-terminated array of shorts, where each short describes
  101.      * the size of the next chunk of memory in structure to be processed.
  102.      * A negative value -x in the groups array indicates a block
  103.      * of endianness-neutral memory, like a string, and causes x bytes
  104.      * of memory to be skipped over.  A positive value x in the groups
  105.      * array indicates an x byte block of memory which should have its
  106.      * bytes flipped end for end.  Only positive values in the set
  107.      * { 2, 4, 8 } are handled. (Other positive values are handled like
  108.      * negative values: space is skipped). Example:
  109.      *
  110.      * struct Foo {
  111.      *     short alpha;
  112.      *     long  beta;
  113.      *     char  gamma[8];
  114.      *     long  delta;
  115.      * };
  116.      * const short fooGroups[] = {
  117.      *     2, // alpha
  118.      *     4, // beta
  119.      *    -8, // gamma 
  120.      *     4, // delta
  121.      *     0, // zero-termination
  122.      * };
  123.      */
  124. {
  125.     register char* p = (char*) structure;
  126.     register char c;
  127.  
  128.     short g = *groups++;                /* next groups entry */
  129.  
  130.     while (g)
  131.     {
  132.         /* we expect 2 and 4 to be the most common values */
  133.         if (g == 2)
  134.         {
  135.             c = *p; *p = p[1]; p[1] = c;
  136.             p += 2;
  137.         }
  138.         else if (g == 4)
  139.         {
  140.                  /* swap bytes 0 and 3 */
  141.             c = *p; *p = p[3]; p[3] = c;
  142.             
  143.             ++p; /* swap bytes 1 and 2 */
  144.             c = *p; *p = p[1]; p[1] = c;
  145.             
  146.             p += 3;
  147.         }
  148.         else if (g == 8)
  149.         {
  150.                  /* swap bytes 0 and 7 */
  151.             c = *p; *p = p[7]; p[7] = c;
  152.             
  153.             ++p; /* swap bytes 1 and 6 */
  154.             c = *p; *p = p[5]; p[5] = c;
  155.             
  156.             ++p; /* swap bytes 2 and 5 */
  157.             c = *p; *p = p[3]; p[3] = c;
  158.             
  159.             ++p; /* swap bytes 3 and 4 */
  160.             c = *p; *p = p[1]; p[1] = c;
  161.             
  162.             p += 5;
  163.         }
  164.         else if (g < 0)
  165.             p += -g;
  166.         else
  167.             p += g;
  168.         
  169.         g = *groups++;
  170.     }
  171. }
  172.  
  173. #ifdef __cplusplus
  174. }
  175. #endif
  176.