Beispiel #1
0
static __tb_inline__ tb_bool_t tb_option_is_float(tb_char_t const* data)
{
    // check
    tb_assert_and_check_return_val(data, tb_false);
    
    // init
    tb_char_t const* p = data;

    // walk
    for (; *p && (tb_isdigit10(*p) || *p == '.'); p++);

    // ok?
    return *p? tb_false : tb_true;
}
Beispiel #2
0
tb_bool_t tb_ipv4_cstr_set(tb_ipv4_ref_t ipv4, tb_char_t const* cstr)
{
    // check
    tb_assert_and_check_return_val(cstr, tb_false);

    // done
    tb_uint32_t         r = 0;
    tb_uint32_t         v = 0;
    tb_char_t           c = '\0';
    tb_size_t           i = 0;
    tb_char_t const*    p = cstr;
    do
    {
        // the character
        c = *p++;

        // digit?
        if (tb_isdigit10(c) && v <= 0xff)
        {
            v *= 10;
            v += (tb_uint32_t)(c - '0') & 0xff;
        }
        // '.' or '\0'?
        else if ((c == '.' || !c) && v <= 0xff)
        {
            r |= ((tb_uint32_t)v) << ((i++) << 3);
            v = 0;
        }
        // failed?
        else 
        {
            // trace
            tb_trace_d("invalid ipv4 addr: %s", cstr);

            // clear it
            i = 0;
            break;
        }

    } while (c);

    // save it if ok
    if (ipv4) ipv4->u32 = r;

    // ok?
    return i == 4;
}
Beispiel #3
0
tb_uint64_t tb_s16tou64(tb_char_t const* s)
{
    // check
    tb_assert_and_check_return_val(s, 0);

    // skip space
    while (tb_isspace(*s)) s++;

    // has sign?
    tb_int_t sign = 0;
    if (*s == '-') 
    {
        sign = 1;
        s++;
    }

    // skip "0x"
    if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
        s += 2;

    // skip '0'
    while ((*s) == '0') s++;

    // compute number
    tb_uint64_t val = 0;
    while (*s)
    {
        tb_char_t ch = *s;
        if (tb_isdigit10(ch))
            val = (val << 4) + (ch - '0');
        else if (ch > ('a' - 1) && ch < ('f' + 1))
            val = (val << 4) + (ch - 'a') + 10;
        else if (ch > ('A' - 1) && ch < ('F' + 1))
            val = (val << 4) + (ch - 'A') + 10;
        else break;
    
        s++;
    }

    // is negative number?
    if (sign) val = ~val + 1;

    // the value
    return val;
}
Beispiel #4
0
tb_uint64_t tb_s10tou64(tb_char_t const* s)
{
    // check
    tb_assert_and_check_return_val(s, 0);

    // skip space
    while (tb_isspace(*s)) s++;

    // has sign?
    tb_int_t sign = 0;
    if (*s == '-') 
    {
        sign = 1;
        s++;
    }

    // skip '0'
    while ((*s) == '0') s++;

    // compute number
    tb_uint64_t val = 0;
    while (*s)
    {
        tb_char_t ch = *s;
        if (tb_isdigit10(ch))
            val = val * 10 + (ch - '0');
        else break;
    
        s++;
    }

    // is negative number?
    if (sign) val = ~val + 1;

    // the value
    return val;
}
Beispiel #5
0
static tb_object_ref_t tb_object_json_reader_func_number(tb_object_json_reader_t* reader, tb_char_t type)
{
    // check
    tb_assert_and_check_return_val(reader && reader->stream, tb_null);

    // init data
    tb_static_string_t  data;
    tb_char_t           buff[256];
    if (!tb_static_string_init(&data, buff, 256)) return tb_null;

    // done
    tb_object_ref_t number = tb_null;
    do
    {
        // append character
        tb_static_string_chrcat(&data, type);

        // walk
        tb_bool_t bs = (type == '-')? tb_true : tb_false;
        tb_bool_t bf = (type == '.')? tb_true : tb_false;
        tb_bool_t failed = tb_false;
        while (!failed && tb_stream_left(reader->stream)) 
        {
            // need one character
            tb_byte_t* p = tb_null;
            if (!tb_stream_need(reader->stream, &p, 1) && p) 
            {
                failed = tb_true;
                break;
            }

            // the character
            tb_char_t ch = *p;

            // is float?
            if (!bf && ch == '.') bf = tb_true;
            else if (bf && ch == '.') 
            {
                failed = tb_true;
                break;
            }

            // append character
            if (tb_isdigit10(ch) || ch == '.' || ch == 'e' || ch == 'E' || ch == '-' || ch == '+') 
                tb_static_string_chrcat(&data, ch);
            else break;

            // skip it
            tb_stream_skip(reader->stream, 1);
        }

        // failed?
        tb_check_break(!failed);

        // check
        tb_assert_and_check_break(tb_static_string_size(&data));

        // trace
        tb_trace_d("number: %s", tb_static_string_cstr(&data));

        // init number 
#ifdef TB_CONFIG_TYPE_FLOAT
        if (bf) number = tb_object_number_init_from_float(tb_stof(tb_static_string_cstr(&data)));
#else
        if (bf) tb_trace_noimpl();
#endif
        else if (bs) 
        {
            tb_sint64_t value = tb_stoi64(tb_static_string_cstr(&data));
            tb_size_t   bytes = tb_object_need_bytes(-value);
            switch (bytes)
            {
            case 1: number = tb_object_number_init_from_sint8((tb_sint8_t)value); break;
            case 2: number = tb_object_number_init_from_sint16((tb_sint16_t)value); break;
            case 4: number = tb_object_number_init_from_sint32((tb_sint32_t)value); break;
            case 8: number = tb_object_number_init_from_sint64((tb_sint64_t)value); break;
            default: break;
            }
            
        }
        else 
        {
            tb_uint64_t value = tb_stou64(tb_static_string_cstr(&data));
            tb_size_t   bytes = tb_object_need_bytes(value);
            switch (bytes)
            {
            case 1: number = tb_object_number_init_from_uint8((tb_uint8_t)value); break;
            case 2: number = tb_object_number_init_from_uint16((tb_uint16_t)value); break;
            case 4: number = tb_object_number_init_from_uint32((tb_uint32_t)value); break;
            case 8: number = tb_object_number_init_from_uint64((tb_uint64_t)value); break;
            default: break;
            }
        }

    } while (0);

    // exit data
    tb_static_string_exit(&data);

    // ok?
    return number;
}
Beispiel #6
0
tb_bool_t tb_hwaddr_cstr_set(tb_hwaddr_ref_t hwaddr, tb_char_t const* cstr)
{
    // check
    tb_assert_and_check_return_val(cstr, tb_false);

    // done
    tb_uint32_t         v = 0;
    tb_char_t           c = '\0';
    tb_size_t           i = 0;
    tb_char_t const*    p = cstr;
    tb_bool_t           ok = tb_true;
    tb_hwaddr_t         temp;
    do
    {
        // the character
        c = *p++;

        // digit?
        if (tb_isdigit16(c) && v <= 0xff)
        {
            // update value
            if (tb_isdigit10(c))
                v = (v << 4) + (c - '0');
            else if (c > ('a' - 1) && c < ('f' + 1))
                v = (v << 4) + (c - 'a') + 10;
            else if (c > ('A' - 1) && c < ('F' + 1))
                v = (v << 4) + (c - 'A') + 10;
            else 
            {
                // abort
                tb_assert(0);

                // failed
                ok = tb_false;
                break;
            }
        }
        // ':' or "-" or '\0'?
        else if (i < 6 && (c == ':' || c == '-' || !c) && v <= 0xff)
        {
            // save value
            temp.u8[i++] = v;

            // clear value
            v = 0;
        }
        // failed?
        else 
        {
            ok = tb_false;
            break;
        }

    } while (c);

    // failed
    if (i != 6) ok = tb_false;

    // save it if ok
    if (ok && hwaddr) *hwaddr = temp;

    // trace
//    tb_assertf(ok, "invalid hwaddr: %s", cstr);

    // ok?
    return ok;
}
Beispiel #7
0
tb_object_ref_t tb_object_seek(tb_object_ref_t object, tb_char_t const* path, tb_size_t type)
{
    // check
    tb_assert_and_check_return_val(object, tb_null);

    // null?
    tb_check_return_val(path, object);

    // walk
    tb_char_t const* p = path;
    tb_char_t const* e = path + tb_strlen(path);
    while (p < e && object)
    {
        // done seek
        switch (*p)
        {
        case '.':
            {
                // check
                tb_assert_and_check_return_val(tb_object_type(object) == TB_OBJECT_TYPE_DICTIONARY, tb_null);

                // skip
                p++;

                // read the key name
                tb_char_t   key[4096] = {0};
                tb_char_t*  kb = key;
                tb_char_t*  ke = key + 4095;
                for (; p < e && kb < ke && *p && (*p != '.' && *p != '[' && *p != ']'); p++, kb++) 
                {
                    if (*p == '\\') p++;
                    *kb = *p;
                }

                // trace
                tb_trace_d("key: %s", key);
            
                // the value
                object = tb_object_dictionary_val(object, key);
            }
            break;
        case '[':
            {
                // check
                tb_assert_and_check_return_val(tb_object_type(object) == TB_OBJECT_TYPE_ARRAY, tb_null);

                // skip
                p++;

                // read the item index
                tb_char_t   index[32] = {0};
                tb_char_t*  ib = index;
                tb_char_t*  ie = index + 31;
                for (; p < e && ib < ie && *p && tb_isdigit10(*p); p++, ib++) *ib = *p;

                // trace
                tb_trace_d("index: %s", index);

                // check
                tb_size_t i = tb_atoi(index);
                tb_assert_and_check_return_val(i < tb_object_array_size(object), tb_null);

                // the value
                object = tb_object_array_item(object, i);
            }
            break;
        case ']':
        default:
            p++;
            break;
        }
    }

    // check it, if not none
    if (object && type != TB_OBJECT_TYPE_NONE) 
    {
        // is this type?
        if (tb_object_type(object) != type) return tb_null;
    }

    // ok?
    return object;
}
Beispiel #8
0
tb_object_ref_t tb_object_seek(tb_object_ref_t object, tb_char_t const* path, tb_bool_t bmacro)
{
    // check
    tb_assert_and_check_return_val(object, tb_null);

    // null?
    tb_check_return_val(path, object);

    // done
    tb_object_ref_t     root = object;
    tb_char_t const*    p = path;
    tb_char_t const*    e = path + tb_strlen(path);
    while (p < e && object)
    {
        // done seek
        switch (*p)
        {
        case '.':
            {
                // check
                tb_assert_and_check_return_val(tb_object_type(object) == TB_OBJECT_TYPE_DICTIONARY, tb_null);

                // skip
                p++;

                // read the key name
                tb_char_t   key[4096] = {0};
                tb_char_t*  kb = key;
                tb_char_t*  ke = key + 4095;
                for (; p < e && kb < ke && *p && (*p != '.' && *p != '[' && *p != ']'); p++, kb++) 
                {
                    if (*p == '\\') p++;
                    *kb = *p;
                }

                // trace
                tb_trace_d("key: %s", key);
            
                // the value
                object = tb_object_dictionary_value(object, key);
            }
            break;
        case '[':
            {
                // check
                tb_assert_and_check_return_val(tb_object_type(object) == TB_OBJECT_TYPE_ARRAY, tb_null);

                // skip
                p++;

                // read the item index
                tb_char_t   index[32] = {0};
                tb_char_t*  ib = index;
                tb_char_t*  ie = index + 31;
                for (; p < e && ib < ie && *p && tb_isdigit10(*p); p++, ib++) *ib = *p;

                // trace
                tb_trace_d("index: %s", index);

                // check
                tb_size_t i = tb_atoi(index);
                tb_assert_and_check_return_val(i < tb_object_array_size(object), tb_null);

                // the value
                object = tb_object_array_item(object, i);
            }
            break;
        case ']':
        default:
            p++;
            break;
        }

        // is macro? done it if be enabled
        if (    object
            &&  bmacro
            &&  tb_object_type(object) == TB_OBJECT_TYPE_STRING
            &&  tb_object_string_size(object)
            &&  tb_object_string_cstr(object)[0] == '$')
        {
            // the next path
            path = tb_object_string_cstr(object) + 1;

            // continue to seek it
            object = tb_object_seek(root, path, bmacro);
        }
    }

    // ok?
    return object;
}
Beispiel #9
0
tb_double_t tb_s16tod(tb_char_t const* s)
{
    // check
    tb_assert_and_check_return_val(s, 0);

    // skip space
    while (tb_isspace(*s)) s++;

    // has sign?
    tb_int_t sign = 0;
    if (*s == '-') 
    {
        sign = 1;
        s++;
    }

    // nan?
    if (s[0] == 'n' && s[1] == 'a' && s[2] == 'n')
        return TB_NAN;

    // inf or -inf?
    if (s[0] == 'i' && s[1] == 'n' && s[2] == 'f')
        return sign? -TB_INF : TB_INF;

    // skip "0x"
    if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
        s += 2;

    // compute double: lhs.rhs
    tb_int_t    dec = 0;
    tb_uint64_t lhs = 0;
    tb_double_t rhs = 0.;
    tb_int_t    zeros = 0;
    tb_int8_t   decimals[256];
    tb_int8_t*  d = decimals;
    tb_int8_t*  e = decimals + 256;
    while (*s)
    {
        tb_char_t ch = *s;

        // is the part of decimal?
        if (ch == '.')
        {
            if (!dec) 
            {
                dec = 1;
                s++;
                continue ;
            }
            else break;
        }

        // parse integer & decimal
        if (tb_isdigit10(ch))
        {
            // save decimals
            if (dec) 
            {
                if (d < e)
                {
                    if (ch != '0')
                    {
                        // fill '0'
                        while (zeros--) *d++ = 0;
                        zeros = 0;

                        // save decimal
                        *d++ = ch - '0';
                    }
                    else zeros++;
                }
            }
            else lhs = (lhs << 4) + (ch - '0');
        }
        else if (ch > ('a' - 1) && ch < ('f' + 1))
        {
            // save decimals
            if (dec) 
            {
                if (d < e)
                {
                    if (ch != '0')
                    {
                        // fill '0'
                        while (zeros--) *d++ = 0;
                        zeros = 0;

                        // save decimal
                        *d++ = (ch - 'a') + 10;
                    }
                    else zeros++;
                }
            }
            else lhs = (lhs << 4) + (ch - 'a') + 10;
        }
        else if (ch > ('A' - 1) && ch < ('F' + 1))
        {
            // save decimals
            if (dec) 
            {
                if (d < e)
                {
                    if (ch != '0')
                    {
                        // fill '0'
                        while (zeros--) *d++ = 0;
                        zeros = 0;

                        // save decimal
                        *d++ = (ch - 'A') + 10;
                    }
                    else zeros++;
                }
            }
            else lhs = (lhs << 4) + (ch - 'A') + 10;
        }
        else break;
    
        s++;
    }

    // check
    tb_assert_and_check_return_val(d <= decimals + 256, 0);

    // compute decimal
    while (d-- > decimals) rhs = (rhs + *d) / 16;

    // merge 
    return (sign? ((tb_double_t)lhs + rhs) * -1. : ((tb_double_t)lhs + rhs));
}