Annotation of libaitio/src/vars.c, revision 1.1.2.6

1.1.2.1   misho       1: /*************************************************************************
                      2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
                      3: *  by Michael Pounov <misho@elwix.org>
                      4: *
                      5: * $Author: misho $
1.1.2.6 ! misho       6: * $Id: vars.c,v 1.1.2.5 2011/09/07 01:26:08 misho Exp $
1.1.2.1   misho       7: *
                      8: **************************************************************************
                      9: The ELWIX and AITNET software is distributed under the following
                     10: terms:
                     11: 
                     12: All of the documentation and software included in the ELWIX and AITNET
                     13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
                     14: 
                     15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
                     16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
                     17: 
                     18: Redistribution and use in source and binary forms, with or without
                     19: modification, are permitted provided that the following conditions
                     20: are met:
                     21: 1. Redistributions of source code must retain the above copyright
                     22:    notice, this list of conditions and the following disclaimer.
                     23: 2. Redistributions in binary form must reproduce the above copyright
                     24:    notice, this list of conditions and the following disclaimer in the
                     25:    documentation and/or other materials provided with the distribution.
                     26: 3. All advertising materials mentioning features or use of this software
                     27:    must display the following acknowledgement:
                     28: This product includes software developed by Michael Pounov <misho@elwix.org>
                     29: ELWIX - Embedded LightWeight unIX and its contributors.
                     30: 4. Neither the name of AITNET nor the names of its contributors
                     31:    may be used to endorse or promote products derived from this software
                     32:    without specific prior written permission.
                     33: 
                     34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
                     35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     44: SUCH DAMAGE.
                     45: */
                     46: #include "global.h"
                     47: 
                     48: 
1.1.2.2   misho      49: /*
                     50:  * io_vals2buffer() Marshaling data from array with variables to buffer
                     51:  * @buf = Buffer
                     52:  * @buflen = Size of buffer
                     53:  * @vars = Variable array
                     54:  * return: -1 error, 0 nothing done or >0 size of marshaled data
                     55:  */
                     56: int
1.1.2.3   misho      57: io_vals2buffer(u_char *buf, int buflen, array_t *vars)
1.1.2.2   misho      58: {
                     59:        int Limit = 0;
                     60:        register int i;
                     61:        ait_val_t *v, *val;
                     62:        u_char *data;
                     63: 
                     64:        assert(buf);
                     65:        assert(vars);
1.1.2.3   misho      66:        if (!buf || !vars)
1.1.2.2   misho      67:                return -1;
                     68:        if (!buflen || !io_arraySize(vars))
                     69:                return 0;
                     70: 
                     71:        Limit = sizeof(ait_val_t) * io_arraySize(vars);
                     72:        if (Limit > buflen) {
                     73:                io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", 
                     74:                                buflen, Limit);
                     75:                return -1;
                     76:        } else {
1.1.2.3   misho      77:                memset(buf, 0, buflen);
1.1.2.2   misho      78: 
1.1.2.3   misho      79:                v = (ait_val_t*) buf;
                     80:                data = buf + Limit;
1.1.2.2   misho      81:        }
                     82: 
                     83:        /* marshaling */
                     84:        for (i = 0; i < io_arraySize(vars); i++) {
                     85:                val = io_array(vars, i, ait_val_t*);
                     86: 
                     87:                v[i].val_type = val->val_type;
                     88:                AIT_LEN(&v[i]) = htobe32(AIT_LEN(val));
                     89: 
                     90:                switch (AIT_TYPE(val)) {
                     91:                        case blob:
                     92:                        case f32:
                     93:                        case f64:
                     94:                        case i8:
                     95:                        case i16:
                     96:                        case i32:
                     97:                        case i64:
                     98:                        case u8:
                     99:                        case u16:
                    100:                        case u32:
                    101:                        case u64:
                    102:                                v[i].val.net = htobe64(val->val.net);
                    103:                                break;
                    104:                        case buffer:
                    105:                        case string:
                    106:                                if (AIT_LEN(val) > buflen - Limit) {
                    107:                                        io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
                    108:                                                        "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
                    109:                                        return -1;
                    110:                                } else
                    111:                                        Limit += AIT_LEN(val);
                    112: 
                    113:                                memcpy(data, val->val.buffer, AIT_LEN(val));
                    114:                                /* Debug:: data offset in packet, not matter for anything! */
1.1.2.3   misho     115:                                v[i].val.net = data - buf;
1.1.2.2   misho     116:                                data += AIT_LEN(val);
                    117:                                break;
                    118:                        default:
                    119:                                io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", 
                    120:                                                AIT_TYPE(val), i);
                    121:                                return -1;
                    122:                }
                    123:        }
                    124: 
                    125:        return Limit;
                    126: }
                    127: 
                    128: /*
                    129:  * io_buffer2vals() De-marshaling data from buffer to array with variables
                    130:  * @buf = Buffer
                    131:  * @buflen = Size of buffer
                    132:  * @vnum = Number of variables into buffer
                    133:  * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and 
                    134:                *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy()
                    135:  * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy()
                    136:  */
                    137: array_t *
                    138: io_buffer2vals(u_char *buf, int buflen, int vnum, int zcpy)
                    139: {
                    140:        array_t *vars;
                    141:        int Limit = 0;
                    142:        register int i;
                    143:        ait_val_t *v, *val;
                    144:        u_char *data;
                    145: 
                    146:        assert(buf);
                    147:        if (!buf || !buflen || !vnum)
                    148:                return NULL;
                    149: 
                    150:        Limit = sizeof(ait_val_t) * vnum;
                    151:        if (Limit > buflen) {
                    152:                io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", 
                    153:                                buflen, Limit);
                    154:                return NULL;
                    155:        } else {
                    156:                if (!(vars = io_arrayInit(vnum)))
                    157:                        return NULL;
                    158: 
                    159:                v = (ait_val_t*) buf;
                    160:                data = buf + Limit;
                    161:        }
                    162: 
                    163:        /* de-marshaling */
                    164:        for (i = 0; i < io_arraySize(vars); i++) {
                    165:                if (!zcpy) {
                    166:                        val = malloc(sizeof(ait_val_t));
                    167:                        if (!val) {
                    168:                                LOGERR;
                    169:                                io_arrayFree(vars);
                    170:                                io_arrayDestroy(&vars);
                    171:                                return NULL;
                    172:                        }
                    173:                } else
                    174:                        val = v + i;
                    175:                io_arraySet(vars, i, val);
                    176: 
                    177:                val->val_type = v[i].val_type;
1.1.2.5   misho     178: #if defined(__OpenBSD__)
1.1.2.2   misho     179:                AIT_LEN(val) = betoh32(AIT_LEN(&v[i]));
1.1.2.5   misho     180: #else
                    181:                AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
                    182: #endif
1.1.2.2   misho     183: 
                    184:                switch (AIT_TYPE(val)) {
                    185:                        case blob:
                    186:                        case f32:
                    187:                        case f64:
                    188:                        case i8:
                    189:                        case i16:
                    190:                        case i32:
                    191:                        case i64:
                    192:                        case u8:
                    193:                        case u16:
                    194:                        case u32:
                    195:                        case u64:
1.1.2.5   misho     196: #if defined(__OpenBSD__)
1.1.2.2   misho     197:                                val->val.net = betoh64(v[i].val.net);
1.1.2.5   misho     198: #else
                    199:                                val->val.net = be64toh(v[i].val.net);
                    200: #endif
1.1.2.2   misho     201:                                break;
                    202:                        case buffer:
                    203:                        case string:
                    204:                                if (AIT_LEN(val) > buflen - Limit) {
                    205:                                        io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
                    206:                                                        "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
                    207:                                        if (!zcpy)
                    208:                                                io_arrayFree(vars);
                    209:                                        io_arrayDestroy(&vars);
                    210:                                        return NULL;
                    211:                                } else
                    212:                                        Limit += AIT_LEN(val);
                    213: 
1.1.2.4   misho     214:                                if (!zcpy) {
                    215:                                        val->val.buffer = malloc(AIT_LEN(val));
                    216:                                        if (!val->val.buffer) {
                    217:                                                LOGERR;
                    218:                                                io_arrayFree(vars);
                    219:                                                io_arrayDestroy(&vars);
                    220:                                                return NULL;
                    221:                                        } else
                    222:                                                memcpy(val->val.buffer, data, AIT_LEN(val));
                    223:                                } else
1.1.2.2   misho     224:                                        val->val.buffer = data;
                    225:                                data += AIT_LEN(val);
                    226:                                break;
                    227:                        default:
                    228:                                io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", 
                    229:                                                AIT_TYPE(val), i);
                    230:                                if (!zcpy)
                    231:                                        io_arrayFree(vars);
                    232:                                io_arrayDestroy(&vars);
                    233:                                return NULL;
                    234:                }
                    235:        }
                    236: 
                    237:        return vars;
                    238: }
1.1.2.6 ! misho     239: 
        !           240: /* buffer marshaling without swapping bytes to network order */
        !           241: 
        !           242: /*
        !           243:  * io_vals2map() Marshaling data from array with variables to memory map
        !           244:  * @buf = Buffer
        !           245:  * @buflen = Size of buffer
        !           246:  * @vars = Variable array
        !           247:  * return: -1 error, 0 nothing done or >0 size of marshaled data
        !           248:  */
        !           249: int
        !           250: io_vals2map(u_char *buf, int buflen, array_t *vars)
        !           251: {
        !           252:        int Limit = 0;
        !           253:        register int i;
        !           254:        ait_val_t *v, *val;
        !           255:        u_char *data;
        !           256: 
        !           257:        assert(buf);
        !           258:        assert(vars);
        !           259:        if (!buf || !vars)
        !           260:                return -1;
        !           261:        if (!buflen || !io_arraySize(vars))
        !           262:                return 0;
        !           263: 
        !           264:        Limit = sizeof(ait_val_t) * io_arraySize(vars);
        !           265:        if (Limit > buflen) {
        !           266:                io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", 
        !           267:                                buflen, Limit);
        !           268:                return -1;
        !           269:        } else {
        !           270:                memset(buf, 0, buflen);
        !           271: 
        !           272:                v = (ait_val_t*) buf;
        !           273:                data = buf + Limit;
        !           274:        }
        !           275: 
        !           276:        /* marshaling */
        !           277:        for (i = 0; i < io_arraySize(vars); i++) {
        !           278:                val = io_array(vars, i, ait_val_t*);
        !           279: 
        !           280:                v[i].val_type = val->val_type;
        !           281:                AIT_LEN(&v[i]) = AIT_LEN(val);
        !           282: 
        !           283:                switch (AIT_TYPE(val)) {
        !           284:                        case blob:
        !           285:                        case f32:
        !           286:                        case f64:
        !           287:                        case i8:
        !           288:                        case i16:
        !           289:                        case i32:
        !           290:                        case i64:
        !           291:                        case u8:
        !           292:                        case u16:
        !           293:                        case u32:
        !           294:                        case u64:
        !           295:                                v[i].val.net = val->val.net;
        !           296:                                break;
        !           297:                        case buffer:
        !           298:                        case string:
        !           299:                                if (AIT_LEN(val) > buflen - Limit) {
        !           300:                                        io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
        !           301:                                                        "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
        !           302:                                        return -1;
        !           303:                                } else
        !           304:                                        Limit += AIT_LEN(val);
        !           305: 
        !           306:                                memcpy(data, val->val.buffer, AIT_LEN(val));
        !           307:                                /* Debug:: data offset in packet, not matter for anything! */
        !           308:                                v[i].val.net = data - buf;
        !           309:                                data += AIT_LEN(val);
        !           310:                                break;
        !           311:                        default:
        !           312:                                io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", 
        !           313:                                                AIT_TYPE(val), i);
        !           314:                                return -1;
        !           315:                }
        !           316:        }
        !           317: 
        !           318:        return Limit;
        !           319: }
        !           320: 
        !           321: /*
        !           322:  * io_map2vals() De-marshaling data from memory map to array with variables
        !           323:  * @buf = Buffer
        !           324:  * @buflen = Size of buffer
        !           325:  * @vnum = Number of variables into buffer
        !           326:  * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and 
        !           327:                *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy()
        !           328:  * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy()
        !           329:  */
        !           330: array_t *
        !           331: io_map2vals(u_char *buf, int buflen, int vnum, int zcpy)
        !           332: {
        !           333:        array_t *vars;
        !           334:        int Limit = 0;
        !           335:        register int i;
        !           336:        ait_val_t *v, *val;
        !           337:        u_char *data;
        !           338: 
        !           339:        assert(buf);
        !           340:        if (!buf || !buflen || !vnum)
        !           341:                return NULL;
        !           342: 
        !           343:        Limit = sizeof(ait_val_t) * vnum;
        !           344:        if (Limit > buflen) {
        !           345:                io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d needed min %d ...\n", 
        !           346:                                buflen, Limit);
        !           347:                return NULL;
        !           348:        } else {
        !           349:                if (!(vars = io_arrayInit(vnum)))
        !           350:                        return NULL;
        !           351: 
        !           352:                v = (ait_val_t*) buf;
        !           353:                data = buf + Limit;
        !           354:        }
        !           355: 
        !           356:        /* de-marshaling */
        !           357:        for (i = 0; i < io_arraySize(vars); i++) {
        !           358:                if (!zcpy) {
        !           359:                        val = malloc(sizeof(ait_val_t));
        !           360:                        if (!val) {
        !           361:                                LOGERR;
        !           362:                                io_arrayFree(vars);
        !           363:                                io_arrayDestroy(&vars);
        !           364:                                return NULL;
        !           365:                        }
        !           366:                } else
        !           367:                        val = v + i;
        !           368:                io_arraySet(vars, i, val);
        !           369: 
        !           370:                val->val_type = v[i].val_type;
        !           371:                AIT_LEN(val) = AIT_LEN(&v[i]);
        !           372: 
        !           373:                switch (AIT_TYPE(val)) {
        !           374:                        case blob:
        !           375:                        case f32:
        !           376:                        case f64:
        !           377:                        case i8:
        !           378:                        case i16:
        !           379:                        case i32:
        !           380:                        case i64:
        !           381:                        case u8:
        !           382:                        case u16:
        !           383:                        case u32:
        !           384:                        case u64:
        !           385:                                val->val.net = v[i].val.net;
        !           386:                                break;
        !           387:                        case buffer:
        !           388:                        case string:
        !           389:                                if (AIT_LEN(val) > buflen - Limit) {
        !           390:                                        io_SetErr(EMSGSIZE, "Error:: too short buffer buflen=%d "
        !           391:                                                        "needed min %d ...\n", buflen, Limit + AIT_LEN(val));
        !           392:                                        if (!zcpy)
        !           393:                                                io_arrayFree(vars);
        !           394:                                        io_arrayDestroy(&vars);
        !           395:                                        return NULL;
        !           396:                                } else
        !           397:                                        Limit += AIT_LEN(val);
        !           398: 
        !           399:                                if (!zcpy) {
        !           400:                                        val->val.buffer = malloc(AIT_LEN(val));
        !           401:                                        if (!val->val.buffer) {
        !           402:                                                LOGERR;
        !           403:                                                io_arrayFree(vars);
        !           404:                                                io_arrayDestroy(&vars);
        !           405:                                                return NULL;
        !           406:                                        } else
        !           407:                                                memcpy(val->val.buffer, data, AIT_LEN(val));
        !           408:                                } else
        !           409:                                        val->val.buffer = data;
        !           410:                                data += AIT_LEN(val);
        !           411:                                break;
        !           412:                        default:
        !           413:                                io_SetErr(EINVAL, "Error:: unsupported variable type=%d at element #%d ...\n", 
        !           414:                                                AIT_TYPE(val), i);
        !           415:                                if (!zcpy)
        !           416:                                        io_arrayFree(vars);
        !           417:                                io_arrayDestroy(&vars);
        !           418:                                return NULL;
        !           419:                }
        !           420:        }
        !           421: 
        !           422:        return vars;
        !           423: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>