ncbi_bswap.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:8k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbi_bswap.hpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/02/12 21:44:08  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [CORE_001] Dev-tree R1.8
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef CORELIB___NCBI_BSWAP__HPP
  10. #define CORELIB___NCBI_BSWAP__HPP
  11. /* $Id: ncbi_bswap.hpp,v 1000.1 2004/02/12 21:44:08 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Author:  Anatoliy Kuznetsov, Kyrill Rotmistrovsky
  37.  *   
  38.  * File Description: Byte swapping functions.
  39.  *
  40.  */
  41. #include <corelib/ncbistl.hpp>
  42. #include <corelib/ncbitype.h>
  43. BEGIN_NCBI_SCOPE
  44. /////////////////////////////////////////////////////////////////////////////
  45. ///
  46. /// CByteSwap --
  47. ///
  48. /// Class encapsulates byte swapping functions to convert between 
  49. /// big endian - little endian architectures
  50. ///
  51. /// Get and Put functions always do the byte swapping 
  52. /// (change the byte order). If the input is BIG ENDIAN it is
  53. /// converted to LITTLE ENDIAN and vice versa.
  54. /// This group of functions is used when we know upfront that the 
  55. /// incoming data were created on architecture with a different byte order 
  56. /// and byte swapping is necessary.
  57. ///
  58. ///
  59. /// Use case:
  60. ///
  61. /// Usually it means sender writes all the data without conversion to network 
  62. /// byte order, instead adds a small characteristic word describing the 
  63. /// original byte order. Reader checks the byte order first and if it is 
  64. /// the same just interprets the data in the regular manner without any 
  65. /// conversion. 
  66. /// In most cases when the data does not cross the border we have no 
  67. /// performance impact (do not call CByteSwap::Get & Put methods).
  68. /// Such "on demand" conversion scheme has potential performance advantage 
  69. /// over the unconditional conversion to network byte order.
  70. ///
  71. class CByteSwap
  72. {
  73. public:
  74.     static Int2 GetInt2(const unsigned char* ptr);
  75.     static void PutInt2(unsigned char* ptr, Int2 value);
  76.     static Int4 GetInt4(const unsigned char* ptr);
  77.     static void PutInt4(unsigned char* ptr, Int4 value);
  78.     static Int8 GetInt8(const unsigned char* ptr);
  79.     static void PutInt8(unsigned char* ptr, Int8 value);
  80.     static float GetFloat(const unsigned char* ptr);
  81.     static void PutFloat(unsigned char* ptr, float value);
  82.     static double GetDouble(const unsigned char* ptr);
  83.     static void PutDouble(unsigned char* ptr, double value);
  84. };
  85. inline
  86. Int2 CByteSwap::GetInt2(const unsigned char* ptr)
  87. {
  88. #ifdef WORDS_BIGENDIAN
  89.     Int2 ret = (Int2(ptr[1]) << 8) | 
  90.                (Int2(ptr[0]));
  91. #else
  92.     Int2 ret = (Int2(ptr[0]) << 8) | 
  93.                (Int2(ptr[1]));
  94. #endif
  95.     return ret;
  96. }
  97. inline
  98. void CByteSwap::PutInt2(unsigned char* ptr, Int2 value)
  99. {
  100. #ifdef WORDS_BIGENDIAN
  101.     ptr[1] = (unsigned char)(value >> 8);
  102.     ptr[0] = (unsigned char)(value);
  103. #else
  104.     ptr[0] = (unsigned char)(value >> 8);
  105.     ptr[1] = (unsigned char)(value);
  106. #endif
  107. }
  108. inline
  109. Int4 CByteSwap::GetInt4(const unsigned char* ptr)
  110. {
  111. #ifdef WORDS_BIGENDIAN
  112.     Int4 ret = (Int4(ptr[3]) << 24) | 
  113.                (Int4(ptr[2]) << 16) | 
  114.                (Int4(ptr[1]) << 8)  | 
  115.                (Int4(ptr[0]));
  116. #else
  117.     Int4 ret = (Int4(ptr[0]) << 24) | 
  118.                (Int4(ptr[1]) << 16) | 
  119.                (Int4(ptr[2]) << 8)  | 
  120.                (Int4(ptr[3]));
  121. #endif
  122.     return ret;
  123. }
  124. inline
  125. void CByteSwap::PutInt4(unsigned char* ptr, Int4 value)
  126. {
  127. #ifdef WORDS_BIGENDIAN
  128.     ptr[3] = (unsigned char)(value >> 24);
  129.     ptr[2] = (unsigned char)(value >> 16);
  130.     ptr[1] = (unsigned char)(value >> 8);
  131.     ptr[0] = (unsigned char)(value);
  132. #else
  133.     ptr[0] = (unsigned char)(value >> 24);
  134.     ptr[1] = (unsigned char)(value >> 16);
  135.     ptr[2] = (unsigned char)(value >> 8);
  136.     ptr[3] = (unsigned char)(value);
  137. #endif
  138. }
  139. inline
  140. Int8 CByteSwap::GetInt8(const unsigned char* ptr)
  141. {
  142. #ifdef WORDS_BIGENDIAN
  143.     Int8 ret = (Int8(ptr[7]) << 56) | 
  144.                (Int8(ptr[6]) << 48) | 
  145.                (Int8(ptr[5]) << 40) | 
  146.                (Int8(ptr[4]) << 32) |
  147.                (Int8(ptr[3]) << 24) |
  148.                (Int8(ptr[2]) << 16) |
  149.                (Int8(ptr[1]) << 8)  |
  150.                (Int8(ptr[0]));
  151. #else
  152.     Int8 ret = (Int8(ptr[0]) << 56) | 
  153.                (Int8(ptr[1]) << 48) | 
  154.                (Int8(ptr[2]) << 40) | 
  155.                (Int8(ptr[3]) << 32) |
  156.                (Int8(ptr[4]) << 24) |
  157.                (Int8(ptr[5]) << 16) |
  158.                (Int8(ptr[6]) << 8)  |
  159.                (Int8(ptr[7]));
  160. #endif
  161.     return ret;
  162. }
  163. inline
  164. void CByteSwap::PutInt8(unsigned char* ptr, Int8 value)
  165. {
  166. #ifdef WORDS_BIGENDIAN
  167.     ptr[7] = (unsigned char)(value >> 56);
  168.     ptr[6] = (unsigned char)(value >> 48);
  169.     ptr[5] = (unsigned char)(value >> 40);
  170.     ptr[4] = (unsigned char)(value >> 32);
  171.     ptr[3] = (unsigned char)(value >> 24);
  172.     ptr[2] = (unsigned char)(value >> 16);
  173.     ptr[1] = (unsigned char)(value >> 8);
  174.     ptr[0] = (unsigned char)(value);
  175. #else
  176.     ptr[0] = (unsigned char)(value >> 56);
  177.     ptr[1] = (unsigned char)(value >> 48);
  178.     ptr[2] = (unsigned char)(value >> 40);
  179.     ptr[3] = (unsigned char)(value >> 32);
  180.     ptr[4] = (unsigned char)(value >> 24);
  181.     ptr[5] = (unsigned char)(value >> 16);
  182.     ptr[6] = (unsigned char)(value >> 8);
  183.     ptr[7] = (unsigned char)(value);
  184. #endif
  185. }
  186. inline
  187. float CByteSwap::GetFloat(const unsigned char* ptr)
  188. {
  189.     Int4 ret = CByteSwap::GetInt4(ptr);
  190.     return *(float*)(&ret);
  191. }
  192. inline
  193. void CByteSwap::PutFloat(unsigned char* ptr, float value)
  194. {
  195.     CByteSwap::PutInt4(ptr, *(Int4*)(&value));
  196. }
  197. inline
  198. double CByteSwap::GetDouble(const unsigned char* ptr)
  199. {
  200.     Int8 ret = CByteSwap::GetInt8(ptr);
  201.     return *(double*)(&ret);
  202. }
  203. inline
  204. void CByteSwap::PutDouble(unsigned char* ptr, double value)
  205. {
  206.     CByteSwap::PutInt8(ptr, *(Int8*)(&value));
  207. }
  208. END_NCBI_SCOPE
  209. /*
  210.  * ===========================================================================
  211.  * $Log: ncbi_bswap.hpp,v $
  212.  * Revision 1000.1  2004/02/12 21:44:08  gouriano
  213.  * PRODUCTION: UPGRADED [CORE_001] Dev-tree R1.8
  214.  *
  215.  * Revision 1.8  2004/02/03 17:23:06  kuznets
  216.  * Improved comments describing CByteSwap design
  217.  *
  218.  * Revision 1.7  2004/01/29 18:53:33  siyan
  219.  * Prefixed conditional compilation macro with CORELIB___ since this is now
  220.  * part of Corelib.
  221.  *
  222.  * Revision 1.6  2003/09/11 16:05:24  kuznets
  223.  * Fixed minor misprint
  224.  *
  225.  * Revision 1.5  2003/09/10 16:44:47  kuznets
  226.  * Fixed a bug with bit shifting without casting to a proper (16,32,64 bit) type.
  227.  * Thanks Eugene Vasilchenko for submitting it.
  228.  *
  229.  * Revision 1.4  2003/09/10 15:13:30  kuznets
  230.  * Fixed minor compilation issues.
  231.  *
  232.  * Revision 1.3  2003/09/09 19:52:25  kuznets
  233.  * Added support for big-little endian byte orders.
  234.  *
  235.  * Revision 1.2  2003/09/09 14:28:54  kuznets
  236.  * All functions joined into one CByteSwap class.
  237.  *
  238.  * Revision 1.1  2003/09/08 20:36:51  kuznets
  239.  * Initial revision
  240.  *
  241.  * ===========================================================================
  242.  */
  243. #endif /* NCBI_BSWAP__HPP */