Advanced C++ Trick: packing data

(1/1)

Richard Marks:
The idea is to store 4 8bit unsigned char values in a single 32bit unsigned long integer variable.

Here is code to do just that.  ;D
Code:

// 8-bits (a single byte)  0 to 255 decimal
typedef unsigned char  u8; 
// 16-bit unsigned integer 0 to 65535 decimal.
typedef unsigned short u16;
// 32-bit unsigned integer 0 to 4294967295 decimal.
typedef unsigned long  u32;

// pack two 8bit values in a 16bit variable
void U16_Packin(u8 a, u8 b, u16& store)
{
   store = ((u16)(((u8)(a)) | (((u16)((u8)(b))) << 8)));
}

// pack two 16bit values in a 32bit variable
void U32_Packin(u16 a, u16 b, u32& store)
{
   store = ((u32)(((u16)(a)) | (((u32)((u16)(b))) << 16)));
}

// unpack two 8bit values from a 16bit variable
void U16_Unpack(u16& packed, u8& storeA, u8& storeB)
{
   storeA = ((u8)(packed));
   storeB = ((u8)(((u16)(packed) >> 8) & 0xFF));
}

// unpack two 16bit values from a 32bit variable
void U32_Unpack(u32& packed, u16& storeA, u16& storeB)
{
   storeA = ((u16)((u32)(packed)));
   storeB = ((u16)(((u32)(packed) >> 16) & 0xFFFF));
}


Here is an example of using it.
Code:

void CreateMapEvent(u8 id, u8* params, u32& store)
{
   u16 packetA, packetB;
   U16_Packin(id, params[0], packetA);
   U16_Packin(params[1], params[2], packetB);
   U32_Packin(packetA, packetB, store);
}

char* GetEventType(u32& evnt)
{
   if (evnt)
   {
      u16 packet, junk;
      U32_Unpack(evnt, packet, junk);
      u8 id, junk2;
      U16_Unpack(packet, id, junk2);
      switch(id)
      {
      case 128:
         {
            return "Map Warp";
         } break;
      default:
         return "Unknown Event Type";
      }
   }
   return "No Event";
}

char get_event_parameter_storage[256];
char* GetEventParameter(u32& evnt, int index)
{
   if (evnt)
   {
      u16 packetA, packetB;
      U32_Unpack(evnt, packetA, packetB);
      u8 param1, param2, param3, junk;
      U16_Unpack(packetA, junk, param1);
      U16_Unpack(packetB, param2, param3);
      ChrMapChar params[] = {param1, param2, param3};
      index -= 1;
      index = index % 3;
      sprintf_s(get_event_parameter_storage,256, "%u", params[index]);
      return get_event_parameter_storage;
   }
   return "?";
}

int main(int argc, char* argv[])
{
   u32 testEvent = 0;
   u8 warpID = 128, x = 24, y = 17;
   u8 params[] = {x, y, 0};
   CreateMapEvent(warpID, params, testEvent);

   printf(2, 2, "Event        : %u", testEvent);
   printf(2, 4, "Event Type   : %s", GetEventType(testEvent));
   printf(2, 6, "Event Param 1: %s", GetEventParameter(testEvent, 1));
   printf(2, 8, "Event Param 2: %s", GetEventParameter(testEvent, 2));
   return 0;
}

Navigation

[0] Message Index