home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osp1.exe / src / utils / FlipEnd.cpp < prev    next >
C/C++ Source or Header  |  1997-04-02  |  5KB  |  205 lines

  1. //====START_GENERATED_PROLOG======================================
  2. //
  3. //
  4. //   COMPONENT_NAME: odutils
  5. //
  6. //   CLASSES: none
  7. //
  8. //   ORIGINS: 82,27
  9. //
  10. //
  11. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  12. //   All Rights Reserved
  13. //   Licensed Materials - Property of IBM
  14. //   US Government Users Restricted Rights - Use, duplication or
  15. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  16. //       
  17. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  18. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  20. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  21. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  22. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  23. //   OR PERFORMANCE OF THIS SOFTWARE.
  24. //
  25. //====END_GENERATED_PROLOG========================================
  26. //
  27. // @(#) 1.4 com/src/utils/FlipEnd.cpp, odutils, od96os2, odos29712d 7/15/96 17:58:01 [ 3/21/97 17:20:52 ]
  28. /*
  29.     File:        FlipEnd.cpp
  30.  
  31.     Contains:    routines to manipulate endianness of memory
  32.  
  33.     Owned by:    David McCusker
  34.  
  35.     Copyright:    ⌐ 1995 by Apple Computer, Inc., all rights reserved.
  36.  
  37.     
  38. */
  39.  
  40. #ifndef _FLIPEND_
  41. #include "FlipEnd.h"
  42. #endif
  43.  
  44. #ifdef __cplusplus
  45. extern "C" {
  46. #endif
  47.  
  48. /*=========================================================================*/
  49. /* ODUShort endianness flipping */
  50. /*=========================================================================*/
  51.  
  52. ODUShort ODFlipShort(ODUShort n)
  53.     /* n is a single 2-byte int; return it with flipped endianness */
  54. {
  55.     /* note it is unorthodox, but legal, to modify stack arguments */
  56.     register ODUShort* p = &n;
  57.  
  58.     char c = *(char*) p;
  59.     *(char*) p = ((char*) p)[1]; 
  60.     ((char*) p)[1] = c;
  61.  
  62.     return *p;
  63. }
  64.  
  65. void ODFlipShortArray(register ODUShort* n, unsigned long count)
  66.     /* n points to count 2-byte ints; flip each int's endianness */
  67. {
  68.     register char c;
  69.     ODUShort* end = n + count; /* one past the end */
  70.     
  71.     --n;
  72.     while (++n < end)
  73.     {
  74.         c = *(char*) n;
  75.         *(char*) n = ((char*) n)[1]; 
  76.         ((char*) n)[1] = c;
  77.     }
  78. }
  79.  
  80. /*=========================================================================*/
  81. /* ODULong endianness flipping */
  82. /*=========================================================================*/
  83.  
  84. ODULong ODFlipLong(ODULong n)
  85.     /* n is a single 4-byte int; return it with flipped endianness */
  86. {
  87.     /* note it is unorthodox, but legal, to modify stack arguments */
  88.     register ODULong* p = &n;
  89.  
  90.     register char c = *(char*) p;
  91.     *(char*) p = ((char*) p)[3]; 
  92.     ((char*) p)[3] = c; 
  93.     
  94.     c = ((char*) p)[1];
  95.     ((char*) p)[1]= ((char*) p)[2]; 
  96.     ((char*) p)[2] = c; 
  97.     
  98.     return *p;
  99. }
  100.  
  101. void ODFlipLongArray(register ODULong* n, unsigned long count)
  102.     /* n points to count 4-byte ints; flip each int's endianness */
  103. {
  104.     register char c;
  105.     ODULong* end = n + count; /* one past the end */
  106.     
  107.     --n;
  108.     while (++n < end)
  109.     {
  110.         c = *(char*) n;
  111.         *(char*) n = ((char*) n)[3]; 
  112.         ((char*) n)[3] = c; 
  113.         
  114.         c = ((char*) n)[1];
  115.         ((char*) n)[1]= ((char*) n)[2]; 
  116.         ((char*) n)[2] = c; 
  117.     }
  118. }
  119.  
  120. #ifndef OD_BUG // function doesn't work, and no one uses it.
  121. /*=========================================================================*/
  122. /* structure endianness flipping */
  123. /*=========================================================================*/
  124.  
  125. void ODFlipStruct(void* structure, const short* groups)
  126.     /* Invert the endianness of the contents of memory in structure
  127.      * according to the layout described by groups, which should
  128.      * be a zero-terminated array of shorts, where each short describes
  129.      * the size of the next chunk of memory in structure to be processed.
  130.      * A negative value -x in the groups array indicates a block
  131.      * of endianness-neutral memory, like a string, and causes x bytes
  132.      * of memory to be skipped over.  A positive value x in the groups
  133.      * array indicates an x byte block of memory which should have its
  134.      * bytes flipped end for end.  Only positive values in the set
  135.      * { 2, 4, 8 } are handled. (Other positive values are handled like
  136.      * negative values: space is skipped). Example:
  137.      *
  138.      * struct Foo {
  139.      *     short alpha;
  140.      *     long  beta;
  141.      *     char  gamma[8];
  142.      *     long  delta;
  143.      * };
  144.      * const short fooGroups[] = {
  145.      *     2, // alpha
  146.      *     4, // beta
  147.      *    -8, // gamma 
  148.      *     4, // delta
  149.      *     0, // zero-termination
  150.      * };
  151.      */
  152. {
  153.     register char* p = (char*) structure;
  154.     register char c;
  155.  
  156.     short g = *groups++;                /* next groups entry */
  157.  
  158.     while (g)
  159.     {
  160.         /* we expect 2 and 4 to be the most common values */
  161.         if (g == 2)
  162.         {
  163.             c = *p; *p = p[1]; p[1] = c;
  164.             p += 2;
  165.         }
  166.         else if (g == 4)
  167.         {
  168.                  /* swap bytes 0 and 3 */
  169.             c = *p; *p = p[3]; p[3] = c;
  170.             
  171.             ++p; /* swap bytes 1 and 2 */
  172.             c = *p; *p = p[1]; p[1] = c;
  173.             
  174.             p += 3;
  175.         }
  176.         else if (g == 8)
  177.         {
  178.                  /* swap bytes 0 and 7 */
  179.             c = *p; *p = p[7]; p[7] = c;
  180.             
  181.             ++p; /* swap bytes 1 and 6 */
  182.             c = *p; *p = p[5]; p[5] = c;
  183.             
  184.             ++p; /* swap bytes 2 and 5 */
  185.             c = *p; *p = p[3]; p[3] = c;
  186.             
  187.             ++p; /* swap bytes 3 and 4 */
  188.             c = *p; *p = p[1]; p[1] = c;
  189.             
  190.             p += 5;
  191.         }
  192.         else if (g < 0)
  193.             p += -g;
  194.         else
  195.             p += g;
  196.         
  197.         g = *groups++;
  198.     }
  199. }
  200. #endif // OD_BUG
  201.  
  202. #ifdef __cplusplus
  203. }
  204. #endif
  205.