| version 1.1.2.2, 2013/06/28 11:06:31 | version 1.6.2.3, 2014/02/13 15:06:44 | 
| Line 1 | Line 1 | 
 |  | /************************************************************************* | 
 |  | * (C) 2013 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org> | 
 |  | *  by Michael Pounov <misho@elwix.org> | 
 |  | * | 
 |  | * $Author$ | 
 |  | * $Id$ | 
 |  | * | 
 |  | ************************************************************************** | 
 |  | The ELWIX and AITNET software is distributed under the following | 
 |  | terms: | 
 |  |  | 
 |  | All of the documentation and software included in the ELWIX and AITNET | 
 |  | Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> | 
 |  |  | 
 |  | Copyright 2004 - 2014 | 
 |  | by Michael Pounov <misho@elwix.org>.  All rights reserved. | 
 |  |  | 
 |  | Redistribution and use in source and binary forms, with or without | 
 |  | modification, are permitted provided that the following conditions | 
 |  | are met: | 
 |  | 1. Redistributions of source code must retain the above copyright | 
 |  | notice, this list of conditions and the following disclaimer. | 
 |  | 2. Redistributions in binary form must reproduce the above copyright | 
 |  | notice, this list of conditions and the following disclaimer in the | 
 |  | documentation and/or other materials provided with the distribution. | 
 |  | 3. All advertising materials mentioning features or use of this software | 
 |  | must display the following acknowledgement: | 
 |  | This product includes software developed by Michael Pounov <misho@elwix.org> | 
 |  | ELWIX - Embedded LightWeight unIX and its contributors. | 
 |  | 4. Neither the name of AITNET nor the names of its contributors | 
 |  | may be used to endorse or promote products derived from this software | 
 |  | without specific prior written permission. | 
 |  |  | 
 |  | THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND | 
 |  | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
 |  | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
 |  | ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
 |  | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
 |  | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
 |  | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
 |  | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
 |  | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
 |  | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
 |  | SUCH DAMAGE. | 
 |  | */ | 
 | #include "global.h" | #include "global.h" | 
 |  |  | 
 |  |  | 
| Line 55  rpack_destroy(rpack_t ** __restrict rp) | Line 100  rpack_destroy(rpack_t ** __restrict rp) | 
 | } | } | 
 |  |  | 
 | /* | /* | 
 |  | * rpack_attach() - Attach dynamic allocating buffer at packet | 
 |  | * | 
 |  | * @rp = raw packet; | 
 |  | * @len = allocate bytes | 
 |  | * return: -1 error or 0 ok, should be detached with rpack_detach() | 
 |  | *                              before call rpack_destroy() after use! | 
 |  | */ | 
 |  | int | 
 |  | rpack_attach(rpack_t * __restrict rp, size_t len) | 
 |  | { | 
 |  | if (!rp) | 
 |  | return -1; | 
 |  |  | 
 |  | rp->r_buf = e_malloc(len); | 
 |  | if (!rp->r_buf) { | 
 |  | RPACK_FREE(rp); | 
 |  | return -1; | 
 |  | } else | 
 |  | rp->r_len = len; | 
 |  | rp->r_next = rp->r_buf; | 
 |  |  | 
 |  | return 0; | 
 |  | } | 
 |  |  | 
 |  | /* | 
 |  | * rpack_resize() - Resize dynamic allocated buffer at packet | 
 |  | * | 
 |  | * @rp = raw packet | 
 |  | * @newlen = resize buffer to bytes | 
 |  | * return: -1 error or 0 ok, should be detached with rpack_detach() | 
 |  | *                              before call rpack_destroy() after use! | 
 |  | */ | 
 |  | int | 
 |  | rpack_resize(rpack_t * __restrict rp, size_t newlen) | 
 |  | { | 
 |  | void *buf = NULL; | 
 |  |  | 
 |  | if (!rp) | 
 |  | return -1; | 
 |  |  | 
 |  | buf = e_realloc(rp->r_buf, newlen); | 
 |  | if (!buf) | 
 |  | return -1; | 
 |  | else { | 
 |  | rp->r_buf = buf; | 
 |  | rp->r_len = newlen; | 
 |  | } | 
 |  |  | 
 |  | if (rp->r_next > (rp->r_buf + rp->r_len)) | 
 |  | rp->r_next = rp->r_buf; | 
 |  |  | 
 |  | return 0; | 
 |  | } | 
 |  |  | 
 |  | /* | 
 |  | * rpack_detach() - Detach and free dynamic allocated buffer from packet | 
 |  | * | 
 |  | * @rp = raw packet | 
 |  | * return: none | 
 |  | */ | 
 |  | void | 
 |  | rpack_detach(rpack_t * __restrict rp) | 
 |  | { | 
 |  | if (!rp) | 
 |  | return; | 
 |  |  | 
 |  | e_free(rp->r_buf); | 
 |  | RPACK_FREE(rp); | 
 |  | } | 
 |  |  | 
 |  | /* | 
 | * rpack_align_and_reserve() - Align & reserve space | * rpack_align_and_reserve() - Align & reserve space | 
 | * | * | 
 | * @rp = raw buffer | * @rp = raw buffer | 
| Line 88  rpack_align_and_reserve(rpack_t * __restrict rp, size_ | Line 204  rpack_align_and_reserve(rpack_t * __restrict rp, size_ | 
 | uint8_t | uint8_t | 
 | rpack_uint8(rpack_t * __restrict rp, uint8_t * __restrict n) | rpack_uint8(rpack_t * __restrict rp, uint8_t * __restrict n) | 
 | { | { | 
 |  | uint8_t u; | 
 |  |  | 
 | if (!RPACK_SANITY(rp)) | if (!RPACK_SANITY(rp)) | 
 | return (uint8_t) -1; | return (uint8_t) -1; | 
 | /* No space left */ | /* No space left */ | 
 | if ((size_t) (rp->r_next - rp->r_buf) >= rp->r_len) | if ((size_t) (rp->r_next - rp->r_buf) >= rp->r_len) | 
 | return (uint8_t) -1; | return (uint8_t) -1; | 
 |  |  | 
 |  | u = *rp->r_next; | 
 | if (n) | if (n) | 
 | *rp->r_next = *n; | *rp->r_next = *n; | 
| return *rp->r_next++; |  | 
|  | rp->r_next++; | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_uint16() - Pack/Unpack 16bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint16_t | 
|  | rpack_uint16(rpack_t * __restrict rp, uint16_t * __restrict n, int be) | 
|  | { | 
|  | uint16_t u; | 
|  | uint8_t *next; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint16_t) -1; | 
|  | /* No space left */ | 
|  | if (!(next = rpack_align_and_reserve(rp, sizeof(uint16_t)))) | 
|  | return (uint16_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_16(next) : EXTRACT_LE_16(next); | 
|  | if (n) | 
|  | RPACK_SET_16(next, n); | 
|  |  | 
|  | rp->r_next = next + sizeof(uint16_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_uint24() - Pack/Unpack 24bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint32_t | 
|  | rpack_uint24(rpack_t * __restrict rp, uint32_t * __restrict n, int be) | 
|  | { | 
|  | uint32_t u; | 
|  | uint8_t *next; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint32_t) -1; | 
|  | /* No space left */ | 
|  | if (!(next = rpack_align_and_reserve(rp, sizeof(uint32_t)))) | 
|  | return (uint32_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_24(next) : EXTRACT_LE_24(next); | 
|  | if (n) | 
|  | RPACK_SET_24(next, n); | 
|  |  | 
|  | rp->r_next = next + sizeof(uint32_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_uint32() - Pack/Unpack 32bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint32_t | 
|  | rpack_uint32(rpack_t * __restrict rp, uint32_t * __restrict n, int be) | 
|  | { | 
|  | uint32_t u; | 
|  | uint8_t *next; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint32_t) -1; | 
|  | /* No space left */ | 
|  | if (!(next = rpack_align_and_reserve(rp, sizeof(uint32_t)))) | 
|  | return (uint32_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_32(next) : EXTRACT_LE_32(next); | 
|  | if (n) | 
|  | RPACK_SET_32(next, n); | 
|  |  | 
|  | rp->r_next = next + sizeof(uint32_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_uint64() - Pack/Unpack 64bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint64_t | 
|  | rpack_uint64(rpack_t * __restrict rp, uint64_t * __restrict n, int be) | 
|  | { | 
|  | uint64_t u; | 
|  | uint8_t *next; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint64_t) -1; | 
|  | /* No space left */ | 
|  | if (!(next = rpack_align_and_reserve(rp, sizeof(uint64_t)))) | 
|  | return (uint64_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_64(next) : EXTRACT_LE_64(next); | 
|  | if (n) | 
|  | RPACK_SET_64(next, n); | 
|  |  | 
|  | rp->r_next = next + sizeof(uint64_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_data() - Pack/Unpack align data | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @dat = data | 
|  | * @datlen = data length | 
|  | * return: NULL error or != NULL get data, must be e_free() after use! | 
|  | */ | 
|  | void * | 
|  | rpack_data(rpack_t * __restrict rp, void * __restrict dat, size_t datlen) | 
|  | { | 
|  | void *buf = NULL; | 
|  | uint8_t *next; | 
|  |  | 
|  | if (!datlen || !RPACK_SANITY(rp)) | 
|  | return NULL; | 
|  | buf = e_malloc(datlen); | 
|  | if (!buf) | 
|  | return NULL; | 
|  | /* No space left */ | 
|  | if (!(next = rpack_align_and_reserve(rp, datlen))) { | 
|  | e_free(buf); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | memcpy(buf, next, datlen); | 
|  | if (dat) | 
|  | memcpy(next, dat, datlen); | 
|  |  | 
|  | rp->r_next = next + datlen; | 
|  | return buf; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_rdata() - Pack/Unpack raw data | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @dat = data | 
|  | * @datlen = data length | 
|  | * return: NULL error or != NULL get data, must be e_free() after use! | 
|  | */ | 
|  | void * | 
|  | rpack_rdata(rpack_t * __restrict rp, void * __restrict dat, size_t datlen) | 
|  | { | 
|  | void *buf = NULL; | 
|  |  | 
|  | if (!datlen || !RPACK_SANITY(rp)) | 
|  | return NULL; | 
|  | buf = e_malloc(datlen); | 
|  | if (!buf) | 
|  | return NULL; | 
|  | /* No space left */ | 
|  | if (datlen + rp->r_next - rp->r_buf > rp->r_len) { | 
|  | e_free(buf); | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | memcpy(buf, rp->r_next, datlen); | 
|  | if (dat) | 
|  | memcpy(rp->r_next, dat, datlen); | 
|  |  | 
|  | rp->r_next += datlen; | 
|  | return buf; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_ruint16() - Pack/Unpack raw 16bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint16_t | 
|  | rpack_ruint16(rpack_t * __restrict rp, uint16_t * __restrict n, int be) | 
|  | { | 
|  | uint16_t u; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint16_t) -1; | 
|  | /* No space left */ | 
|  | if (sizeof(uint16_t) + rp->r_next - rp->r_buf > rp->r_len) | 
|  | return (uint16_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_16(rp->r_next) : EXTRACT_LE_16(rp->r_next); | 
|  | if (n) | 
|  | RPACK_SET_16(rp->r_next, n); | 
|  |  | 
|  | rp->r_next += sizeof(uint16_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_ruint24() - Pack/Unpack raw 24bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint32_t | 
|  | rpack_ruint24(rpack_t * __restrict rp, uint32_t * __restrict n, int be) | 
|  | { | 
|  | uint32_t u; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint32_t) -1; | 
|  | /* No space left */ | 
|  | if (sizeof(uint32_t) + rp->r_next - rp->r_buf > rp->r_len) | 
|  | return (uint32_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_24(rp->r_next) : EXTRACT_LE_24(rp->r_next); | 
|  | if (n) | 
|  | RPACK_SET_24(rp->r_next, n); | 
|  |  | 
|  | rp->r_next += sizeof(uint32_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_ruint32() - Pack/Unpack raw 32bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint32_t | 
|  | rpack_ruint32(rpack_t * __restrict rp, uint32_t * __restrict n, int be) | 
|  | { | 
|  | uint32_t u; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint32_t) -1; | 
|  | /* No space left */ | 
|  | if (sizeof(uint32_t) + rp->r_next - rp->r_buf > rp->r_len) | 
|  | return (uint32_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_32(rp->r_next) : EXTRACT_LE_32(rp->r_next); | 
|  | if (n) | 
|  | RPACK_SET_32(rp->r_next, n); | 
|  |  | 
|  | rp->r_next += sizeof(uint32_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_ruint64() - Pack/Unpack raw 64bit value | 
|  | * | 
|  | * @rp = raw buffer | 
|  | * @n = set value if !=NULL | 
|  | * @be = extract in big-endian | 
|  | * return: -1 error or get value | 
|  | */ | 
|  | uint64_t | 
|  | rpack_ruint64(rpack_t * __restrict rp, uint64_t * __restrict n, int be) | 
|  | { | 
|  | uint64_t u; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return (uint64_t) -1; | 
|  | /* No space left */ | 
|  | if (sizeof(uint64_t) + rp->r_next - rp->r_buf > rp->r_len) | 
|  | return (uint64_t) -1; | 
|  |  | 
|  | u = be ? EXTRACT_BE_64(rp->r_next) : EXTRACT_LE_64(rp->r_next); | 
|  | if (n) | 
|  | RPACK_SET_64(rp->r_next, n); | 
|  |  | 
|  | rp->r_next += sizeof(uint64_t); | 
|  | return u; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_next() - Get and set current position | 
|  | * | 
|  | * @rp = raw packet | 
|  | * @after_len = move aligned current position after length | 
|  | * return: NULL error or current position | 
|  | */ | 
|  | uint8_t * | 
|  | rpack_next(rpack_t * __restrict rp, size_t after_len) | 
|  | { | 
|  | uint8_t *cur = NULL, *next = NULL; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return NULL; | 
|  | /* No space left */ | 
|  | if (!(next = rpack_align_and_reserve(rp, after_len))) | 
|  | return NULL; | 
|  |  | 
|  | cur = rp->r_next; | 
|  |  | 
|  | rp->r_next = next + after_len; | 
|  | return cur; | 
|  | } | 
|  |  | 
|  | /* | 
|  | * rpack_rnext() - Get and set raw current position | 
|  | * | 
|  | * @rp = raw packet | 
|  | * @after_len = !=0 move current position after length | 
|  | * return: NULL error or raw current position | 
|  | */ | 
|  | uint8_t * | 
|  | rpack_rnext(rpack_t * __restrict rp, size_t after_len) | 
|  | { | 
|  | uint8_t *next = NULL; | 
|  |  | 
|  | if (!RPACK_SANITY(rp)) | 
|  | return NULL; | 
|  | /* No space left */ | 
|  | if (after_len + rp->r_next - rp->r_buf > rp->r_len) | 
|  | return NULL; | 
|  |  | 
|  | next = rp->r_next; | 
|  |  | 
|  | rp->r_next += after_len; | 
|  | return next; | 
 | } | } |