Esempio n. 1
0
/* Append the specified binary-safe string pointed by 't' of 'len' bytes to the
 * end of the specified sds string 's'.
 *
 * After the call, the passed sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call. */
sds sds_cat_len(sds s, const void *t, size_t len) {
    struct sdshdr *sh;
    size_t curlen = sds_len(s);

    s = sds_make_room_for(s,len);
    if (s == NULL) return NULL;
    sh = (void*) (s-(sizeof(struct sdshdr)));
    memcpy(s+curlen, t, len);
    sh->len = curlen+len;
    sh->free = sh->free-len;
    s[curlen+len] = '\0';
    return s;
}
Esempio n. 2
0
dictEntry* dict_find(dict *d, void *key)
{
    unsigned idx, h;
    dictEntry *he;

    h = dict_genhashfunction((sds)key,sds_len((sds)key));
    idx = h & d->ht.sizemask;

    he = d->ht.table[idx];
    DD("key = %s he->key = %s", key, he->key);
    while(he)
    {
       if(dict_comparekeys(d, key, he->key) == 0)
            return he;
        he = he->next;
    }

    return NULL;
}
Esempio n. 3
0
/* Enlarge the free space at the end of the sds string so that the caller
 * is sure that after calling this function can overwrite up to addlen
 * bytes after the end of the string, plus one more byte for nul term.
 *
 * Note: this does not change the *length* of the sds string as returned
 * by sds_len(), but only the free buffer space we have. */
sds sds_make_room_for(sds s, size_t addlen) {
    struct sdshdr *sh, *newsh;
    size_t free = sds_avail(s);
    size_t len, newlen;

    if (free >= addlen) return s;
    len = sds_len(s);
    sh = (void*) (s-(sizeof(struct sdshdr)));
    newlen = (len + addlen);
    if (newlen < SDS_MAX_PREALLOC)
        newlen *= 2;
    else
        newlen += SDS_MAX_PREALLOC;
    newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
    if (newsh == NULL) return NULL;

    newsh->free = newlen - len;
    return newsh->buf;
}
Esempio n. 4
0
static int _dict_keyindex(dict *d, const void *key)
{
    unsigned idx, h;
    dictEntry *he;

    if(_dict_expand_ifneed(d) == DICT_ERR)
        return -1;

    h = dict_genhashfunction((sds)key,sds_len((sds)key));
    idx = h & d->ht.sizemask;

    he = d->ht.table[idx];
    while(he)
    {
        /*if the key already exists , -1 is returned*/
        if(dict_comparekeys(d, key, he->key) == 0)
            return KEY_EXISTS;
        he = he->next;
    }

    return idx;
}
Esempio n. 5
0
/* This function is similar to sds_cat_printf, but much faster as it does
 * not rely on sprintf() family functions implemented by the libc that
 * are often very slow. Moreover directly handling the sds string as
 * new data is concatenated provides a performance improvement.
 *
 * However this function only handles an incompatible subset of printf-alike
 * format specifiers:
 *
 * %s - C String
 * %S - SDS string
 * %i - signed int
 * %I - 64 bit signed integer (long long, int64_t)
 * %u - unsigned int
 * %U - 64 bit unsigned integer (unsigned long long, uint64_t)
 * %% - Verbatim "%" character.
 */
sds sds_cat_fmt(sds s, char const *fmt, ...) {
    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
    size_t initlen = sds_len(s);
    const char *f = fmt;
    int i;
    va_list ap;

    va_start(ap,fmt);
    f = fmt;    /* Next format specifier byte to process. */
    i = initlen; /* Position of the next byte to write to dest str. */
    while(*f) {
        char next, *str;
        unsigned int l;
        long long num;
        unsigned long long unum;

        /* Make sure there is always space for at least 1 char. */
        if (sh->free == 0) {
            s = sds_make_room_for(s,1);
            sh = (void*) (s-(sizeof(struct sdshdr)));
        }

        switch(*f) {
        case '%':
            next = *(f+1);
            f++;
            switch(next) {
            case 's':
            case 'S':
                str = va_arg(ap,char*);
                l = (next == 's') ? strlen(str) : sds_len(str);
                if (sh->free < l) {
                    s = sds_make_room_for(s,l);
                    sh = (void*) (s-(sizeof(struct sdshdr)));
                }
                memcpy(s+i,str,l);
                sh->len += l;
                sh->free -= l;
                i += l;
                break;
            case 'i':
            case 'I':
                if (next == 'i')
                    num = va_arg(ap,int);
                else
                    num = va_arg(ap,long long);
                {
                    char buf[SDS_LLSTR_SIZE];
                    l = sdsll2str(buf,num);
                    if (sh->free < l) {
                        s = sds_make_room_for(s,l);
                        sh = (void*) (s-(sizeof(struct sdshdr)));
                    }
                    memcpy(s+i,buf,l);
                    sh->len += l;
                    sh->free -= l;
                    i += l;
                }
                break;
            case 'u':
            case 'U':
                if (next == 'u')
                    unum = va_arg(ap,unsigned int);
                else
                    unum = va_arg(ap,unsigned long long);
                {
                    char buf[SDS_LLSTR_SIZE];
                    l = sdsull2str(buf,unum);
                    if (sh->free < l) {
                        s = sds_make_room_for(s,l);
                        sh = (void*) (s-(sizeof(struct sdshdr)));
                    }
                    memcpy(s+i,buf,l);
                    sh->len += l;
                    sh->free -= l;
                    i += l;
                }
                break;
            default: /* Handle %% and generally %<unknown>. */
                s[i++] = next;
                sh->len += 1;
                sh->free -= 1;
                break;
            }
            break;
        default:
            s[i++] = *f;
            sh->len += 1;
            sh->free -= 1;
            break;
        }
Esempio n. 6
0
/* Append the specified sds 't' to the existing sds 's'.
 *
 * After the call, the modified sds string is no longer valid and all the
 * references must be substituted with the new pointer returned by the call. */
sds sds_cat_sds(sds s, const sds t) {
    return sds_cat_len(s, t, sds_len(t));
}
Esempio n. 7
0
/* Duplicate an sds string. */
sds sds_dup(const sds s) {
    return sds_new_len(s, sds_len(s));
}