in TPMCmd/tpm/src/support/TableDrivenMarshal.c [724:900]
UINT16 Marshal(
UINT16 typeIndex, // IN: the thing to marshal
void *source, // IN: were the data comes from
UINT8 **buffer, // IN/OUT: the data source buffer
INT32 *size // IN/OUT: the remaining size
)
{
#define _source ((UINT8 *)source)
const MarshalHeader_mst *sel;
UINT16 retVal;
//
sel = GetDescriptor(typeIndex);
switch(sel->marshalType)
{
case VALUES_MTYPE:
case UINT_MTYPE:
case TABLE_MTYPE:
case MIN_MAX_MTYPE:
case ATTRIBUTES_MTYPE:
case COMPOSITE_MTYPE:
{
#if BIG_ENDIAN_TPM
#define MM16 0
#define MM32 0
#define MM64 0
#else
// These flip the constant index values so that they count in reverse order when doing
// little-endian stuff
#define MM16 1
#define MM32 3
#define MM64 7
#endif
// Just change the name and cast the type of the input parameters for typing purposes
#define mb (*buffer)
#define _source ((UINT8 *)source)
retVal = (1 << (sel->modifiers & SIZE_MASK));
if(buffer != NULL)
{
if((size == NULL) || ((*size -= retVal) >= 0))
{
if(retVal == 4)
{
mb[0 ^ MM32] = _source[0];
mb[1 ^ MM32] = _source[1];
mb[2 ^ MM32] = _source[2];
mb[3 ^ MM32] = _source[3];
}
else if(retVal == 2)
{
mb[0 ^ MM16] = _source[0];
mb[1 ^ MM16] = _source[1];
}
else if(retVal == 1)
mb[0] = _source[0];
else
{
mb[0 ^ MM64] = _source[0];
mb[1 ^ MM64] = _source[1];
mb[2 ^ MM64] = _source[2];
mb[3 ^ MM64] = _source[3];
mb[4 ^ MM64] = _source[4];
mb[5 ^ MM64] = _source[5];
mb[6 ^ MM64] = _source[6];
mb[7 ^ MM64] = _source[7];
}
*buffer += retVal;
}
}
break;
}
case STRUCTURE_MTYPE:
{
//#define _mst ((StructMarshal_mst *)sel)
StructMarshal_mst *mst = ((StructMarshal_mst *)sel);
int i;
const UINT16 *value = mst->values;
//
for(retVal = 0, i = mst->elements; i > 0; value = &value[3], i--)
{
UINT16 des = value[0];
marshalIndex_t index = value[1];
UINT8 *offset = _source + value[2];
//
switch(GET_ELEMENT_TYPE(des))
{
case UNION_STYPE:
{
UINT32 choice;
//
choice = GetSelector(source, mst->values, des);
retVal += MarshalUnion(index, offset, buffer, size, choice);
break;
}
case ARRAY_STYPE:
{
UINT32 count;
//
count = GetSelector(source, mst->values, des);
retVal += ArrayMarshal(index, offset, buffer, size, count);
break;
}
case SIMPLE_STYPE:
default:
{
// This is either another structure or a simple type
retVal += Marshal(index, offset, buffer, size);
break;
}
}
}
break;
}
case TPM2B_MTYPE:
{
// Get the number of bytes being marshaled
INT32 val = (int32_t)*((UINT16 *)source);
//
retVal = Marshal(UINT16_MARSHAL_REF, source, buffer, size);
// This is a standard 2B with a byte buffer
retVal += MarshalBytes(((TPM2B *)_source)->buffer, buffer, size, val);
break;
}
case TPM2BS_MTYPE: // A structure in a TPM2B
{
Tpm2bsMarshal_mst *m2bst = (Tpm2bsMarshal_mst *)sel;
UINT8 *offset;
UINT16 amount;
UINT8 *marshaledSize;
//
// Save the address of where the size should go
marshaledSize = *buffer;
// marshal the size (checks the space and advanced the pointer)
retVal = Marshal(UINT16_MARSHAL_REF, source, buffer, size);
// This gets the 'offsetof' the structure to marshal. It was placed in the
// modifiers byte because the offset from the start of the TPM2B to the
// start of the structure is going to be less than 8 and the modifiers
// byte isn't needed for anything else.
offset = _source + (m2bst->modifiers & SIGNED_MASK);
// Marshal the structure and get its size
amount = Marshal(m2bst->dataIndex, offset, buffer, size);
// put the size in the space used when the size was marshaled.
if(buffer != NULL)
UINT16_TO_BYTE_ARRAY(amount, marshaledSize);
retVal += amount;
break;
}
case LIST_MTYPE:
{
ListMarshal_mst * mlt = ((ListMarshal_mst *)sel);
UINT8 *offset = _source + (mlt->modifiers & SIGNED_MASK);
retVal = Marshal(UINT32_MARSHAL_REF, source, buffer, size);
retVal += ArrayMarshal((marshalIndex_t)(mlt->arrayRef), offset,
buffer, size, *((UINT32 *)source));
break;
}
case NULL_MTYPE:
retVal = 0;
break;
case ERROR_MTYPE:
default:
{
if(size != NULL)
*size = -1;
retVal = 0;
break;
}
}
return retVal;
}