Ejemplo n.º 1
0
PyObject * fudgepyc_convertStringToPython ( FudgeString source )
{
    PyObject * target = 0;
    fudge_byte * buffer;
    size_t written, bufsize;

    bufsize = FudgeString_getSize ( source ) * sizeof ( Py_UNICODE );
    if ( ! ( buffer = ( fudge_byte * ) PyMem_Malloc ( bufsize ) ) )
        return 0;

    /* See comment in fudgepyc_convertPythonToString for explanation */
    switch ( sizeof ( Py_UNICODE ) )
    {
        case 2:
            written = FudgeString_copyToUTF16 ( buffer, bufsize, source );
            break;

        case 4:
            written = FudgeString_copyToUTF32 ( buffer, bufsize, source );
            break;

        default:
            exception_raise_any ( PyExc_RuntimeError,
                                  "Cannot decode Fudge string; Python "
                                  "interpreter not using UCS2 or UCS4 for"
                                  "internal unicode encoding" );
            return 0;
    }

    target = PyUnicode_FromUnicode ( ( Py_UNICODE * ) buffer,
                                     written / sizeof ( Py_UNICODE ) );
    PyMem_Free ( buffer );
    return target;
}
Ejemplo n.º 2
0
/* Type coercing function for AddressDetails. Required, but can simply refuse
   to coerce the value (returning either FUDGE_COERCION_NOT_REQUIRED if the
   types match or FUDGE_INVALID_TYPE_COERCION if not).
   For this example a simple string conversion is supported. */
FudgeStatus FudgeType_coerceAddressDetails ( const FudgeField * source,
        const fudge_type_id type,
        FudgeFieldData * target,
        fudge_i32 * numbytes )
{
    /* Used for string output */
    static const char * statusString [ 3 ] = { "Unknown", "Active", "Past" };
    size_t statusInt;

    switch ( type )
    {
    case FUDGE_TYPE_ADDRESSDETAILS:
        return FUDGE_COERCION_NOT_REQUIRED;
    case FUDGE_TYPE_STRING:
    {
        FudgeStatus status;
        char * tempstr;
        const AddressDetails * details = ( const AddressDetails * ) source->data.bytes;
        int stringlen;

        /* Calculate how much space will be needed for the string and set
           the return value */
        stringlen = ADDRESSDETAILS_NAME_FIELD_LEN +
                    ADDRESSDETAILS_CITY_FIELD_LEN +
                    ADDRESSDETAILS_POST_FIELD_LEN + 32;

        /* Allocate string space in temporary buffer */
        if ( ! ( tempstr = ( char * ) malloc ( stringlen ) ) )
            return FUDGE_OUT_OF_MEMORY;

        /* Encode string - yes snprintf is better, but it's not portable
           enough for the example code. */
        statusInt = ( size_t ) ( details->status >= 0 && details->status <= 3 ? details->status
                                 : Status_Unknown );
        sprintf ( tempstr,
                  "[%s] %d %s, %s. %s.",
                  statusString [ statusInt ],
                  details->house_number,
                  details->street_name,
                  details->city,
                  details->postal_code );

        /* Use the temporary string to create the return value FudgeString */
        status = FudgeString_createFromASCIIZ ( &( target->string ), tempstr );
        free ( tempstr );
        *numbytes = FudgeString_getSize ( target->string );
        return status;
    }
    default:
        return FUDGE_INVALID_TYPE_COERCION;
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
FudgeStatus FudgeMsg_addFieldData ( FudgeMsg message,
                                    fudge_type_id type,
                                    const FudgeString name,
                                    const fudge_i16 * ordinal,
                                    FudgeFieldData * data,
                                    fudge_i32 numbytes )
{
    FudgeStatus status;
    FieldListNode * node;
    const FudgeTypeDesc * typedesc = FudgeRegistry_getTypeDesc ( type );

    if ( ! ( message && data ) )
        return FUDGE_NULL_POINTER;

    /* Adding a field will invalidate the message's width */
    message->width = -1;

    /* Allocate and initialise the new node, taking a copy of the name if required */
    if ( ! ( node = ( FieldListNode * ) malloc ( sizeof ( FieldListNode ) ) ) )
        return FUDGE_OUT_OF_MEMORY;
    node->next = 0;
    node->field.type = type;
    node->field.numbytes = numbytes;
    node->field.flags = 0;

    /* Copy across the data */
    if ( typedesc->payload == FUDGE_TYPE_PAYLOAD_SUBMSG && ! data->message )
        return FUDGE_NULL_POINTER;
    else if ( typedesc->payload == FUDGE_TYPE_PAYLOAD_STRING && ! data->string )
        return FUDGE_NULL_POINTER;
    node->field.data = *data;

    /* Set the field name (if required) */
    if ( name )
    {
        /* Names may not have a length greater than 255 bytes (only one byte is
           available for their length) */
        if ( FudgeString_getSize ( name ) >= 256 )
        {
            status = FUDGE_NAME_TOO_LONG;
            goto release_node_and_fail;
        }

        if ( ( status = FudgeString_retain ( name ) ) != FUDGE_OK )
            goto release_node_and_fail;

        node->field.name = name;
        node->field.flags |= FUDGE_FIELD_HAS_NAME;
    }
    else
    {
        node->field.name = 0;
    }

    /* Set the field ordinal (if required) */
    if ( ordinal )
    {
        node->field.ordinal = *ordinal;
        node->field.flags |= FUDGE_FIELD_HAS_ORDINAL;
    }
    else
        node->field.ordinal = 0;

    /* Append the node to the message's list */
    if ( message->fieldtail )
    {
        if ( message->fieldtail->next )
        {
            /* Field tail is pointing at a non-tail node - something's gone very wrong */
            assert ( message->fieldtail->next == 0 );
            FieldListNode_destroy ( node );
            return FUDGE_INTERNAL_LIST_STATE;
        }

        message->fieldtail->next = node;
        message->fieldtail = node;
    }
    else
        message->fieldhead = message->fieldtail = node;

    message->numfields += 1ul;
    return FUDGE_OK;

release_node_and_fail:
    free ( node );
    return status;
}