Endian.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:15k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /*
  2.      File:       Endian.h
  3.  
  4.      Contains:   QuickTime Interfaces
  5.  
  6.      Version:    Technology: QuickTime 3.0
  7.                  Release:    QuickTime 6.0.2
  8.  
  9.      Copyright:  (c) 1997-2001 by Apple Computer, Inc., all rights reserved
  10.  
  11.      Bugs?:      For bug reports, consult the following page on
  12.                  the World Wide Web:
  13.  
  14.                      http://developer.apple.com/bugreporter/
  15.  
  16. */
  17. #ifndef __ENDIAN__
  18. #define __ENDIAN__
  19. #ifndef __CONDITIONALMACROS__
  20. #include "ConditionalMacros.h"
  21. #endif
  22. #ifndef __MACTYPES__
  23. #include "MacTypes.h"
  24. #endif
  25. #if PRAGMA_ONCE
  26. #pragma once
  27. #endif
  28. #ifdef __cplusplus
  29. extern "C" {
  30. #endif
  31. #if PRAGMA_IMPORT
  32. #pragma import on
  33. #endif
  34. #if PRAGMA_STRUCT_ALIGN
  35.     #pragma options align=mac68k
  36. #elif PRAGMA_STRUCT_PACKPUSH
  37.     #pragma pack(push, 2)
  38. #elif PRAGMA_STRUCT_PACK
  39.     #pragma pack(2)
  40. #endif
  41. /*
  42.     This file provides Endian Flipping routines for dealing with converting data
  43.     between Big-Endian and Little-Endian machines.  These routines are useful
  44.     when writing code to compile for both Big and Little Endian machines and  
  45.     which must handle other endian number formats, such as reading or writing 
  46.     to a file or network packet.
  47.     
  48.     These routines are named as follows:
  49.     
  50.         Endian<U><W>_<S>to<D>
  51.     where
  52.         <U> is whether the integer is signed ('S') or unsigned ('U')
  53.         <W> is integer bit width: 16, 32, or 64 
  54.         <S> is the source endian format: 'B' for big, 'L' for little, or 'N' for native
  55.         <D> is the destination endian format: 'B' for big, 'L' for little, or 'N' for native
  56.     
  57.     For example, to convert a Big Endian 32-bit unsigned integer to the current native format use:
  58.         
  59.         long i = EndianU32_BtoN(data);
  60.         
  61.     This file is set up so that the function macro to nothing when the target runtime already
  62.     is the desired format (e.g. on Big Endian machines, EndianU32_BtoN() macros away).
  63.             
  64.     If long long's are not supported, you cannot get 64-bit quantities as a single value.
  65.     The macros are not defined in that case.
  66.     
  67.     
  68.     
  69.                                 <<< W A R N I N G >>>
  70.     
  71.     It is very important not to put any autoincrements inside the macros.  This 
  72.     will produce erroneous results because each time the address is accessed in the macro, 
  73.     the increment occurs.
  74.     
  75.  */
  76. /*
  77.    Note: These functions are currently not implemented in any library
  78.          and are only listed here as function prototypes to document the macros
  79. */
  80. #if CALL_NOT_IN_CARBON
  81. EXTERN_API_C( SInt16 )
  82. EndianS16_BtoN                  (SInt16                 value);
  83. EXTERN_API_C( SInt16 )
  84. EndianS16_NtoB                  (SInt16                 value);
  85. EXTERN_API_C( SInt16 )
  86. EndianS16_LtoN                  (SInt16                 value);
  87. EXTERN_API_C( SInt16 )
  88. EndianS16_NtoL                  (SInt16                 value);
  89. EXTERN_API_C( SInt16 )
  90. EndianS16_LtoB                  (SInt16                 value);
  91. EXTERN_API_C( SInt16 )
  92. EndianS16_BtoL                  (SInt16                 value);
  93. EXTERN_API_C( UInt16 )
  94. EndianU16_BtoN                  (UInt16                 value);
  95. EXTERN_API_C( UInt16 )
  96. EndianU16_NtoB                  (UInt16                 value);
  97. EXTERN_API_C( UInt16 )
  98. EndianU16_LtoN                  (UInt16                 value);
  99. EXTERN_API_C( UInt16 )
  100. EndianU16_NtoL                  (UInt16                 value);
  101. EXTERN_API_C( UInt16 )
  102. EndianU16_LtoB                  (UInt16                 value);
  103. EXTERN_API_C( UInt16 )
  104. EndianU16_BtoL                  (UInt16                 value);
  105. EXTERN_API_C( SInt32 )
  106. EndianS32_BtoN                  (SInt32                 value);
  107. EXTERN_API_C( SInt32 )
  108. EndianS32_NtoB                  (SInt32                 value);
  109. EXTERN_API_C( SInt32 )
  110. EndianS32_LtoN                  (SInt32                 value);
  111. EXTERN_API_C( SInt32 )
  112. EndianS32_NtoL                  (SInt32                 value);
  113. EXTERN_API_C( SInt32 )
  114. EndianS32_LtoB                  (SInt32                 value);
  115. EXTERN_API_C( SInt32 )
  116. EndianS32_BtoL                  (SInt32                 value);
  117. EXTERN_API_C( UInt32 )
  118. EndianU32_BtoN                  (UInt32                 value);
  119. EXTERN_API_C( UInt32 )
  120. EndianU32_NtoB                  (UInt32                 value);
  121. EXTERN_API_C( UInt32 )
  122. EndianU32_LtoN                  (UInt32                 value);
  123. EXTERN_API_C( UInt32 )
  124. EndianU32_NtoL                  (UInt32                 value);
  125. EXTERN_API_C( UInt32 )
  126. EndianU32_LtoB                  (UInt32                 value);
  127. EXTERN_API_C( UInt32 )
  128. EndianU32_BtoL                  (UInt32                 value);
  129. #endif  /* CALL_NOT_IN_CARBON */
  130. #if !TYPE_LONGLONG
  131. /*
  132.    Note: If these Int64 functions ever were implemented in a library,
  133.          we would need two libraries, one for compilers that
  134.          support long long and one for other compilers.
  135. */
  136. #if CALL_NOT_IN_CARBON
  137. EXTERN_API_C( SInt64 )
  138. EndianS64_BtoN                  (SInt64                 value);
  139. EXTERN_API_C( SInt64 )
  140. EndianS64_NtoB                  (SInt64                 value);
  141. EXTERN_API_C( SInt64 )
  142. EndianS64_LtoN                  (SInt64                 value);
  143. EXTERN_API_C( SInt64 )
  144. EndianS64_NtoL                  (SInt64                 value);
  145. EXTERN_API_C( SInt64 )
  146. EndianS64_LtoB                  (SInt64                 value);
  147. EXTERN_API_C( SInt64 )
  148. EndianS64_BtoL                  (SInt64                 value);
  149. EXTERN_API_C( UInt64 )
  150. EndianU64_BtoN                  (UInt64                 value);
  151. EXTERN_API_C( UInt64 )
  152. EndianU64_NtoB                  (UInt64                 value);
  153. EXTERN_API_C( UInt64 )
  154. EndianU64_LtoN                  (UInt64                 value);
  155. EXTERN_API_C( UInt64 )
  156. EndianU64_NtoL                  (UInt64                 value);
  157. EXTERN_API_C( UInt64 )
  158. EndianU64_LtoB                  (UInt64                 value);
  159. EXTERN_API_C( UInt64 )
  160. EndianU64_BtoL                  (UInt64                 value);
  161. #endif  /* CALL_NOT_IN_CARBON */
  162. #endif  /* !TYPE_LONGLONG */
  163. /*
  164.    These types are used for structures that contain data that is
  165.    always in BigEndian format.  This extra typing prevents little
  166.    endian code from directly changing the data, thus saving much
  167.    time in the debugger.
  168. */
  169. #if TARGET_RT_LITTLE_ENDIAN
  170. struct BigEndianLong {
  171.     long                            bigEndianValue;
  172. };
  173. typedef struct BigEndianLong            BigEndianLong;
  174. struct BigEndianUnsignedLong {
  175.     unsigned long                   bigEndianValue;
  176. };
  177. typedef struct BigEndianUnsignedLong    BigEndianUnsignedLong;
  178. struct BigEndianShort {
  179.     short                           bigEndianValue;
  180. };
  181. typedef struct BigEndianShort           BigEndianShort;
  182. struct BigEndianUnsignedShort {
  183.     unsigned short                  bigEndianValue;
  184. };
  185. typedef struct BigEndianUnsignedShort   BigEndianUnsignedShort;
  186. struct BigEndianFixed {
  187.     Fixed                           bigEndianValue;
  188. };
  189. typedef struct BigEndianFixed           BigEndianFixed;
  190. struct BigEndianUnsignedFixed {
  191.     UnsignedFixed                   bigEndianValue;
  192. };
  193. typedef struct BigEndianUnsignedFixed   BigEndianUnsignedFixed;
  194. struct BigEndianOSType {
  195.     OSType                          bigEndianValue;
  196. };
  197. typedef struct BigEndianOSType          BigEndianOSType;
  198. #else
  199. typedef long                            BigEndianLong;
  200. typedef unsigned long                   BigEndianUnsignedLong;
  201. typedef short                           BigEndianShort;
  202. typedef unsigned short                  BigEndianUnsignedShort;
  203. typedef Fixed                           BigEndianFixed;
  204. typedef UnsignedFixed                   BigEndianUnsignedFixed;
  205. typedef OSType                          BigEndianOSType;
  206. #endif  /* TARGET_RT_LITTLE_ENDIAN */
  207. /*
  208.     Macro away no-op functions
  209. */
  210. #if TARGET_RT_BIG_ENDIAN
  211.  #define EndianS16_BtoN(value)               (value)
  212.     #define EndianS16_NtoB(value)               (value)
  213.     #define EndianU16_BtoN(value)               (value)
  214.     #define EndianU16_NtoB(value)               (value)
  215.     #define EndianS32_BtoN(value)               (value)
  216.     #define EndianS32_NtoB(value)               (value)
  217.     #define EndianU32_BtoN(value)               (value)
  218.     #define EndianU32_NtoB(value)               (value)
  219.     #define EndianS64_BtoN(value)               (value)
  220.     #define EndianS64_NtoB(value)               (value)
  221.     #define EndianU64_BtoN(value)               (value)
  222.     #define EndianU64_NtoB(value)               (value)
  223. #else
  224.   #define EndianS16_LtoN(value)               (value)
  225.     #define EndianS16_NtoL(value)               (value)
  226.     #define EndianU16_LtoN(value)               (value)
  227.     #define EndianU16_NtoL(value)               (value)
  228.     #define EndianS32_LtoN(value)               (value)
  229.     #define EndianS32_NtoL(value)               (value)
  230.     #define EndianU32_LtoN(value)               (value)
  231.     #define EndianU32_NtoL(value)               (value)
  232.     #define EndianS64_LtoN(value)               (value)
  233.     #define EndianS64_NtoL(value)               (value)
  234.     #define EndianU64_LtoN(value)               (value)
  235.     #define EndianU64_NtoL(value)               (value)
  236. #endif
  237. /*
  238.     Map native to actual
  239. */
  240. #if TARGET_RT_BIG_ENDIAN
  241.    #define EndianS16_LtoN(value)               EndianS16_LtoB(value)
  242.   #define EndianS16_NtoL(value)               EndianS16_BtoL(value)
  243.   #define EndianU16_LtoN(value)               EndianU16_LtoB(value)
  244.   #define EndianU16_NtoL(value)               EndianU16_BtoL(value)
  245.   #define EndianS32_LtoN(value)               EndianS32_LtoB(value)
  246.   #define EndianS32_NtoL(value)               EndianS32_BtoL(value)
  247.   #define EndianU32_LtoN(value)               EndianU32_LtoB(value)
  248.   #define EndianU32_NtoL(value)               EndianU32_BtoL(value)
  249.   #define EndianS64_LtoN(value)               EndianS64_LtoB(value)
  250.   #define EndianS64_NtoL(value)               EndianS64_BtoL(value)
  251.   #define EndianU64_LtoN(value)               EndianU64_LtoB(value)
  252.   #define EndianU64_NtoL(value)               EndianU64_BtoL(value)
  253. #else
  254.     #define EndianS16_BtoN(value)               EndianS16_BtoL(value)
  255.   #define EndianS16_NtoB(value)               EndianS16_LtoB(value)
  256.   #define EndianU16_BtoN(value)               EndianU16_BtoL(value)
  257.   #define EndianU16_NtoB(value)               EndianU16_LtoB(value)
  258.   #define EndianS32_BtoN(value)               EndianS32_BtoL(value)
  259.   #define EndianS32_NtoB(value)               EndianS32_LtoB(value)
  260.   #define EndianU32_BtoN(value)               EndianU32_BtoL(value)
  261.   #define EndianU32_NtoB(value)               EndianU32_LtoB(value)
  262.   #define EndianS64_BtoN(value)               EndianS64_BtoL(value)
  263.   #define EndianS64_NtoB(value)               EndianS64_LtoB(value)
  264.   #define EndianU64_BtoN(value)               EndianU64_BtoL(value)
  265.   #define EndianU64_NtoB(value)               EndianU64_LtoB(value)
  266. #endif
  267. /*
  268.     Implement 臠toB and 臖toL
  269. */
  270. #define EndianS16_LtoB(value)              ((SInt16)Endian16_Swap(value))
  271. #define EndianS16_BtoL(value)                ((SInt16)Endian16_Swap(value))
  272. #define EndianU16_LtoB(value)                ((UInt16)Endian16_Swap(value))
  273. #define EndianU16_BtoL(value)                ((UInt16)Endian16_Swap(value))
  274. #define EndianS32_LtoB(value)                ((SInt32)Endian32_Swap(value))
  275. #define EndianS32_BtoL(value)                ((SInt32)Endian32_Swap(value))
  276. #define EndianU32_LtoB(value)                ((UInt32)Endian32_Swap(value))
  277. #define EndianU32_BtoL(value)                ((UInt32)Endian32_Swap(value))
  278. #define EndianS64_LtoB(value)                ((SInt64)Endian64_Swap((UInt64)value))
  279. #define EndianS64_BtoL(value)                ((SInt64)Endian64_Swap((UInt64)value))
  280. #define EndianU64_LtoB(value)                ((UInt64)Endian64_Swap(value))
  281. #define EndianU64_BtoL(value)                ((UInt64)Endian64_Swap(value))
  282. /*
  283.     Implement low level 臺Swap functions.
  284.   
  285.        extern UInt16 Endian16_Swap(UInt16 value);
  286.      extern UInt32 Endian32_Swap(UInt32 value);
  287.      extern UInt64 Endian64_Swap(UInt64 value);
  288.      
  289.    Note: Depending on the processor, you might want to implement
  290.         these as function calls instead of macros.
  291.    
  292. */
  293. #if TARGET_CPU_68K && TARGET_OS_MAC
  294.     #pragma parameter __D0 Endian16_Swap(__D0)
  295.  pascal UInt16 Endian16_Swap(UInt16 value)
  296.       = { 0xE158 };
  297.   
  298.    #pragma parameter __D0 Endian32_Swap (__D0)
  299.     pascal UInt32 Endian32_Swap(UInt32 value)
  300.       = { 0xE158, 0x4840, 0xE158 };
  301. #else
  302.     #define Endian16_Swap(value)                 
  303.          (((((UInt16)value)<<8) & 0xFF00)   | 
  304.           ((((UInt16)value)>>8) & 0x00FF))
  305.   
  306.    #define Endian32_Swap(value)                     
  307.          (((((UInt32)value)<<24) & 0xFF000000)  | 
  308.           ((((UInt32)value)<< 8) & 0x00FF0000)  | 
  309.           ((((UInt32)value)>> 8) & 0x0000FF00)  | 
  310.           ((((UInt32)value)>>24) & 0x000000FF))
  311. #endif
  312. #if TYPE_LONGLONG
  313.  #if TARGET_OS_WIN32
  314.         /* the inline macros crash MSDEV's optimizer on Windows. */
  315.         extern UInt64 Endian64_Swap(UInt64 value);
  316.  #elif defined(__MWERKS__) && (__MWERKS__ < 0x1800)
  317.      /* older Metrowerks compilers errored on LL suffix */
  318.       #define Endian64_Swap(value)                             
  319.              (((((UInt64)value)<<56) & 0xFF00000000000000)  | 
  320.               ((((UInt64)value)<<40) & 0x00FF000000000000)  | 
  321.               ((((UInt64)value)<<24) & 0x0000FF0000000000)  | 
  322.               ((((UInt64)value)<< 8) & 0x000000FF00000000)  | 
  323.               ((((UInt64)value)>> 8) & 0x00000000FF000000)  | 
  324.               ((((UInt64)value)>>24) & 0x0000000000FF0000)  | 
  325.               ((((UInt64)value)>>40) & 0x000000000000FF00)  | 
  326.               ((((UInt64)value)>>56) & 0x00000000000000FF))
  327.  #else
  328.       #define Endian64_Swap(value)                             
  329.              (((((UInt64)value)<<56) & 0xFF00000000000000ULL)  | 
  330.                ((((UInt64)value)<<40) & 0x00FF000000000000ULL)  | 
  331.                ((((UInt64)value)<<24) & 0x0000FF0000000000ULL)  | 
  332.                ((((UInt64)value)<< 8) & 0x000000FF00000000ULL)  | 
  333.                ((((UInt64)value)>> 8) & 0x00000000FF000000ULL)  | 
  334.                ((((UInt64)value)>>24) & 0x0000000000FF0000ULL)  | 
  335.                ((((UInt64)value)>>40) & 0x000000000000FF00ULL)  | 
  336.                ((((UInt64)value)>>56) & 0x00000000000000FFULL))
  337.   #endif
  338. #else
  339.    /* 
  340.         Note: When using C compilers that don't support "long long",
  341.              Endian64_Swap must be implemented as glue. 
  342.   */
  343.  #ifdef __cplusplus
  344.      inline static UInt64 Endian64_Swap(UInt64 value)
  345.        {
  346.           UInt64 temp;
  347.            ((UnsignedWide*)&temp)->lo = Endian32_Swap(((UnsignedWide*)&value)->hi);
  348.            ((UnsignedWide*)&temp)->hi = Endian32_Swap(((UnsignedWide*)&value)->lo);
  349.            return temp;
  350.        }
  351.   #else
  352.       extern UInt64 Endian64_Swap(UInt64 value);
  353.  #endif
  354. #endif
  355. #if PRAGMA_STRUCT_ALIGN
  356.     #pragma options align=reset
  357. #elif PRAGMA_STRUCT_PACKPUSH
  358.     #pragma pack(pop)
  359. #elif PRAGMA_STRUCT_PACK
  360.     #pragma pack()
  361. #endif
  362. #ifdef PRAGMA_IMPORT_OFF
  363. #pragma import off
  364. #elif PRAGMA_IMPORT
  365. #pragma import reset
  366. #endif
  367. #ifdef __cplusplus
  368. }
  369. #endif
  370. #endif /* __ENDIAN__ */