Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jsmn_parse in loop results: Object expected Error #181

Open
forest-roby opened this issue Dec 26, 2019 · 1 comment
Open

jsmn_parse in loop results: Object expected Error #181

forest-roby opened this issue Dec 26, 2019 · 1 comment

Comments

@forest-roby
Copy link

forest-roby commented Dec 26, 2019

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

@forest-roby
Copy link
Author

forest-roby commented Dec 26, 2019

I was too hasty asking your help!
Farther bugging showed the error. Problem was with: JSON_STRING
This change helped:

static const char* JSON_STRING = NULL;
JSON_STRING = chunk.memory;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant