From: Pekka Riikonen Date: Wed, 9 Oct 2002 19:00:10 +0000 (+0000) Subject: Added silc_attribute_payload_encode_data, renamed parse_list to X-Git-Tag: silc.client.0.9.6~40 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=7134a9d911de0a5bf49f855f54b0252e70f0b58e;p=silc.git Added silc_attribute_payload_encode_data, renamed parse_list to parse. Added silc_attribute_payload_alloc as well. Some bugfixes. --- diff --git a/lib/silccore/silcattrs.c b/lib/silccore/silcattrs.c index 370d91ef..302c17be 100644 --- a/lib/silccore/silcattrs.c +++ b/lib/silccore/silcattrs.c @@ -35,62 +35,22 @@ struct SilcAttributePayloadStruct { unsigned char *data; }; -/* Parse one attribute payload */ - -SilcAttributePayload -silc_attribute_payload_parse(const unsigned char *payload, - SilcUInt32 payload_len) +/* Internal routine for encoding a attribute */ + +static unsigned char * +silc_attribute_payload_encode_int(SilcAttribute attribute, + SilcAttributeFlags flags, + void *object, + SilcUInt32 object_size, + SilcUInt32 *ret_len) { - SilcBufferStruct buffer; - SilcAttributePayload newp; - int ret; - - SILC_LOG_DEBUG(("Parsing attribute payload")); - - silc_buffer_set(&buffer, (unsigned char *)payload, payload_len); - newp = silc_calloc(1, sizeof(*newp)); - if (!newp) - return NULL; - - /* Parse the Attribute Payload. */ - ret = silc_buffer_unformat(&buffer, - SILC_STR_UI_CHAR(&newp->attribute), - SILC_STR_UI_CHAR(&newp->flags), - SILC_STR_UI16_NSTRING_ALLOC(&newp->data, - &newp->data_len), - SILC_STR_END); - if (ret == -1) - goto err; - - if (newp->data_len > buffer.len - 4) { - SILC_LOG_ERROR(("Incorrect attribute payload")); - goto err; - } - - return newp; - - err: - silc_attribute_payload_free(newp); - return NULL; -} - -/* Encode one attribute payload to buffer */ - -SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, - SilcAttribute attribute, - SilcAttributeFlags flags, - void *object, - SilcUInt32 object_size) -{ - SilcBuffer buffer, tmpbuf = NULL; - unsigned char tmp[4], *str = NULL; + SilcBuffer tmpbuf = NULL; + unsigned char tmp[4], *str = NULL, *ret; int len; - SILC_LOG_DEBUG(("Encoding Attribute Payload")); - /* Encode according to attribute type */ if (flags & SILC_ATTRIBUTE_FLAG_VALID) { - if (!object || !object_size) + if (!object && !object_size) return NULL; switch (attribute) { @@ -112,6 +72,8 @@ SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, SILC_PUT16_MSB(len, str + 4); memcpy(str + 6, service->address, len); str[6 + len] = service->status; + object = str; + object_size = 7 + len; } break; @@ -174,6 +136,8 @@ SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, SILC_STR_UI16_STRING(geo->altitude), SILC_STR_UI16_STRING(geo->accuracy), SILC_STR_END); + object = tmpbuf->data; + object_size = tmpbuf->len; } break; @@ -197,6 +161,8 @@ SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, SILC_STR_UI16_STRING(dev->model), SILC_STR_UI16_STRING(dev->language), SILC_STR_END); + object = tmpbuf->data; + object_size = tmpbuf->len; } break; @@ -215,6 +181,8 @@ SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, SILC_STR_UI16_STRING(pk->type), SILC_STR_UI_XNSTRING(pk->data, pk->data_len), SILC_STR_END); + object = tmpbuf->data; + object_size = tmpbuf->len; } break; @@ -233,41 +201,53 @@ SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, return NULL; break; } - } - buffer = attrs; - len = 4 + object_size; + ret = silc_memdup(object, object_size); + + if (tmpbuf) + silc_buffer_free(tmpbuf); + silc_free(str); - if (!buffer) { - buffer = silc_buffer_alloc_size(len); - } else { - buffer = silc_buffer_realloc(buffer, - (buffer ? buffer->truelen + len : len)); - silc_buffer_pull_tail(buffer, (buffer->end - buffer->data)); + if (ret_len) + *ret_len = object_size; + + return ret; } - silc_buffer_format(buffer, - SILC_STR_UI_CHAR(attribute), - SILC_STR_UI_CHAR(flags), - SILC_STR_UI_SHORT((SilcUInt16)object_size), - SILC_STR_UI_XNSTRING(object, object_size), - SILC_STR_END); + return NULL; +} - silc_buffer_pull(buffer, len); - if (buffer) - silc_buffer_push(buffer, buffer->data - buffer->head); +/* Allocates attribute payload and encodes the attribute there */ - if (tmpbuf) - silc_buffer_free(tmpbuf); - silc_free(str); +SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute, + SilcAttributeFlags flags, + void *object, + SilcUInt32 object_size) +{ + SilcAttributePayload attr; - return buffer; + attr = silc_calloc(1, sizeof(*attr)); + if (!attr) + return NULL; + + attr->attribute = attribute; + attr->flags = flags; + attr->data = + silc_attribute_payload_encode_int(attribute, flags, object, + object_size, + (SilcUInt32 *)&attr->data_len); + if (!attr->data) { + silc_free(attr); + return NULL; + } + + return attr; } /* Parse list of payloads */ -SilcDList silc_attribute_payload_parse_list(const unsigned char *payload, - SilcUInt32 payload_len) +SilcDList silc_attribute_payload_parse(const unsigned char *payload, + SilcUInt32 payload_len) { SilcBufferStruct buffer; SilcDList list; @@ -312,6 +292,53 @@ SilcDList silc_attribute_payload_parse_list(const unsigned char *payload, return NULL; } +/* Encode one attribute payload to buffer */ + +SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, + SilcAttribute attribute, + SilcAttributeFlags flags, + void *object, + SilcUInt32 object_size) +{ + object = silc_attribute_payload_encode_int(attribute, flags, object, + object_size, &object_size); + attrs = silc_attribute_payload_encode_data(attrs, attribute, flags, + (const unsigned char *)object, + object_size); + silc_free(object); + return attrs; +} + +/* Encoded the attribute data directly to buffer */ + +SilcBuffer silc_attribute_payload_encode_data(SilcBuffer attrs, + SilcAttribute attribute, + SilcAttributeFlags flags, + const unsigned char *data, + SilcUInt32 data_len) +{ + SilcBuffer buffer = attrs; + int len; + + len = 4 + data_len; + buffer = silc_buffer_realloc(buffer, + (buffer ? buffer->truelen + len : len)); + if (!buffer) + return NULL; + silc_buffer_pull(buffer, buffer->len); + silc_buffer_pull_tail(buffer, len); + silc_buffer_format(buffer, + SILC_STR_UI_CHAR(attribute), + SILC_STR_UI_CHAR(flags), + SILC_STR_UI_SHORT((SilcUInt16)data_len), + SILC_STR_UI_XNSTRING(data, data_len), + SILC_STR_END); + if (buffer) + silc_buffer_push(buffer, buffer->data - buffer->head); + + return buffer; +} + /* Free Attribute Payload */ void silc_attribute_payload_free(SilcAttributePayload payload) @@ -362,17 +389,15 @@ const unsigned char *silc_attribute_get_data(SilcAttributePayload payload, /* Return parsed attribute object */ bool silc_attribute_get_object(SilcAttributePayload payload, - SilcAttribute attribute, void **object, SilcUInt32 object_size) { SilcUInt16 len; bool ret = FALSE; - if (!attribute || payload->attribute != attribute || !object || !(*object) || - payload->flags & SILC_ATTRIBUTE_FLAG_INVALID) + if (!object || !(*object) || payload->flags & SILC_ATTRIBUTE_FLAG_INVALID) return FALSE; - switch (attribute) { + switch (payload->attribute) { case SILC_ATTRIBUTE_USER_INFO: SILC_NOT_IMPLEMENTED("SILC_ATTRIBUTE_USER_INFO"); break; diff --git a/lib/silccore/silcattrs.h b/lib/silccore/silcattrs.h index dd924708..deb8a026 100644 --- a/lib/silccore/silcattrs.h +++ b/lib/silccore/silcattrs.h @@ -177,23 +177,48 @@ typedef enum { } SilcAttributeDevice; /***/ +/****f* silccore/SilcAttributesAPI/silc_attribute_payload_alloc + * + * SYNOPSIS + * + * SilcAttributesPayload + * silc_attribute_payload_alloc(SilcAttribute attribute, + * SilcAttributeFlags flags, + * void *object, + * SilcUInt32 object_size); + * + * DESCRIPTION + * + * Allocates and encodes the attribute indicated by `attribute' and + * returns pointer to the attribute. + * + * The `object' must always be the same data type as defined with + * SilcAttribute (see the comments) for all attributes. + * + ***/ +SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute, + SilcAttributeFlags flags, + void *object, + SilcUInt32 object_size); + /****f* silccore/SilcAttributesAPI/silc_attribute_payload_parse * * SYNOPSIS * - * SilcAttributePayload + * SilcDList * silc_attribute_payload_parse(const unsigned char *payload, * SilcUInt32 payload_len); * * DESCRIPTION * - * Parses one attribute payload sent as argument and saves it to - * SilcAttributePayload context. The new allocated context is returned. + * Parses list of Attribute payloads returning list of payloads. + * One entry in the returned list is SilcAttributesPayload. You + * can produce such a list with silc_attribute_payload_encode + * function. * ***/ -SilcAttributePayload -silc_attribute_payload_parse(const unsigned char *payload, - SilcUInt32 payload_len); +SilcDList silc_attribute_payload_parse(const unsigned char *payload, + SilcUInt32 payload_len); /****f* silccore/SilcAttributesAPI/silc_attribute_payload_encode * @@ -212,7 +237,8 @@ silc_attribute_payload_parse(const unsigned char *payload, * was reallocated. If `attrs' is NULL for first attribute this * allocates the buffer and returns it. This can be called multiple * times to add multiple attributes to the `attrs' buffer. The `flags' - * indicates the validity of the added attribute. + * indicates the validity of the added attribute. Returns NULL on + * error. * * The `object' must always be the same data type as defined with * SilcAttribute (see the comments) for all attributes. @@ -224,25 +250,32 @@ SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, void *object, SilcUInt32 object_size); -/****f* silccore/SilcAttributesAPI/silc_attribute_payload_parse_list +/****f* silccore/SilcAttributesAPI/silc_attribute_payload_encode_data * * SYNOPSIS * - * SilcDList - * silc_attribute_payload_parse_list(const unsigned char *payload, - * SilcUInt32 payload_len); + * SilcBuffer + * silc_attribute_payload_encode_data(SilcBuffer attrs, + * SilcAttribute attribute, + * SilcAttributeFlags flags, + * const unsigned char *data, + * SilcUInt32 data_len); * * DESCRIPTION * - * Parses list of Attribute payloads returning list of payloads. This - * is equivalent to the silc_attribute_payload_parse except that the - * `buffer' now includes multiple Attribute Payloads one after the other. - * You can produce such a list with silc_attribute_payload_encode - * function. + * Same function as silc_attribute_payload_encode except the attribute + * is already encoded into `data' of `data_len' bytes in length. + * Encodes the attribute into the `attrs' buffer and returns pointer + * to the buffer, which may be different in case the buffer was + * reallocated. If `attrs' is NULL for first attribute this allocates + * the buffer and returns it. Returns NULL on error. * ***/ -SilcDList silc_attribute_payload_parse_list(const unsigned char *payload, - SilcUInt32 payload_len); +SilcBuffer silc_attribute_payload_encode_data(SilcBuffer attrs, + SilcAttribute attribute, + SilcAttributeFlags flags, + const unsigned char *data, + SilcUInt32 data_len); /****f* silccore/SilcAttributesAPI/silc_attribute_payload_free * @@ -424,24 +457,24 @@ typedef struct { * SYNOPSIS * * bool silc_attribute_get_object(SilcAttributePayload payload, - * SilcAttribute attribute, * void **object, * SilcUInt32 object_size); * * DESCRIPTION * - * Returns the already parsed attribute object by the attribute type - * indicated by `attribute'. Copies the data into the `object' which + * Returns the already parsed attribute object from the payload + * indicated by `payload'. Copies the data into the `object' which * must be sent as argument (and must be of correct type and size). * The `object_size' indicates the size of the `*object' sent. * Returns TRUE if the `attribute' attribute was found and FALSE * if such attribute is not present in the `payload', or the `object_size' * is not sufficient. See the definition of SilcAttribute for the * list of attributes and the required object types for attributes. + * You can use silc_attribute_get_attribute to get the SilcAttribute + * type from the `payload'. * ***/ bool silc_attribute_get_object(SilcAttributePayload payload, - SilcAttribute attribute, void **object, SilcUInt32 object_size); #endif /* SILCATTRS_H */