March 01, 1998
Control How COM Marshals Your Data
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
| |||||||||