예제 #1
0
파일: std.cpp 프로젝트: 0branch/frobtads
/*
 *   Limited-length atoi, with auto-advance of the string
 */
int lib_atoi_adv(const char *&str, size_t &len)
{
    /* parse the sign, if present */
    int s = 1;
    if (len >= 1 && *str == '-')
        s = -1, ++str, --len;
    else if (len >= 1 && *str == '+')
        ++str, --len;

    /* scan digits */
    int acc;
    for (acc = 0 ; len > 0 && is_digit(*str) ;
         acc *= 10, acc += value_of_digit(*str), ++str, --len) ;

    /* apply the sign and return the result */
    return s * acc;
}
예제 #2
0
    /* 
     *   Set up the thread.  All string parameters are provided in internal
     *   string format, with VMB_LEN length prefixes.  
     */
    HttpReqThread(VMG_ const vm_val_t *id, const char *url,
                  const char *verb, int32 options,
                  const char *hdrs, vm_val_t *body, const char *body_type,
                  const vm_rcdesc *rc)
    {
        /* save the VM globals */
        vmg = VMGLOB_ADDR;

        /* add a reference on the net event queue */
        if ((queue = G_net_queue) != 0)
            queue->add_ref();

        /* create a global for the ID value */
        idg = G_obj_table->create_global_var();
        idg->val = *id;

        /* save the option flags */
        this->options = options;

        /* set up to parse the URL */
        size_t urll = vmb_get_len(url);
        url += VMB_LEN;

        /* note whether the scheme is plain http or https */
        https = (urll >= 8 && memcmp(url, "https://", 8) == 0);

        /* we don't have any URL pieces yet */
        host = 0;
        resource = 0;
        port = (https ? 443 : 80);

        /* skip the scheme prefix */
        size_t pfx = (urll >= 7 && memcmp(url, "http://", 7) == 0 ? 7 :
                      urll >= 8 && memcmp(url, "https://", 8) == 0 ? 8 : 0);
        url += pfx, urll -= pfx;

        /* the host name is the part up to the ':', '/', or end of string */
        const char *start;
        for (start = url ; urll > 0 && *url != ':' && *url != '/' ;
             ++url, --urll) ;

        /* save the host name */
        host = lib_copy_str(start, url - start);

        /* parse the port, if present */
        if (urll > 0 && *url == ':')
        {
            /* parse the port number string */
            for (--urll, start = ++url, port = 0 ; urll > 0 && *url != '/' ;
                 ++url, --urll)
            {
                if (is_digit(*url))
                    port = port*10 + value_of_digit(*url);
            }
        }

        /* 
         *   The rest (including the '/') is the resource string.  If there's
         *   nothing left, the resource is implicitly '/'. 
         */
        if (urll > 0)
            resource = lib_copy_str(url, urll);
        else
            resource = lib_copy_str("/");

        /* make null-terminated copies of the various strings */
        this->verb = lib_copy_str(verb + VMB_LEN, vmb_get_len(verb));
        this->hdrs = (hdrs == 0 ? 0 :
                      lib_copy_str(hdrs + VMB_LEN, vmb_get_len(hdrs)));

        /* if there's a content body, set up the payload */
        this->body = 0;
        if (body != 0)
        {
            /* set up an empty payload */
            this->body = new OS_HttpPayload();
            
            /* 
             *   Convert the body to a stream payload, if it's a string or
             *   ByteArray.  If it's a LookupTable, it's a set of form
             *   fields.
             */
            if (body->typ == VM_OBJ
                && CVmObjLookupTable::is_lookup_table_obj(vmg_ body->val.obj))
            {
                /* 
                 *   The body is a LookupTable, so we have a set of form
                 *   fields to encode as HTML form data. 
                 */
                
                /* cast the object value */
                CVmObjLookupTable *tab =
                    (CVmObjLookupTable *)vm_objp(vmg_ body->val.obj);
                
                /* add each key in the table as a form field */
                iter_body_table_ctx ctx(this, rc);
                tab->for_each(vmg_ iter_body_table, &ctx);
            }
            else
            {
                /* 
                 *   It's not a lookup table, so it must be bytes to upload,
                 *   as a string or ByteArray.
                 */
                const char *def_mime_type = 0;
                CVmStream *stream = val_to_stream(vmg_ body, &def_mime_type);
                
                /* presume we're going to use the default mime type */
                const char *mime_type = def_mime_type;
                size_t mime_type_len =
                    (mime_type != 0 ? strlen(mime_type) : 0);

                /* if the caller specified a mime type, use it instead */
                if (body_type != 0)
                {
                    mime_type = body_type + VMB_LEN;
                    mime_type_len = vmb_get_len(body_type);
                }
                
                /* add the stream */
                this->body->add(
                    "", 0, "", 0, mime_type, mime_type_len, stream);
            }
        }
    }
예제 #3
0
파일: std.cpp 프로젝트: 0branch/frobtads
/*
 *   buffer-checked vsprintf implementation 
 */
size_t t3vsprintf(char *buf, size_t buflen, const char *fmt, va_list args0)
{
    size_t rem;
    size_t need = 0;
    char *dst;

    /* 
     *   make a private copy of the arguments, to ensure that we don't modify
     *   the caller's copy (on some platforms, va_list is a reference type;
     *   the caller might want to reuse their argument pointer for a two-pass
     *   operation, such as a pre-format pass to measure how much space is
     *   needed) 
     */
    va_list args;
    os_va_copy(args, args0);

    /* scan the buffer */
    for (dst = buf, rem = buflen ; *fmt != '\0' ; ++fmt)
    {
        /* check for a format specifier */
        if (*fmt == '%')
        {
            const char *fmt_start = fmt;
            const char *nth = "";
            const char *txt;
            size_t txtlen;
            char buf[20];
            int fld_wid = -1;
            int fld_prec = -1;
            char lead_char = ' ';
            int plus = FALSE;
            int approx = FALSE;
            int add_ellipsis = FALSE;
            int left_align = FALSE;
            size_t i;

            /* skip the '%' */
            ++fmt;

            /* check for the "approximation" flag */
            if (*fmt == '~')
            {
                approx = TRUE;
                ++fmt;
            }

            /* check for an explicit sign */
            if (*fmt == '+')
            {
                plus = TRUE;
                ++fmt;
            }

            /* check for left alignment */
            if (*fmt == '-')
            {
                left_align = TRUE;
                ++fmt;
            }

            /* if leading zeros are desired, note it */
            if (*fmt == '0')
                lead_char = '0';

            /* check for a field width specifier */
            if (is_digit(*fmt))
            {
                /* scan the digits */
                for (fld_wid = 0 ; is_digit(*fmt) ; ++fmt)
                {
                    fld_wid *= 10;
                    fld_wid += value_of_digit(*fmt);
                }
            }
            else if (*fmt == '*')
            {
                /* the value is an integer taken from the arguments */
                fld_wid = va_arg(args, int);

                /* skip the '*' */
                ++fmt;
            }

            /* check for a precision specifier */
            if (*fmt == '.')
            {
                /* skip the '.' */
                ++fmt;

                /* check what we have */
                if (*fmt == '*')
                {
                    /* the value is an integer taken from the arguments */
                    fld_prec = va_arg(args, int);

                    /* skip the '*' */
                    ++fmt;
                }
                else
                {
                    /* scan the digits */
                    for (fld_prec = 0 ; is_digit(*fmt) ; ++fmt)
예제 #4
0
/*
 *   buffer-checked vsprintf implementation 
 */
void t3vsprintf(char *buf, size_t buflen, const char *fmt, va_list args)
{
    size_t rem;
    char *dst;

    /* if there's no room at all in the buffer, give up immediately */
    if (buflen == 0)
        return;
    
    /* scan the buffer */
    for (dst = buf, rem = buflen - 1 ; *fmt != '\0' && rem != 0 ; ++fmt)
    {
        /* check for a format specifier */
        if (*fmt == '%')
        {
            const char *fmt_start = fmt;
            const char *txt;
            size_t txtlen;
            char buf[20];
            int fld_wid = -1;
            int fld_prec = -1;
            char lead_char = ' ';
            int approx = FALSE;
            int add_ellipsis = FALSE;
            int left_align = FALSE;
            size_t i;

            /* skip the '%' */
            ++fmt;

            /* check for the "approximation" flag */
            if (*fmt == '~')
            {
                approx = TRUE;
                ++fmt;
            }

            /* check for left alignment */
            if (*fmt == '-')
            {
                left_align = TRUE;
                ++fmt;
            }

            /* if leading zeroes are desired, note it */
            if (*fmt == '0')
                lead_char = '0';

            /* check for a field width specifier */
            if (is_digit(*fmt))
            {
                /* scan the digits */
                for (fld_wid = 0 ; is_digit(*fmt) ; ++fmt)
                {
                    fld_wid *= 10;
                    fld_wid += value_of_digit(*fmt);
                }
            }
            else if (*fmt == '*')
            {
                /* the value is an integer taken from the arguments */
                fld_wid = va_arg(args, int);

                /* skip the '*' */
                ++fmt;
            }

            /* check for a precision specifier */
            if (*fmt == '.')
            {
                /* skip the '.' */
                ++fmt;

                /* check what we have */
                if (*fmt == '*')
                {
                    /* the value is an integer taken from the arguments */
                    fld_prec = va_arg(args, int);

                    /* skip the '*' */
                    ++fmt;
                }
                else
                {
                    /* scan the digits */
                    for (fld_prec = 0 ; is_digit(*fmt) ; ++fmt)