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

1.2     ! misho       1: /*************************************************************************
        !             2: * (C) 2011 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
        !             3: *  by Michael Pounov <misho@elwix.org>
        !             4: *
        !             5: * $Author: misho $
        !             6: * $Id: vars.c,v 1.1.2.6 2011/09/07 13:49:28 misho Exp $
        !             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: 
        !            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
        !            57: io_vals2buffer(u_char *buf, int buflen, array_t *vars)
        !            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);
        !            66:        if (!buf || !vars)
        !            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 {
        !            77:                memset(buf, 0, buflen);
        !            78: 
        !            79:                v = (ait_val_t*) buf;
        !            80:                data = buf + Limit;
        !            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! */
        !           115:                                v[i].val.net = data - buf;
        !           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;
        !           178: #if defined(__OpenBSD__)
        !           179:                AIT_LEN(val) = betoh32(AIT_LEN(&v[i]));
        !           180: #else
        !           181:                AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
        !           182: #endif
        !           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:
        !           196: #if defined(__OpenBSD__)
        !           197:                                val->val.net = betoh64(v[i].val.net);
        !           198: #else
        !           199:                                val->val.net = be64toh(v[i].val.net);
        !           200: #endif
        !           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: 
        !           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
        !           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: }
        !           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>