Ejemplo n.º 1
0
/**
	@brief Parse an array, and create a JSON_ARRAY for it.
	@param parser Pointer to a Parser.
	@return Pointer to a newly created jsonObject of type JSON_ARRAY, or NULL upon error.

	Look for a series of JSON nodes, separated by commas and terminated by a right square
	bracket.  Parse each node recursively, collect them all into a newly created jsonObject
	of type JSON_ARRAY, and return a pointer to the result.

	Upon error, log an error message and return NULL.
*/
static jsonObject* get_array( Parser* parser ) {

	jsonObject* array = jsonNewObjectType( JSON_ARRAY );

	char c = skip_white_space( parser );
	if( ']' == c )
		return array;          // Empty array

	for( ;; ) {
		jsonObject* obj = get_json_node( parser, c );
		if( !obj ) {
			jsonObjectFree( array );
			return NULL;         // Failed to get anything
		}

		// Add the entry to the array
		jsonObjectPush( array, obj );

		// Look for a comma or right bracket
		c = skip_white_space( parser );
		if( ']' == c )
			break;
		else if( c != ',' ) {
			report_error( parser, c, "Expected comma or bracket in array; didn't find it\n" );
			jsonObjectFree( array );
			return NULL;
		}
		c = skip_white_space( parser );
	}

	return array;
}
Ejemplo n.º 2
0
/**
	@brief Parse a JSON string into a jsonObject.
	@param s Pointer to the string to be parsed.
	@param decode A boolean; true means decode class hints, false means don't.
	@return Pointer to the newly created jsonObject.

	Set up a Parser.  Call get_json_node() to do the real work, then make sure that there's
	nothing but white space at the end.
*/
static jsonObject* parse_it( const char* s, int decode ) {

	if( !s || !*s )
		return NULL;    // Nothing to parse

	Parser parser;

	parser.str_buf = NULL;
	parser.index = 0;
	parser.buff = s;
	parser.decode = decode;

	jsonObject* obj = get_json_node( &parser, skip_white_space( &parser ) );

	// Make sure there's nothing but white space at the end
	char c;
	if( obj && (c = skip_white_space( &parser )) ) {
		report_error( &parser, c, "Extra material follows JSON string" );
		jsonObjectFree( obj );
		obj = NULL;
	}

	buffer_free( parser.str_buf );
	return obj;
}
Ejemplo n.º 3
0
int json_solve_str(void ** root, char *str)
{
    JSON_NODE * root_node;
    JSON_NODE * father_node;
    JSON_NODE * curr_node;
    JSON_VALUE * curr_value;
    int value_type;
    char value_buffer[1024];

    char * tempstr;
    int i;
    int offset=0;
    int state=0;
    int ret;

    // give the root node value

    root_node=get_json_node(NULL);
    if(root_node==NULL)
        return -ENOMEM;
    father_node=NULL;
    curr_node=root_node;
    curr_node->layer=0;
    root_node->elem_type=JSON_ELEM_INIT;

    curr_node->solve_state=SOLVE_INIT;


    while(str[offset]!='\0')
    {
        switch(curr_node->solve_state)
        {
            case SOLVE_INIT:
                while(str[offset]!=0)
                {
                    if(!IsSplitChar(str[offset]))
                        break;
                    offset++;
                }
                if(str[offset]!='{')
                    return -EINVAL;
                // get an object node,then switch to the SOLVE_OBJECT
                father_node=curr_node;
                curr_node=get_json_node(father_node);
                curr_node->elem_type=JSON_ELEM_MAP;
                curr_node->solve_state=SOLVE_MAP;
                offset++;
                break;
           case SOLVE_MAP:
                while(str[offset]!=0)
                {
                    if(!IsSplitChar(str[offset]))
                        break;
                    offset++;
                }
                if(str[offset]!='\"'){
                    // if this map is empty,then finish this MAP
                    if(str[offset]=='}')
                    {
                        offset++;
                        curr_node->solve_state=SOLVE_UPGRADE;
                        break;
                    }
                    // if we should to find another elem
                    if(str[offset]==',')
                    {
                        offset++;
                        break;
                    }
                    else
                        return -EINVAL;
                }
                // we should build a name:value json node
                father_node=curr_node;
                curr_node=get_json_node(father_node);
                curr_node->elem_str=str+offset;
                offset++;
                curr_node->solve_state=SOLVE_NAME;
                break;
           case SOLVE_NAME:
                ret=get_json_strvalue(value_buffer,str+offset);
                if(ret<0)
                    return ret;
                if(ret>=DIGEST_SIZE*2)
                    return ret;
                offset+=ret;
		{
			 int len=strlen(value_buffer);
			 if(len<=DIGEST_SIZE*2)
               	        	 memcpy(curr_node->name,value_buffer,len+1);
			 else
               	        	 memcpy(curr_node->name,value_buffer,DIGEST_SIZE*2);
               		 offset++;
		}
                while(str[offset]!=0)
                {
                    if(!IsSplitChar(str[offset]))
                        break;
                    offset++;
                }
                if(str[offset]!=':')
                    return -EINVAL;
                offset++;
                curr_node->solve_state=SOLVE_VALUE;
                break;
           case SOLVE_VALUE:
                while(str[offset]!=0)
                {
                    if(!IsSplitChar(str[offset]))
                        break;
                    offset++;
                }
                if(str[offset]=='{')
                {
                // get an object node,then switch to the SOLVE_MAP
                   curr_node->elem_type=JSON_ELEM_MAP;
                   offset++;
                   curr_node->solve_state=SOLVE_MAP;
                   break;
                }
                if(str[offset]=='[')
                {
                // get an array node,then switch to the SOLVE_ARRAY
                    curr_node->elem_type=JSON_ELEM_ARRAY;
                    offset++;
                    curr_node->solve_state=SOLVE_ARRAY;
                    break;
                }
                if(str[offset]=='\"')   // value is JSON_STRING
                {
                    offset++;
                    i=get_json_strvalue(value_buffer,str+offset);
                    if(i>=0)
                    {
                        offset+=i+1;
                        curr_node->elem_type=JSON_ELEM_STRING;
                    }
                    else
                        return -EINVAL;
                }
                else
                {
                     i=get_json_numvalue(value_buffer,str+offset);
                     if(i>0)
                     {
                         offset+=i;
                         curr_node->elem_type=JSON_ELEM_NUM;
                     }
                     else
                     {
                          i=get_json_boolvalue(value_buffer,str+offset);
                          if(i>0)
                          {
                               offset+=i;
                               curr_node->elem_type=JSON_ELEM_BOOL;
                           }
                           else
                           {
                                 i=get_json_nullvalue(value_buffer,str+offset);
                                 if(i>0)
                                 {
                                       offset+=i;
                                       curr_node->elem_type=JSON_ELEM_NULL;
                                 }
                                 else
                                     return -EINVAL;

                            }

                       }
                 }
                 curr_node->value_str=dup_str(value_buffer,0);
                 curr_node->solve_state=SOLVE_UPGRADE;
                 break;
           case SOLVE_ARRAY:
                while(str[offset]!=0)
                {
                    if(!IsSplitChar(str[offset]))
                        break;
                    offset++;
                }
                if(str[offset]==']')
                {
                    offset++;
                    curr_node->solve_state=SOLVE_UPGRADE;
                    break;
                }
                // if we should to find another elem
                if(str[offset]==',')
                {
                    offset++;
                    break;
                }

            // we should build a name:value json node
                father_node=curr_node;
                curr_node=get_json_node(father_node);
                curr_node->elem_str=str+offset;
 //             offset++;
                curr_node->solve_state=SOLVE_VALUE;
                break;
            case SOLVE_UPGRADE:  // get value process
                curr_node->solve_state=SOLVE_FINISH;
                if(father_node->elem_type==JSON_ELEM_INIT)
                    break;
                curr_node=father_node;
                father_node=curr_node->father;
                break;

            default:
                return -EINVAL;
        }
        if(curr_node->solve_state==SOLVE_FINISH)
            break;
    }
    *root=curr_node;
    return offset;
}
Ejemplo n.º 4
0
/**
	@brief Parse a hash (JSON object), and create a JSON_HASH for it; decode class hints.
	@param parser Pointer to a Parser.
	@return Pointer to a newly created jsonObject, or NULL upon error.

	This function is similar to get_hash(), @em except:

	If the hash includes a member with a key equal to JSON_CLASS_KEY ("__c" by default),
	then look for a member whose key is JSON_DATA_KEY ("__p" by default).  If you find one,
	return the data associated with it; otherwise return a jsonObject of type JSON_NULL.

	If there is no member with a key equal to JSON_CLASS_KEY, then return the same sort of
	jsonObject as get_hash() would return (except of course that lower levels may be
	decoded as described above).
*/
static jsonObject* get_decoded_hash( Parser* parser ) {
	jsonObject* hash = jsonNewObjectType( JSON_HASH );

	char c = skip_white_space( parser );
	if( '}' == c )
		return hash;           // Empty hash

	char* class_name = NULL;

	for( ;; ) {

		// Get the key string
		if( '"' != c ) {
			report_error( parser, c,
					"Expected quotation mark to begin hash key; didn't find it\n" );
			jsonObjectFree( hash );
			return NULL;
		}

		const char* key = get_string( parser );
		if( ! key ) {
			jsonObjectFree( hash );
			return NULL;
		}
		char* key_copy = strdup( key );

		if( jsonObjectGetKeyConst( hash, key_copy ) ) {
			report_error( parser, '"', "Duplicate key in JSON object" );
			jsonObjectFree( hash );
			return NULL;
		}

		// Get the colon
		c = skip_white_space( parser );
		if( c != ':' ) {
			report_error( parser, c,
					"Expected colon after hash key; didn't find it\n" );
			free( key_copy );
			jsonObjectFree( hash );
			return NULL;
		}

		// Get the associated value
		jsonObject* obj = get_json_node( parser, skip_white_space( parser ) );
		if( !obj ) {
			free( key_copy );
			jsonObjectFree( hash );
			return NULL;
		}

		// Add a new entry to the hash
		jsonObjectSetKey( hash, key_copy, obj );

		// Save info for class hint, if present
		if( !strcmp( key_copy, JSON_CLASS_KEY ) )
			class_name = jsonObjectToSimpleString( obj );

		free( key_copy );

		// Look for comma or right brace
		c = skip_white_space( parser );
		if( '}' == c )
			break;
		else if( c != ',' ) {
			report_error( parser, c,
					"Expected comma or brace in hash, didn't find it" );
			jsonObjectFree( hash );
			return NULL;
		}
		c = skip_white_space( parser );
	}

	if( class_name ) {
		// We found a class hint.  Extract the data node and return it.
		jsonObject* class_data = osrfHashExtract( hash->value.h, JSON_DATA_KEY );
		if( class_data ) {
			class_data->parent = NULL;
			jsonObjectFree( hash );
			hash = class_data;
			hash->parent = NULL;
			hash->classname = class_name;
		} else {
			// Huh?  We have a class name but no data for it.
			// Throw away what we have and return a JSON_NULL.
			jsonObjectFree( hash );
			hash = jsonNewObjectType( JSON_NULL );
		}

	} else {
		if( class_name )
			free( class_name );
	}

	return hash;
}
Ejemplo n.º 5
0
/**
	@brief Parse a hash (JSON object), and create a JSON_HASH for it.
	@param parser Pointer to a Parser.
	@return Pointer to a newly created jsonObject of type JSON_HASH, or NULL upon error.

	Look for a series of name/value pairs, separated by commas and terminated by a right
	curly brace.  Each name/value pair consists of a quoted string, followed by a colon,
	followed a JSON node of any sort.  Parse the value recursively.

	Collect the name/value pairs into a newly created jsonObject of type JSON_ARRAY, and
	return a pointer to it.

	Upon error, log an error message and return NULL.
*/
static jsonObject* get_hash( Parser* parser ) {
	jsonObject* hash = jsonNewObjectType( JSON_HASH );

	char c = skip_white_space( parser );
	if( '}' == c )
		return hash;           // Empty hash

	for( ;; ) {

		// Get the key string
		if( '"' != c ) {
			report_error( parser, c,
						  "Expected quotation mark to begin hash key; didn't find it\n" );
			jsonObjectFree( hash );
			return NULL;
		}

		const char* key = get_string( parser );
		if( ! key ) {
			jsonObjectFree( hash );
			return NULL;
		}
		char* key_copy = strdup( key );

		if( jsonObjectGetKeyConst( hash, key_copy ) ) {
			report_error( parser, '"', "Duplicate key in JSON object" );
			jsonObjectFree( hash );
			return NULL;
		}

		// Get the colon
		c = skip_white_space( parser );
		if( c != ':' ) {
			report_error( parser, c,
						  "Expected colon after hash key; didn't find it\n" );
			free( key_copy );
			jsonObjectFree( hash );
			return NULL;
		}

		// Get the associated value
		jsonObject* obj = get_json_node( parser, skip_white_space( parser ) );
		if( !obj ) {
			free( key_copy );
			jsonObjectFree( hash );
			return NULL;
		}

		// Add a new entry to the hash
		jsonObjectSetKey( hash, key_copy, obj );
		free( key_copy );

		// Look for comma or right brace
		c = skip_white_space( parser );
		if( '}' == c )
			break;
		else if( c != ',' ) {
			report_error( parser, c,
						  "Expected comma or brace in hash, didn't find it" );
			jsonObjectFree( hash );
			return NULL;
		}
		c = skip_white_space( parser );
	}

	return hash;
}