Annotation of libelwix/src/vars.c, revision 1.13

1.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.13    ! misho       6: * $Id: vars.c,v 1.12.6.1 2022/10/24 00:09:07 misho Exp $
1.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: 
1.10      misho      15: Copyright 2004 - 2022
1.1       misho      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.4       misho      49: static inline int
1.1       misho      50: vars2buffer(u_char * __restrict buf, int buflen, int be, array_t * __restrict vars)
                     51: {
                     52:        int Limit = 0;
                     53:        register int i;
                     54:        ait_val_t *v, *val;
                     55:        u_char *dat;
                     56: 
                     57:        assert(buf);
                     58:        assert(vars);
                     59:        if (!buf || !vars)
                     60:                return -1;
                     61:        if (!buflen || !array_Size(vars))
                     62:                return 0;
                     63:        be = !!be;
                     64: 
                     65:        Limit = sizeof(ait_val_t) * array_Size(vars);
                     66:        if (Limit > buflen) {
                     67:                elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", 
                     68:                                buflen, Limit);
                     69:                return -1;
                     70:        } else {
                     71:                memset(buf, 0, buflen);
                     72: 
                     73:                v = (ait_val_t*) buf;
                     74:                dat = buf + Limit;
                     75:        }
                     76: 
                     77:        /* marshaling */
                     78:        for (i = 0; i < array_Size(vars); i++) {
                     79:                val = array(vars, i, ait_val_t*);
                     80: 
                     81:                v[i].val_type = val->val_type;
                     82:                AIT_IN(&v[i]) = 1;
                     83:                AIT_BE(&v[i]) = be;
                     84:                AIT_LE(&v[i]) = !be;
                     85:                if (AIT_BE(&v[i])) {
                     86:                        AIT_KEY(&v[i]) = htobe16(AIT_KEY(val));
                     87:                        AIT_LEN(&v[i]) = htobe32(AIT_LEN(val));
                     88:                }
                     89:                if (AIT_LE(&v[i])) {
                     90:                        AIT_KEY(&v[i]) = htole16(AIT_KEY(val));
                     91:                        AIT_LEN(&v[i]) = htole32(AIT_LEN(val));
                     92:                }
                     93: 
                     94:                switch (AIT_TYPE(val)) {
                     95:                        case blob:
                     96:                        case f32:
                     97:                        case f64:
                     98:                        case i8:
                     99:                        case i16:
                    100:                        case i32:
                    101:                        case i64:
                    102:                        case u8:
                    103:                        case u16:
                    104:                        case u32:
                    105:                        case u64:
                    106:                                if (AIT_BE(&v[i]))
                    107:                                        v[i].val.net = htobe64(val->val.net);
                    108:                                if (AIT_LE(&v[i]))
                    109:                                        v[i].val.net = htole64(val->val.net);
                    110:                                break;
                    111:                        case data:
                    112:                                if (AIT_LEN(val) > buflen - Limit) {
                    113:                                        elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d "
                    114:                                                        "needed min %d", buflen, Limit + AIT_LEN(val));
                    115:                                        return -1;
                    116:                                } else
                    117:                                        Limit += AIT_LEN(val);
                    118: 
                    119:                                memcpy(dat, val->val_data, AIT_LEN(val));
                    120:                                /* Debug:: data offset in packet, not matter for anything! */
                    121:                                v[i].val.net = dat - buf;
                    122:                                dat += AIT_LEN(val);
                    123:                                break;
                    124:                        case buffer:
                    125:                        case string:
1.5       misho     126:                        case ptr:
1.1       misho     127:                                if (AIT_LEN(val) > buflen - Limit) {
                    128:                                        elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d "
                    129:                                                        "needed min %d", buflen, Limit + AIT_LEN(val));
                    130:                                        return -1;
                    131:                                } else
                    132:                                        Limit += AIT_LEN(val);
                    133: 
                    134:                                memcpy(dat, val->val.buffer, AIT_LEN(val));
                    135:                                /* Debug:: data offset in packet, not matter for anything! */
                    136:                                v[i].val.net = dat - buf;
                    137:                                dat += AIT_LEN(val);
                    138:                                break;
                    139:                        default:
                    140:                                elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", 
                    141:                                                AIT_TYPE(val), i);
                    142:                                return -1;
                    143:                }
                    144:        }
                    145: 
                    146:        return Limit;
                    147: }
                    148: 
1.4       misho     149: static inline array_t *
1.1       misho     150: buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
                    151: {
                    152:        array_t *vars;
                    153:        int Limit = 0;
                    154:        register int i;
                    155:        ait_val_t *v, *val;
                    156:        u_char *dat;
                    157: 
                    158:        assert(buf);
                    159:        if (!buf || !buflen || !vnum)
                    160:                return NULL;
                    161: 
                    162:        Limit = sizeof(ait_val_t) * vnum;
                    163:        if (Limit > buflen) {
                    164:                elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", 
                    165:                                buflen, Limit);
                    166:                return NULL;
                    167:        } else {
                    168:                if (!(vars = array_Init(vnum)))
                    169:                        return NULL;
                    170: 
                    171:                v = (ait_val_t*) buf;
                    172:                dat = buf + Limit;
                    173:        }
                    174: 
                    175:        /* de-marshaling */
                    176:        for (i = 0; i < array_Size(vars); i++) {
                    177:                if (!zcpy) {
                    178:                        val = e_malloc(sizeof(ait_val_t));
                    179:                        if (!val) {
                    180:                                if (!zcpy)
                    181:                                        array_Free(vars);
                    182:                                array_Destroy(&vars);
                    183:                                return NULL;
                    184:                        }
                    185:                        AIT_IN(val) = 0;
                    186:                } else {
                    187:                        val = v + i;
                    188:                        AIT_IN(val) = 1;
                    189:                }
                    190:                array_Set(vars, i, val);
                    191: 
                    192:                val->val_type = v[i].val_type;
                    193:                AIT_BE(val) = AIT_BE(&v[i]);
                    194:                AIT_LE(val) = AIT_LE(&v[i]);
                    195:                if (AIT_BE(val)) {
                    196:                        AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
                    197:                        AIT_KEY(val) = be16toh(AIT_KEY(&v[i]));
                    198:                }
                    199:                if (AIT_LE(val)) {
                    200:                        AIT_LEN(val) = le32toh(AIT_LEN(&v[i]));
                    201:                        AIT_KEY(val) = le16toh(AIT_KEY(&v[i]));
                    202:                }
                    203: 
                    204:                switch (AIT_TYPE(val)) {
                    205:                        case blob:
                    206:                        case f32:
                    207:                        case f64:
                    208:                        case i8:
                    209:                        case i16:
                    210:                        case i32:
                    211:                        case i64:
                    212:                        case u8:
                    213:                        case u16:
                    214:                        case u32:
                    215:                        case u64:
                    216:                                if (AIT_BE(val))
                    217:                                        val->val.net = be64toh(v[i].val.net);
                    218:                                if (AIT_LE(val))
                    219:                                        val->val.net = le64toh(v[i].val.net);
                    220:                                break;
                    221:                        case data:
1.5       misho     222:                        case ptr:
                    223:                                /* WARNING:: remap data and ptr type to buffer! */
1.1       misho     224:                                val->val_type = buffer;
                    225:                        case buffer:
                    226:                        case string:
                    227:                                if (!zcpy) {
                    228:                                        val->val.buffer = e_malloc(AIT_LEN(val));
                    229:                                        if (!val->val.buffer) {
                    230:                                                array_Free(vars);
                    231:                                                array_Destroy(&vars);
                    232:                                                return NULL;
                    233:                                        } else
                    234:                                                memcpy(val->val.buffer, dat, AIT_LEN(val));
                    235:                                } else
                    236:                                        val->val.buffer = dat;
                    237:                                dat += AIT_LEN(val);
                    238:                                break;
                    239:                        default:
                    240:                                elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", 
                    241:                                                AIT_TYPE(val), i);
                    242:                                if (!zcpy)
                    243:                                        array_Free(vars);
                    244:                                array_Destroy(&vars);
                    245:                                return NULL;
                    246:                }
                    247:        }
                    248: 
                    249:        return vars;
                    250: }
                    251: 
1.10      misho     252: /*
1.12      misho     253:  * ait_var2tlv() - Marshaling data from variable to TLV buffer
                    254:  *
                    255:  * @buf = Buffer, If =NULL then we return only needed buffer size
                    256:  * @buflen = Size of buffer
                    257:  * @var = Variable
                    258:  * return: -1 error, 0 nothing done or >0 size of marshaled data
                    259:  */
                    260: int
                    261: ait_var2tlv(u_char * __restrict buf, int buflen, ait_val_t * __restrict v)
                    262: {
                    263:        int Limit = 0;
                    264:        u_char *dat;
                    265: 
                    266:        assert(v);
                    267:        if (!v)
                    268:                return -1;
                    269:        if (AIT_TYPE(v) == empty)
                    270:                return 0;
                    271: 
                    272:        /* calculate amount of data into buffer */
                    273:        Limit = 5 + AIT_LEN(v);
                    274:        /* check only needed buffer size */
                    275:        if (!buf)
                    276:                return Limit;
                    277:        else
                    278:                dat = buf;
                    279: 
                    280:        if (Limit > buflen) {
                    281:                elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", 
                    282:                                buflen, Limit);
                    283:                return -1;
                    284:        } else
                    285:                memset(buf, 0, buflen);
                    286: 
                    287:        /* marshaling */
                    288:        *dat++ = AIT_TYPE(v); 
                    289: 
                    290:        *((uint32_t*) dat) = htonl(AIT_LEN(v));
                    291:        dat += sizeof(uint32_t);
                    292: 
                    293:        switch (AIT_TYPE(v)) {
                    294:                case i8:
                    295:                        *((int8_t*) dat) = AIT_GET_I8(v);
                    296:                        break;
                    297:                case u8:
                    298:                        *((uint8_t*) dat) = AIT_GET_U8(v);
                    299:                        break;
                    300:                case i16:
                    301:                        *((int16_t*) dat) = AIT_GET_I16(v);
                    302:                        break;
                    303:                case u16:
                    304:                        *((uint16_t*) dat) = AIT_GET_U16(v);
                    305:                        break;
                    306:                case i32:
                    307:                        *((int32_t*) dat) = AIT_GET_I32(v);
                    308:                        break;
                    309:                case blob:
                    310:                case u32:
                    311:                        *((uint32_t*) dat) = AIT_GET_U32(v);
                    312:                        break;
                    313:                case i64:
                    314:                        *((int64_t*) dat) = AIT_GET_I64(v);
                    315:                        break;
                    316:                case u64:
                    317:                        *((uint64_t*) dat) = AIT_GET_U64(v);
                    318:                        break;
                    319:                case f32:
                    320:                        *((float*) dat) = AIT_GET_F32(v);
                    321:                        break;
                    322:                case f64:
                    323:                        *((double*) dat) = AIT_GET_F64(v);
                    324:                        break;
                    325:                case data:
                    326:                        memcpy(dat, AIT_GET_DATA(v), AIT_LEN(v));
                    327:                        break;
                    328:                case buffer:
                    329:                        memcpy(dat, AIT_GET_BUF(v), AIT_LEN(v));
                    330:                        break;
                    331:                case string:
                    332:                        memcpy(dat, AIT_GET_STR(v), AIT_LEN(v));
                    333:                        break;
                    334:                case ptr:
                    335:                        memcpy(dat, AIT_GET_PTR(v), AIT_LEN(v));
                    336:                        break;
                    337:                default:
                    338:                        elwix_SetErr(EINVAL, "Unsupported variable type=%d", AIT_TYPE(v));
                    339:                        return -1;
                    340:        }
                    341: 
                    342:        return Limit;
                    343: }
                    344: 
                    345: /*
1.10      misho     346:  * ait_vars2tlv() - Marshaling data from array with variables to TLV buffer
                    347:  *
                    348:  * @buf = Buffer, If =NULL then we return only needed buffer size
                    349:  * @buflen = Size of buffer
                    350:  * @vars = Variable array
                    351:  * return: -1 error, 0 nothing done or >0 size of marshaled data
                    352:  */
                    353: int
                    354: ait_vars2tlv(u_char * __restrict buf, int buflen, array_t * __restrict vars)
                    355: {
                    356:        int Limit = 0;
                    357:        register int i;
                    358:        ait_val_t *val;
                    359:        u_char *dat;
                    360: 
                    361:        assert(vars);
                    362:        if (!vars)
                    363:                return -1;
                    364:        if (!array_Size(vars))
                    365:                return 0;
                    366: 
                    367:        /* calculate amount of data into buffer */
                    368:        for (i = 0, Limit = 0; i < array_Size(vars); 
                    369:                        Limit += 5 + AIT_LEN(array(vars, i, ait_val_t*)), i++);
                    370:        /* check only needed buffer size */
                    371:        if (!buf)
                    372:                return Limit;
                    373: 
                    374:        if (Limit > buflen) {
                    375:                elwix_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", 
                    376:                                buflen, Limit);
                    377:                return -1;
                    378:        } else
                    379:                memset(buf, 0, buflen);
                    380: 
                    381:        /* marshaling */
                    382:        for (i = 0, dat = buf; i < array_Size(vars) && dat < (buf + Limit); i++) {
                    383:                val = array(vars, i, ait_val_t*);
                    384: 
                    385:                *dat++ = AIT_TYPE(val); 
                    386: 
                    387:                *((uint32_t*) dat) = htonl(AIT_LEN(val));
                    388:                dat += sizeof(uint32_t);
                    389: 
                    390:                switch (AIT_TYPE(val)) {
                    391:                        case i8:
                    392:                                *((int8_t*) dat) = AIT_GET_I8(val);
                    393:                                break;
                    394:                        case u8:
                    395:                                *((uint8_t*) dat) = AIT_GET_U8(val);
                    396:                                break;
                    397:                        case i16:
                    398:                                *((int16_t*) dat) = AIT_GET_I16(val);
                    399:                                break;
                    400:                        case u16:
                    401:                                *((uint16_t*) dat) = AIT_GET_U16(val);
                    402:                                break;
                    403:                        case i32:
                    404:                                *((int32_t*) dat) = AIT_GET_I32(val);
                    405:                                break;
                    406:                        case blob:
                    407:                        case u32:
                    408:                                *((uint32_t*) dat) = AIT_GET_U32(val);
                    409:                                break;
                    410:                        case i64:
                    411:                                *((int64_t*) dat) = AIT_GET_I64(val);
                    412:                                break;
                    413:                        case u64:
                    414:                                *((uint64_t*) dat) = AIT_GET_U64(val);
                    415:                                break;
                    416:                        case f32:
                    417:                                *((float*) dat) = AIT_GET_F32(val);
                    418:                                break;
                    419:                        case f64:
                    420:                                *((double*) dat) = AIT_GET_F64(val);
                    421:                                break;
                    422:                        case data:
                    423:                                memcpy(dat, AIT_GET_DATA(val), AIT_LEN(val));
                    424:                                break;
                    425:                        case buffer:
                    426:                                memcpy(dat, AIT_GET_BUF(val), AIT_LEN(val));
                    427:                                break;
                    428:                        case string:
                    429:                                memcpy(dat, AIT_GET_STR(val), AIT_LEN(val));
                    430:                                break;
                    431:                        case ptr:
                    432:                                memcpy(dat, AIT_GET_PTR(val), AIT_LEN(val));
                    433:                                break;
                    434:                        default:
                    435:                                elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", 
                    436:                                                AIT_TYPE(val), i);
                    437:                                return -1;
                    438:                }
                    439:                dat += AIT_LEN(val);
                    440:        }
                    441: 
                    442:        return Limit;
                    443: }
                    444: 
                    445: /*
1.12      misho     446:  * ait_tlv2var() - De-marshaling data from TLV buffer to variable
                    447:  *
                    448:  * @buf = Buffer
                    449:  * @buflen = Size of buffer
                    450:  * @next_tlv = Next TLV position, if it is !=NULL 
                    451:  * return: =NULL error, !=NULL allocated variable array, after use must free with ait_freeVar()
                    452:  */
                    453: ait_val_t *
                    454: ait_tlv2var(u_char * __restrict buf, int buflen, off_t *next_tlv)
                    455: {
                    456:        ait_val_t *val;
                    457:        u_char *dat;
                    458: 
                    459:        assert(buf);
                    460:        if (!buf || !buflen)
                    461:                return NULL;
                    462: 
                    463:        if (!(val = ait_allocVar()))
                    464:                return NULL;
                    465:        else
                    466:                dat = buf;
                    467: 
                    468:        /* de-marshaling */
                    469:        if (*dat != empty) {
                    470:                val->val_type = *dat++;
                    471:                AIT_LEN(val) = ntohl(*((uint32_t*) dat));
                    472:                dat += sizeof(uint32_t);
                    473:                
                    474:                switch (AIT_TYPE(val)) {
                    475:                        case f32:
                    476:                                AIT_SET_F32(val, *((float*) dat));
                    477:                                break;
                    478:                        case f64:
                    479:                                AIT_SET_F64(val, *((double*) dat));
                    480:                                break;
                    481:                        case i8:
                    482:                                AIT_SET_I8(val, *((int8_t*) dat));
                    483:                                break;
                    484:                        case i16:
                    485:                                AIT_SET_I16(val, *((int16_t*) dat));
                    486:                                break;
                    487:                        case i32:
                    488:                                AIT_SET_I32(val, *((int32_t*) dat));
                    489:                                break;
                    490:                        case i64:
                    491:                                AIT_SET_I64(val, *((int64_t*) dat));
                    492:                                break;
                    493:                        case u8:
                    494:                                AIT_SET_U8(val, *((uint8_t*) dat));
                    495:                                break;
                    496:                        case u16:
                    497:                                AIT_SET_U16(val, *((uint16_t*) dat));
                    498:                                break;
                    499:                        case blob:
                    500:                        case u32:
                    501:                                AIT_SET_U32(val, *((uint32_t*) dat));
                    502:                                break;
                    503:                        case u64:
                    504:                                AIT_SET_U64(val, *((uint64_t*) dat));
                    505:                                break;
                    506:                        case data:
                    507:                                AIT_SET_DATA(val, dat, AIT_LEN(val));
                    508:                                break;
                    509:                        case ptr:
                    510:                        case buffer:
                    511:                                AIT_SET_BUF(val, dat, AIT_LEN(val));
                    512:                                break;
                    513:                        case string:
                    514:                                AIT_SET_STR(val, (char*) dat);
                    515:                                break;
                    516:                        default:
                    517:                                elwix_SetErr(EINVAL, "Unsupported variable type=%d", AIT_TYPE(val));
                    518:                                ait_freeVar(&val);
                    519:                                return NULL;
                    520:                }
                    521:                dat += AIT_LEN(val);
                    522:        }
                    523: 
                    524:        if (next_tlv)
                    525:                *next_tlv = dat - buf;
                    526: 
                    527:        return val;
                    528: }
                    529: 
                    530: /*
1.10      misho     531:  * ait_tlv2vars() - De-marshaling data from TLV buffer to array with variables
                    532:  *
                    533:  * @buf = Buffer
                    534:  * @buflen = Size of buffer
                    535:  * return: =NULL error, !=NULL allocated variable array, after use must free with ait_freeVars()
                    536:  */
                    537: array_t *
                    538: ait_tlv2vars(u_char * __restrict buf, int buflen)
                    539: {
                    540:        array_t *vars;
                    541:        register int i;
                    542:        ait_val_t *val;
                    543:        u_char *dat;
                    544: 
                    545:        assert(buf);
                    546:        if (!buf || !buflen)
                    547:                return NULL;
                    548: 
                    549:        if (!(vars = ait_allocVars(1)))
                    550:                return NULL;
                    551: 
                    552:        /* de-marshaling */
                    553:        for (i = 0, dat = buf; *dat != empty && dat < (buf + buflen); i++) {
                    554:                val = ait_getVars(&vars, i);
                    555:                if (!val) {
                    556:                        ait_freeVars(&vars);
                    557:                        return NULL;
                    558:                }
                    559: 
                    560:                val->val_type = *dat++;
                    561:                AIT_LEN(val) = ntohl(*((uint32_t*) dat));
                    562:                dat += sizeof(uint32_t);
                    563:                
                    564:                switch (AIT_TYPE(val)) {
                    565:                        case f32:
                    566:                                AIT_SET_F32(val, *((float*) dat));
                    567:                                break;
                    568:                        case f64:
                    569:                                AIT_SET_F64(val, *((double*) dat));
                    570:                                break;
                    571:                        case i8:
                    572:                                AIT_SET_I8(val, *((int8_t*) dat));
                    573:                                break;
                    574:                        case i16:
                    575:                                AIT_SET_I16(val, *((int16_t*) dat));
                    576:                                break;
                    577:                        case i32:
                    578:                                AIT_SET_I32(val, *((int32_t*) dat));
                    579:                                break;
                    580:                        case i64:
                    581:                                AIT_SET_I64(val, *((int64_t*) dat));
                    582:                                break;
                    583:                        case u8:
                    584:                                AIT_SET_U8(val, *((uint8_t*) dat));
                    585:                                break;
                    586:                        case u16:
                    587:                                AIT_SET_U16(val, *((uint16_t*) dat));
                    588:                                break;
                    589:                        case blob:
                    590:                        case u32:
                    591:                                AIT_SET_U32(val, *((uint32_t*) dat));
                    592:                                break;
                    593:                        case u64:
                    594:                                AIT_SET_U64(val, *((uint64_t*) dat));
                    595:                                break;
                    596:                        case data:
                    597:                                AIT_SET_DATA(val, dat, AIT_LEN(val));
                    598:                                break;
                    599:                        case ptr:
                    600:                        case buffer:
                    601:                                AIT_SET_BUF(val, dat, AIT_LEN(val));
                    602:                                break;
                    603:                        case string:
                    604:                                AIT_SET_STR(val, (char*) dat);
                    605:                                break;
                    606:                        default:
                    607:                                elwix_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", 
                    608:                                                AIT_TYPE(val), i);
                    609:                                ait_freeVars(&vars);
                    610:                                return NULL;
                    611:                }
                    612:                dat += AIT_LEN(val);
                    613:        }
                    614: 
                    615:        return vars;
                    616: }
1.1       misho     617: 
                    618: /* buffer marshaling with swapping bytes to network order */
                    619: 
                    620: /*
                    621:  * ait_vars2buffer() - Marshaling data from array with variables to buffer
                    622:  *
                    623:  * @buf = Buffer
                    624:  * @buflen = Size of buffer
                    625:  * @vars = Variable array
                    626:  * return: -1 error, 0 nothing done or >0 size of marshaled data
                    627:  */
1.4       misho     628: int
1.1       misho     629: ait_vars2buffer(u_char * __restrict buf, int buflen, array_t * __restrict vars)
                    630: {
                    631:        return vars2buffer(buf, buflen, 42, vars);
                    632: }
                    633: 
                    634: /*
                    635:  * ait_buffer2vars() - De-marshaling data from buffer to array with variables
                    636:  *
                    637:  * @buf = Buffer
                    638:  * @buflen = Size of buffer
                    639:  * @vnum = Number of variables into buffer
                    640:  * @zcpy = Zero-copy for variables, if !=0 don't use array_Free() for free variables and 
                    641:                *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy()
                    642:  * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy()
                    643:  */
1.4       misho     644: array_t *
1.1       misho     645: ait_buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
                    646: {
                    647:        return buffer2vars(buf, buflen, vnum, zcpy);
                    648: }
                    649: 
                    650: /* buffer marshaling without swapping bytes to network order */
                    651: 
                    652: /*
                    653:  * ait_vars2map() - Marshaling data from array with variables to memory map
                    654:  *
                    655:  * @buf = Buffer
                    656:  * @buflen = Size of buffer
                    657:  * @vars = Variable array
                    658:  * return: -1 error, 0 nothing done or >0 size of marshaled data
                    659:  */
1.4       misho     660: int
1.1       misho     661: ait_vars2map(u_char *buf, int buflen, array_t *vars)
                    662: {
                    663:        return vars2buffer(buf, buflen, 0, vars);
                    664: }
                    665: 
                    666: /*
                    667:  * ait_map2vars() - De-marshaling data from memory map to array with variables
                    668:  *
                    669:  * @buf = Buffer
                    670:  * @buflen = Size of buffer
                    671:  * @vnum = Number of variables into buffer
                    672:  * @zcpy = Zero-copy for variables, if !=0 don't use array_Free() for free variables and 
                    673:                *DON'T MODIFY OR DESTROY BUFFER*. =0 call array_Free() before array_Destroy()
                    674:  * return: =NULL error, !=NULL allocated variable array, after use must free with array_Destroy()
                    675:  */
1.4       misho     676: array_t *
1.1       misho     677: ait_map2vars(u_char *buf, int buflen, int vnum, int zcpy)
                    678: {
                    679:        return buffer2vars(buf, buflen, vnum, zcpy);
                    680: }
                    681: 
1.10      misho     682: /*
                    683:  * ait_array2vars() - Build array with variables from Null Terminated String Array
                    684:  *
                    685:  * @args = Null-terminated array with strings
                    686:  * @dn = Convert numbers from strings to numbers into variables
                    687:  * return: =NULL error, !=NULL allocated variable array, after use must free with ait_freeVars()
                    688:  */
                    689: array_t *
                    690: ait_array2vars(const char **args, int dn)
                    691: {
                    692:        array_t *vars;
                    693:        ait_val_t *val;
                    694:        register int i;
                    695:        long n;
                    696:        double d;
                    697:        char *str;
                    698: 
                    699:        if (!args)
                    700:                return NULL;
                    701: 
                    702:        vars = ait_allocVars(0);
                    703:        if (!vars)
                    704:                return NULL;
                    705: 
                    706:        for (i = 0; *args; i++, args++) {
                    707:                val = ait_getVars(&vars, i);
                    708:                if (!val) {
                    709:                        ait_freeVars(&vars);
                    710:                        return NULL;
                    711:                }
                    712: 
                    713:                if (dn) {
                    714:                        n = strtol(*args, &str, 0);
                    715:                        if (!str || !*str) {
                    716:                                AIT_SET_I64(val, (int64_t) n);
                    717:                                continue;
                    718:                        }
                    719:                        d = strtod(*args, &str);
                    720:                        if (!str || !*str) {
                    721:                                AIT_SET_F64(val, d);
                    722:                                continue;
                    723:                        }
                    724:                        AIT_SET_STR(val, *args);
                    725:                } else
                    726:                        AIT_SET_STR(val, *args);
                    727:        }
                    728: 
                    729:        return vars;
                    730: }
1.1       misho     731: 
                    732: /* variables array */
                    733: 
                    734: /*
                    735:  * ait_allocVars() - Allocate ait_val_t array
                    736:  *
                    737:  * @varnum = Number of variables
                    738:  * return: =NULL error or !=NULL allocated array
                    739:  */
1.4       misho     740: array_t *
1.1       misho     741: ait_allocVars(int varnum)
                    742: {
                    743:        array_t *arr;
                    744:        register int i;
                    745:        ait_val_t *v;
                    746: 
                    747:        if (!(arr = array_Init(varnum)))
                    748:                return NULL;
                    749: 
                    750:        for (i = 0; i < array_Size(arr); i++) {
                    751:                if (!(v = ait_allocVar())) {
                    752:                        ait_freeVars(&arr);
                    753:                        return NULL;
                    754:                } else
                    755:                        array_Set(arr, i, v);
                    756:        }
                    757: 
                    758:        return arr;
                    759: }
                    760: 
                    761: /*
                    762:  * ait_getVars() - Get ait_val_t element from array and if not exists allocate it
                    763:  *
                    764:  * @vars = Variable array
                    765:  * @n = index of variable into array
                    766:  * return: NULL error or !=NULL ait_val_t element
                    767:  */
1.4       misho     768: ait_val_t *
1.1       misho     769: ait_getVars(array_t ** __restrict vars, int n)
                    770: {
                    771:        register int i;
                    772:        ait_val_t *v;
                    773: 
                    774:        if (!vars)
                    775:                return NULL;
                    776: 
                    777:        if (!*vars) {
                    778:                if (!(*vars = ait_allocVars(n + 1)))
                    779:                        return NULL;
                    780:        } else if (n >= (i = array_Size(*vars))) {
                    781:                if (array_Grow(*vars, n + 1, 0))
                    782:                        return NULL;
                    783:                for (; i < array_Size(*vars); i++)
                    784:                        if (!array_Get(*vars, i)) {
                    785:                                if (!(v = ait_allocVar()))
                    786:                                        return NULL;
                    787:                                else
                    788:                                        array_Set(*vars, i, v);
                    789:                        }
                    790:        }
                    791: 
                    792:        return array(*vars, n, ait_val_t*);
                    793: }
                    794: 
                    795: /*
                    796:  * ait_clrVars() - Clear ait_val_t elements from array
                    797:  *
                    798:  * @vars = Variable array
                    799:  * return: -1 error or size of array
                    800:  */
1.4       misho     801: int
1.1       misho     802: ait_clrVars(array_t * __restrict vars)
                    803: {
                    804:        register int i;
                    805:        ait_val_t *v;
                    806: 
                    807:        if (!vars)
                    808:                return -1;
                    809: 
                    810:        for (i = 0; i < array_Size(vars); i++)
                    811:                if ((v = array(vars, i, ait_val_t*)))
                    812:                        AIT_FREE_VAL(v);
                    813: 
                    814:        return array_Size(vars);
                    815: }
                    816: 
                    817: /*
                    818:  * ait_freeVars() - Free ait_val_t array
                    819:  *
                    820:  * @vars = Variable array
                    821:  * return: none
                    822:  */
1.4       misho     823: void
1.1       misho     824: ait_freeVars(array_t ** __restrict vars)
                    825: {
1.6       misho     826:        register int i;
                    827:        ait_val_t *v;
                    828: 
1.1       misho     829:        if (!vars || !*vars)
                    830:                return;
                    831: 
1.6       misho     832:        for (i = 0; i < array_Size(*vars); i++)
                    833:                if ((v = array(*vars, i, ait_val_t*))) {
                    834:                        /* free memory if isn't zero copy */
                    835:                        if (!AIT_IN(v)) {
                    836:                                AIT_FREE_VAL(v);
                    837:                                if ((*vars)->arr_data[i])
                    838:                                        e_free((*vars)->arr_data[i]);
                    839:                        } else
                    840:                                AIT_FREE_VAL(v);
                    841:                        (*vars)->arr_data[i] = NULL;
                    842:                }
                    843:        (*vars)->arr_last = -1;
                    844: 
1.1       misho     845:        array_Destroy(vars);
                    846: }
                    847: 
1.5       misho     848: /*
                    849:  * ait_resideVars() - Calculate footprint of resided variables into array
                    850:  *
                    851:  * @vars = Variable array
                    852:  * return: bytes for whole array
                    853:  */
                    854: size_t
                    855: ait_resideVars(array_t * __restrict vars)
                    856: {
                    857:        size_t ret = 0;
                    858:        register int i;
                    859: 
                    860:        if (vars) {
                    861:                ret = array_Size(vars) * sizeof(ait_val_t);
                    862:                for (i = 0; i < array_Size(vars); i++)
                    863:                        switch (AIT_TYPE(array(vars, i, ait_val_t*))) {
                    864:                                case buffer:
                    865:                                case string:
                    866:                                case data:
                    867:                                case ptr:
                    868:                                        ret += AIT_LEN(array(vars, i, ait_val_t*));
                    869:                                        break;
                    870:                                default:
                    871:                                        break;
                    872:                        }
                    873:        }
                    874: 
                    875:        return ret;
                    876: }
                    877: 
1.1       misho     878: 
                    879: /*
                    880:  * ait_allocVar() - Allocate memory for variable
                    881:  *
                    882:  * return: NULL error or new variable, after use free variable with ait_freeVar()
                    883:  */
1.4       misho     884: ait_val_t *
1.1       misho     885: ait_allocVar(void)
                    886: {
                    887:        ait_val_t *v = NULL;
                    888: 
                    889:        v = e_malloc(sizeof(ait_val_t));
                    890:        if (!v)
                    891:                return NULL;
                    892:        else
                    893:                memset(v, 0, sizeof(ait_val_t));
                    894:        v->val_type = empty;
                    895: 
                    896:        return v;
                    897: }
                    898: 
                    899: /*
                    900:  * ait_freeVar() - Free allocated memory for variable
                    901:  *
                    902:  * @val = Variable
                    903:  * return: none
                    904:  */
1.4       misho     905: void
1.1       misho     906: ait_freeVar(ait_val_t ** __restrict val)
                    907: {
                    908:        if (val && *val) {
                    909:                AIT_FREE_VAL(*val);
                    910:                e_free(*val);
                    911:                *val = NULL;
                    912:        }
                    913: }
                    914: 
                    915: /*
                    916:  * ait_makeVar() - Allocate memory and fill variable
                    917:  *
                    918:  * @type = type of variable
                    919:  * @... = arg1 is value of variable
                    920:  * @... = arg2 is length of variabla. Not required for numbers and strings!
                    921:  * return: NULL error or new variable, after use free variable with io_freeVar()
                    922:  */
                    923: ait_val_t *
                    924: ait_makeVar(ait_type_t type, ...)
                    925: {
                    926:        ait_val_t *v = NULL;
                    927:        va_list lst;
                    928:        void *p = NULL;
                    929:        uint32_t len = 0;
                    930:        uint64_t n = 0LL;
                    931: 
                    932:        v = ait_allocVar();
                    933:        if (!v)
                    934:                return NULL;
                    935: 
                    936:        va_start(lst, type);
                    937:        switch (type) {
                    938:                case empty:
                    939:                        v->val_type = (uint8_t) empty;
                    940:                        break;
                    941:                case ptr:
                    942:                        p = va_arg(lst, void*);
                    943:                        len = va_arg(lst, uint32_t);
                    944:                        AIT_SET_PTR(v, p, len);
                    945:                        break;
                    946:                case data:
                    947:                        p = va_arg(lst, void*);
                    948:                        len = va_arg(lst, uint32_t);
                    949:                        AIT_SET_DATA(v, p, len);
                    950:                        break;
                    951:                case buffer:
                    952:                        p = va_arg(lst, void*);
                    953:                        len = va_arg(lst, uint32_t);
                    954:                        AIT_SET_BUF(v, p, len);
                    955:                        break;
                    956:                case string:
                    957:                        p = va_arg(lst, char*);
                    958:                        AIT_SET_STR(v, (char*) p);
                    959:                        break;
                    960:                case blob:
                    961:                        n = va_arg(lst, uint32_t);
                    962:                        len = va_arg(lst, uint32_t);
                    963:                        AIT_SET_BLOB(v, n, len);
                    964:                        break;
                    965:                case f32:
                    966:                        AIT_SET_F32(v, (float) va_arg(lst, double));
                    967:                        break;
                    968:                case f64:
                    969:                        AIT_SET_F64(v, va_arg(lst, double));
                    970:                        break;
                    971:                case u8:
                    972:                        AIT_SET_U8(v, (uint8_t) va_arg(lst, int));
                    973:                        break;
                    974:                case u16:
                    975:                        AIT_SET_U16(v, (uint16_t) va_arg(lst, int));
                    976:                        break;
                    977:                case u32:
                    978:                        AIT_SET_U32(v, va_arg(lst, uint32_t));
                    979:                        break;
                    980:                case u64:
                    981:                        AIT_SET_U64(v, va_arg(lst, uint64_t));
                    982:                        break;
                    983:                case i8:
                    984:                        AIT_SET_I8(v, (int8_t) va_arg(lst, int));
                    985:                        break;
                    986:                case i16:
                    987:                        AIT_SET_I16(v, (int16_t) va_arg(lst, int));
                    988:                        break;
                    989:                case i32:
                    990:                        AIT_SET_I32(v, va_arg(lst, int32_t));
                    991:                        break;
                    992:                case i64:
                    993:                        AIT_SET_I64(v, va_arg(lst, int64_t));
                    994:                        break;
                    995:        }
                    996:        va_end(lst);
                    997: 
                    998:        return v;
                    999: }
                   1000: 
                   1001: static int
                   1002: _cmp_arr_key_asc(const void *a, const void *b)
                   1003: {
                   1004:        return AIT_KEY(*(ait_val_t**) a) - AIT_KEY(*(ait_val_t**) b);
                   1005: }
                   1006: 
                   1007: static int
                   1008: _cmp_arr_key_desc(const void *a, const void *b)
                   1009: {
                   1010:        return AIT_KEY(*(ait_val_t**) b) - AIT_KEY(*(ait_val_t**) a);
                   1011: }
                   1012: 
                   1013: static int
                   1014: _cmp_arr_val_asc(const void *a, const void *b)
                   1015: {
                   1016:        return AIT_RAW(*(ait_val_t**) a) - AIT_RAW(*(ait_val_t**) b);
                   1017: }
                   1018: 
                   1019: static int
                   1020: _cmp_arr_val_desc(const void *a, const void *b)
                   1021: {
                   1022:        return AIT_RAW(*(ait_val_t**) b) - AIT_RAW(*(ait_val_t**) a);
                   1023: }
                   1024: 
                   1025: /*
                   1026:  * ait_sortVarsByVal() - Sorting array with variables by value
                   1027:  *
                   1028:  * @vars = Variable array
                   1029:  * @order = Sort order. If =0 ascend or !=0 descend
                   1030:  * @cmp = Custom compare function for sorting. If =NULL compare by value
                   1031:  * return: none
                   1032:  */
1.4       misho    1033: void
1.1       misho    1034: ait_sortVarsByVal(array_t * __restrict vars, int order,  int (*cmp)(const void*, const void*))
                   1035: {
                   1036:        if (!vars)
                   1037:                return;
                   1038: 
                   1039:        if (cmp)
1.2       misho    1040:                qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), cmp);
1.1       misho    1041:        else if (order)
1.2       misho    1042:                qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_val_desc);
1.1       misho    1043:        else
1.2       misho    1044:                qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_val_asc);
1.1       misho    1045: }
                   1046: 
                   1047: /*
                   1048:  * ait_sortVarsByKey() - Sorting array with variables by key
                   1049:  *
                   1050:  * @vars = Variable array
                   1051:  * @order = Sort order. If =0 ascend or !=0 descend
                   1052:  * return: none
                   1053:  */
1.4       misho    1054: void
1.1       misho    1055: ait_sortVarsByKey(array_t * __restrict vars, int order)
                   1056: {
                   1057:        if (!vars)
                   1058:                return;
                   1059: 
                   1060:        if (order)
1.2       misho    1061:                qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_key_desc);
1.1       misho    1062:        else
1.2       misho    1063:                qsort(vars->arr_data, vars->arr_num, sizeof(uintptr_t), _cmp_arr_key_asc);
1.1       misho    1064: }
                   1065: 
                   1066: /*
                   1067:  * ait_findKeyVars() - Find variable by key from array
                   1068:  *
                   1069:  * @vars = Variables
                   1070:  * @key = Search key
                   1071:  * return: NULL error or not found, !=NULL valid element
                   1072:  */
                   1073: ait_val_t *
                   1074: ait_findKeyVars(array_t * __restrict vars, u_short key)
                   1075: {
                   1076:        array_t *tmp;
                   1077:        ait_val_t **vv, *v = NULL;
                   1078:        register int i;
                   1079:        const u_char *p;
                   1080: 
                   1081:        if (!vars)
                   1082:                return NULL;
                   1083: 
                   1084:        if (array_Copy(&tmp, vars) == -1)
                   1085:                return NULL;
                   1086:        else
1.2       misho    1087:                qsort(tmp->arr_data, tmp->arr_num, sizeof(uintptr_t), _cmp_arr_key_asc);
1.1       misho    1088: 
                   1089:        /* binary search */
                   1090:        for (p = (const u_char*) tmp->arr_data, i = array_Size(tmp); i; i >>= 1) {
1.2       misho    1091:                vv = (ait_val_t**) (p + (i >> 1) * sizeof(uintptr_t));
1.1       misho    1092:                if (!(key - AIT_KEY(*vv))) {    /* found! */
                   1093:                        v = *vv;
                   1094:                        break;
                   1095:                }
                   1096:                if ((key - AIT_KEY(*vv)) > 0) { /* move right key > current */
1.2       misho    1097:                        p = (const u_char*) vv + sizeof(uintptr_t);
1.1       misho    1098:                        i--;
                   1099:                }                               /* else move left */
                   1100:        }
                   1101: 
                   1102:        array_Destroy(&tmp);
                   1103:        return v;
                   1104: }
                   1105: 
                   1106: /*
                   1107:  * ait_hashVar() - Generate hash key for variable from string or value
                   1108:  *
                   1109:  * @v = variable
                   1110:  * @key = key string for hash, if =NULL hash will built from variable
                   1111:  * return: hash key
                   1112:  */
                   1113: u_short
                   1114: ait_hashVar(ait_val_t * __restrict v, const char * __restrict key)
                   1115: {
                   1116:        void *p;
                   1117:        u_short cksum;
                   1118:        int l;
                   1119: 
                   1120:        if (!v)
                   1121:                return 0;
                   1122: 
                   1123:        if (key) {
                   1124:                p = (void*) key;
                   1125:                l = (strlen(key) + 1) / 2;
                   1126:        } else {
                   1127:                switch (AIT_TYPE(v)) {
                   1128:                        case empty:
                   1129:                                AIT_KEY(v) = 0;
                   1130:                                return 0;
                   1131:                        case string:
                   1132:                        case buffer:
                   1133:                                p = AIT_ADDR(v);
                   1134:                                l = AIT_LEN(v) / 2;
                   1135:                                break;
                   1136:                        case data:
                   1137:                                p = v->val_data;
                   1138:                                l = AIT_LEN(v) / 2;
                   1139:                                break;
                   1140:                        default:
                   1141:                                p = &AIT_RAW(v);
                   1142:                                l = sizeof AIT_RAW(v) / 2;
                   1143:                                break;
                   1144:                }
                   1145:        }
                   1146: 
                   1147:        cksum = crcFletcher16((u_short*) p, l);
                   1148: 
                   1149:        if (AIT_BE(v))
                   1150:                AIT_KEY(v) = htobe16(cksum);
                   1151:        else if (AIT_LE(v))
                   1152:                AIT_KEY(v) = htole16(cksum);
                   1153:        else
                   1154:                AIT_KEY(v) = cksum;
                   1155: 
                   1156:        return AIT_KEY(v);
                   1157: }
                   1158: 
                   1159: /*
                   1160:  * ait_hashKeyVars() - Generate hash keys for variables
                   1161:  *
                   1162:  * @vars = Variables
                   1163:  * return -1 error or 0 ok
                   1164:  */
1.4       misho    1165: int
1.1       misho    1166: ait_hashKeyVars(array_t * __restrict vars)
                   1167: {
                   1168:        register int i;
                   1169: 
                   1170:        if (!vars)
                   1171:                return -1;
                   1172: 
                   1173:        for (i = 0; i < array_Size(vars); i++)
                   1174:                ait_hashVar(array(vars, i, ait_val_t*), NULL);
                   1175: 
                   1176:        return 0;
                   1177: }
                   1178: 
                   1179: /*
                   1180:  * ait_findKeyHash() - Find variable by hash string from array
                   1181:  *
                   1182:  * @vars = Variables
                   1183:  * @key = Search string
                   1184:  * return: NULL error or not found, !=NULL valid element
                   1185:  */
1.4       misho    1186: ait_val_t *
1.1       misho    1187: ait_findKeyHash(array_t * __restrict vars, const char * __restrict key)
                   1188: {
                   1189:        u_short k = 0;
                   1190: 
                   1191:        if (!vars || !key)
                   1192:                return NULL;
                   1193: 
                   1194:        k = crcFletcher16((u_short*) key, (strlen(key) + 1) / 2);
                   1195:        return ait_findKeyVars(vars, k);
                   1196: }
                   1197: 
                   1198: /*
                   1199:  * ait_sprintfVar() - Builtin string variable from formatted input
                   1200:  *
                   1201:  * @v = variable
                   1202:  * @fmt = format string
                   1203:  * @... = argument(s)
                   1204:  * return: -1 error or >0 copied bytes to variable
                   1205:  */
                   1206: int
1.2       misho    1207: ait_sprintfVar(ait_val_t * __restrict v, const char *fmt, ...)
1.1       misho    1208: {
                   1209:        int ret = 0;
                   1210:        va_list lst;
1.13    ! misho    1211:        char str[65536] = { [0 ... 65535] = 0 };
1.1       misho    1212: 
                   1213:        if (!v || !fmt)
                   1214:                return -1;
                   1215: 
                   1216:        va_start(lst, fmt);
1.9       misho    1217:        ret = vsnprintf(str, sizeof str - 1, fmt, lst);
1.1       misho    1218:        va_end(lst);
                   1219: 
1.9       misho    1220:        if (ret > -1) {
1.1       misho    1221:                AIT_FREE_VAL(v);
                   1222:                AIT_SET_STR(v, str);
                   1223:        } else
                   1224:                LOGERR;
                   1225: 
                   1226:        return ret;
                   1227: }
                   1228: 
                   1229: /*
                   1230:  * ait_setlikeVar() - Set variable like ...
                   1231:  *
                   1232:  * @v = variable
                   1233:  * @t = type of data
                   1234:  * @l = length of data
                   1235:  * @... = data
                   1236:  * return: -1 error or 0 ok
                   1237:  */
1.4       misho    1238: int
1.1       misho    1239: ait_setlikeVar(ait_val_t * __restrict v, ait_type_t t, u_int l, ...)
                   1240: {
                   1241:        va_list lst;
                   1242: 
                   1243:        if (!v)
                   1244:                return -1;
                   1245: 
                   1246:        AIT_FREE_VAL(v);
                   1247:        AIT_INIT_VAL2(v, t);
                   1248:        AIT_LEN(v) = l;
                   1249:        AIT_IN(v) = 1;
                   1250: 
                   1251:        va_start(lst, l);
                   1252:        switch (AIT_TYPE(v)) {
                   1253:                case ptr:
                   1254:                case buffer:
                   1255:                case string:
                   1256:                        AIT_ADDR(v) = va_arg(lst, void*);
                   1257:                        break;
                   1258:                default:
                   1259:                        AIT_RAW(v) = va_arg(lst, uint64_t);
                   1260:                        break;
                   1261:        }
                   1262:        va_end(lst);
                   1263: 
                   1264:        return 0;
                   1265: }
                   1266: 
                   1267: /*
                   1268:  * ait_getlikeVar() - Get variable like ...
                   1269:  *
                   1270:  * @v = variable
                   1271:  * return: return raw data
                   1272:  */
1.4       misho    1273: uint64_t
1.1       misho    1274: ait_getlikeVar(ait_val_t * __restrict v)
                   1275: {
                   1276:        if (!v)
                   1277:                return (uintptr_t) -1;
                   1278: 
                   1279:        return AIT_RAW(v);
                   1280: }
                   1281: 
                   1282: /*
                   1283:  * ait_cmpVar() - Compare two variables
                   1284:  *
                   1285:  * @a = 1st variable
                   1286:  * @b = 2nd variable
                   1287:  * return: 0 is equal or !=0 is different
                   1288:  */
1.4       misho    1289: int
1.1       misho    1290: ait_cmpVar(ait_val_t * __restrict a, ait_val_t * __restrict b)
                   1291: {
                   1292:        intptr_t ret;
                   1293: 
                   1294:        if (!(ret = (a - b)))
                   1295:                return ret;
                   1296:        if ((ret = AIT_TYPE(a) - AIT_TYPE(b)))
                   1297:                return ret;
                   1298:        if ((ret = AIT_LEN(a) - AIT_LEN(b)))
                   1299:                return ret;
                   1300: 
                   1301:        switch (AIT_TYPE(a)) {
                   1302:                case buffer:
                   1303:                        ret = memcmp(AIT_GET_BUF(a), AIT_GET_BUF(b), AIT_LEN(a));
                   1304:                        break;
                   1305:                case string:
                   1306:                        ret = strncmp(AIT_GET_STR(a), AIT_GET_STR(b), AIT_LEN(a));
                   1307:                        break;
                   1308:                case data:
                   1309:                        ret = memcmp(AIT_GET_DATA(a), AIT_GET_DATA(b), AIT_LEN(a));
                   1310:                        break;
                   1311:                case ptr:
                   1312:                        ret = AIT_ADDR(a) - AIT_ADDR(b);
                   1313:                        break;
                   1314:                default:
                   1315:                        ret = AIT_RAW(a) - AIT_RAW(b);
                   1316:                        break;
                   1317:        }
                   1318: 
                   1319:        return (int) ret;
                   1320: }

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