void FieldListNode_destroy ( FieldListNode * node ) { assert ( node ); switch ( node->field.type ) { /* Fudge message type: free the message pointer */ case FUDGE_TYPE_FUDGE_MSG: if ( node->field.data.message ) FudgeMsg_release ( node->field.data.message ); break; /* Fudge string type: free the string pointer */ case FUDGE_TYPE_STRING: if ( node->field.data.string ) FudgeString_release ( node->field.data.string ); break; /* Primitive type: nothing needs freeing */ case FUDGE_TYPE_INDICATOR: case FUDGE_TYPE_BOOLEAN: case FUDGE_TYPE_BYTE: case FUDGE_TYPE_SHORT: case FUDGE_TYPE_INT: case FUDGE_TYPE_LONG: case FUDGE_TYPE_FLOAT: case FUDGE_TYPE_DOUBLE: case FUDGE_TYPE_DATE: case FUDGE_TYPE_TIME: case FUDGE_TYPE_DATETIME: break; /* Every other type will store its data in the bytes array */ default: free ( ( fudge_byte * ) node->field.data.bytes ); break; } if ( node->field.name ) FudgeString_release ( node->field.name ); free ( node ); }
FudgeStatus FudgeMsg_addFieldString ( FudgeMsg message, const FudgeString name, const fudge_i16 * ordinal, FudgeString string ) { FudgeStatus status; FudgeFieldData data; size_t stringbytes; if ( ! ( message && string ) ) return FUDGE_NULL_POINTER; stringbytes = FudgeString_getSize ( string ); if ( stringbytes > 0x7FFFFFFF ) return FUDGE_PAYLOAD_TOO_LONG; if ( ( status = FudgeString_retain ( string ) ) != FUDGE_OK ) return status; data.string = string; if ( ( status = FudgeMsg_addFieldData ( message, FUDGE_TYPE_STRING, name, ordinal, &data, ( fudge_i32 ) stringbytes ) ) != FUDGE_OK ) FudgeString_release ( string ); return status; }
FudgeStatus FudgeCodec_decodeField ( FudgeMsg message, FudgeFieldHeader header, fudge_i32 width, const fudge_byte * bytes, fudge_i32 numbytes ) { FudgeStatus status; FudgeTypeDecoder decoder; FudgeFieldData data; FudgeString name; const FudgeTypeDesc * typedesc = FudgeRegistry_getTypeDesc ( header.type ); if ( width > numbytes ) return FUDGE_OUT_OF_BYTES; /* If available for this type, use the registered decoder. Failing that, treat it as an array of bytes. */ decoder = typedesc->decoder ? typedesc->decoder : FudgeCodec_decodeFieldByteArray; memset ( &data, 0, sizeof ( data ) ); if ( ( status = decoder ( bytes, width, &data ) ) != FUDGE_OK ) return status; /* Construct the name string if required */ if ( header.name ) { if ( ( status = FudgeString_createFromUTF8 ( &name, header.name, header.namelen ) ) != FUDGE_OK ) return status; } else name = 0; status = FudgeMsg_addFieldData ( message, header.type, name, FudgeHeader_getOrdinal ( &header ), &data, FudgeCodec_getNumBytes ( typedesc, width ) ); if ( header.name ) FudgeString_release ( name ); return status; }
int main ( int argc, char * argv [ ] ) { FudgeStatus status; FudgeMsg message; FudgeMsgEnvelope envelope; AddressDetails * details [ 2 ]; fudge_i16 ordinal; fudge_byte * encoded; fudge_i32 encodedsize; /* Initialise the Fudge library */ if ( ( status = Fudge_init ( ) ) ) fatalFudgeError ( status, "Failed to initialise Fudge library" ); /* Register the AddressDetails type */ if ( ( status = FudgeRegistry_registerType ( FUDGE_TYPE_ADDRESSDETAILS, FUDGE_TYPE_PAYLOAD_BYTES, FudgeCodec_decodeFieldAddressDetails, FudgeCodec_encodeFieldAddressDetails, FudgeType_coerceAddressDetails ) ) ) fatalFudgeError ( status, "Failed to register AddressDetails type" ); /* Construct and encode two address details */ details [ 0 ] = constructAddressDetails ( Status_Past, 123, "Fake St.", "Some City", "P05 T4L" ); details [ 1 ] = constructAddressDetails ( Status_Active, 45, "Faux Road", "Some Town", "FUD 63C" ); /* Create a message and add the two details */ if ( ( status = FudgeMsg_create ( &message ) ) ) fatalFudgeError ( status, "Failed to create Fudge message" ); for ( ordinal = 0; ordinal < 2; ++ordinal ) FudgeMsg_addFieldAddressDetails ( message, 0, &ordinal, details [ ordinal ] ); /* Encode the message */ if ( ( status = FudgeMsgEnvelope_create ( &envelope, 0, 0, 0, message ) ) ) fatalFudgeError ( status, "Failed to create Fudge messag envelope" ); if ( ( status = FudgeCodec_encodeMsg ( envelope, &encoded, &encodedsize ) ) ) fatalFudgeError ( status, "Failed to encode Fudge message" ); /* Clean up source details and messge */ free ( details [ 0 ] ); free ( details [ 1 ] ); FudgeMsgEnvelope_release ( envelope ); FudgeMsg_release ( message ); /* Decode the message and release the encoded bytes array */ if ( ( status = FudgeCodec_decodeMsg ( &envelope, encoded, encodedsize ) ) ) fatalFudgeError ( status, "Failed to decode Fudge message" ); free ( encoded ); /* Retrieve, convert and display the fields */ for ( ordinal = 0; ordinal < 2; ++ordinal ) { FudgeField field; FudgeFieldData data; FudgeTypePayload payload; fudge_i32 datasize; char * ascii; if ( ( status = FudgeMsg_getFieldByOrdinal ( &field, FudgeMsgEnvelope_getMessage ( envelope ), ordinal ) ) ) fatalFudgeError ( status, "Failed to find field" ); /* Convert the field in to a string */ if ( ( status = FudgeMsg_getFieldAs ( &field, FUDGE_TYPE_STRING, &data, &payload, &datasize ) ) ) fatalFudgeError ( status, "Failed to convert field to string" ); /* This is a bit paranoid, but it's checking that the string conversion actually resulted in string payload */ if ( payload != FUDGE_TYPE_PAYLOAD_STRING ) { fprintf ( stderr, "FATAL ERROR: Retrieving field %d as a string returned a non-string!\n", ordinal ); exit ( 1 ); } FudgeString_convertToASCIIZ ( &ascii, data.string ); printf ( "Field %d: %s\n", ordinal, ascii ); free ( ascii ); FudgeString_release ( data.string ); } /* Clean up */ FudgeMsgEnvelope_release ( envelope ); return 0; }