⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 benc_util.c.svn-base

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
            break;    }    // error happened    benc_obj_delete((benc_obj*) bobj_arr);    return NULL;FoundArrayEnd:    *dataInOut = data;    *lenInOut = len;    return bobj_arr;}static benc_dict *_parse_dict(const char** dataInOut, size_t* lenInOut){    char            c;    const char *    data = *dataInOut;    size_t          len = *lenInOut;    const char *    key;    size_t          keyLen;    benc_obj *      val = NULL;    benc_dict * dict = benc_dict_new();    if (!dict)        return NULL;    while (len > 0) {        c = *data;        if ('e' == c) {            ++data;            --len;            goto FoundDictEnd;        }        keyLen = _parse_str_help(&data, &len);        if (IVALID_LEN == keyLen)            break;        key = data;        data += keyLen;        len -= keyLen;        assert(len > 0);        val = _benc_obj_from_data(&data, &len, FALSE);        if (!val)            break;        if (!benc_dict_insert(dict, key, keyLen, val))            break;    }    // error happened    if (val)        benc_obj_delete(val);    benc_obj_delete((benc_obj*) dict);    return NULL;FoundDictEnd:    *dataInOut = data;    *lenInOut = len;    return dict;}static benc_obj *_benc_obj_from_data(const char** dataInOut, size_t* lenInOut, BOOL must_be_last){    char            c;    BOOL            ok;    int64_t         int64val;    benc_obj *      bobj;    const char *    data = *dataInOut;    size_t          len = *lenInOut;    /*assert(data);*/    /*assert(len > 0);*/    if (!data || (len <= 0)) return NULL;    while (len >= 0) {        c = *data++;        --len;        if ('i' == c) {            ok = _parse_int64(&data, &len, &int64val);            if (!ok)                return NULL;            bobj = (benc_obj*) benc_int64_new(int64val);            break;        } else if ('d' == c) {            bobj = (benc_obj*) _parse_dict(&data, &len);            break;        } else if ('l' == c) {            bobj = (benc_obj*) _parse_array(&data, &len);            break;        } else {            /* must be string */            --data;            ++len;            bobj = (benc_obj*)_parse_str(&data, &len);            break;        }    }    if (bobj && must_be_last && (len > 0)) {        benc_obj_delete(bobj);        return NULL;    }    *dataInOut = data;    *lenInOut = len;    return bobj;}benc_obj *benc_obj_from_data(const char *data, size_t len){    return _benc_obj_from_data(&data, &len, TRUE);}static size_t _len_for_int64(benc_int64* bobj){    /* 2 is for "i" and "e" */    return 2 + digits_for_number(bobj->m_val);}static size_t _len_for_txt(const char* txt){    size_t txt_len = strlen(txt);    return 1 + txt_len + digits_for_number(txt_len);}static size_t _len_for_str(benc_str* bobj){    /* 1 is for ":" */    return 1 + bobj->m_len + digits_for_number(bobj->m_len);}static size_t _len_for_array(benc_array* bobj){    size_t len = 2;    benc_array_data *data = &(bobj->m_data);    assert(BOT_ARRAY == bobj->m_type);    while (data) {        size_t i;        benc_array_data *next = data->m_next;        for (i=0; i < data->m_used; i++) {            len += _benc_obj_to_data(data->m_data[i], PHASE_CALC_LEN, NULL);        }        data = next;    }    return len;}static size_t _len_for_dict(benc_dict* bobj){    size_t len = 2;    benc_dict_data *data = &(bobj->m_data);    assert(BOT_DICT == bobj->m_type);    while (data) {        size_t i;        benc_dict_data *next = data->m_next;        for (i=0; i < data->m_used; i++) {            len += _len_for_txt(data->m_keys[i]);            len += _benc_obj_to_data(data->m_values[i], PHASE_CALC_LEN, NULL);        }        data = next;    }    return len;}static void _str_reverse(char *start, char *end){    while (start < end) {        char tmp = *start;        *start++ = *end;        *end-- = tmp;    }}/* Convert 'val' to string in a buffer 'data' of size 'dataLen'. NULL-terminates   the string.   Returns FALSE if not enough space in the buffer.   TODO: should return the size of needed buffer.   TODO: for simplicity of code, if buffer is not big enough, will not use         the last byte of the buffer   TODO: move it to some other place like str_util.[h|c]?*/BOOL int64_to_string(int64_t val, char* data, size_t dataLen){    char *  numStart;    size_t  dataLenRest = dataLen;    if (val < 0) {        if (dataLenRest < 2) {            *data = 0;            return FALSE;        }        *data++ = '-';                    --dataLenRest;        val = -val;    }    numStart = data;    while (val > 9) {        int digit = (int)(val % 10);        if (dataLenRest < 2) {            *data = 0;            return FALSE;        }        *data++ = (char)(digit + '0');        --dataLenRest;        val = val / 10;    }    if (dataLenRest < 2) {        *data = 0;        return FALSE;    }    data[0] = (char)(val + '0');    data[1] = 0;    _str_reverse(numStart, data);    return TRUE;}BOOL int64_to_string_zero_pad(int64_t val, size_t pad, char* data, size_t dataLen){    size_t len;    assert(dataLen >= pad + 1);    if (dataLen < pad + 1)        return FALSE;    if (!int64_to_string(val, data, dataLen))        return FALSE;    len = strlen(data);    if (len < pad) {        size_t toPad = pad - len;        size_t toMove = len + 1;        memmove(data + toPad, data, toMove);        while (toPad != 0) {            data[toPad-1] = '0';            --toPad;        }    }    return TRUE;}static size_t _serialize_int64_num(int64_t val, char* data){    char *  numStart;    size_t  len;    char *  start = data;    if (val < 0) {        *data++ = '-';        val = -val;    }    numStart = data;    while (val > 9) {        int digit = (int)(val % 10);        *data++ = (char)(digit + '0');        val = val / 10;    }    *data = (char)(val + '0');    _str_reverse(numStart, data);    len = data + 1 - start;    return len;}static size_t _serialize_int64(benc_int64* bobj, char* data){    size_t len;    *data++ = 'i';    len = _serialize_int64_num(bobj->m_val, data);    data += len;    *data++ = 'e';    len += 2;    assert(len == _len_for_int64(bobj));    return len;}static size_t _serialize_str_help(char *str, size_t strLen, char* data){    size_t len = _serialize_int64_num(strLen, data);    data += len;    *data++ = ':';    memcpy(data, str, strLen);    return len + 1 + strLen;}static size_t _serialize_str(benc_str* bobj, char* data){    size_t len = _serialize_str_help(bobj->m_str, bobj->m_len, data);    assert(len == _len_for_str(bobj));    return len;}static size_t _serialize_array(benc_array* arr, char* data){    int i;    size_t len;    int arr_len = benc_array_len(arr);    char *start = data;    *data++ = 'l';    for (i = 0; i < arr_len; i++) {        benc_obj *bobj = benc_array_get(arr, i);        size_t len_tmp = _benc_obj_to_data(bobj, PHASE_FORM_DATA, data);        data += len_tmp;    }    *data++ = 'e';    len = data - start;    assert(len == _len_for_array(arr));    return len;}static size_t _serialize_dict(benc_dict* dict, char* data){    benc_dict_data * curr;    size_t len = 2; /* for 'd' and 'e' */    size_t i, lenTmp, used;    *data++ = 'd';    curr = &(dict->m_data);    assert(!curr->m_next); /* not using segments yet */    while (curr) {        used = curr->m_used;        for (i = 0; i < used; i++) {            char *key = curr->m_keys[i];            benc_obj *val = curr->m_values[i];            lenTmp = _serialize_str_help(key, strlen(key), data);            data += lenTmp;            len += lenTmp;            lenTmp = _benc_obj_to_data(val, PHASE_FORM_DATA, data);            data += lenTmp;            len += lenTmp;        }        curr = curr->m_next;    }    *data++ = 'e';    assert(len == _len_for_dict(dict));    return len;}static size_t _benc_obj_to_data(benc_obj* bobj, phase_t phase, char* data){    size_t len;    assert((PHASE_CALC_LEN == phase) || (PHASE_FORM_DATA == phase));    assert((PHASE_CALC_LEN == phase) || data);    if (BOT_INT64 == bobj->m_type) {        if (PHASE_CALC_LEN == phase)            len = _len_for_int64((benc_int64*)bobj);        else            len = _serialize_int64((benc_int64*)bobj, data);    } else if (BOT_STRING == bobj->m_type) {        if (PHASE_CALC_LEN == phase)            len = _len_for_str((benc_str*)bobj);        else            len = _serialize_str((benc_str*)bobj, data);    } else if (BOT_ARRAY == bobj->m_type) {        if (PHASE_CALC_LEN == phase)            len = _len_for_array((benc_array*)bobj);        else            len = _serialize_array((benc_array*)bobj, data);            } else if (BOT_DICT == bobj->m_type) {        if (PHASE_CALC_LEN == phase)            len = _len_for_dict((benc_dict*)bobj);        else            len = _serialize_dict((benc_dict*)bobj, data);        } else {        assert(0);        len = 0;    }    return len;}char * benc_obj_to_data(benc_obj *bobj, size_t* lenOut){    size_t len;    char *data;    assert(bobj);    if (!bobj)        return NULL;    len = _benc_obj_to_data(bobj, PHASE_CALC_LEN, NULL);    assert(len > 0);    data = (char*)malloc(len+1);    if (!data)        return NULL;    data[len] = 0; /* NULL-terminate to make life easier */    _benc_obj_to_data(bobj, PHASE_FORM_DATA, data);    *lenOut = len;    return data;}size_t benc_array_len(benc_array *bobj){    benc_array_data *data = (benc_array_data*) &(bobj->m_data);    size_t len = data->m_used;    while (data->m_next) {        data = data->m_next;        len += data->m_used;    }    return len;        }benc_obj *benc_array_get(benc_array *bobj, size_t idx){    benc_array_data *data = (benc_array_data*) &(bobj->m_data);    while (data) {        if (idx < data->m_used) {            return data->m_data[idx];        }        idx -= data->m_used;        data = data->m_next;    }    assert(0);  /* asked for an non-existing item */    return NULL;}benc_int64* benc_obj_as_int64(benc_obj *bobj){    if (!bobj)        return NULL;    if (BOT_INT64 == bobj->m_type)        return (benc_int64 *)bobj;    return NULL;}benc_str* benc_obj_as_str(benc_obj *bobj){    if (!bobj)        return NULL;    if (BOT_STRING == bobj->m_type)        return (benc_str *)bobj;    return NULL;}benc_dict* benc_obj_as_dict(benc_obj *bobj){    if (!bobj)        return NULL;    if (BOT_DICT == bobj->m_type)        return (benc_dict *)bobj;    return NULL;}benc_array* benc_obj_as_array(benc_obj *bobj){    if (!bobj)        return NULL;    if (BOT_ARRAY == bobj->m_type)        return (benc_array *)bobj;    return NULL;}size_t benc_dict_len(benc_dict *bobj){    /* A hack, but works because benc_array and benc_dict share enough of       common data layout */    return benc_array_len((benc_array*)bobj);}size_t benc_obj_len(benc_obj* bobj){    if (BOT_ARRAY == bobj->m_type)        return benc_array_len((benc_array*)bobj);    else if (BOT_DICT == bobj->m_type)        return benc_dict_len((benc_dict*)bobj);    else        return -1;}void benc_array_delete(benc_array *bobj){    benc_array_data *data = &(bobj->m_data);    assert(BOT_ARRAY == bobj->m_type);    while (data) {        size_t i;        benc_array_data *next = data->m_next;        for (i=0; i < data->m_used; i++) {            benc_obj_delete(data->m_data[i]);        }        free(data->m_data);        if (data != &(bobj->m_data)) {            /* first m_data is within benc_array, but all others are heap allocated */            free(data);        }        data = next;    }}static void benc_dict_delete(benc_dict *bobj){    benc_dict_data *data = &(bobj->m_data);    assert(BOT_DICT == bobj->m_type);    while (data) {        size_t i;        benc_dict_data *next = data->m_next;        for (i=0; i < data->m_used; i++) {            free(data->m_keys[i]);            benc_obj_delete(data->m_values[i]);        }        free(data->m_values);        free(data->m_keys);        data = next;    }}/* Release all memory used by bencoded object */void benc_obj_delete(benc_obj *bobj){    if (BOT_INT64 == bobj->m_type) {        /* do nothing */    } else if (BOT_STRING == bobj->m_type) {        benc_str *bobj_str = (benc_str*)bobj;        free(bobj_str->m_str);    } else if (BOT_ARRAY == bobj->m_type) {        benc_array_delete((benc_array*)bobj);    } else if (BOT_DICT == bobj->m_type) {        benc_dict_delete((benc_dict*)bobj);    } else {        assert(0);    }    free(bobj);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -