Example #1
0
File: sds.c Project: prownd/ccufl
/* Split 's' with separator in 'sep'. An array
 * of sds strings is returned. *count will be set
 * by reference to the number of tokens returned.
 *
 * On out of memory, zero length string, zero length
 * separator, NULL is returned.
 *
 * Note that 'sep' is able to split a string using
 * a multi-character separator. For example
 * sdssplit("foo_-_bar","_-_"); will return two
 * elements "foo" and "bar".
 *
 * This version of the function is binary-safe but
 * requires length arguments. sdssplit() is just the
 * same function but for zero-terminated strings.
 */
sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count) {
    int elements = 0, slots = 5, start = 0, j;

    sds *tokens = malloc(sizeof(sds)*slots);
#ifdef SDS_ABORT_ON_OOM
    if (tokens == NULL) sdsOomAbort();
#endif
    if (seplen < 1 || len < 0 || tokens == NULL) return NULL;
    for (j = 0; j < (len-(seplen-1)); j++) {
        /* make sure there is room for the next element and the final one */
        if (slots < elements+2) {
            slots *= 2;
            sds *newtokens = realloc(tokens,sizeof(sds)*slots);
            if (newtokens == NULL) {
#ifdef SDS_ABORT_ON_OOM
                sdsOomAbort();
#else
                goto cleanup;
#endif
            }
            tokens = newtokens;
        }
        /* search the separator */
        if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
            tokens[elements] = sdsnewlen(s+start,j-start);
            if (tokens[elements] == NULL) {
#ifdef SDS_ABORT_ON_OOM
                sdsOomAbort();
#else
                goto cleanup;
#endif
            }
            elements++;
            start = j+seplen;
            j = j+seplen-1; /* skip the separator */
        }
    }
    /* Add the final element. We are sure there is room in the tokens array. */
    tokens[elements] = sdsnewlen(s+start,len-start);
    if (tokens[elements] == NULL) {
#ifdef SDS_ABORT_ON_OOM
                sdsOomAbort();
#else
                goto cleanup;
#endif
    }
    elements++;
    *count = elements;
    return tokens;

#ifndef SDS_ABORT_ON_OOM
cleanup:
    {
        int i;
        for (i = 0; i < elements; i++) sdsfree(tokens[i]);
        free(tokens);
        return NULL;
    }
#endif
}
Example #2
0
//试图把fmt格式的内容加入到s的后面
sds sdscatprintf(sds s,const char*fmt,...)
{
    va_list	ap;
    char	*buf,*t;
    size_t	buflen=32;

    while(1){
	buf=malloc(buflen);
	if(buf==NULL) sdsOomAbort();
	buf[buflen-2]='\0';
	va_start(ap,fmt);
	vsnprintf(buf,buflen,fmt,ap);
	va_end(ap);
	if(buf[buflen-2]!='\0'){//如果被覆盖了,显然需要重新分配更大的buf
	    free(buf);
	    buflen*=2;
	    continue;
	}
	break;
    }
    //首先通过buf作为中间存放fmt格式的内容
    t=sdscat(s,buf);
    free(buf);
    return t;
}
Example #3
0
File: sds.c Project: prownd/ccufl
sds sdscatprintf(sds s, const char *fmt, ...) {
    va_list ap;
    char *buf, *t;
    size_t buflen = 32;

    va_start(ap, fmt);
    while(1) {
        buf = malloc(buflen);
#ifdef SDS_ABORT_ON_OOM
        if (buf == NULL) sdsOomAbort();
#else
        if (buf == NULL) return NULL;
#endif
        buf[buflen-2] = '\0';
        vsnprintf(buf, buflen, fmt, ap);
        if (buf[buflen-2] != '\0') {
            free(buf);
            buflen *= 2;
            continue;
        }
        break;
    }
    va_end(ap);
    t = sdscat(s, buf);
    free(buf);
    return t;
}
Example #4
0
/** make a new string with length of initlen, copy *init to the new string if *init is not null 
 *  be careful if strlen(init) < initlen, such as
 *  a = sdsnewlen("abc", 10);
 *  a = sdscat(a, "abc");
 *  printf("%s", a) ====> "abc", because a[4] == '\0'!!!
 ***/
sds sdsnewlen(const void *init, size_t initlen) {
    struct sdshdr *sh;
    /**
     * allocate the memory
     * sizeof(struct sdshdr) -> sizeof of struct
     * initlen  -> sizeof the string
     * 1  -> room for '\0'
     **/
    sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
#ifdef SDS_ABORT_ON_OOM
    if (sh == NULL) sdsOomAbort();
#else
    if (sh == NULL) return NULL;
#endif
    /**
     * update struct sh
     * setup sh->len and sh->free
     * change size_t(initlen) to long(sh->len), there may get problem
     */
    sh->len = initlen;
    sh->free = 0;
    if (initlen) {/*initlen > 0 */
        /* setup sh->buf */
        if (init) memcpy(sh->buf, init, initlen); /* copy the content from init */
        else memset(sh->buf,0,initlen); /* set all the elements of sh->buf to 0 */
    }
    /* add '\0' at then end of sh->buf */
    sh->buf[initlen] = '\0';
    /**
     * return the new string
     * sds --> typedef of char*
     **/
    return (char*)sh->buf;
}
Example #5
0
sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
    va_list cpy;
    char *buf, *t;
    size_t buflen = 16;

    while(1) {
        buf = zmalloc(buflen);
#ifdef SDS_ABORT_ON_OOM
        if (buf == NULL) sdsOomAbort();
#else
        if (buf == NULL) return NULL;
#endif
        buf[buflen-2] = '\0';
        va_copy(cpy,ap);
        vsnprintf(buf, buflen, fmt, cpy);
        if (buf[buflen-2] != '\0') {
            zfree(buf);
            buflen *= 2;
            continue;
        }
        break;
    }
    t = sdscat(s, buf);
    zfree(buf);
    return t;
}
Example #6
0
/**
 * concat some format characters after s,
 * the format likes the parameter of printf
 */
sds sdscatprintf(sds s, const char *fmt, ...) {
    /* ap : va_list */
    va_list ap;
    char *buf, *t;
    /* start buf size */
    size_t buflen = 32;

    /* look for a suffient buf size */
    while(1) {
        buf = zmalloc(buflen);
#ifdef SDS_ABORT_ON_OOM
        if (buf == NULL) sdsOomAbort();
#else
        if (buf == NULL) return NULL;
#endif
        buf[buflen-2] = '\0';
        /* print the format string to buf */
        va_start(ap, fmt);
        vsnprintf(buf, buflen, fmt, ap);
        va_end(ap);
        /* if buf isn't bigger enough to hold the format string
         * keeping on looking*/
        if (buf[buflen-2] != '\0') {
            zfree(buf);
            buflen *= 2;
            continue;
        }
        break;
    }
    /* concat the format string after s */
    t = sdscat(s, buf);
    /* free the memory we allocated before */
    zfree(buf);
    return t;
}
Example #7
0
/**
 * make room for addlen byte after s
 * @s  : the original string
 * @addlen: the length we want to add
 **/
static sds sdsMakeRoomFor(sds s, size_t addlen) {
    /* @sh : point the the struct contains s
     * @newsh : points the new struct
     */
    struct sdshdr *sh, *newsh;
    /* calculate the free space of sh */
    size_t free = sdsavail(s);
    size_t len, newlen;
    /* if there are enough free space for addlen */
    if (free >= addlen) return s;
    len = sdslen(s);
    sh = (void*) (s-(sizeof(struct sdshdr)));
    /**
     * allocate (len + addlen)*2 space
     * we want (len + addlen)
     * so we may not reallocate memory next time
     **/
    newlen = (len+addlen)*2;
    /* realloc the memory */
    newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
#ifdef SDS_ABORT_ON_OOM
    if (newsh == NULL) sdsOomAbort();
#else
    if (newsh == NULL) return NULL;
#endif
    /**
     * update the struct , newsh->len doesn't change
     **/
    newsh->free = newlen - len;
    return newsh->buf;
}
Example #8
0
sds sdsnewlen(const void*init,size_t initlen)
{
    struct sdshdr *sh;
    sh=malloc(sizeof(*sh)+initlen+1);
    if(sh==NULL) sdsOomAbort();
    sh->len=initlen;
    sh->free=0;
    if(initlen){
	if(init)memcpy(sh->buf,init,initlen);
	else    memset(sh->buf,0,initlen);
    }
    sh->buf[initlen]='\0';
    return (char*)sh->buf;
}
Example #9
0
static sds sdsMakeRoomFor(sds s,size_t addlen)
{
    struct sdshdr*sh,*newsh;
    size_t free=sdsavail(s);
    size_t len,newlen;

    if(free>=addlen) return s;
    len=sdslen(s);
    sh=(void*)(s-(sizeof(struct sdshdr)));
    newlen=(len+addlen)*2;
    newsh=realloc(sh,sizeof(struct sdshdr)+newlen+1);
    if(newsh==NULL) sdsOomAbort();
    newsh->free=newlen-len;
    return newsh->buf;
}
Example #10
0
File: sds.c Project: prownd/ccufl
sds sdsnewlen(const void *init, size_t initlen) {
    struct sdshdr *sh;

    sh = malloc(sizeof(struct sdshdr)+initlen+1);
#ifdef SDS_ABORT_ON_OOM
    if (sh == NULL) sdsOomAbort();
#else
    if (sh == NULL) return NULL;
#endif
    sh->len = initlen;
    sh->free = 0;
    if (initlen) {
        if (init) memcpy(sh->buf, init, initlen);
        else memset(sh->buf,0,initlen);
    }
    sh->buf[initlen] = '\0';
    return (char*)sh->buf;
}
Example #11
0
static sds sdsMakeRoomFor(sds s, size_t addlen) {
    struct sdshdr *sh, *newsh;
    size_t free = sdsavail(s);
    size_t len, newlen;

    if (free >= addlen) return s;
    len = sdslen(s);
    sh = (void*) (s-(sizeof(struct sdshdr)));
    newlen = (len+addlen)*2;
    newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
#ifdef SDS_ABORT_ON_OOM
    if (newsh == NULL) sdsOomAbort();
#else
    if (newsh == NULL) return NULL;
#endif

    newsh->free = (int)(newlen - len);
    return newsh->buf;
}
Example #12
0
sds sdsMakeRoomFor(sds s, size_t addlen) {
    struct sdshdr *sh, *newsh;
    size_t free = sdsavail(s);
    size_t len, newlen;

    if (free >= addlen) return s;
    len = sdslen(s);
    sh = (void*) (s-(sizeof(struct sdshdr)));
    newlen = (len+addlen);
    if (newlen < SDS_MAX_PREALLOC)
        newlen *= 2;
    else
        newlen += SDS_MAX_PREALLOC;
    newsh = realloc(sh, sizeof(struct sdshdr)+newlen+1);
#ifdef SDS_ABORT_ON_OOM
    if (newsh == NULL) sdsOomAbort();
#else
    if (newsh == NULL) return NULL;
#endif

    newsh->free = newlen - len;
    return newsh->buf;
}
Example #13
0
/* Split 's' with separator in 'sep'. An array
 * of sds strings is returned. *count will be set
 * by reference to the number of tokens returned.
 *
 * On out of memory, zero length string, zero length
 * separator, NULL is returned.
 *
 * Note that 'sep' is able to split a string using
 * a multi-character separator. For example
 * sdssplit("foo_-_bar","_-_"); will return two
 * elements "foo" and "bar".
 *
 * This version of the function is binary-safe but
 * requires length arguments. sdssplit() is just the
 * same function but for zero-terminated strings.
 */
sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count) {
    /**
     * @elements : count of split string
     * @slots : count of split string we could have *at most*, used for allocating memory
     * @start : the start position of next split string
     * @j : the current index of s
     */
    int elements = 0, slots = 5, start = 0, j;
    /**
     * @tokens : store the split string
     */
    sds *tokens = zmalloc(sizeof(sds)*slots);
#ifdef SDS_ABORT_ON_OOM
    if (tokens == NULL) sdsOomAbort();
#endif
    /* empty sep, empty s or can't out of memory */
    if (seplen < 1 || len < 0 || tokens == NULL) return NULL;
    /* split the string */
    for (j = 0; j < (len-(seplen-1)); j++) {
        /* make sure there is room for the next element and the final one */
        if (slots < elements+2) {
            sds *newtokens;

            /* double slots */
            slots *= 2;
            /* realloct new room */
            newtokens = zrealloc(tokens,sizeof(sds)*slots);
            if (newtokens == NULL) {
#ifdef SDS_ABORT_ON_OOM
                sdsOomAbort();
#else
                goto cleanup;
#endif
            }
            tokens = newtokens;
        }
        /* search the separator */
        if ((seplen == 1 && *(s+j) == sep[0]) || (memcmp(s+j,sep,seplen) == 0)) {
            /* make a new sdshdr to hold new string */
            tokens[elements] = sdsnewlen(s+start,j-start);
            if (tokens[elements] == NULL) {
#ifdef SDS_ABORT_ON_OOM
                sdsOomAbort();
#else
                goto cleanup;
#endif
            }
            /* update elements, start and j */
            elements++;
            start = j+seplen;
            j = j+seplen-1; /* skip the separator */
        }
    }
    /* Add the final element. We are sure there is room in the tokens array. */
    tokens[elements] = sdsnewlen(s+start,len-start);
    if (tokens[elements] == NULL) {
#ifdef SDS_ABORT_ON_OOM
                sdsOomAbort();
#else
                goto cleanup;
#endif
    }
    /* update info, and return */
    elements++;
    *count = elements;
    return tokens;

#ifndef SDS_ABORT_ON_OOM
cleanup: /* cleanup */
    {
        int i;
        for (i = 0; i < elements; i++) sdsfree(tokens[i]);
        zfree(tokens);
        return NULL;
    }
#endif
}