Chinaunix首页 | 论坛 | 博客
  • 博客访问: 161895
  • 博文数量: 76
  • 博客积分: 1513
  • 博客等级: 上尉
  • 技术积分: 755
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-25 15:15
文章分类

全部博文(76)

文章存档

2012年(2)

2011年(74)

我的朋友

分类: C/C++

2011-11-25 20:10:10

  1. #ifndef ENDIAN_HPP

  2. #define ENDIAN_HPP

  3.   

  4. #include <sys/types.h>

  5. #include <stdint.h>

  6. #ifdef __linux__

  7. #include <stdint.h>

  8. #endif

  9.  

  10. class EndianIOBase

  11. {

  12.   public:
  13.   

  14. // ----(abstract virtual methods)----
  15.  
  16.     virtual uint16_t read16( uint8_t * p )= 0;

  17.     virtual uint32_t read32( uint8_t * p )= 0;

  18.     virtual uint64_t read64( uint8_t * p )= 0;

  19.     virtual void write16( uint8_t * p, uint16_t w )= 0;

  20.     virtual void write32( uint8_t * p, uint32_t w )= 0;

  21.     virtual void write64( uint8_t * p, uint64_t w )= 0;

  22.  

  23.     // declare special methods for data we know is byte-aligned

  24.     virtual uint16_t read16a( uint8_t * p )= 0;

  25.     virtual uint16_t read16a( uint16_t * p )= 0;

  26.     virtual uint32_t read32a( uint8_t * p )= 0;

  27.     virtual uint32_t read32a( uint32_t * p )= 0;

  28.     virtual uint64_t read64a( uint8_t * p )= 0;

  29.     virtual uint64_t read64a( uint64_t * p )= 0;

  30.     virtual void write16a( uint8_t * p, uint16_t w )= 0;

  31.     virtual void write16a( uint16_t * p, uint16_t w )= 0;

  32.     virtual void write32a( uint8_t * p, uint32_t w )= 0;

  33.     virtual void write32a( uint32_t * p, uint32_t w )= 0;

  34.     virtual void write64a( uint8_t * p, uint64_t w )= 0;

  35.     virtual void write64a( uint64_t * p, uint64_t w )= 0;

  36.     

  37. // ----(common 16-bit i/o operations )----
  38.   
  39.     uint16_t read16( uint16_t * p )

  40.     {

  41.       return read16( reinterpret_cast < uint8_t * >( p ) );

  42.     }

  43.     

  44.     uint16_t read16( uint16_t p )

  45.     {

  46.       return read16( &p );

  47.     }

  48.     

  49.     uint16_t read16( char *p )

  50.     {

  51.       return read16( reinterpret_cast < uint8_t * >( p ) );

  52.     }

  53.     

  54.     void write16( uint16_t * p, uint16_t w )

  55.     {

  56.       write16( reinterpret_cast < uint8_t * >( p ), w );

  57.     }

  58.     

  59.     uint16_t write16( uint16_t w )

  60.     {

  61.       uint16_t w16;

  62.       

  63.       write16( &w16, w );

  64.       return w16;

  65.     }

  66.     

  67. // ----(common 32-bit i/o operations)----
  68.   
  69.     uint32_t read32( uint32_t * p )

  70.     {

  71.       return read32( reinterpret_cast < uint8_t * >( p ) );

  72.     }

  73.     

  74.     uint32_t read32( char *p )

  75.     {

  76.       return read32( reinterpret_cast < uint8_t * >( p ) );

  77.     }

  78.     

  79.     uint32_t read32( uint32_t p )

  80.     {

  81.       return read32( &p );

  82.     }

  83.     

  84.     void write32( uint32_t * p, uint32_t w )

  85.     {

  86.       write32( reinterpret_cast < uint8_t * >( p ), w );

  87.     }

  88.     

  89.     uint32_t write32( uint32_t w )

  90.     {

  91.       uint32_t w32;

  92.       

  93.       write32( &w32, w );

  94.       return w32;

  95.     }

  96.     

  97. // ----(common 64-bit i/o operations)----

  98.     uint64_t read64( uint64_t * p )

  99.     {

  100.       return read64( reinterpret_cast < uint8_t * >( p ) );

  101.     }

  102.     

  103.     uint64_t read64( char *p )

  104.     {

  105.       return read64( reinterpret_cast < uint8_t * >( p ) );

  106.     }

  107.     

  108.     uint64_t read64( uint64_t p )

  109.     {

  110.       return read64( &p );

  111.     }

  112.     

  113.     void write64( uint64_t * p, uint64_t w )

  114.     {

  115.       write64( reinterpret_cast < uint8_t * >( p ), w );

  116.     }

  117.     

  118.     uint64_t write64( uint64_t w )

  119.     {

  120.       uint64_t w64;
  121.   
  122.       write64( &w64, w );

  123.       return w64;

  124.     }

  125. };

  126.  

  127. #ifdef __sgi

  128.   // our sgi boxes are not fast enough (and the optimizer is not smart enough)

  129.   // so we need to do the i/o the old way.

  130.   class BigEndianIO: public EndianIOBase

  131.   {

  132.     public:

  133.     virtual uint16_t read16( uint8_t * p ) { uint16_t w; memcpy( &w, p, 2); return w; };

  134.     virtual uint16_t read16a( uint8_t * p ) { return *(uint16_t*)p; };

  135.     virtual uint16_t read16a( uint16_t * p ) { return *p; };

  136.     virtual uint32_t read32( uint8_t * p ) { uint32_t w; memcpy( &w, p, 4); return w; };

  137.     virtual uint32_t read32a( uint8_t * p ) { return *(uint32_t*)p; };

  138.     virtual uint32_t read32a( uint32_t * p ) { return *p; };

  139.     virtual uint64_t read64( uint8_t * p ) { uint64_t w; memcpy( &w, p, 8); return w; };

  140.     virtual uint64_t read64a( uint8_t * p ) { return *(uint64_t*)p; };

  141.     virtual uint64_t read64a( uint64_t * p ) { return *p; };

  142.     virtual void write16( uint8_t * p, uint16_t w ) { memcpy( p, &w, 2); };

  143.     virtual void write16a( uint8_t * p, uint16_t w ) { *(uint16_t*)p = w; };

  144.     virtual void write16a( uint16_t * p, uint16_t w ) { *p = w; };

  145.     virtual void write32( uint8_t * p, uint32_t w ) { memcpy( p, &w, 4); };

  146.     virtual void write32a( uint8_t * p, uint32_t w ) { *(uint32_t*)p = w; };

  147.     virtual void write32a( uint32_t * p, uint32_t w ) { *p = w; };

  148.     virtual void write64( uint8_t * p, uint64_t w ) { memcpy( p, &w, 8); };

  149.     virtual void write64a( uint8_t * p, uint64_t w ) { *(uint64_t*)p = w; };

  150.     virtual void write64a( uint64_t * p, uint64_t w ) { *p = w; };

  151.   };

  152.  

  153. #else

  154.  

  155.   class BigEndianIO: public EndianIOBase

  156.   {

  157.     public:

  158. // ----(16-bit read operation)----

  159.       virtual uint16_t read16( uint8_t * p )

  160.     {

  161.       uint16_t w;

  162.       uint16_t hi, lo;

  163.       

  164.       // read the high byte, then the low byte

  165.       hi = *p;

  166.       lo = *( p + 1 );

  167.       w = hi << 8 | lo;

  168.       return w;

  169.     }

  170.     

  171. // ----(32-bit read operation)----

  172.     virtual uint32_t read32( uint8_t * p )

  173.     {

  174.       uint32_t w;

  175.       uint32_t hi, lo;

  176.       // read the high half, then the low half

  177.       hi = read16( p );

  178.       lo = read16( p + 2 );

  179.       w = hi << 16 | lo;

  180.       return w;

  181.     }

  182.     

  183. // ----(64-bit read operation)----

  184.     virtual uint64_t read64( uint8_t * p )

  185.     {

  186.       uint64_t w;

  187.       uint64_t hi, lo;

  188.       // read the high half, then the low half

  189.       hi = read32( p );

  190.       lo = read32( p + 4 );

  191.       w = hi << 32 | lo;

  192.       return w;

  193.     }

  194.     

  195. // ----(16-bit write operation)----

  196.     virtual void write16( uint8_t * p, uint16_t w )

  197.     {

  198.       uint8_t hi, lo;

  199.       hi =( w >> 8 )& 0xff;

  200.       lo = w & 0xff;

  201.       // write the high byte, then the low byte

  202.       *p = hi;

  203.       *( p + 1 )= lo;

  204.     }

  205.     

  206. // ----(32-bit write operation)----

  207.     virtual void write32( uint8_t * p, uint32_t w )

  208.     {

  209.       uint16_t hi, lo;

  210.       

  211.       hi =( w >> 16 )& 0xffff;

  212.       lo = w & 0xffff;

  213.       // write the high half, then the low half

  214.       write16( p, hi );

  215.       write16( ( p + 2 ), lo );

  216.     }

  217.     

  218. // ----(64-bit write operation)----

  219.  

  220.     virtual void write64( uint8_t * p, uint64_t w )

  221.     {

  222.       uint32_t hi, lo;

  223.       hi =( w >> 32 )& 0xffffffff;

  224.       lo = w & 0xffffffff;

  225.       // write the high half, then the low half

  226.       write32( p, hi );

  227.       write32( ( p + 4 ), lo );

  228.     }

  229.  

  230.     virtual uint16_t read16a( uint8_t * p ) { return read16( p ); };

  231.     virtual uint16_t read16a( uint16_t * p ) { return read16( (uint8_t*)p ); };

  232.     virtual uint32_t read32a( uint8_t * p ) { return read32( p ); };

  233.     virtual uint32_t read32a( uint32_t * p ) { return read32( (uint8_t*)p ); };

  234.     virtual uint64_t read64a( uint8_t * p ) { return read64( p ); };

  235.     virtual uint64_t read64a( uint64_t * p ) { return read64( (uint8_t*)p ); };

  236.     virtual void write16a( uint8_t * p, uint16_t w ) { write16( p, w ); };

  237.     virtual void write16a( uint16_t * p, uint16_t w ) { write16( (uint8_t*)p, w ); };

  238.     virtual void write32a( uint8_t * p, uint32_t w ) { write32( p, w ); };

  239.     virtual void write32a( uint32_t * p, uint32_t w ) { write32( (uint8_t*)p, w ); };

  240.     virtual void write64a( uint8_t * p, uint64_t w ) { write64( p, w ); };

  241.     virtual void write64a( uint64_t * p, uint64_t w ) { write64( (uint8_t*)p, w ); };

  242.   };

  243.  

  244. #endif


  245. class LittleEndianIO: public EndianIOBase

  246. {

  247.   public:

  248.     virtual uint16_t read16( uint8_t * p )

  249.     {

  250.       uint16_t w;

  251.       uint16_t hi, lo;

  252.       lo = *p;

  253.       hi = *( p + 1 );

  254.       w = hi << 8 | lo;

  255.       return w;

  256.     }

  257.     

  258.     virtual uint32_t read32( uint8_t * p )

  259.     {

  260.       uint32_t w;

  261.       uint32_t hi,

  262.       lo;

  263.       lo = read16( p );

  264.       hi = read16( p + 2 );

  265.       w = hi << 16 | lo;

  266.       return w;

  267.     }

  268.     

  269.     virtual uint64_t read64( uint8_t * p )

  270.     {

  271.       uint64_t w;

  272.       uint64_t hi,

  273.       lo;

  274.       lo = read32( p );

  275.       hi = read32( p + 4 );

  276.       w = hi << 32 | lo;

  277.       return w;

  278.     }

  279.     

  280.     virtual void write16( uint8_t * p, uint16_t w )

  281.     {

  282.       uint8_t hi,

  283.       lo;

  284.       hi =( w >> 8 )& 0xff;

  285.       lo = w & 0xff;

  286.       *p = lo;

  287.       *( p + 1 )= hi;

  288.     }

  289.     

  290.     virtual void write32( uint8_t * p, uint32_t w )

  291.     {

  292.       uint16_t hi,

  293.       lo;

  294.       hi =( w >> 16 )& 0xffff;

  295.       lo = w & 0xffff;

  296.       write16( p, lo );

  297.       write16( ( p + 2 ), hi );

  298.     }

  299.     

  300.     virtual void write64( uint8_t * p, uint64_t w )

  301.     {

  302.       uint32_t hi,

  303.       lo;

  304.       hi =( w >> 32 )& 0xffffffff;

  305.       lo = w & 0xffffffff;

  306.       write32( p, lo );

  307.       write32( ( p + 4 ), hi );

  308.     }

  309.     

  310.     // declare special methods for data we know is byte-aligned

  311.     virtual uint16_t read16a( uint8_t * p ) { return read16( p ); };

  312.     virtual uint16_t read16a( uint16_t * p ) { return read16( (uint8_t*)p ); };

  313.     virtual uint32_t read32a( uint8_t * p ) { return read32( p ); };

  314.     virtual uint32_t read32a( uint32_t * p ) { return read32( (uint8_t*)p ); };

  315.     virtual uint64_t read64a( uint8_t * p ) { return read64( p ); };

  316.     virtual uint64_t read64a( uint64_t * p ) { return read64( (uint8_t*)p ); };

  317.     virtual void write16a( uint8_t * p, uint16_t w ) { write16( p, w ); };

  318.     virtual void write16a( uint16_t * p, uint16_t w ) { write16( (uint8_t*)p, w ); };

  319.     virtual void write32a( uint8_t * p, uint32_t w ) { write32( p, w ); };

  320.     virtual void write32a( uint32_t * p, uint32_t w ) { write32( (uint8_t*)p, w ); };

  321.     virtual void write64a( uint8_t * p, uint64_t w ) { write64( p, w ); };

  322.     virtual void write64a( uint64_t * p, uint64_t w ) { write64( (uint8_t*)p, w ); };

  323. };

  324.  

  325. static EndianIOBase *BigEndian = new BigEndianIO( );

  326. static EndianIOBase *LittleEndian = new LittleEndianIO( );

  327.  

  328. #endif // ENDIAN_HPP
下面是main.cpp函数:
  1. #include "Endian.hpp"

  2. #include <stdint.h>

  3.  

  4. #include <stdio.h>

  5. #include <string.h>

  6.  

  7. int main( int argc, char *argv[] )

  8. {

  9.   uint8_t x[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };

  10.   uint8_t z[sizeof( x )];

  11.   uint16_t w16;

  12.   uint32_t w32;

  13.   uint64_t w64;

  14.   

  15.   uint16_t be16 = BigEndian->read16( x );

  16.   uint32_t be32 = BigEndian->read32( x );

  17.   uint64_t be64 = BigEndian->read64( x );

  18.   

  19.   printf( "be16 =%04x\n", be16 );

  20.   printf( "be32 =%08x\n", be32 );

  21.   printf( "be64 =%016llx\n", be64 );

  22.   

  23.   memset( z, 0, sizeof( z ) );

  24.   BigEndian->write16( z, be16 );

  25.   w16 = BigEndian->write16( be16 );

  26.   printf( "z = %02x %02x w16=%04x\n", z[0], z[1], w16 );

  27.   

  28.   memset( z, 0, sizeof( z ) );

  29.   BigEndian->write32( z, be32 );

  30.   w32 = BigEndian->write32( be32 );

  31.   printf( "z = %02x %02x %02x %02x w32=%08x\n", z[0], z[1], z[2], z[3], w32 );

  32.   

  33.   memset( z, 0, sizeof( z ) );

  34.   BigEndian->write64( z, be64 );

  35.   w64 = BigEndian->write64( be64 );

  36.   printf( "z = %02x %02x %02x %02x %02x %02x %02x %02x w64=%016llx\n", z[0],

  37.           z[1], z[2], z[3], z[4], z[5], z[6], z[7], w64 );

  38.           

  39.   uint16_t le16 = LittleEndian->read16( x );

  40.   uint32_t le32 = LittleEndian->read32( x );

  41.   uint64_t le64 = LittleEndian->read64( x );

  42.   

  43.   printf( "le16 =%04x\n", le16 );

  44.   printf( "le32 =%08x\n", le32 );

  45.   printf( "le64 =%016llx\n", le64 );

  46.   

  47.   memset( z, 0, sizeof( z ) );

  48.   LittleEndian->write16( z, le16 );

  49.   w16 = BigEndian->write16( be16 );

  50.   printf( "z = %02x %02x w16=%04x\n", z[0], z[1], w16 );

  51.   

  52.   memset( z, 0, sizeof( z ) );

  53.   LittleEndian->write32( z, le32 );

  54.   w32 = BigEndian->write32( be32 );

  55.   printf( "z = %02x %02x %02x %02x w32=%08x\n", z[0], z[1], z[2], z[3], w32 );

  56.   

  57.   memset( z, 0, sizeof( z ) );

  58.   LittleEndian->write64( z, le64 );

  59.   w64 = BigEndian->write64( be64 );

  60.   printf( "z = %02x %02x %02x %02x %02x %02x %02x %02x w64=%016llx\n", z[0],

  61.           z[1], z[2], z[3], z[4], z[5], z[6], z[7], w64 );

  62.           

  63.   return 0;

  64. }


Output:

be16 =0123

be32 =01234567

be64 =0123456789abcdef

z = 01 23 w16=2301

z = 01 23 45 67 w32=67452301

z = 01 23 45 67 89 ab cd ef w64=efcdab8967452301

le16 =2301

le32 =67452301

le64 =efcdab8967452301

z = 01 23 w16=2301

z = 01 23 45 67 w32=67452301

z = 01 23 45 67 89 ab cd ef w64=efcdab8967452301

阅读(588) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~