Esempio n. 1
0
File: zson.c Progetto: fvdsn/ZSON
bool zson_next(zson_t *z){
    zsnode_t *cz = z->stack + z->stack_index;

    if(zson_has_error(z)){
        return false;
    }else if(z->stack_index == 0 && !z->started){
        z->started = true;
        _decode(z, cz, z->mem, 0, z->mem_size, false, z->bit64);
        return !zson_has_error(z);
    }else if(cz->has_next){
        zsnode_t *pz = z->stack + z->stack_index - 1;
        size_t start = cz->start + cz->size;
        _decode(z, cz, z->mem, start, pz->size + pz->start - start, 
                       pz->type == ZSON_OBJECT, z->bit64 );
        cz->has_next = cz->start + cz->size < pz->start + pz->size;
        return !zson_has_error(z);
    }
    return false;
}
Esempio n. 2
0
bool AP_GPS_NMEA::read(void)
{
    int numc;
    bool parsed = false;

    numc = _port->available();
    while (numc--) {
        if (_decode(_port->read())) {
            parsed = true;
        }
    }
    return parsed;
}
Esempio n. 3
0
File: zson.c Progetto: fvdsn/ZSON
bool zson_child(zson_t *z){
    zsnode_t *pz = z->stack + z->stack_index;
    if(zson_has_error(z)){
        return false;
    }else if(pz->has_child){
        zson_push_node(z);
        zsnode_t *cz = z->stack + z->stack_index;
        _decode(z, cz, z->mem, pz->start + pz->content_start, 
                              pz->size - pz->content_start, 
                              pz->type == ZSON_OBJECT, z->bit64 ); 
        cz->has_next = cz->start + cz->size < pz->start + pz->size;
        return !zson_has_error(z);
    }

    return false;
}
Esempio n. 4
0
File: zson.c Progetto: fvdsn/ZSON
static bool _decode( zson_t *zd, zsnode_t *z, const char *src, size_t start, 
                   size_t maxsize, bool keyval, bool bit64 ){
    memset(z,0,sizeof(zsnode_t));
    const char* origin = src;
    int header  = src[start];
    int minsize = bit64 ? minsize64[header] : minsize32[header];
    int headersize = bit64 ? headersize64[header] : headersize32[header];
    size_t size = minsize;

    z->type = header;
    z->start = start;
    z->entity = src;
    z->has_next = false;
    z->content_start = headersize; 
    z->content = src + headersize;
    z->size = minsize;

    if(header == 0 || header >= ZSON_TYPE_COUNT){
        zson_set_error(zd, ZSON_ERROR_INVALID_HEADER, "invalid header");
        return false;
    }else if(minsize > maxsize){
        zson_set_error(zd, ZSON_ERROR_INVALID_SIZE, "exceeding parent size");
        return false; 
    }

    src = src+start;

    switch(header){
        case ZSON_NO_ENT:
        case ZSON_NULL:     break;
        case ZSON_TRUE:     z->value.boolean = 1;                           break;
        case ZSON_FALSE:    z->value.boolean = 0;                           break;
        case ZSON_INT8:     z->value.int8    = (int8_t)src[1];              break;
        case ZSON_INT16:    z->value.int16   = GET_VAL(src,1,int16_t);      break;
        case ZSON_INT32:    z->value.int32   = GET_VAL(src,1,int32_t);      break;
        case ZSON_INT64:    z->value.int64   = GET_VAL(src,1,int64_t);      break;
        case ZSON_UINT8:    z->value.uint8   = (int8_t)src[1];              break;
        case ZSON_UINT16:   z->value.uint16  = GET_VAL(src,1,uint16_t);     break;
        case ZSON_UINT32:   z->value.uint32  = GET_VAL(src,1,uint32_t);     break;
        case ZSON_UINT64:   z->value.uint64  = GET_VAL(src,1,uint64_t);     break;
        case ZSON_FLOAT32:  z->value.float32 = GET_VAL(src,1,float);        break;
        case ZSON_FLOAT64:  z->value.float64 = GET_VAL(src,1,double);       break;
        case ZSON_STRING4:
        case ZSON_STRING8:
        case ZSON_STRING12:
            z->value.string  = src + 1;
            if(src[z->size -1] != 0){
                zson_set_error( zd, ZSON_ERROR_RUNAWAY_STRING,
                               "strings must be null terminated");
                return false; 
            }
            break;
        default:
        {
            size = bit64 ? GET_VAL(src,1,uint64_t) : GET_VAL(src,1,uint32_t);
            z->size = size;

            if(size > maxsize){
                zson_set_error( zd, ZSON_ERROR_INVALID_SIZE, "size exceeds parent size");
                return false;
            }else if( size < minsize){
                zson_set_error(zd, ZSON_ERROR_INVALID_SIZE, "size too small");
                return false;
            }

            if (header == ZSON_STRING){
                if(size - headersize <= 0 || src[z->size -1] != 0){
                    zson_set_error( zd, ZSON_ERROR_RUNAWAY_STRING,
                                    "zero length strings must also be null terminated");
                    return false;
                }
                z->value.string = src + headersize;
                z->length = size - headersize - 1;
            }else if(header == ZSON_OBJECT || header == ZSON_ARRAY){
                z->has_child = size > headersize;
            }else if(header >= ZSON_ARRAY_INT8 && header <= ZSON_ARRAY_FLOAT64){
                if( size == headersize){
                    z->value.ptr = NULL;
                    z->length = 0;
                }else{
                    int padding = subsize[z->type];
                        padding = padding <= 1 ? 0 : (padding - start % padding) % padding;
                    if( headersize + padding > size){
                        zson_set_error( zd, ZSON_ERROR_INVALID_PADDING, 
                                        "padding going outside of entity");
                        return false;
                    }
                    z->value.ptr = src + headersize + padding;
                    z->length = (z->size - headersize - padding) / subsize[z->type];
                    z->content_start += padding;
                }
            }
        }
    }

    if(keyval){
        if(z->type < ZSON_STRING || z->type > ZSON_STRING12){
            zson_set_error( zd, ZSON_ERROR_INVALID_KEY, 
                            "key value pairs must start with a string" );
            return false;
        }
        if(!_decode(zd, z, origin, start+size, maxsize-size, false, bit64 )){
            return false;
        }
        z->key = src + headersize;
        z->size += size;
        z->content_start += size;
        z->start = start;
    }

    return z->type;
}
Esempio n. 5
0
int url_parse(struct url *dst, const char *src)
{
	int i, j;
	int mp;

	dst->extra_free_me3 = NULL;
	dst->extra_free_me4 = NULL;

	/* special case: mailto urls don't have // */
	if ((src[0] == 'm' || src[0] == 'M')
	&&  (src[1] == 'a' || src[1] == 'A')
	&&  (src[2] == 'i' || src[2] == 'I')
	&&  (src[3] == 'l' || src[3] == 'L')
	&&  (src[4] == 't' || src[4] == 'T')
	&&  (src[5] == 'o' || src[5] == 'O')
	&&  src[6] == ':') {
		if (src[7] == '/' || src[8] == '/') return 0;

		memset(dst,0,sizeof(struct url));
		dst->original_url = strdup(src);
		dst->extra_free_me1 = strdup(src);
		if (!dst->original_url || !dst->extra_free_me1)
			abort(); /* OOM */
		dst->schema = "mailto";
		dst->emailaddr = dst->extra_free_me1+7;
		i = 7;
		goto GOT_PATH; /* for ?-string processing */
	}

	/* TODO special case: news urls might not have // */

	for (i = 0; src[i]; i++) {
		if (src[i] >= 'A' && src[i] <= 'Z') continue;
		if (src[i] >= 'a' && src[i] <= 'z') continue;
		if (src[i] == ':') {
			if (src[i+1] == '/'
			&&  src[i+2] == '/') {
				break;
			}
		}
		return 0; /* fail */
	}
	if (!src[i]) return 0;

	memset(dst,0,sizeof(struct url));
	dst->original_url = strdup(src);
	dst->extra_free_me1 = strdup(src);
	dst->extra_free_me2 = strdup(src);
	if (!dst->original_url || !dst->extra_free_me1 || !dst->extra_free_me2)
		abort(); /* OOM */

	dst->schema = dst->extra_free_me1;
	dst->extra_free_me1[i] = '\0'; /* : from above */
	dst->port = -1;

	i += 3;
	for (j = i; src[j]; j++) {
		if (src[j] == ':') {
			/* okay, that was _probably_ a username */
			dst->username = dst->extra_free_me1+i;
			dst->extra_free_me1[j] = '\0'; /* : from above */
			j++;
			mp = 1;
			for (i = j; src[j]; j++) {
				if (mp) {
					/* maybe port */
					if (src[j] >= '0' && src[j] <= '9') {
						continue;
					} else if (src[j] == '/') {
						/* that was hostname:port! */
						dst->hostname = dst->username;
						dst->username = NULL;
						dst->path = dst->extra_free_me2 + j;
						dst->extra_free_me1[j] = '\0';
						dst->port = atoi(dst->extra_free_me1+i);
						i = j;
						goto GOT_PATH;
					}
					mp = 0;
				}

				if (src[j] == '@') {
					dst->password = dst->extra_free_me1+i;
					dst->extra_free_me1[j] = '\0'; /* : from above */
					j++;
					dst->hostname = dst->extra_free_me1+j;
					i = j;
					goto GOT_HOSTNAME;
				} else if (src[j] == '/' || src[j] == ':') {
					goto FAIL;
				}
			}
			goto FAIL;
		} else if (src[j] == '@') {
			/* okay, that was a username */
			dst->username = dst->extra_free_me1+i;
			dst->extra_free_me1[j] = '\0'; /* : from above */
			j++;
			dst->hostname = dst->extra_free_me1+j;
			i = j;
			goto GOT_HOSTNAME;
		} else if (src[j] == '/') {
			/* hostname */
			dst->hostname = dst->extra_free_me1+i;
			dst->extra_free_me1[j] = '\0'; /* : from above */
			dst->path = dst->extra_free_me2 + j;
			i = j;
			goto GOT_PATH;
		}
	}
	/* hostname _only; no path */
	_decode(dst->username);
	_decode(dst->password);
	_decode(dst->hostname);
	dst->path = "/";
	dst->hostname = dst->extra_free_me1 + i;
	goto FINISH;

GOT_HOSTNAME:
	/* i points to the first word of the hostname */
	for (j = i; src[j]; j++) {
		if (src[j] == ':') {
			/* port */
			dst->extra_free_me1[j] = '\0';
			j++;
			for (i = j; src[j]; j++) {
				if (src[j] >= '0' && src[j] <= '9') continue;
				if (src[j] != '/') goto FAIL;
				dst->extra_free_me1[j] = '\0';
				dst->port = atoi(dst->extra_free_me1+i);
				j++;
				i = j;
				dst->path = dst->extra_free_me2 + j;
				goto GOT_PATH;
			}
			/* hostname:port */
			dst->port = atoi(dst->extra_free_me1+i);
			dst->path = "/";
			goto GOT_PATH;
		} else if (src[j] == '/') {
			dst->extra_free_me1[j] = '\0';
			dst->path = dst->extra_free_me2 + j;
			i = j;
			goto GOT_PATH;
		} else if (src[j] == '@') {
			goto FAIL;
		}
	}
	_decode(dst->username);
	_decode(dst->password);
	_decode(dst->hostname);
	dst->path = "/";
	goto FINISH;

GOT_PATH:
	_decode(dst->username);
	_decode(dst->password);
	_decode(dst->hostname);

	/* i points to the first word of the path */
	for (j = i; src[j]; j++) {
		if (src[j] == '?') { 
			dst->querystr = dst->extra_free_me2+(j+1);
			dst->extra_free_me2[j] = '\0';
			j++;
			for (i = j; src[j]; j++) {
				if (src[j] == '#') {
					dst->fragment = dst->extra_free_me2+(j+1);
					dst->extra_free_me2[j] = '\0';
					_decode(dst->fragment);
					goto FINISH;
				}
			}
			break;

		} else if (src[j] == '#') {
			dst->fragment = dst->extra_free_me2+(j+1);
			dst->extra_free_me2[j] = '\0';
			_decode(dst->fragment);
			goto FINISH;
		}
	}

FINISH:
	for (i = 0; dst->schema[i]; i++)
		dst->schema[i] = tolower(((unsigned)dst->schema[i]));
	if (!strcmp(dst->schema, "file")) {
		if (dst->hostname && !dst->hostname[0])
			dst->hostname = NULL;
	} else if (!dst->hostname || !dst->hostname[0]) {
		if (!strcmp(dst->schema, "news") || !strcmp(dst->schema, "mailto")) {
			/* no valid thing as a hostname */
		} else {
			/* hostname required */
			goto FAIL;
		}
	}

	if (dst->port == -1) {
		if (!strcmp(dst->schema, "http")) {
			dst->port = 80;
		} else if (!strcmp(dst->schema, "https")) {
			dst->port = 443;
		} else if (!strcmp(dst->schema, "ftp")) {
			dst->port = 21;
		} else if (!strcmp(dst->schema, "gopher")) {
			dst->port = 70;
		} else if (!strcmp(dst->schema, "mailto")) {
			/* NA */
		} else if (!strcmp(dst->schema, "news")) {
			/* NA */
		} else if (!strcmp(dst->schema, "file")) {
			/* NA */
		} else if (!strcmp(dst->schema, "nntp")) {
			dst->port = 119;
		} else if (!strcmp(dst->schema, "ssh")) {
			dst->port = 22;
		} else if (!strcmp(dst->schema, "sftp")) {
			dst->port = 22;
		} else if (!strcmp(dst->schema, "ssh1")) {
			dst->port = 22;
		} else if (!strcmp(dst->schema, "ssh2")) {
			dst->port = 22;
		}
	}

	return 1;
FAIL:
	free(dst->original_url);
	free(dst->extra_free_me1);
	free(dst->extra_free_me2);
	free(dst->extra_free_me3);
	free(dst->extra_free_me4);
	memset(dst,0,sizeof(struct url));
	return 0;
}