Exemplo n.º 1
0
json_t *json_true(void)
{
    static json_t the_true = {
        .type = JSON_TRUE,
        .refcount = (unsigned int)1
    };
    return &the_true;
}


json_t *json_false(void)
{
    static json_t the_false = {
        .type = JSON_FALSE,
        .refcount = (unsigned int)1
    };
    return &the_false;
}


json_t *json_null(void)
{
    static json_t the_null = {
        .type = JSON_NULL,
        .refcount = (unsigned int)1
    };
    return &the_null;
}


/*** deletion ***/

void json_delete(json_t *json)
{
    if(json_is_object(json))
        json_delete_object(json_to_object(json));

    else if(json_is_array(json))
        json_delete_array(json_to_array(json));

    else if(json_is_string(json))
        json_delete_string(json_to_string(json));

    else if(json_is_integer(json))
        json_delete_integer(json_to_integer(json));

    else if(json_is_real(json))
        json_delete_real(json_to_real(json));

    /* json_delete is not called for true, false or null */
}
Exemplo n.º 2
0
void json_delete(json_t *json)
{
    if(json_is_object(json))
        json_delete_object(json_to_object(json));

    else if(json_is_array(json))
        json_delete_array(json_to_array(json));

    else if(json_is_string(json))
        json_delete_string(json_to_string(json));

    else if(json_is_integer(json))
        json_delete_integer(json_to_integer(json));

    else if(json_is_real(json))
        json_delete_real(json_to_real(json));

    /* json_delete is not called for true, false or null */
}
Exemplo n.º 3
0
json_t *json_true(void)
{
    static json_t the_true = {
        .type = JSON_TRUE,
        .refcount = (unsigned int)1
    };
    return &the_true;
}


json_t *json_false(void)
{
    static json_t the_false = {
        .type = JSON_FALSE,
        .refcount = (unsigned int)1
    };
    return &the_false;
}


json_t *json_null(void)
{
    static json_t the_null = {
        .type = JSON_NULL,
        .refcount = (unsigned int)1
    };
    return &the_null;
}


/*** deletion ***/

void json_delete(json_t *json)
{
    if(json_is_object(json))
        json_delete_object(json_to_object(json));

    else if(json_is_array(json))
        json_delete_array(json_to_array(json));

    else if(json_is_string(json))
        json_delete_string(json_to_string(json));

    else if(json_is_integer(json))
        json_delete_integer(json_to_integer(json));

    else if(json_is_real(json))
        json_delete_real(json_to_real(json));

    /* json_delete is not called for true, false or null */
}


/*** equality ***/

int json_equal(json_t *json1, json_t *json2)
{
    if(!json1 || !json2)
        return 0;

    if(json_typeof(json1) != json_typeof(json2))
        return 0;

    /* this covers true, false and null as they are singletons */
    if(json1 == json2)
        return 1;

    if(json_is_object(json1))
        return json_object_equal(json1, json2);

    if(json_is_array(json1))
        return json_array_equal(json1, json2);

    if(json_is_string(json1))
        return json_string_equal(json1, json2);

    if(json_is_integer(json1))
        return json_integer_equal(json1, json2);

    if(json_is_real(json1))
        return json_real_equal(json1, json2);

    return 0;
}


/*** copying ***/

json_t *json_copy(json_t *json)
{
    if(!json)
        return NULL;

    if(json_is_object(json))
        return json_object_copy(json);

    if(json_is_array(json))
        return json_array_copy(json);

    if(json_is_string(json))
        return json_string_copy(json);

    if(json_is_integer(json))
        return json_integer_copy(json);

    if(json_is_real(json))
        return json_real_copy(json);

    if(json_is_true(json) || json_is_false(json) || json_is_null(json))
        return json;

    return NULL;
}

json_t *json_deep_copy(json_t *json)
{
    if(!json)
        return NULL;

    if(json_is_object(json))
        return json_object_deep_copy(json);

    if(json_is_array(json))
        return json_array_deep_copy(json);

    /* for the rest of the types, deep copying doesn't differ from
       shallow copying */

    if(json_is_string(json))
        return json_string_copy(json);

    if(json_is_integer(json))
        return json_integer_copy(json);

    if(json_is_real(json))
        return json_real_copy(json);

    if(json_is_true(json) || json_is_false(json) || json_is_null(json))
        return json;

    return NULL;
}
Exemplo n.º 4
0
int json_parse_object( json_task_t *task, json_object_t *parent ) {
    char ch;
    json_object_t node, * append = NULL;
    
    node.next = parent;
    node.key = NULL;
    node.key_len = 0;
    
    if( !task->callback ) {
        if( !task->root ) {
            append = task->root = json_create_object();
        } else {
            append = parent->value.p = json_create_object();
        }
    }
    
    task->status = STS_OBJECT_START;

    while(( ch = *(task->str + task->count) )) {
        task->count ++;
        
        if( ch == ' ' || ch == '\n' || ch == '\t' ) {
            continue;
        }
        
        switch( task->status ) {
            case STS_OBJECT_START:
                if( ch == '"' ) {
                    node.key = task->str + task->count;
                    if( json_parse_string( task ) != 0 ) {
                        return -1;
                    }
                    // WARNING: key_len 可能发生溢出
                    node.key_len = task->str + task->count - node.key - 1;
                    
                    task->status = STS_OBJECT_COLON;
                } else if( ch == '}' ) {
                    // 空对象 {},忽略
                    return 0;
                } else {
                    task->err_msg = "expect '\"' or '}'";
                    return -1;
                }
                break;
            case STS_OBJECT_COLON:
                if( ch == ':' ) {
                    task->status = STS_OBJECT_VALUE;
                } else {
                    task->err_msg = "expect ':'";
                    return -1;
                }
                break;
            case STS_OBJECT_VALUE:
                /* 这里需要将计数减一,因为 json_parse_value 需要根据这一个字符判断 value 类型 */
                task->count --;
                
                node.value.s = task->str + task->count;
                if( json_parse_value( task, &node ) != 0 ) {
                    if( node.value_type == JSON_OBJECT ||
                        node.value_type == JSON_ARRAY ) {
                        json_delete_object(node.value.p);
                    }
                    return -1;
                }
                // WARNING: value_len 可能发生溢出
                node.value_len = task->str + task->count - node.value.s;

                task->status = STS_OBJECT_COMMA;
                break;
            case STS_OBJECT_COMMA:
                if( ( ch == ',' || ch == '}' ) ) {
                    // 对 value 进行处理
                    switch(node.value_type) {
                        case JSON_STRING:
                            // 去除字符串两端的引号
                            node.value.s += 1;
                            node.value_len -= 2;
                            break;
                        case JSON_DOUBLE:
                            node.value.d = atof(node.value.s);
                            break;
                        case JSON_LONGLONG:
                            node.value.l = atoll(node.value.s);
                            break;
                        case JSON_ARRAY:
                        case JSON_OBJECT:
                            break;
                    }

                    if( task->callback ) {
                        task->callback( task, &node );
                    }
                    
                    if( !task->callback ) {
                        switch( node.value_type ) {
                            case JSON_ARRAY:
                            case JSON_OBJECT:
                            case JSON_STRING:
                                append = json_append(append, node.key, node.key_len,
                                        node.value_type, node.value.p, node.value_len);
                                break;
                            default:
                                append = json_append(append, node.key, node.key_len,
                                        node.value_type, &node.value, node.value_len);
                        }
                    }
                }
                
                if( ch == ',' ) {
                    task->status = STS_OBJECT_START;
                } else if( ch == '}' ) {
                    return 0;
                } else {
                    task->err_msg = "expect ',' or '}'";
                    return -1;
                }
                break;
            default:
                task->err_msg = "unknown status";
                return -1;
        }
    }
    
    task->err_msg = "unexpect EOF";
    return -1;
}
Exemplo n.º 5
0
int json_parse_array( json_task_t *task, json_object_t *parent ) {
    char ch;
    json_object_t node, * append = NULL;
    
    node.next = parent;
    node.key = NULL;
    node.key_len = 0;
    
    if( !task->callback ) {
        if( !task->root ) {
            append = task->root = json_create_array();
        } else {
            append = parent->value.p = json_create_array();
        }
    }
    
    task->status = STS_ARRAY_START;

    while(( ch = *(task->str + task->count) )) {
        task->count ++;
        
        if( ch == ' ' || ch == '\n' || ch == '\t' ) {
            continue;
        }
        
        switch( task->status ) {
            case STS_ARRAY_START:
                if( ch == ']' ) {
                    return 0;
                } else {
                    /* 这里需要将计数减一,因为 json_parse_value 需要根据这一个字符判断 value 类型 */
                    task->count --;

                    node.value.s = task->str + task->count;
                    if( json_parse_value( task, &node ) != 0 ) {
                        if( node.value_type == JSON_OBJECT ||
                            node.value_type == JSON_ARRAY ) {
                            json_delete_object(node.value.p);
                        }
                        return -1;
                    }
                    // WARNING: value_len 可能发生溢出
                    node.value_len = task->str + task->count - node.value.s;
                    
                    // 对 value 进行处理
                    switch(node.value_type) {
                        case JSON_STRING:
                            // 去除字符串两端的引号
                            node.value.s += 1;
                            node.value_len -= 2;
                            break;
                        case JSON_DOUBLE:
                            // TODO 在解析测试用例时,atof 与 atoll 使解析时间延长了几乎一半
                            // 移除对数值的默认解析可以显著提升性能
                            node.value.d = atof(node.value.s);
                            break;
                        case JSON_LONGLONG:
                            node.value.l = atoll(node.value.s);
                            break;
                        case JSON_ARRAY:
                        case JSON_OBJECT:
                            break;
                    }

                    // 需要放在 node.key_len ++ 之前以便正确输出数组下标
                    if( task->callback ) {
                        task->callback( task, &node );
                    }

                    if( !task->callback ) {
                        switch( node.value_type ) {
                            case JSON_ARRAY:
                            case JSON_OBJECT:
                            case JSON_STRING:
                                append = json_append(append, node.key, node.key_len,
                                        node.value_type, node.value.p, node.value_len);
                                break;
                            default:
                                append = json_append(append, node.key, node.key_len,
                                        node.value_type, &node.value, node.value_len);
                        }
                    }
                    
                    node.key_len ++;
                    task->status = STS_ARRAY_COMMA;
                }
                break;
            case STS_ARRAY_COMMA:
                if( ch == ',' ) {
                    task->status = STS_ARRAY_START;
                } else if( ch == ']' ) {
                    return 0;
                } else {
                    task->err_msg = "expect ',' or ']'";
                    return -1;
                }
                break;
            default:
                task->err_msg = "unknown status";
                return -1;
        }
    }

    task->err_msg = "unexpect EOF";
    return -1;
}