Example #1
0
File: sha.c Project: ljx0305/tbox
tb_void_t tb_sha_spak(tb_sha_t* sha, tb_byte_t const* data, tb_size_t size)
{
    // check
    tb_assert_and_check_return(sha && data);

    // update count
    tb_uint32_t j = (tb_uint32_t)sha->count & 63;
    sha->count += size;

    // done
    tb_uint32_t i;
#ifdef __tb_small__
    for (i = 0; i < size; i++) 
    {
        sha->buffer[j++] = data[i];
        if (64 == j) 
        {
            sha->transform(sha->state, sha->buffer);
            j = 0;
        }
    }
#else
    if ((j + size) > 63)
    {
        tb_memcpy(&sha->buffer[j], data, (i = 64 - j));
        sha->transform(sha->state, sha->buffer);
        for (; i + 63 < size; i += 64)
            sha->transform(sha->state, &data[i]);
        j = 0;
    } 
    else i = 0;
    tb_memcpy(&sha->buffer[j], &data[i], size - i);
#endif
}
Example #2
0
tb_size_t tb_wcslcpy(tb_wchar_t* s1, tb_wchar_t const* s2, tb_size_t n)
{
    // check
    tb_assert_and_check_return_val(s1 && s2, 0);

    // no size or same? 
    tb_check_return_val(n && s1 != s2, tb_wcslen(s1));

    // copy
#if 0
    tb_wchar_t const* s = s2; --n;
    while (*s1 = *s2) 
    {
        if (n) 
        {
            --n;
            ++s1;
        }
        ++s2;
    }
    return s2 - s;
#else
    tb_size_t sn = tb_wcslen(s2);
    tb_memcpy(s1, s2, tb_min(sn + 1, n) * sizeof(tb_wchar_t));
    return tb_min(sn, n);
#endif
}
Example #3
0
tb_wchar_t* tb_wcscpy(tb_wchar_t* s1, tb_wchar_t const* s2)
{
    tb_assert_and_check_return_val(s1 && s2, tb_null);

    __tb_register__ tb_wchar_t* s = s1;
    if (s1 == s2) return s;

#if 1
    tb_memcpy(s1, s2, (tb_wcslen(s2) + 1) * sizeof(tb_wchar_t));
#elif defined(__tb_small__)
    while ((*s++ = *s2++)) ;
#else
    while (1) 
    {
        if (!(s1[0] = s2[0])) break;
        if (!(s1[1] = s2[1])) break;
        if (!(s1[2] = s2[2])) break;
        if (!(s1[3] = s2[3])) break;
        s1 += 4;
        s2 += 4;
    }
#endif

    return s;
}
Example #4
0
/*!the insertion sort
 *
 * <pre>
 * old:     5       2       6       2       8       6       1
 *
 *        (hole)
 * step1: ((5))     2       6       2       8       6       1
 *        (next) <=
 *
 *        (hole)  
 * step2: ((2))    (5)      6       2       8       6       1
 *                (next) <=
 *
 *                        (hole)
 * step3:   2       5     ((6))     2       8       6       1
 *                        (next) <=
 *
 *                 (hole)       
 * step4:   2      ((2))   (5)     (6)      8       6       1
 *                                (next) <=
 *
 *                                        (hole)
 * step5:   2       2       5       6     ((8))     6       1
 *                                        (next) <=
 *
 *                                        (hole) 
 * step6:   2       2       5       6     ((6))    (8)       1
 *                                                (next) <=
 *
 *        (hole)                                         
 * step7: ((1))    (2)     (2)     (5)     (6)     (6)      (8)       
 *                                                        (next)
 * </pre>
 */
tb_void_t tb_insert_sort(tb_iterator_ref_t iterator, tb_size_t head, tb_size_t tail, tb_iterator_comp_t comp)
{   
    // check
    tb_assert_and_check_return(iterator);
    tb_assert_and_check_return((tb_iterator_mode(iterator) & TB_ITERATOR_MODE_FORWARD));
    tb_assert_and_check_return((tb_iterator_mode(iterator) & TB_ITERATOR_MODE_REVERSE));
    tb_check_return(head != tail);
    
    // init
    tb_size_t       step = tb_iterator_step(iterator);
    tb_pointer_t    temp = step > sizeof(tb_pointer_t)? tb_malloc(step) : tb_null;
    tb_assert_and_check_return(step <= sizeof(tb_pointer_t) || temp);

    // the comparer
    if (!comp) comp = tb_iterator_comp;

    // sort
    tb_size_t last, next;
    for (next = tb_iterator_next(iterator, head); next != tail; next = tb_iterator_next(iterator, next))
    {
        // save next
        if (step <= sizeof(tb_pointer_t)) temp = tb_iterator_item(iterator, next);
        else tb_memcpy(temp, tb_iterator_item(iterator, next), step);

        // look for hole and move elements[hole, next - 1] => [hole + 1, next]
        for (last = next; last != head && (last = tb_iterator_prev(iterator, last), comp(iterator, temp, tb_iterator_item(iterator, last)) < 0); next = last)
                tb_iterator_copy(iterator, next, tb_iterator_item(iterator, last));

        // item => hole
        tb_iterator_copy(iterator, next, temp);
    }

    // free
    if (temp && step > sizeof(tb_pointer_t)) tb_free(temp);
}
Example #5
0
tb_wchar_t* tb_wcsncpy(tb_wchar_t* s1, tb_wchar_t const* s2, tb_size_t n)
{
    // check
    tb_assert_and_check_return_val(s1 && s2, s1);

    // no size or same? 
    tb_check_return_val(n && s1 != s2, s1);

    // copy
#if 0
    tb_wchar_t* s = s1;
    while (n) 
    {
        if (*s = *s2) s2++;
        ++s;
        --n;
    }
    return s1;
#else
    tb_size_t sn = tb_wcslen(s2);
    tb_size_t cn = tb_min(sn, n);
    tb_size_t fn = sn < n? n - sn : 0;
    tb_memcpy(s1, s2, cn * sizeof(tb_wchar_t));
    if (fn) tb_memset(s1 + cn, 0, fn * sizeof(tb_wchar_t));
    return s1;
#endif
}
Example #6
0
tb_void_t tb_vector_copy(tb_vector_ref_t vector, tb_vector_ref_t hcopy)
{
    // check
    tb_vector_impl_t*       impl = (tb_vector_impl_t*)vector;
    tb_vector_impl_t const* copy = (tb_vector_impl_t const*)hcopy;
    tb_assert_and_check_return(impl && copy);

    // check func
    tb_assert_and_check_return(impl->func.type == copy->func.type);
    tb_assert_and_check_return(impl->func.size == copy->func.size);

    // check itor
    tb_assert_and_check_return(impl->itor.mode == copy->itor.mode);
    tb_assert_and_check_return(impl->itor.step == copy->itor.step);

    // null? clear it
    if (!copy->size) 
    {
        tb_vector_clear(vector);
        return ;
    }
    
    // resize if small
    if (impl->size < copy->size) tb_vector_resize(vector, copy->size);
    tb_assert_and_check_return(impl->data && copy->data && impl->size >= copy->size);

    // copy data
    if (copy->data != impl->data) tb_memcpy(impl->data, copy->data, copy->size * copy->func.size);

    // copy size
    impl->size = copy->size;
}
Example #7
0
int sha256_process(sha256_state * md, const unsigned char *in, unsigned long inlen)
{
    unsigned long n;
    int           err;

    if (md == NULL || in == NULL)
        return -1;
    if (md->curlen > sizeof(md->buf))
        return -1;

    while (inlen > 0) {                                                          
        if (md->curlen == 0 && inlen >= SHA256_BLOCK_SIZE) {
            if ((err = sha256_compress(md, (unsigned char *)in)) != 0) {
                return err;
            }
            md->length += SHA256_BLOCK_SIZE * 8;          
            in += SHA256_BLOCK_SIZE;                      
            inlen -= SHA256_BLOCK_SIZE;                      
        } else {                                              
           n = MIN(inlen, (SHA256_BLOCK_SIZE - md->curlen));
           tb_memcpy(md->buf + md->curlen, in, (size_t)n);
           md->curlen += n;
           in += n;
           inlen -= n;
           if (md->curlen == SHA256_BLOCK_SIZE) {
              if ((err = sha256_compress(md, md->buf)) != 0) {
                 return err;
              }
              md->length += 8*SHA256_BLOCK_SIZE;
              md->curlen = 0;
           }
       }
    }
    return 0;                                                                 
}
Example #8
0
tb_long_t tb_queue_buffer_writ(tb_queue_buffer_ref_t buffer, tb_byte_t const* data, tb_size_t size)
{
    // check
    tb_assert_and_check_return_val(buffer && data && buffer->maxn, -1);

    // no data?
    if (!buffer->data)
    {
        // make data
        buffer->data = tb_malloc_bytes(buffer->maxn);
        tb_assert_and_check_return_val(buffer->data, -1);

        // init it
        buffer->head = buffer->data;
        buffer->size = 0;
    }
    tb_assert_and_check_return_val(buffer->data && buffer->head, -1);

    // full?
    tb_size_t left = buffer->maxn - buffer->size;
    tb_check_return_val(left, 0);

    // attempt to write data in tail directly if the tail space is enough
    tb_byte_t* tail = buffer->head + buffer->size;
    if (buffer->data + buffer->maxn >= tail + size)
    {
        tb_memcpy(tail, data, size);
        buffer->size += size;
        return (tb_long_t)size;
    }

    // move data to head
    if (buffer->head != buffer->data)
    {
        if (buffer->size) tb_memmov(buffer->data, buffer->head, buffer->size);
        buffer->head = buffer->data;
    }

    // write data
    tb_size_t writ = left > size? size : left;
    tb_memcpy(buffer->data + buffer->size, data, writ);
    buffer->size += writ;

    // ok
    return writ;
}
Example #9
0
File: mem.c Project: siwuxian/xmake
static tb_void_t tb_iterator_mem_copy(tb_iterator_ref_t iterator, tb_size_t itor, tb_cpointer_t item)
{
    // check
    tb_assert(iterator && itor < ((tb_array_iterator_ref_t)iterator)->count);

    // copy
    tb_memcpy((tb_byte_t*)((tb_array_iterator_ref_t)iterator)->items + itor * iterator->step, item, iterator->step);
}
Example #10
0
tb_char_t const* tb_addrinfo_name(tb_ipaddr_ref_t addr, tb_char_t* name, tb_size_t maxn)
{
    // check
    tb_assert_and_check_return_val(addr && name && maxn, tb_null);

#if defined(TB_CONFIG_POSIX_HAVE_GETNAMEINFO)
    // load socket address
    struct sockaddr_storage saddr;
    socklen_t saddrlen = (socklen_t)tb_sockaddr_load(&saddr, addr);
    tb_assert_and_check_return_val(saddrlen, tb_null);

    // get host name from address
    return !getnameinfo((struct sockaddr const*)&saddr, saddrlen, name, maxn, tb_null, 0, NI_NAMEREQD)? name : tb_null;
#elif defined(TB_CONFIG_POSIX_HAVE_GETHOSTBYNAME)

    // done
    struct hostent* hostaddr = tb_null;
    switch (tb_ipaddr_family(addr))
    {
    case TB_IPADDR_FAMILY_IPV4:
        {
            // init ip address
            struct in_addr ipaddr = {0};
            ipaddr.s_addr = tb_ipaddr_ip_is_any(addr)? INADDR_ANY : addr->u.ipv4.u32;

            // get host name from address
            hostaddr = gethostbyaddr((tb_char_t const*)&ipaddr, sizeof(ipaddr), AF_INET);
        }
        break;
    case TB_IPADDR_FAMILY_IPV6:
        {
            // init ip address
            struct in6_addr ipaddr;
            tb_memset(&ipaddr, 0, sizeof(ipaddr));

            // save ipv6
            if (tb_ipaddr_ip_is_any(addr)) ipaddr = in6addr_any;
            else tb_memcpy(ipaddr.s6_addr, addr->u.ipv6.addr.u8, sizeof(ipaddr.s6_addr));

            // get host name from address
            hostaddr = gethostbyaddr((tb_char_t const*)&ipaddr, sizeof(ipaddr), AF_INET6);
        }
        break;
    default:
        break;
    }
    tb_check_return_val(hostaddr && hostaddr->h_name, tb_null);

    // save name
    tb_strlcpy(name, hostaddr->h_name, maxn);

    // ok?
    return name;
#else
    tb_trace_noimpl();
    return tb_null;
#endif
}
Example #11
0
static tb_void_t tb_iterator_init_mem_copy(tb_iterator_ref_t iterator, tb_size_t itor, tb_cpointer_t item)
{
    // check
    tb_assert_return(iterator);
    tb_assert_return(itor < (tb_size_t)iterator->priv && item);

    // copy
    tb_memcpy((tb_byte_t*)iterator->data + itor * iterator->step, item, iterator->step);
}
Example #12
0
File: str.c Project: ljx0305/tbox
static tb_void_t tb_element_str_repl(tb_element_ref_t element, tb_pointer_t buff, tb_cpointer_t data)
{
    // check
    tb_assert_and_check_return(element && element->dupl && buff);

#if 0
    // free it
    if (element->free) element->free(element, buff);

    // dupl it
    element->dupl(element, buff, data);
#else
    // replace it
    tb_pointer_t cstr = *((tb_pointer_t*)buff);
    if (cstr && data)
    {
        // attempt to replace it
        tb_char_t*          p = (tb_char_t*)cstr;
        tb_char_t const*    q = (tb_char_t const*)data;
        while (*p && *q) *p++ = *q++;

        // not enough space?
        if (!*p && *q)
        {
            // the left size
            tb_size_t left = tb_strlen(q);
            tb_assert(left);

            // the copy size
            tb_size_t copy = p - (tb_char_t*)cstr;

            // grow size
            cstr = tb_ralloc(cstr, copy + left + 1);
            tb_assert(cstr);

            // copy the left data
            tb_memcpy((tb_char_t*)cstr + copy, q, left + 1); 

            // update the cstr
            *((tb_pointer_t*)buff) = cstr;
        }
        // end
        else *p = '\0';
    }
    // duplicate it
    else if (data) element->dupl(element, buff, data);
    // free it
    else if (element->free) element->free(element, buff);
    // clear it
    else *((tb_char_t const**)buff) = tb_null;
#endif
}
Example #13
0
File: style.c Project: cosim/gbox2
tb_void_t g2_style_copy(tb_handle_t style, tb_handle_t copy)
{
	g2_style_t* gstyle = (g2_style_t*)style;
	g2_style_t* gcopy = (g2_style_t*)style;
	tb_assert_and_check_return(gstyle && gcopy);

	// refn++
	if (gcopy->shader) g2_shader_inc(gcopy->shader);

	// refn--
	if (gstyle->shader) g2_shader_dec(gstyle->shader);

	// copy
	tb_memcpy(gstyle, copy, sizeof(g2_style_t));
}
Example #14
0
tb_char_t* tb_strndup(tb_char_t const* s, tb_size_t n)
{
    // check
    tb_assert_and_check_return_val(s, tb_null);

    // done
    n = tb_strnlen(s, n);
    __tb_register__ tb_char_t* p = tb_malloc_cstr(n + 1);
    if (p)
    {
        tb_memcpy(p, s, n);
        p[n] = '\0';
    }

    return p;
}
Example #15
0
tb_void_t tb_md5_exit(tb_md5_t* md5, tb_byte_t* data, tb_size_t size)
{
    // check
    tb_assert_and_check_return(md5 && data);

    // init
    tb_uint32_t ip[16];
    tb_int_t    mdi = 0;
    tb_size_t   i = 0;
    tb_size_t   ii = 0;
    tb_size_t   pad_n = 0;

    // save number of bits 
    ip[14] = md5->i[0];
    ip[15] = md5->i[1];

    // compute number of bytes mod 64
    mdi = (tb_int_t)((md5->i[0] >> 3) & 0x3F);

    // pad out to 56 mod 64
    pad_n = (mdi < 56) ? (56 - mdi) : (120 - mdi);
    tb_md5_spak (md5, g_md5_padding, pad_n);

    // append length ip bits and transform
    for (i = 0, ii = 0; i < 14; i++, ii += 4)
    {
        ip[i] =     (((tb_uint32_t)md5->ip[ii + 3]) << 24)
                |   (((tb_uint32_t)md5->ip[ii + 2]) << 16)
                |   (((tb_uint32_t)md5->ip[ii + 1]) <<  8)
                |   ((tb_uint32_t)md5->ip[ii]);
    }
    tb_md5_transform (md5->sp, ip);

    // store buffer ip data
    for (i = 0, ii = 0; i < 4; i++, ii += 4)
    {
        md5->data[ii]   = (tb_byte_t)( md5->sp[i]        & 0xff);
        md5->data[ii+1] = (tb_byte_t)((md5->sp[i] >>  8) & 0xff);
        md5->data[ii+2] = (tb_byte_t)((md5->sp[i] >> 16) & 0xff);
        md5->data[ii+3] = (tb_byte_t)((md5->sp[i] >> 24) & 0xff);
    }

    // output
    tb_memcpy(data, md5->data, 16);
}
Example #16
0
tb_byte_t* tb_buffer_memncpyp(tb_buffer_t* buffer, tb_size_t p, tb_byte_t const* b, tb_size_t n)
{
    // check
    tb_assert_and_check_return_val(buffer && b, tb_null);
    
    // check
    tb_check_return_val(n, tb_buffer_data(buffer));

    // resize
    tb_byte_t* d = tb_buffer_resize(buffer, p + n);
    tb_assert_and_check_return_val(d, tb_null);

    // copy it
    tb_memcpy(d + p, b, n);

    // ok
    return d;
}
Example #17
0
tb_char_t* tb_strdup(tb_char_t const* s)
{
    // check
    tb_assert_and_check_return_val(s, tb_null);

    // make 
    __tb_register__ tb_size_t   n = tb_strlen(s);
    __tb_register__ tb_char_t*  p = tb_malloc_cstr(n + 1);
    tb_assert_and_check_return_val(p, tb_null);

    // copy
    tb_memcpy(p, s, n);

    // end
    p[n] = '\0';

    // ok
    return p;
}
Example #18
0
tb_long_t tb_queue_buffer_read(tb_queue_buffer_ref_t buffer, tb_byte_t* data, tb_size_t size)
{
    // check
    tb_assert_and_check_return_val(buffer && data, -1);

    // no data?
    tb_check_return_val(buffer->data && buffer->size && size, 0);
    tb_assert_and_check_return_val(buffer->head, -1);

    // read data
    tb_long_t read = buffer->size > size? size : buffer->size;
    tb_memcpy(data, buffer->head, read);
    buffer->head += read;
    buffer->size -= read;

    // null? reset head
    if (!buffer->size) buffer->head = buffer->data;

    // ok
    return read;
}
Example #19
0
File: parser.c Project: waruqi/vm86
tb_bool_t vm86_parser_get_instruction_name(tb_char_t const** pp, tb_char_t const* e, tb_char_t* name, tb_size_t maxn)
{
    // check
    tb_assert(pp && e && name && maxn);

    // done
    tb_bool_t           ok = tb_false;
    tb_char_t const*    p = *pp;
    do
    {
        // save base
        tb_char_t const* b = p;

        // skip name
        while (p < e && tb_isalpha(*p)) p++;
        tb_check_break(p <= e && p - b < maxn);

        // not instruction name?
        if (p < e && !tb_isspace(*p)) break;

        // save name
        tb_memcpy(name, b, p - b);

        // end
        name[p - b] = '\0';

        // skip the space
        while (p < e && tb_isspace(*p)) p++;

        // ok
        ok = tb_true;

    } while (0);

    // update the code pointer if ok
    if (ok) *pp = p;

    // ok?
    return ok;
}
Example #20
0
File: parser.c Project: waruqi/vm86
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_bool_t vm86_parser_get_variable_name(tb_char_t const** pp, tb_char_t const* e, tb_char_t* name, tb_size_t maxn)
{
    // check
    tb_assert(pp && e && name && maxn);

    // done
    tb_bool_t           ok = tb_false;
    tb_char_t const*    p = *pp;
    do
    {
        // save base
        tb_char_t const* b = p;

        // check
        tb_check_break(p < e && (tb_isalpha(*p) || *p == '_'));
        p++;

        // get name
        while (p < e && (tb_isalpha(*p) || *p == '_' || tb_isdigit(*p))) p++;
        tb_check_break(p <= e && p - b < maxn);
        tb_memcpy(name, b, p - b);

        // end
        name[p - b] = '\0';

        // skip the space
        while (p < e && tb_isspace(*p)) p++;

        // ok
        ok = tb_true;

    } while (0);

    // update the code pointer if ok
    if (ok) *pp = p;

    // ok?
    return ok;
}
Example #21
0
tb_byte_t* tb_buffer_memncat(tb_buffer_t* buffer, tb_byte_t const* b, tb_size_t n)
{   
    // check
    tb_assert_and_check_return_val(buffer && b, tb_null);
    
    // check
    tb_check_return_val(n, tb_buffer_data(buffer));

    // is null?
    tb_size_t p = tb_buffer_size(buffer);
    if (!p) return tb_buffer_memncpy(buffer, b, n);

    // resize
    tb_byte_t* d = tb_buffer_resize(buffer, p + n);
    tb_assert_and_check_return_val(d, tb_null);

    // memcat
    tb_memcpy(d + p, b, n);

    // ok?
    return d;
}
Example #22
0
tb_long_t tb_queue_buffer_writ(tb_queue_buffer_t* buffer, tb_byte_t const* data, tb_size_t size)
{
    // check
    tb_assert_and_check_return_val(buffer && data && buffer->maxn, -1);

    // no data?
    if (!buffer->data)
    {
        // make data
        buffer->data = tb_malloc_bytes(buffer->maxn);
        tb_assert_and_check_return_val(buffer->data, -1);

        // init it
        buffer->head = buffer->data;
        buffer->size = 0;
    }
    tb_assert_and_check_return_val(buffer->data && buffer->head, -1);

    // no left?
    tb_size_t left = buffer->maxn - buffer->size;
    tb_check_return_val(left, 0);

    // move data to head
    if (buffer->head != buffer->data)
    {
        if (buffer->size) tb_memmov(buffer->data, buffer->head, buffer->size);
        buffer->head = buffer->data;
    }

    // writ data
    tb_size_t writ = left > size? size : left;
    tb_memcpy(buffer->data + buffer->size, data, writ);
    buffer->size += writ;

    // ok
    return writ;
}
Example #23
0
static tb_void_t tb_ifaddrs_interface_load4(tb_list_ref_t interfaces)
{
    // check
    tb_assert_and_check_return(interfaces);

    // done
    PIP_ADAPTER_INFO adapter_info = tb_null;
    do
    {
        // make the adapter info 
        adapter_info = tb_malloc0_type(IP_ADAPTER_INFO);
        tb_assert_and_check_break(adapter_info);

        // get the real adapter info size
        ULONG size = sizeof(IP_ADAPTER_INFO);
        if (tb_iphlpapi()->GetAdaptersInfo(adapter_info, &size) == ERROR_BUFFER_OVERFLOW)
        {
            // grow the adapter info buffer
            adapter_info = (PIP_ADAPTER_INFO)tb_ralloc(adapter_info, size);
            tb_assert_and_check_break(adapter_info);

            // reclear it
            tb_memset(adapter_info, 0, size);
        }
    
        // get the adapter info 
        if (tb_iphlpapi()->GetAdaptersInfo(adapter_info, &size) != NO_ERROR) break;

        // done
        PIP_ADAPTER_INFO adapter = adapter_info;
        while (adapter)
        {
            // check
            tb_assert(adapter->AdapterName);

            /* attempt to get the interface from the cached interfaces
             * and make a new interface if no the cached interface
             */
            tb_ifaddrs_interface_t      interface_new = {0};
            tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, adapter->AdapterName);
            if (!interface) interface = &interface_new;

            // check
            tb_assert(interface == &interface_new || interface->name);

            // save flags
            if (adapter->Type == MIB_IF_TYPE_LOOPBACK) interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

            // save hwaddr
            if (adapter->AddressLength == sizeof(interface->hwaddr.u8))
            {
                interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;
                tb_memcpy(interface->hwaddr.u8, adapter->Address, sizeof(interface->hwaddr.u8));
            }

            // save ipaddrs
            PIP_ADDR_STRING ipAddress = &adapter->IpAddressList;
            while (ipAddress && (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR) != TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR)
            {
                // done
                tb_ipaddr_t ipaddr;
                if (    ipAddress->IpAddress.String
                    &&  tb_ipaddr_ip_cstr_set(&ipaddr, ipAddress->IpAddress.String, TB_IPADDR_FAMILY_NONE))
                {
                    if (ipaddr.family == TB_IPADDR_FAMILY_IPV4)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
                        interface->ipaddr4 = ipaddr.u.ipv4;
                    }
                    else if (ipaddr.family == TB_IPADDR_FAMILY_IPV6)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;
                        interface->ipaddr6 = ipaddr.u.ipv6;
                    }
                }

                // the next
                ipAddress = ipAddress->Next;
            }

            // new interface? save it
            if (    interface == &interface_new
                &&  interface->flags)
            {
                // save interface name
                interface->name = tb_strdup(adapter->AdapterName);
                tb_assert(interface->name);

                // save interface
                tb_list_insert_tail(interfaces, interface);
            }

            // the next adapter
            adapter = adapter->Next;
        }

    } while (0);

    // exit the adapter info
    if (adapter_info) tb_free(adapter_info);
    adapter_info = tb_null;
}
Example #24
0
static tb_void_t tb_ifaddrs_interface_load6(tb_list_ref_t interfaces)
{
    // check
    tb_assert_and_check_return(interfaces);

    // done
    PIP_ADAPTER_ADDRESSES addresses = tb_null;
    do
    {
        // make the addresses
        addresses = (PIP_ADAPTER_ADDRESSES)tb_malloc0_type(IP_ADAPTER_ADDRESSES);
        tb_assert_and_check_break(addresses);

        // get the real adapter info size
        ULONG size = sizeof(IP_ADAPTER_ADDRESSES);
        if (tb_iphlpapi()->GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_DNS_SERVER, tb_null, addresses, &size) == ERROR_BUFFER_OVERFLOW)
        {
            // grow the adapter info buffer
            addresses = (PIP_ADAPTER_ADDRESSES)tb_ralloc(addresses, size);
            tb_assert_and_check_break(addresses);

            // reclear it
            tb_memset(addresses, 0, size);
        }
     
        // get the addresses
        if (tb_iphlpapi()->GetAdaptersAddresses(AF_INET6, GAA_FLAG_SKIP_DNS_SERVER, tb_null, addresses, &size) != NO_ERROR) break;

        // done
        PIP_ADAPTER_ADDRESSES address = addresses;
        while (address)
        {
            // check
            tb_assert(address->AdapterName);

            /* attempt to get the interface from the cached interfaces
             * and make a new interface if no the cached interface
             */
            tb_ifaddrs_interface_t      interface_new = {0};
            tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, address->AdapterName);
            if (!interface) interface = &interface_new;

            // check
            tb_assert(interface == &interface_new || interface->name);

            // save flags
            if (address->IfType == IF_TYPE_SOFTWARE_LOOPBACK) interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

            // save hwaddr
            if (address->PhysicalAddressLength == sizeof(interface->hwaddr.u8))
            {
                interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;
                tb_memcpy(interface->hwaddr.u8, address->PhysicalAddress, sizeof(interface->hwaddr.u8));
            }

            // save ipaddrs
            PIP_ADAPTER_UNICAST_ADDRESS ipAddress = address->FirstUnicastAddress;
            while (ipAddress && (interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR) != TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR)
            {
                // done
                tb_ipaddr_t ipaddr;
                struct sockaddr_storage* saddr = (struct sockaddr_storage*)ipAddress->Address.lpSockaddr;
                if (saddr && tb_sockaddr_save(&ipaddr, saddr))
                {
                    if (ipaddr.family == TB_IPADDR_FAMILY_IPV4)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
                        interface->ipaddr4 = ipaddr.u.ipv4;
                    }
                    else if (ipaddr.family == TB_IPADDR_FAMILY_IPV6)
                    {
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;
                        interface->ipaddr6 = ipaddr.u.ipv6;
                    }
                }

                // the next
                ipAddress = ipAddress->Next;
            }

            // new interface? save it
            if (    interface == &interface_new
                &&  interface->flags)
            {
                // save interface name
                interface->name = tb_strdup(address->AdapterName);
                tb_assert(interface->name);

                // save interface
                tb_list_insert_tail(interfaces, interface);
            }

            // the next address
            address = address->Next;
        }

    } while (0);

    // exit the addresses
    if (addresses) tb_free(addresses);
    addresses = tb_null;
}
Example #25
0
tb_iterator_ref_t tb_ifaddrs_itor(tb_ifaddrs_ref_t ifaddrs, tb_bool_t reload)
{
    // check
    tb_list_ref_t interfaces = (tb_list_ref_t)ifaddrs;
    tb_assert_and_check_return_val(interfaces, tb_null);

    // uses the cached interfaces?
    tb_check_return_val(reload, (tb_iterator_ref_t)interfaces); 

    // clear interfaces first
    tb_list_clear(interfaces);

    // query the list of interfaces.
    struct ifaddrs* list = tb_null;
    if (!getifaddrs(&list) && list)
    {
#if 0
        // init sock
        tb_long_t sock = socket(AF_INET, SOCK_DGRAM, 0);
#endif

        // done
        struct ifaddrs* item = tb_null;
        for (item = list; item; item = item->ifa_next)
        {
            // check
            tb_check_continue(item->ifa_addr && item->ifa_name);

            /* attempt to get the interface from the cached interfaces
             * and make a new interface if no the cached interface
             */
            tb_ifaddrs_interface_t      interface_new = {0};
            tb_ifaddrs_interface_ref_t  interface = tb_ifaddrs_interface_find((tb_iterator_ref_t)interfaces, item->ifa_name);
            if (!interface) interface = &interface_new;

            // check
            tb_assert(interface == &interface_new || interface->name);

            // done
            switch (item->ifa_addr->sa_family)
            {
            case AF_INET:
                {
                    // the address
                    struct sockaddr_storage const* addr = (struct sockaddr_storage const*)item->ifa_addr;

                    // save ipaddr4
                    tb_ipaddr_t ipaddr4;
                    if (!tb_sockaddr_save(&ipaddr4, addr)) break;
                    interface->ipaddr4 = ipaddr4.u.ipv4;

                    // save flags
                    interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR4;
                    if ((item->ifa_flags & IFF_LOOPBACK) || tb_ipaddr_ip_is_loopback(&ipaddr4)) 
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

#if 0
                    // no hwaddr? get it
                    if (!(interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR))
                    {
                        // attempt get the hwaddr
                        struct ifreq ifr;
                        tb_memset(&ifr, 0, sizeof(ifr));
                        tb_strcpy(ifr.ifr_name, item->ifa_name);
                        if (!ioctl(sock, SIOCGIFHWADDR, &ifr))
                        {
                            // have hwaddr
                            interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;

                            // save hwaddr
                            tb_memcpy(interface->hwaddr.u8, ifr.ifr_hwaddr.sa_data, sizeof(interface->hwaddr.u8));
                        }
                    }
#endif

                    // new interface? save it
                    if (interface == &interface_new)
                    {
                        // save interface name
                        interface->name = tb_strdup(item->ifa_name);
                        tb_assert(interface->name);

                        // save interface
                        tb_list_insert_tail(interfaces, interface);
                    }
                }
                break;
            case AF_INET6:
                {
                    // the address
                    struct sockaddr_storage const* addr = (struct sockaddr_storage const*)item->ifa_addr;

                    // save ipaddr6
                    tb_ipaddr_t ipaddr6;
                    if (!tb_sockaddr_save(&ipaddr6, addr)) break;
                    interface->ipaddr6 = ipaddr6.u.ipv6;

                    // save flags
                    interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_IPADDR6;
                    if ((item->ifa_flags & IFF_LOOPBACK) || tb_ipaddr_ip_is_loopback(&ipaddr6))
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_IS_LOOPBACK;

#if 0
                    // no hwaddr? get it
                    if (!(interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR))
                    {
                        // attempt get the hwaddr
                        struct ifreq ifr;
                        tb_memset(&ifr, 0, sizeof(ifr));
                        tb_strcpy(ifr.ifr_name, item->ifa_name);
                        if (!ioctl(sock, SIOCGIFHWADDR, &ifr))
                        {
                            // have hwaddr
                            interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;

                            // save hwaddr
                            tb_memcpy(interface->hwaddr.u8, ifr.ifr_hwaddr.sa_data, sizeof(interface->hwaddr.u8));
                        }
                    }
#endif

                    // new interface? save it
                    if (interface == &interface_new)
                    {
                        // save interface name
                        interface->name = tb_strdup(item->ifa_name);
                        tb_assert(interface->name);

                        // save interface
                        tb_list_insert_tail(interfaces, interface);
                    }
                }
                break;
            case AF_PACKET:
                {
                    // the address
                    struct sockaddr_ll const* addr = (struct sockaddr_ll const*)item->ifa_addr;

                    // check
                    tb_check_break(addr->sll_halen == sizeof(interface->hwaddr.u8));

                    // no hwaddr? get it
                    if (!(interface->flags & TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR))
                    {
                        // have hwaddr
                        interface->flags |= TB_IFADDRS_INTERFACE_FLAG_HAVE_HWADDR;

                        // save hwaddr
                        tb_memcpy(interface->hwaddr.u8, addr->sll_addr, sizeof(interface->hwaddr.u8));

                        // new interface? save it
                        if (interface == &interface_new)
                        {
                            // save interface name
                            interface->name = tb_strdup(item->ifa_name);
                            tb_assert(interface->name);

                            // save interface
                            tb_list_insert_tail(interfaces, interface);
                        }
                    }
                }
                break;
            default:
                {
                    // trace
                    tb_trace_d("unknown family: %d", item->ifa_addr->sa_family);
                }
                break;
            }
        }

#if 0
        // exit socket
        if (sock) close(sock);
        sock = 0;
#endif

        // exit the interface list
        freeifaddrs(list);
    }

    // ok?
    return (tb_iterator_ref_t)interfaces;
}
Example #26
0
File: path.c Project: richwu/tbox
/* //////////////////////////////////////////////////////////////////////////////////////
 * implementation
 */
tb_size_t tb_path_translate(tb_char_t* path, tb_size_t size, tb_size_t maxn)
{
    // check
    tb_assert_and_check_return_val(path, 0);

    // file://?
    tb_char_t* p = path;
    if (!tb_strnicmp(p, "file:", 5)) p += 5;
    // is user directory?
    else if (path[0] == '~')
    {
        // get the home directory
        tb_char_t home[TB_PATH_MAXN];
        tb_size_t home_size = tb_directory_home(home, sizeof(home) - 1);
        tb_assert_and_check_return_val(home_size, 0);

        // check the path space
        tb_size_t path_size = size? size : tb_strlen(path);
        tb_assert_and_check_return_val(home_size + path_size - 1 < maxn, 0);

        // move the path and ensure the enough space for the home directory
        tb_memmov(path + home_size, path + 1, path_size - 1);

        // copy the home directory 
        tb_memcpy(path, home, home_size);
        path[home_size + path_size - 1] = '\0';
    }

    // remove repeat separator
    tb_char_t*  q = path;
    tb_size_t   repeat = 0;
    for (; *p; p++)
    {
        if (tb_path_is_separator(*p))
        {
            // save the separator if not exists
            if (!repeat) *q++ = TB_PATH_SEPARATOR;

            // repeat it
            repeat++;
        }
        else 
        {
            // save character
            *q++ = *p;

            // clear repeat
            repeat = 0;
        }
    }

    // remove the tail separator and not root: '/'
    if (q > path + 1 && *(q - 1) == TB_PATH_SEPARATOR) q--;

    // end
    *q = '\0';

    // is windows path? 
    if (q > path + 1 && tb_isalpha(path[0]) && path[1] == ':')
    {
        // get the upper drive prefix
        path[0] = tb_toupper(path[0]);

        // append the drive separator if not exists
        if (q - path == 2)
        {
            *q++ = TB_PATH_SEPARATOR;
            *q = '\0';
        }
    }

    // trace
    tb_trace_d("translate: %s", path);

    // ok
    return q - path;
}
Example #27
0
/*! put impl
 *
 * <pre>
 * init:
 * 
 *                                          1(head)
 *                               -------------------------
 *                              |                         |
 *                              4                         2
 *                        --------------             -------------
 *                       |              |           |             |
 *                       6(parent)      9           7             8
 *                   ---------       
 *                  |         |     
 *                  10(last) (hole) <= 5(val)
 * after:
 *
 *                                          1(head)
 *                               -------------------------
 *                              |                         |
 *                              4                         2
 *                        --------------             -------------
 *                       |              |           |             |
 *                       5(hole)      9           7             8
 *                   ---------       
 *                  |         |     
 *                  10(last)  6(last)
 * </pre>
 */
tb_void_t tb_heap_put(tb_heap_ref_t heap, tb_cpointer_t data)
{
    // check
    tb_heap_impl_t* impl = (tb_heap_impl_t*)heap;
    tb_assert_and_check_return(impl && impl->data);

    // full? grow it
    if (impl->size == impl->maxn)
    {
        // the maxn
        tb_size_t maxn = tb_align4(impl->maxn + impl->grow);
        tb_assert_and_check_return(maxn < TB_HEAD_MAXN);

        // realloc data
        impl->data = (tb_byte_t*)tb_ralloc(impl->data, maxn * impl->func.size);
        tb_assert_and_check_return(impl->data);

        // must be align by 4-bytes
        tb_assert_and_check_return(!(((tb_size_t)(impl->data)) & 3));

        // clear the grow data
        tb_memset(impl->data + impl->size * impl->func.size, 0, (maxn - impl->maxn) * impl->func.size);

        // save maxn
        impl->maxn = maxn;
    }

    // check
    tb_assert_and_check_return(impl->size < impl->maxn);
    
    // init func
    tb_item_func_comp_t func_comp = impl->func.comp;
    tb_item_func_data_t func_data = impl->func.data;
    tb_assert_and_check_return(func_comp && func_data);

    // walk, (hole - 1) / 2: the parent node of the hole
    tb_size_t           parent = 0;
    tb_byte_t*          head = impl->data;
    tb_size_t           hole = impl->size;
    tb_size_t           step = impl->func.size;
    switch (step)
    {
#ifndef __tb_small__
    case sizeof(tb_uint64_t):
        {
            for (parent = (hole - 1) >> 1; hole && (func_comp(&impl->func, func_data(&impl->func, head + parent * step), data) > 0); parent = (hole - 1) >> 1)
            {
                // move item: parent => hole
                *((tb_uint64_t*)(head + hole * step)) = *((tb_uint64_t*)(head + parent * step));

                // move node: hole => parent
                hole = parent;
            }
        }
        break;
    case sizeof(tb_uint32_t):
        {
            for (parent = (hole - 1) >> 1; hole && (func_comp(&impl->func, func_data(&impl->func, head + parent * step), data) > 0); parent = (hole - 1) >> 1)
            {
                // move item: parent => hole
                *((tb_uint32_t*)(head + hole * step)) = *((tb_uint32_t*)(head + parent * step));

                // move node: hole => parent
                hole = parent;
            }
        }
        break;
    case sizeof(tb_uint16_t):
        {
            for (parent = (hole - 1) >> 1; hole && (func_comp(&impl->func, func_data(&impl->func, head + parent * step), data) > 0); parent = (hole - 1) >> 1)
            {
                // move item: parent => hole
                *((tb_uint16_t*)(head + hole * step)) = *((tb_uint16_t*)(head + parent * step));

                // move node: hole => parent
                hole = parent;
            }
        }
        break;
    case sizeof(tb_uint8_t):
        {
            for (parent = (hole - 1) >> 1; hole && (func_comp(&impl->func, func_data(&impl->func, head + parent * step), data) > 0); parent = (hole - 1) >> 1)
            {
                // move item: parent => hole
                *((tb_uint8_t*)(head + hole * step)) = *((tb_uint8_t*)(head + parent * step));

                // move node: hole => parent
                hole = parent;
            }
        }
        break;
#endif
    default:
        for (parent = (hole - 1) >> 1; hole && (func_comp(&impl->func, func_data(&impl->func, head + parent * step), data) > 0); parent = (hole - 1) >> 1)
        {
            // move item: parent => hole
            tb_memcpy(head + hole * step, head + parent * step, step);

            // move node: hole => parent
            hole = parent;
        }
        break;
    }

    // save data
    impl->func.dupl(&impl->func, head + hole * step, data);

    // size++
    impl->size++;

    // check
//  tb_heap_check(impl);
}
Example #28
0
/*! remove the impl item
 *
 * <pre>
 * init:
 *                                          1(head)
 *                               -------------------------
 *                              |                         |
 *                           (hole)                       2
 *                        --------------             -------------
 *                       |              |           |             |
 *                       6(smaler)      9           7             8
 *                   ---------       ----                                            (hole) <-
 *                  |         |     |                                                         |
 *                 10        16    8 (last)---------------------------------------------> 8 (val)
 *
 *
 * after:
 *                                          1(head)
 *                               -------------------------
 *                              |                         |
 *                              6                         2
 *                        --------------             -------------
 *                       |              |           |             |
 *                     (hole)           9           7             8
 *                   ---------                                                              <-
 *                  |         |                                                               |
 *                 10(smaller)16                                                          8 (val)
 *
 *
 * after:
 *                                          1(head)
 *                               -------------------------
 *                              |                         |
 *                              6                         2
 *                        --------------             -------------
 *                       |              |           |             |
 *                       8              9           7             8
 *                   ---------                                                              
 *                  |         |                                                               
 *                 10        16 
 * 
 * </pre>
 */
static tb_void_t tb_heap_itor_remove(tb_iterator_ref_t iterator, tb_size_t itor)
{
    // check
    tb_heap_impl_t* impl = (tb_heap_impl_t*)iterator;
    tb_assert_and_check_return(impl && impl->data && impl->size && itor < impl->size);

    // init func
    tb_item_func_comp_t func_comp = impl->func.comp;
    tb_item_func_data_t func_data = impl->func.data;
    tb_assert_and_check_return(func_comp && func_data);

    // walk, 2 * hole + 1: the left child node of hole
    tb_size_t           step = impl->func.size;
    tb_byte_t*          head = impl->data;
    tb_byte_t*          hole = head + itor * step;
    tb_byte_t*          tail = head + impl->size * step;
    tb_byte_t*          last = head + (impl->size - 1) * step;
    tb_byte_t*          child = head + ((itor << 1) + 1) * step;
    tb_pointer_t        data_child = tb_null;
    tb_pointer_t        data_rchild = tb_null;
    tb_pointer_t        data_last = func_data(&impl->func, last);
    switch (step)
    {
#ifndef __tb_small__
    case sizeof(tb_uint64_t):
        {
            for (; child < tail; child = head + (((child - head) << 1) + step))
            {   
                // the smaller child node
                data_child = func_data(&impl->func, child);
                if (child + step < tail && func_comp(&impl->func, data_child, (data_rchild = func_data(&impl->func, child + step))) > 0) 
                {
                    child += step;
                    data_child = data_rchild;
                }

                // end?
                if (func_comp(&impl->func, data_child, data_last) > 0) break;

                // the smaller child node => hole
                *((tb_uint64_t*)hole) = *((tb_uint64_t*)child);

                // move the hole down to it's larger child node 
                hole = child;
            }
        }
        break;
    case sizeof(tb_uint32_t):
        {
            for (; child < tail; child = head + (((child - head) << 1) + step))
            {   
                // the smaller child node
                data_child = func_data(&impl->func, child);
                if (child + step < tail && func_comp(&impl->func, data_child, (data_rchild = func_data(&impl->func, child + step))) > 0) 
                {
                    child += step;
                    data_child = data_rchild;
                }

                // end?
                if (func_comp(&impl->func, data_child, data_last) > 0) break;

                // the smaller child node => hole
                *((tb_uint32_t*)hole) = *((tb_uint32_t*)child);

                // move the hole down to it's larger child node 
                hole = child;
            }
        }
        break;
    case sizeof(tb_uint16_t):
        {
            for (; child < tail; child = head + (((child - head) << 1) + step))
            {   
                // the smaller child node
                data_child = func_data(&impl->func, child);
                if (child + step < tail && func_comp(&impl->func, data_child, (data_rchild = func_data(&impl->func, child + step))) > 0) 
                {
                    child += step;
                    data_child = data_rchild;
                }

                // end?
                if (func_comp(&impl->func, data_child, data_last) > 0) break;

                // the smaller child node => hole
                *((tb_uint16_t*)hole) = *((tb_uint16_t*)child);

                // move the hole down to it's larger child node 
                hole = child;
            }
        }
        break;
    case sizeof(tb_uint8_t):
        {
            for (; child < tail; child = head + (((child - head) << 1) + step))
            {   
                // the smaller child node
                data_child = func_data(&impl->func, child);
                if (child + step < tail && func_comp(&impl->func, data_child, (data_rchild = func_data(&impl->func, child + step))) > 0) 
                {
                    child += step;
                    data_child = data_rchild;
                }

                // end?
                if (func_comp(&impl->func, data_child, data_last) > 0) break;

                // the smaller child node => hole
                *((tb_uint8_t*)hole) = *((tb_uint8_t*)child);

                // move the hole down to it's larger child node 
                hole = child;
            }

        }
        break;
#endif
    default:
        {
            for (; child < tail; child = head + (((child - head) << 1) + step))
            {   
                // the smaller child node
                data_child = func_data(&impl->func, child);
                if (child + step < tail && func_comp(&impl->func, data_child, (data_rchild = func_data(&impl->func, child + step))) > 0) 
                {
                    child += step;
                    data_child = data_rchild;
                }

                // end?
                if (func_comp(&impl->func, data_child, data_last) > 0) break;

                // the smaller child node => hole
                tb_memcpy(hole, child, step);

                // move the hole down to it's larger child node 
                hole = child;
            }
        }
        break;
    }

    // the last node => hole
    if (hole != last) tb_memcpy(hole, last, step);

    // size--
    impl->size--;

    // check
//  tb_heap_check(impl);
}
Example #29
0
static tb_long_t tb_aiop_rtor_select_wait(tb_aiop_rtor_impl_t* rtor, tb_aioe_ref_t list, tb_size_t maxn, tb_long_t timeout)
{   
    // check
    tb_aiop_rtor_select_impl_t* impl = (tb_aiop_rtor_select_impl_t*)rtor;
    tb_assert_and_check_return_val(impl && rtor->aiop && list && maxn, -1);

    // the aiop
    tb_aiop_impl_t* aiop = rtor->aiop;
    tb_assert_and_check_return_val(aiop, tb_false);

    // init time
    struct timeval t = {0};
    if (timeout > 0)
    {
#ifdef TB_CONFIG_OS_WINDOWS
        t.tv_sec = (LONG)(timeout / 1000);
#else
        t.tv_sec = (timeout / 1000);
#endif
        t.tv_usec = (timeout % 1000) * 1000;
    }

    // loop
    tb_long_t wait = 0;
    tb_bool_t stop = tb_false;
    tb_hong_t time = tb_mclock();
    while (!wait && !stop && (timeout < 0 || tb_mclock() < time + timeout))
    {
        // enter
        tb_spinlock_enter(&impl->lock.pfds);

        // init fdo
        tb_size_t sfdm = impl->sfdm;
        tb_memcpy(&impl->rfdo, &impl->rfdi, sizeof(fd_set));
        tb_memcpy(&impl->wfdo, &impl->wfdi, sizeof(fd_set));

        // leave
        tb_spinlock_leave(&impl->lock.pfds);

        // wait
#ifdef TB_CONFIG_OS_WINDOWS
        tb_long_t sfdn = tb_ws2_32()->select((tb_int_t)sfdm + 1, &impl->rfdo, &impl->wfdo, tb_null, timeout >= 0? &t : tb_null);
#else
        tb_long_t sfdn = select(sfdm + 1, &impl->rfdo, &impl->wfdo, tb_null, timeout >= 0? &t : tb_null);
#endif
        tb_assert_and_check_return_val(sfdn >= 0, -1);

        // timeout?
        tb_check_return_val(sfdn, 0);
        
        // enter
        tb_spinlock_enter(&impl->lock.hash);

        // sync
        tb_size_t itor = tb_iterator_head(impl->hash);
        tb_size_t tail = tb_iterator_tail(impl->hash);
        for (; itor != tail && wait >= 0 && (tb_size_t)wait < maxn; itor = tb_iterator_next(impl->hash, itor))
        {
            tb_hash_map_item_ref_t item = (tb_hash_map_item_ref_t)tb_iterator_item(impl->hash, itor);
            if (item)
            {
                // the sock
                tb_socket_ref_t sock = (tb_socket_ref_t)item->name;
                tb_assert_and_check_return_val(sock, -1);

                // spak?
                if (sock == aiop->spak[1] && FD_ISSET(((tb_long_t)aiop->spak[1] - 1), &impl->rfdo))
                {
                    // read spak
                    tb_char_t spak = '\0';
                    if (1 != tb_socket_recv(aiop->spak[1], (tb_byte_t*)&spak, 1)) wait = -1;

                    // killed?
                    if (spak == 'k') wait = -1;
                    tb_check_break(wait >= 0);

                    // stop to wait
                    stop = tb_true;

                    // continue it
                    continue ;
                }

                // filter spak
                tb_check_continue(sock != aiop->spak[1]);

                // the fd
                tb_long_t fd = (tb_long_t)item->name - 1;

                // the aioo
                tb_aioo_impl_t* aioo = (tb_aioo_impl_t*)item->data;
                tb_assert_and_check_return_val(aioo && aioo->sock == sock, -1);

                // init aioe
                tb_aioe_t aioe = {0};
                aioe.priv   = aioo->priv;
                aioe.aioo   = (tb_aioo_ref_t)aioo;
                if (FD_ISSET(fd, &impl->rfdo)) 
                {
                    aioe.code |= TB_AIOE_CODE_RECV;
                    if (aioo->code & TB_AIOE_CODE_ACPT) aioe.code |= TB_AIOE_CODE_ACPT;
                }
                if (FD_ISSET(fd, &impl->wfdo)) 
                {
                    aioe.code |= TB_AIOE_CODE_SEND;
                    if (aioo->code & TB_AIOE_CODE_CONN) aioe.code |= TB_AIOE_CODE_CONN;
                }
                    
                // ok?
                if (aioe.code) 
                {
                    // save aioe
                    list[wait++] = aioe;

                    // oneshot? clear it
                    if (aioo->code & TB_AIOE_CODE_ONESHOT)
                    {
                        // clear aioo
                        aioo->code = TB_AIOE_CODE_NONE;
                        aioo->priv = tb_null;

                        // clear events
                        tb_spinlock_enter(&impl->lock.pfds);
                        FD_CLR(fd, &impl->rfdi);
                        FD_CLR(fd, &impl->wfdi);
                        tb_spinlock_leave(&impl->lock.pfds);
                    }
                }
            }
        }

        // leave
        tb_spinlock_leave(&impl->lock.hash);
    }

    // ok
    return wait;
}
Example #30
0
tb_byte_t* tb_buffer_resize(tb_buffer_t* buffer, tb_size_t size)
{
    // check
    tb_assert_and_check_return_val(buffer && size, tb_null);

    // done
    tb_bool_t   ok = tb_false;
    tb_byte_t*  buff_data = buffer->data;
    tb_size_t   buff_size = buffer->size;
    tb_size_t   buff_maxn = buffer->maxn;
    do
    {
        // check
        tb_assert_and_check_break(buff_data);

        // using static buffer?
        if (buff_data == buffer->buff)
        {
            // grow?
            if (size > buff_maxn)
            {
                // grow maxn
                buff_maxn = tb_align8(size + TB_BUFFER_GROW_SIZE);
                tb_assert_and_check_break(size <= buff_maxn);

                // grow data
                buff_data = tb_malloc_bytes(buff_maxn);
                tb_assert_and_check_break(buff_data);

                // copy data
                tb_memcpy(buff_data, buffer->buff, buff_size);
            }

            // update the size
            buff_size = size;
        }
        else
        {
            // grow?
            if (size > buff_maxn)
            {
                // grow maxn
                buff_maxn = tb_align8(size + TB_BUFFER_GROW_SIZE);
                tb_assert_and_check_break(size <= buff_maxn);

                // grow data
                buff_data = (tb_byte_t*)tb_ralloc(buff_data, buff_maxn);
                tb_assert_and_check_break(buff_data);
            }
#if 0
            // decrease to the static buffer
            else if (size <= sizeof(buffer->buff))
            {
                // update the maxn
                buff_maxn = sizeof(buffer->buff);

                // copy data
                tb_memcpy(buffer->buff, buff_data, size);

                // free data
                tb_free(buff_data);

                // using the static buffer
                buff_data = buffer->buff;
            }
#endif

            // update the size
            buff_size = size;
        }

        // update the buffer
        buffer->data = buff_data;
        buffer->size = buff_size;
        buffer->maxn = buff_maxn;

        // ok 
        ok = tb_true;

    } while (0);

    // trace
    if (!ok) tb_trace_e("resize buffer failed: %lu => %lu", buff_size, size);

    // ok
    return ok? (tb_byte_t*)buffer->data : tb_null;
}