Listing 2: marshal.c Custom data marshaling/unmarshaling code
// Custom Marshalling Code to compress/decompress BOOL Array // before and after transmission. // Author : Fran Heeran #include "objidl.h" #include "rpcproxy.h" #include "sobj.h" #include "marsamp.h" // ==================================================== // Called to Marshal Array of BOOLS into the RPC buffer // ==================================================== unsigned char __RPC_FAR * __RPC_USER LPMYARRAY_UserMarshal( ULONG __RPC_FAR *pFlags, BYTE __RPC_FAR *pBuffer, LPMYARRAY __RPC_FAR *pArr) { BOOL *pBoolArr = *pArr; int i; BYTE mask = 0x80; BYTE value = 0; // We need to be true to our wire_type definition so // insert the data size here *((short *)pBuffer) = (FLAG_ARRAY_SIZE / 8); pBuffer += sizeof(short); // Loop through the array packing 8 BOOL values per BYTE for (i = 0;i < FLAG_ARRAY_SIZE;i++) { if (*pBoolArr++) value |= mask; // If we are doing the 8th element - Store // the value and reset mask and value elements if (mask == 1) { mask = 0x80; *pBuffer++ = value; value = 0; } else mask = mask >> 1; // On to the next bit } // pBuffer must point to the first byte after our marshalled data return pBuffer; } // ========================================================= // Called to Unmarshal bitfields back into an Array of BOOLS // ========================================================= unsigned char __RPC_FAR * __RPC_USER LPMYARRAY_UserUnmarshal( ULONG __RPC_FAR *pFlags, BYTE __RPC_FAR *pBuffer, LPMYARRAY __RPC_FAR *pArr) { BOOL *pArray; BYTE mask = 0x80; int i; pBuffer += sizeof(short); // Skip past tthe size field // Allocate user memory for the array pArray = CoTaskMemAlloc(FLAG_ARRAY_SIZE * sizeof(BOOL)); *pArr = pArray; // Rebuild the original data from bitfields by cycling // through each bit in the bytes for (i = 0;i < FLAG_ARRAY_SIZE;i++) { if (*pBuffer & mask) *pArray++ = TRUE; else *pArray++ = FALSE; if (mask == 1) { mask = 0x80; pBuffer++; } else mask = mask >> 1; } // pBuffer must point to first byte after our marshaled data return pBuffer; } // ============================================================= // Returns the amount of space our compressed array will require // ============================================================= unsigned long __RPC_USER LPMYARRAY_UserSize( ULONG __RPC_FAR *pFlags, ULONG startingSize, LPMYARRAY __RPC_FAR *pStr) { return startingSize + (FLAG_ARRAY_SIZE / 8) + sizeof(short); } // =========================================================== // Free's the memory allocated when the array was unmarshalled // =========================================================== void __RPC_USER LPMYARRAY_UserFree(ULONG __RPC_FAR *pFlags, LPMYARRAY __RPC_FAR *pStr) { CoTaskMemFree((LPVOID)*pStr); } //End of File