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

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 $
1.10.2.1! misho       6: * $Id: vars.c,v 1.10 2012/07/03 08:51:05 misho Exp $
1.2       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.5       misho      15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
1.2       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.10.2.1! misho      49: static int
        !            50: vars2buffer(u_char * __restrict buf, int buflen, int be, array_t * __restrict vars)
1.2       misho      51: {
                     52:        int Limit = 0;
                     53:        register int i;
                     54:        ait_val_t *v, *val;
1.5       misho      55:        u_char *dat;
1.2       misho      56: 
                     57:        assert(buf);
                     58:        assert(vars);
                     59:        if (!buf || !vars)
                     60:                return -1;
                     61:        if (!buflen || !io_arraySize(vars))
                     62:                return 0;
1.10.2.1! misho      63:        be = !!be;
1.2       misho      64: 
                     65:        Limit = sizeof(ait_val_t) * io_arraySize(vars);
                     66:        if (Limit > buflen) {
1.6       misho      67:                io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", 
1.2       misho      68:                                buflen, Limit);
                     69:                return -1;
                     70:        } else {
                     71:                memset(buf, 0, buflen);
                     72: 
                     73:                v = (ait_val_t*) buf;
1.5       misho      74:                dat = buf + Limit;
1.2       misho      75:        }
                     76: 
                     77:        /* marshaling */
                     78:        for (i = 0; i < io_arraySize(vars); i++) {
                     79:                val = io_array(vars, i, ait_val_t*);
                     80: 
                     81:                v[i].val_type = val->val_type;
1.10.2.1! misho      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:                }
1.2       misho      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:
1.10.2.1! misho     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);
1.2       misho     110:                                break;
1.5       misho     111:                        case data:
                    112:                                if (AIT_LEN(val) > buflen - Limit) {
1.6       misho     113:                                        io_SetErr(EMSGSIZE, "Short buffer buflen=%d "
                    114:                                                        "needed min %d", buflen, Limit + AIT_LEN(val));
1.5       misho     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;
1.2       misho     124:                        case buffer:
                    125:                        case string:
                    126:                                if (AIT_LEN(val) > buflen - Limit) {
1.6       misho     127:                                        io_SetErr(EMSGSIZE, "Short buffer buflen=%d "
                    128:                                                        "needed min %d", buflen, Limit + AIT_LEN(val));
1.2       misho     129:                                        return -1;
                    130:                                } else
                    131:                                        Limit += AIT_LEN(val);
                    132: 
1.5       misho     133:                                memcpy(dat, val->val.buffer, AIT_LEN(val));
1.2       misho     134:                                /* Debug:: data offset in packet, not matter for anything! */
1.5       misho     135:                                v[i].val.net = dat - buf;
                    136:                                dat += AIT_LEN(val);
1.2       misho     137:                                break;
                    138:                        default:
1.6       misho     139:                                io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", 
1.2       misho     140:                                                AIT_TYPE(val), i);
                    141:                                return -1;
                    142:                }
                    143:        }
                    144: 
                    145:        return Limit;
                    146: }
                    147: 
1.10.2.1! misho     148: static array_t *
        !           149: buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
1.2       misho     150: {
                    151:        array_t *vars;
                    152:        int Limit = 0;
                    153:        register int i;
                    154:        ait_val_t *v, *val;
1.5       misho     155:        u_char *dat;
1.2       misho     156: 
                    157:        assert(buf);
                    158:        if (!buf || !buflen || !vnum)
                    159:                return NULL;
                    160: 
                    161:        Limit = sizeof(ait_val_t) * vnum;
                    162:        if (Limit > buflen) {
1.6       misho     163:                io_SetErr(EMSGSIZE, "Short buffer buflen=%d needed min %d", 
1.2       misho     164:                                buflen, Limit);
                    165:                return NULL;
                    166:        } else {
                    167:                if (!(vars = io_arrayInit(vnum)))
                    168:                        return NULL;
                    169: 
                    170:                v = (ait_val_t*) buf;
1.5       misho     171:                dat = buf + Limit;
1.2       misho     172:        }
                    173: 
                    174:        /* de-marshaling */
                    175:        for (i = 0; i < io_arraySize(vars); i++) {
                    176:                if (!zcpy) {
1.10      misho     177:                        val = io_malloc(sizeof(ait_val_t));
1.2       misho     178:                        if (!val) {
                    179:                                LOGERR;
                    180:                                io_arrayFree(vars);
                    181:                                io_arrayDestroy(&vars);
                    182:                                return NULL;
                    183:                        }
1.10.2.1! misho     184:                        AIT_IN(val) = 0;
        !           185:                } else {
1.2       misho     186:                        val = v + i;
1.10.2.1! misho     187:                        AIT_IN(val) = 1;
        !           188:                }
1.2       misho     189:                io_arraySet(vars, i, val);
                    190: 
                    191:                val->val_type = v[i].val_type;
1.10.2.1! misho     192:                AIT_BE(val) = AIT_BE(&v[i]);
        !           193:                AIT_LE(val) = AIT_LE(&v[i]);
        !           194:                if (AIT_BE(val)) {
        !           195:                        AIT_LEN(val) = be32toh(AIT_LEN(&v[i]));
        !           196:                        AIT_KEY(val) = be16toh(AIT_KEY(&v[i]));
        !           197:                }
        !           198:                if (AIT_LE(val)) {
        !           199:                        AIT_LEN(val) = le32toh(AIT_LEN(&v[i]));
        !           200:                        AIT_KEY(val) = le16toh(AIT_KEY(&v[i]));
        !           201:                }
1.2       misho     202: 
                    203:                switch (AIT_TYPE(val)) {
                    204:                        case blob:
                    205:                        case f32:
                    206:                        case f64:
                    207:                        case i8:
                    208:                        case i16:
                    209:                        case i32:
                    210:                        case i64:
                    211:                        case u8:
                    212:                        case u16:
                    213:                        case u32:
                    214:                        case u64:
1.10.2.1! misho     215:                                if (AIT_BE(val))
        !           216:                                        val->val.net = be64toh(v[i].val.net);
        !           217:                                if (AIT_LE(val))
        !           218:                                        val->val.net = le64toh(v[i].val.net);
1.2       misho     219:                                break;
1.5       misho     220:                        case data:
                    221:                                /* WARNING:: remap data type to buffer */
                    222:                                val->val_type = buffer;
1.2       misho     223:                        case buffer:
                    224:                        case string:
                    225:                                if (AIT_LEN(val) > buflen - Limit) {
1.6       misho     226:                                        io_SetErr(EMSGSIZE, "Short buffer buflen=%d "
                    227:                                                        "needed min %d", buflen, Limit + AIT_LEN(val));
1.2       misho     228:                                        if (!zcpy)
                    229:                                                io_arrayFree(vars);
                    230:                                        io_arrayDestroy(&vars);
                    231:                                        return NULL;
                    232:                                } else
                    233:                                        Limit += AIT_LEN(val);
                    234: 
                    235:                                if (!zcpy) {
1.10      misho     236:                                        val->val.buffer = io_malloc(AIT_LEN(val));
1.2       misho     237:                                        if (!val->val.buffer) {
                    238:                                                LOGERR;
                    239:                                                io_arrayFree(vars);
                    240:                                                io_arrayDestroy(&vars);
                    241:                                                return NULL;
                    242:                                        } else
1.5       misho     243:                                                memcpy(val->val.buffer, dat, AIT_LEN(val));
1.2       misho     244:                                } else
1.5       misho     245:                                        val->val.buffer = dat;
                    246:                                dat += AIT_LEN(val);
1.2       misho     247:                                break;
                    248:                        default:
1.6       misho     249:                                io_SetErr(EINVAL, "Unsupported variable type=%d at element #%d", 
1.2       misho     250:                                                AIT_TYPE(val), i);
                    251:                                if (!zcpy)
                    252:                                        io_arrayFree(vars);
                    253:                                io_arrayDestroy(&vars);
                    254:                                return NULL;
                    255:                }
                    256:        }
                    257: 
                    258:        return vars;
                    259: }
                    260: 
1.10.2.1! misho     261: 
        !           262: /* buffer marshaling with swapping bytes to network order */
1.2       misho     263: 
                    264: /*
1.10.2.1! misho     265:  * io_vars2buffer() - Marshaling data from array with variables to buffer
1.5       misho     266:  *
1.2       misho     267:  * @buf = Buffer
                    268:  * @buflen = Size of buffer
                    269:  * @vars = Variable array
                    270:  * return: -1 error, 0 nothing done or >0 size of marshaled data
                    271:  */
1.10.2.1! misho     272: inline int
        !           273: io_vars2buffer(u_char * __restrict buf, int buflen, array_t * __restrict vars)
1.2       misho     274: {
1.10.2.1! misho     275:        return vars2buffer(buf, buflen, 42, vars);
        !           276: }
1.5       misho     277: 
1.10.2.1! misho     278: /*
        !           279:  * io_buffer2vars() - De-marshaling data from buffer to array with variables
        !           280:  *
        !           281:  * @buf = Buffer
        !           282:  * @buflen = Size of buffer
        !           283:  * @vnum = Number of variables into buffer
        !           284:  * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and 
        !           285:                *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy()
        !           286:  * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy()
        !           287:  */
        !           288: inline array_t *
        !           289: io_buffer2vars(u_char * __restrict buf, int buflen, int vnum, int zcpy)
        !           290: {
        !           291:        return buffer2vars(buf, buflen, vnum, zcpy);
        !           292: }
1.2       misho     293: 
1.10.2.1! misho     294: /* buffer marshaling without swapping bytes to network order */
1.2       misho     295: 
1.10.2.1! misho     296: /*
        !           297:  * io_vars2map() - Marshaling data from array with variables to memory map
        !           298:  *
        !           299:  * @buf = Buffer
        !           300:  * @buflen = Size of buffer
        !           301:  * @vars = Variable array
        !           302:  * return: -1 error, 0 nothing done or >0 size of marshaled data
        !           303:  */
        !           304: inline int
        !           305: io_vars2map(u_char *buf, int buflen, array_t *vars)
        !           306: {
        !           307:        return vars2buffer(buf, buflen, 0, vars);
1.2       misho     308: }
                    309: 
                    310: /*
1.6       misho     311:  * io_map2vars() - De-marshaling data from memory map to array with variables
1.5       misho     312:  *
1.2       misho     313:  * @buf = Buffer
                    314:  * @buflen = Size of buffer
                    315:  * @vnum = Number of variables into buffer
                    316:  * @zcpy = Zero-copy for variables, if !=0 don't use io_arrayFree() for free variables and 
                    317:                *DON'T MODIFY OR DESTROY BUFFER*. =0 call io_arrayFree() before io_arrayDestroy()
                    318:  * return: =NULL error, !=NULL allocated variable array, after use must free with io_arrayDestroy()
                    319:  */
1.10.2.1! misho     320: inline array_t *
1.3       misho     321: io_map2vars(u_char *buf, int buflen, int vnum, int zcpy)
1.2       misho     322: {
1.10.2.1! misho     323:        return buffer2vars(buf, buflen, vnum, zcpy);
1.2       misho     324: }
1.3       misho     325: 
                    326: 
                    327: /*
1.6       misho     328:  * io_allocVars() - Allocate ait_val_t array
1.5       misho     329:  *
1.3       misho     330:  * @varnum = Number of variables
                    331:  * return: =NULL error or !=NULL allocated array
                    332:  */
                    333: inline array_t *
                    334: io_allocVars(int varnum)
                    335: {
                    336:        array_t *arr;
                    337:        register int i;
                    338:        ait_val_t *v;
                    339: 
1.8       misho     340:        if (!(arr = io_arrayInit(varnum)))
1.3       misho     341:                return NULL;
                    342: 
                    343:        for (i = 0; i < io_arraySize(arr); i++) {
1.6       misho     344:                if (!(v = io_allocVar())) {
1.3       misho     345:                        io_freeVars(&arr);
                    346:                        return NULL;
1.6       misho     347:                } else
1.3       misho     348:                        io_arraySet(arr, i, v);
                    349:        }
                    350: 
                    351:        return arr;
                    352: }
                    353: 
                    354: /*
1.8       misho     355:  * io_getVars() - Get ait_val_t element from array and if not exists allocate it
                    356:  *
                    357:  * @vars = Variable array
                    358:  * @n = index of variable into array
                    359:  * return: NULL error or !=NULL ait_val_t element
                    360:  */
                    361: inline ait_val_t *
                    362: io_getVars(array_t ** __restrict vars, int n)
                    363: {
                    364:        register int i;
                    365:        ait_val_t *v;
                    366: 
                    367:        if (!vars)
                    368:                return NULL;
                    369: 
                    370:        if (!*vars) {
                    371:                if (!(*vars = io_allocVars(n + 1)))
                    372:                        return NULL;
                    373:        } else {
                    374:                if (n >= (i = io_arraySize(*vars))) {
                    375:                        if (io_arrayGrow(*vars, n + 1, 0))
                    376:                                return NULL;
                    377:                        for (; i < io_arraySize(*vars); i++)
                    378:                                if (!io_arrayGet(*vars, i)) {
                    379:                                        if (!(v = io_allocVar()))
                    380:                                                return NULL;
                    381:                                        else
                    382:                                                io_arraySet(*vars, n, v);
                    383:                                }
                    384:                }
                    385:        }
                    386: 
                    387:        return io_array(*vars, n, ait_val_t*);
                    388: }
                    389: 
                    390: /*
1.6       misho     391:  * io_clrVars() - Clear ait_val_t elements from array
1.5       misho     392:  *
1.3       misho     393:  * @vars = Variable array
                    394:  * return: -1 error or size of array
                    395:  */
                    396: inline int
                    397: io_clrVars(array_t * __restrict vars)
                    398: {
                    399:        register int i;
1.7       misho     400:        ait_val_t *v;
1.3       misho     401: 
                    402:        if (!vars)
                    403:                return -1;
                    404: 
                    405:        for (i = 0; i < io_arraySize(vars); i++)
1.7       misho     406:                if ((v = io_array(vars, i, ait_val_t*)))
                    407:                        AIT_FREE_VAL(v);
1.3       misho     408: 
                    409:        return io_arraySize(vars);
                    410: }
                    411: 
                    412: /*
1.6       misho     413:  * io_freeVars() - Free ait_val_t array
1.5       misho     414:  *
1.3       misho     415:  * @vars = Variable array
                    416:  * return: none
                    417:  */
                    418: inline void
                    419: io_freeVars(array_t ** __restrict vars)
                    420: {
                    421:        if (!vars || !*vars)
                    422:                return;
                    423: 
                    424:        io_clrVars(*vars);
1.7       misho     425:        io_arrayFree(*vars);
1.3       misho     426:        io_arrayDestroy(vars);
                    427: }
1.4       misho     428: 
                    429: /*
1.6       misho     430:  * io_allocVar() - Allocate memory for variable
1.5       misho     431:  *
1.4       misho     432:  * return: NULL error or new variable, after use free variable with io_freeVar()
                    433:  */
                    434: inline ait_val_t *
                    435: io_allocVar(void)
                    436: {
                    437:        ait_val_t *v = NULL;
                    438: 
1.10      misho     439:        v = io_malloc(sizeof(ait_val_t));
1.4       misho     440:        if (!v) {
                    441:                LOGERR;
                    442:                return NULL;
                    443:        } else
                    444:                memset(v, 0, sizeof(ait_val_t));
                    445:        v->val_type = empty;
                    446: 
                    447:        return v;
                    448: }
                    449: 
                    450: /*
1.6       misho     451:  * io_freeVar() - Free allocated memory for variable
1.5       misho     452:  *
1.4       misho     453:  * @val = Variable
                    454:  * return: none
                    455:  */
                    456: inline void
1.6       misho     457: io_freeVar(ait_val_t ** __restrict val)
                    458: {
                    459:        if (val && *val) {
                    460:                AIT_FREE_VAL(*val);
1.10      misho     461:                io_free(*val);
1.6       misho     462:                *val = NULL;
                    463:        }
                    464: }
                    465: 
                    466: static int
                    467: _cmp_arr_key_asc(const void *a, const void *b)
                    468: {
                    469:        return AIT_KEY(*(ait_val_t**) a) - AIT_KEY(*(ait_val_t**) b);
                    470: }
                    471: 
                    472: static int
                    473: _cmp_arr_key_desc(const void *a, const void *b)
                    474: {
                    475:        return AIT_KEY(*(ait_val_t**) b) - AIT_KEY(*(ait_val_t**) a);
                    476: }
                    477: 
1.10.2.1! misho     478: static int
        !           479: _cmp_arr_val_asc(const void *a, const void *b)
        !           480: {
        !           481:        return AIT_RAW(*(ait_val_t**) a) - AIT_RAW(*(ait_val_t**) b);
        !           482: }
        !           483: 
        !           484: static int
        !           485: _cmp_arr_val_desc(const void *a, const void *b)
        !           486: {
        !           487:        return AIT_RAW(*(ait_val_t**) b) - AIT_RAW(*(ait_val_t**) a);
        !           488: }
        !           489: 
1.6       misho     490: /*
1.10.2.1! misho     491:  * io_sortVarsByVal() - Sorting array with variables by value
1.6       misho     492:  *
                    493:  * @vars = Variable array
                    494:  * @order = Sort order. If =0 ascend or !=0 descend
1.10.2.1! misho     495:  * @cmp = Custom compare function for sorting. If =NULL compare by value
1.6       misho     496:  * return: none
                    497:  */
                    498: inline void
1.10.2.1! misho     499: io_sortVarsByVal(array_t * __restrict vars, int order,  int (*cmp)(const void*, const void*))
1.4       misho     500: {
1.6       misho     501:        if (!vars)
                    502:                return;
                    503: 
                    504:        if (cmp)
                    505:                qsort(vars->arr_data, vars->arr_num, sizeof(void*), cmp);
                    506:        else if (order)
1.10.2.1! misho     507:                qsort(vars->arr_data, vars->arr_num, sizeof(void*), _cmp_arr_val_desc);
        !           508:        else
        !           509:                qsort(vars->arr_data, vars->arr_num, sizeof(void*), _cmp_arr_val_asc);
        !           510: }
        !           511: 
        !           512: /*
        !           513:  * io_sortVarsByKey() - Sorting array with variables by key
        !           514:  *
        !           515:  * @vars = Variable array
        !           516:  * @order = Sort order. If =0 ascend or !=0 descend
        !           517:  * return: none
        !           518:  */
        !           519: inline void
        !           520: io_sortVarsByKey(array_t * __restrict vars, int order)
        !           521: {
        !           522:        if (!vars)
        !           523:                return;
        !           524: 
        !           525:        if (order)
1.6       misho     526:                qsort(vars->arr_data, vars->arr_num, sizeof(void*), _cmp_arr_key_desc);
                    527:        else
                    528:                qsort(vars->arr_data, vars->arr_num, sizeof(void*), _cmp_arr_key_asc);
                    529: }
                    530: 
                    531: /*
                    532:  * io_findKeyVars() - Find variable by key from array
                    533:  *
                    534:  * @vars = Variables
                    535:  * @key = Search key
                    536:  * return: NULL error or not found, !=NULL valid element
                    537:  */
                    538: ait_val_t *
                    539: io_findKeyVars(array_t * __restrict vars, u_short key)
                    540: {
                    541:        array_t *tmp;
                    542:        ait_val_t **vv, *v = NULL;
                    543:        register int i;
                    544:        const u_char *p;
                    545: 
                    546:        if (!vars)
                    547:                return NULL;
                    548: 
                    549:        if (io_arrayCopy(&tmp, vars) == -1)
                    550:                return NULL;
                    551:        else
                    552:                qsort(tmp->arr_data, tmp->arr_num, sizeof(void*), _cmp_arr_key_asc);
                    553: 
                    554:        /* binary search */
                    555:        for (p = (const u_char*) tmp->arr_data, i = io_arraySize(tmp); i; i >>= 1) {
                    556:                vv = (ait_val_t**) (p + (i >> 1) * sizeof(void*));
                    557:                if (!(key - AIT_KEY(*vv))) {    /* found! */
                    558:                        v = *vv;
                    559:                        break;
                    560:                }
                    561:                if ((key - AIT_KEY(*vv)) > 0) { /* move right key > current */
                    562:                        p = (const u_char*) vv + sizeof(void*);
                    563:                        i--;
                    564:                }                               /* else move left */
1.4       misho     565:        }
1.6       misho     566: 
                    567:        io_arrayDestroy(&tmp);
                    568:        return v;
1.4       misho     569: }

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