library/src/javascript/JSON/BP-JSON.cc
// Returns a parse state object to be used by the parser.  Errors/warnings/notices are
// tracked in the parent json structure.
Returns a parse state object to be used by the parser.  Errors/warnings/notices are
tracked in the parent json structure.
Returns a parse state object to be used by the parser . Errors / warnings / notices are tracked in the parent json structure .
P_BP_JSON_PARSE_STATE BP_JSONCreateInitialParseState
(
		P_BP_JSON json,
		char  *buffer,
		size_t buffer_size,
		size_t max_depth_for_token_allocation,
		size_t max_tokens_total
)
{
	if(!json)
		return NULL;
	if(!buffer)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because passed in buffer was null.");
		return NULL;
	}
	if(!buffer_size)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because passed in buffer_size was zero.");
		return NULL;
	}
	if(!BP_StringIsReasonablePrintableString(buffer, buffer_size, BP_TRUE, BP_TRUE))
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because passed in buffer was unreasonable/non-printable.");
		return NULL;
	}
	if(!max_depth_for_token_allocation)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because max_depth_for_token_allocation was zero");
		return NULL;
	}
	if(!max_tokens_total)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because max_tokens_total was zero");
		return NULL;
	}
	P_BP_LINKL tq = BP_CreateLinkL(".", BP_TRUE);
	if(!tq)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because we were unable to create a internal tail queue allocator.  This is a critical internal memory error and could possibly be an indicator that the system is out of memory.  Administrators have been notified.");
		return NULL;
	}
	P_BP_JSON_PARSE_STATE new_state = (P_BP_JSON_PARSE_STATE) tq_calloc(tq, sizeof(BP_JSON_PARSE_STATE), 1, BPLN);
	if(!new_state)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because we were unable to allocate memory for the state.  Critical error.");
		BP_DestroyLinkL(tq, BP_TRUE);
		return NULL;
	}
	new_state->tq = tq;
	new_state->buffer = (char *) tq_strndup(new_state->tq, buffer, buffer_size, BPLN);
	new_state->buffer_size = buffer_size;
	new_state->jsmn_tokens = (jsmntok_t *) tq_calloc
	(
		new_state->tq,
		sizeof(jsmntok_t) * (max_tokens_total + 1),
		1,
		BPLN
	);
	if(!new_state->jsmn_tokens)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Initial parse state creation failed because we were unable to allocate memory for the state tokens.  Critical error.");
		BP_DestroyLinkL(tq, BP_TRUE);
		return NULL;
	}
	new_state->jsmn_tokens_allocated_n = max_tokens_total;
	new_state->token_element_stack = (P_BP_JSON_PARSE_TOKEN_ELEMENT) tq_calloc
	(
		new_state->tq,
		sizeof(BP_JSON_PARSE_TOKEN_ELEMENT) * (max_tokens_total + 1),
		1,
		BPLN
	);
	if(!new_state->token_element_stack)
	{
		BP_DestroyLinkL(tq, BP_TRUE);
		return NULL;
	}
	new_state->token_element_stack_items_allocated_n = max_tokens_total;
	jsmn_init(json, &new_state->p);
	int parse_token_cnt = jsmn_parse
	(
		json,
		&new_state->p,
		new_state->buffer,
		new_state->buffer_size,
		new_state->jsmn_tokens,
		new_state->jsmn_tokens_allocated_n
	);
	if(parse_token_cnt < 0)
	{
		switch(parse_token_cnt)
		{
			case JSMN_ERROR_INVAL:
				BP_JSONParseAddErrorMsg(json, NULL, "Parser failed reporting JSMN_ERROR_INVAL.  This means there is an error in your JSON which prevented it from being parsed as valid JSON.  Please attempt to check your json for bad values (such as via jslint.com).");
				break;
			case JSMN_ERROR_NOMEM:
				BP_JSONParseAddErrorMsg(json, NULL, "Parser failed reporting JSMN_ERROR_NOMEM.  If this message gets added it will be a miracle because we're already out of memory somehow.  Will attempt to notify admins.");
				break;
			case JSMN_ERROR_PART:
				BP_JSONParseAddErrorMsg(json, NULL, "Parser failed reporting JSMN_ERROR_PART.  This means that JSON was parsing ok, but JSON data was unexpectedly cut short.");
				break;
			default:
				BP_JSONParseAddErrorMsg(json, NULL, "Parser failed reporting an unknown error type.  This is undefined behanvior.");
				break;
		}
		BP_DestroyLinkL(tq, BP_TRUE);
		return NULL;
	}
	if(parse_token_cnt == 0)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Parser failed reporting that JSON parsed ok, but somehow has a zero token count.");
		BP_DestroyLinkL(tq, BP_TRUE);
		return NULL;
	}
	/*
	// check first token type
	if(new_state->jsmn_tokens[0].type != JSMN_OBJECT)
	{
		BP_JSONParseAddErrorMsg(json, NULL, "Parser failed reporting that JSON parsed ok, but the first token was somehow not an object.  Enusre that your json is wrapped in exterior {} characters.");
		BP_DestroyLinkL(tq, BP_TRUE);
		return NULL;
	}
	*/
	new_state->parsed_token_count = (size_t) parse_token_cnt;
	new_state->parsed_tokens_remaining = new_state->parsed_token_count;
	return new_state;
}
P_BP_JSON_PARSE_STATE BP_JSONCreateInitialParseState ( P_BP_JSON json , char * buffer , size_t buffer_size , size_t max_depth_for_token_allocation , size_t max_tokens_total ) { if ( ! json ) return NULL ; if ( ! buffer ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; return NULL ; } if ( ! buffer_size ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; return NULL ; } if ( ! BP_StringIsReasonablePrintableString ( buffer , buffer_size , BP_TRUE , BP_TRUE ) ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; return NULL ; } if ( ! max_depth_for_token_allocation ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; return NULL ; } if ( ! max_tokens_total ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; return NULL ; } P_BP_LINKL tq = BP_CreateLinkL ( " " , BP_TRUE ) ; if ( ! tq ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; return NULL ; } P_BP_JSON_PARSE_STATE new_state = ( P_BP_JSON_PARSE_STATE ) tq_calloc ( tq , sizeof ( BP_JSON_PARSE_STATE ) , 1 , BPLN ) ; if ( ! new_state ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; BP_DestroyLinkL ( tq , BP_TRUE ) ; return NULL ; } new_state -> tq = tq ; new_state -> buffer = ( char * ) tq_strndup ( new_state -> tq , buffer , buffer_size , BPLN ) ; new_state -> buffer_size = buffer_size ; new_state -> jsmn_tokens = ( jsmntok_t * ) tq_calloc ( new_state -> tq , sizeof ( jsmntok_t ) * ( max_tokens_total + 1 ) , 1 , BPLN ) ; if ( ! new_state -> jsmn_tokens ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; BP_DestroyLinkL ( tq , BP_TRUE ) ; return NULL ; } new_state -> jsmn_tokens_allocated_n = max_tokens_total ; new_state -> token_element_stack = ( P_BP_JSON_PARSE_TOKEN_ELEMENT ) tq_calloc ( new_state -> tq , sizeof ( BP_JSON_PARSE_TOKEN_ELEMENT ) * ( max_tokens_total + 1 ) , 1 , BPLN ) ; if ( ! new_state -> token_element_stack ) { BP_DestroyLinkL ( tq , BP_TRUE ) ; return NULL ; } new_state -> token_element_stack_items_allocated_n = max_tokens_total ; jsmn_init ( json , & new_state -> p ) ; int parse_token_cnt = jsmn_parse ( json , & new_state -> p , new_state -> buffer , new_state -> buffer_size , new_state -> jsmn_tokens , new_state -> jsmn_tokens_allocated_n ) ; if ( parse_token_cnt < 0 ) { switch ( parse_token_cnt ) { case JSMN_ERROR_INVAL : BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; break ; case JSMN_ERROR_NOMEM : BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; break ; case JSMN_ERROR_PART : BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; break ; default : BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; break ; } BP_DestroyLinkL ( tq , BP_TRUE ) ; return NULL ; } if ( parse_token_cnt == 0 ) { BP_JSONParseAddErrorMsg ( json , NULL , " " ) ; BP_DestroyLinkL ( tq , BP_TRUE ) ; return NULL ; } new_state -> parsed_token_count = ( size_t ) parse_token_cnt ; new_state -> parsed_tokens_remaining = new_state -> parsed_token_count ; return new_state ; }
Returns a parse state object to be used by the parser.
Returns a parse state object to be used by the parser .
// json structure check // ensure we have buffer and buffer size // ensure max depth and max tokens have been passed ok // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Create Parse State %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // create new tail queue allocator // create new parse state // set allocator internally // ---- set buffer --------- // duplicate buffer to parse from (prevents ptr shenanigans which could possibly occur during any threading) // set buffer size // ---- create token extractions -------------- // allocate space for jsmn tokens // ensure we have created our tokens // set the tokens allocated count // ---- create space for token element array ---- // allocate space for jsmn tokens // ensure we have created our tokens // set the item stack // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%% Init and Create Space Allocations for Parse %%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // initialize the parser // attempt json parse and get parse token count as integer // handle error val (less than zero is parse error) // printf("\n [!!] JSON parse failed due to bad parse."); // destroy jsmn tokens before exit // Handle zero error.  Zero indicates that parse was ok but object was empty. // printf("\n [!!] JSON parse failed due to zero token count."); // destroy jsmn_tokens before exit /*
	// check first token type
	if(new_state->jsmn_tokens[0].type != JSMN_OBJECT)
	{
		// printf("\n [!!] JSON parse failed due to zero token count.");
		// destroy jsmn_tokens before exit
		BP_JSONParseAddErrorMsg(json, NULL, "Parser failed reporting that JSON parsed ok, but the first token was somehow not an object.  Enusre that your json is wrapped in exterior {} characters.");
		BP_DestroyLinkL(tq, BP_TRUE);
		return NULL;

	}
	*/ // convert from int to size_t and assign here (previous negative value check ensure's value is within signed range) // set parsed_tokens_remaining item (same as count/decremented as parse occurs) // Due to calloc()/all other elements are set to zero/null automatically. // return the filled out state