Skip to content

jsmn_parse in loop results: Object expected Error #181

@forest-roby

Description

@forest-roby

Dear All,
I am playing with JSMN for the first time. It is working for my purposes but I would like to run it in a loop, continouly updating information.
When I run the function for the first time everything works, after that in each loop I receive: Object expected error message.
here is the code: (you have to get your own api key )

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <conio.h>
#include <jsmn.h>

struct memory{
	char* memory;
	size_t size;
};

static size_t writecallback(char* contents, size_t size, size_t nmemb, void *userp){
	
	size_t realsize = size * nmemb;
	struct memory* mem = (struct memory*)userp;

	char *ptr = (char*) realloc(mem->memory, mem->size + realsize + 1); //VC++ miatt kell a (char*) a realloc elé.
	if (ptr == NULL)
		return(0);

	mem->memory = ptr;
	memcpy(&mem->memory[mem->size], contents, realsize);
	mem->size += realsize;
	mem->memory[mem->size] = 0;
	return realsize;

	//fprintf(stderr, "\r%s", contents);
	//fflush(stdout);
	//return size * nmemb;
}

//jsmn
static const char *JSON_STRING = "";

static int jsoneq(const char* json, jsmntok_t* tok, const char* s) {
	if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start &&
		strncmp(json + tok->start, s, tok->end - tok->start) == 0) {
		return 0;
	}
	return -1;
}
//JSMN vége


int get_coordinates(double *lat, double *lon, double *alt, double *azi, double *ele, double *_ra, double *_dec, long long *_times) {

	CURL* curl;
	CURLcode res;
	struct memory chunk;

	chunk.memory = NULL;
	chunk.size = 0;
	curl_global_init(CURL_GLOBAL_ALL);

	//jsmn rész
	int i = 0;
	int r = -1;
	jsmn_parser p;
	jsmntok_t t[500]; /* We expect no more than 128 tokens */
	//jsmn rész vége


	curl = curl_easy_init();
	if (curl) {
		curl_easy_setopt(curl, CURLOPT_URL, "https://www.n2yo.com/rest/v1/satellite/positions/25544/46.3185/17.7515/0/1/&apiKey=*HERE IS MY KEY*");
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecallback);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);

		res = curl_easy_perform(curl);
		if (res != CURLE_OK) {
			fprintf(stderr, "curl_easy_perform() returned %s\n",
				curl_easy_strerror(res));
		}
		else {
			//Itt töltöttük le az adatokat:
			//printf("We got %d bytes to our callback. We received the following text:\n\n", (int)chunk.size);
			printf("%s\n\n", chunk.memory);
			//
			//	JSMN próba
			//
			static const char* JSON_STRING = chunk.memory;

			jsmn_init(&p);
			r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t,
				sizeof(t) / sizeof(t[0]));
			if (r < 0) {
				printf("Failed to parse JSON: %d\n", r);
				return 1;
			}

			/* Assume the top-level element is an object */
			if (r < 1 || t[0].type != JSMN_OBJECT) {
				printf("Object expected\n");
				//printf("%d\n", r);
				//printf("%d\n", t[0]);
				return 1;
			}

			/* Loop over all keys of the root object */
			for (i = 1; i < r; i++) {
				if (jsoneq(JSON_STRING, &t[i], "user") == 0) {
					/* We may use strndup() to fetch string value */
					printf("- User: %.*s\n", t[i + 1].end - t[i + 1].start,
						JSON_STRING + t[i + 1].start);
					i++;
				}
				else if (jsoneq(JSON_STRING, &t[i], "admin") == 0) {
					/* We may additionally check if the value is either "true" or "false" */
					printf("- Admin: %.*s\n", t[i + 1].end - t[i + 1].start,
						JSON_STRING + t[i + 1].start);
					i++;
				}
				else if (jsoneq(JSON_STRING, &t[i], "uid") == 0) {
					/* We may want to do strtol() here to get numeric value */
					printf("- UID: %.*s\n", t[i + 1].end - t[i + 1].start,
						JSON_STRING + t[i + 1].start);
					i++;
				}
				else if (jsoneq(JSON_STRING, &t[i], "groups") == 0) {
					int j;
					printf("- Groups:\n");
					if (t[i + 1].type != JSMN_ARRAY) {
						continue; /* We expect groups to be an array of strings */
					}
					for (j = 0; j < t[i + 1].size; j++) {
						jsmntok_t* g = &t[i + j + 2];
						printf("  * %.*s\n", g->end - g->start, JSON_STRING + g->start);
					}
					i += t[i + 1].size + 1;
				}
				else {
					//
					//printf("%.*s, i: %d\n", t[i].end - t[i].start, JSON_STRING + t[i].start, i);
					//strncpy_s(tomb, t[i].end - t[i].start, JSON_STRING + t[i].start, t[i].end - t[i].start);
				}
			}
			//printf("% .*s: % .*s\n", t[1].end - t[1].start, JSON_STRING + t[1].start, t[2].end - t[2].start, JSON_STRING + t[2].start);
			//printf("% .*s: % .*s\n", t[5].end - t[5].start, JSON_STRING + t[5].start, t[6].end - t[6].start, JSON_STRING + t[6].start );
			//printf("% .*s: % .*s\n", t[7].end - t[7].start, JSON_STRING + t[7].start, t[8].end - t[8].start, JSON_STRING + t[8].start);

			sscanf_s((JSON_STRING + t[13].start), "%lf", lat);
			sscanf_s((JSON_STRING + t[15].start), "%lf", lon);
			sscanf_s((JSON_STRING + t[17].start), "%lf", alt);
			sscanf_s((JSON_STRING + t[19].start), "%lf", azi);
			sscanf_s((JSON_STRING + t[21].start), "%lf", ele);
			sscanf_s((JSON_STRING + t[23].start), "%lf", _ra);
			sscanf_s((JSON_STRING + t[25].start), "%lf", _dec);
			sscanf_s((JSON_STRING + t[27].start), "%d", _times);

			//
			//JSMN vége
			//
		}

		free(chunk.memory);
		curl_easy_cleanup(curl);

	}
	curl_global_cleanup();


return(0);
};





int main(void) {

	double latitude, longitude, altitude, azimuth, elevation, ra, dec;
	long long timestamp;
	int c = 1;

	//-------------------------------------------------------------------
		while (c != 'n')             // until correct key is pressed
		{
			do {                    // forever
				//do
	//
	get_coordinates(&latitude, &longitude, &altitude, &azimuth, &elevation, &ra, &dec, &timestamp);
	printf("\nLatitude:\t%lf", latitude);
	printf("\nLongitude:\t%lf", longitude);
	printf("\nAltitude:\t%lf", altitude);
	printf("\nAzimuth:\t%lf", azimuth);
	printf("\nElevation:\t%lf", elevation);
	printf("\nRa:\t\t%lf", ra);
	printf("\nDec:\t\t%lf", dec);
	printf("\nTimestamp:\t%ld", timestamp);
	printf("\n");
	//-------------------------------------------------------------------
			//do
			} while (!_kbhit());      // until a key press detected
			c = _getch();            // fetch that key press
		}
	//

	return(0);
}

(Visual Studio 2019, windows 10)

The received text looks like this:
{"info":{"satname":"SPACE STATION","satid":25544,"transactionscount":91},"positions":[{"satlatitude":-51.79721854,"satlongitude":-12.7783,"sataltitude":439.3,"azimuth":198.83,"elevation":-49.23,"ra":316.23335672,"dec":-77.09388627,"timestamp":1577393729}]}

I learned to program in C about 15 years ago in Linux - I was quite good at it and never used it since. I am sure the code is not elegant. First I want it to work.
I appreciate any help you can provide.

Robert

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions