From 5945af1f1b0f92877dd7e2fc959d95fa92d976f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Thu, 16 Sep 2021 22:08:05 +0200 Subject: not tested yet, but added parsing users: myself and friends --- src/api.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- src/h.c | 9 ++++++- src/lib.c | 5 ++++ 3 files changed, 77 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/api.c b/src/api.c index d76393b..850ae30 100644 --- a/src/api.c +++ b/src/api.c @@ -23,8 +23,9 @@ void dc_api_stack (struct dc_api_io i) { /* stack output struct to be delivered signed char dc_json_cb (struct lejp_ctx * ctx, char /* enum lejp_callbacks */ reason) { enum dc_json_paths path = ctx->path_match-1; /* we assume that the order of incoming data is */ struct dc_lws_pass * pass = ctx->user; /* correct. op should come first, etc. */ + struct dc_client * client = pass->api_io.client; + struct dc_program * program = pass->api_io.program; char * cp; - char buf[LEJP_MAX_PATH+1]; pass->json_reason = reason; if (reason == LEJPCB_FAILED) { DC_API_IO_GC(pass->api_io); @@ -32,7 +33,7 @@ signed char dc_json_cb (struct lejp_ctx * ctx, char /* enum lejp_callbacks */ re pass->parsing_status = NULL; return '\0'; } - fprintf(stderr, "JSON: %s reason: %d %.*s\n", ctx->path, reason, 40, pass->cp); + fprintf(stderr, "JSON: %s %s\n", ctx->path, ctx->buf); if (ctx->path_match && reason & LEJP_FLAG_CB_IS_VALUE) { switch (path) { case DC_JSON_S: /* packet sequence number */ @@ -50,35 +51,79 @@ signed char dc_json_cb (struct lejp_ctx * ctx, char /* enum lejp_callbacks */ re } return '\0'; } - if (pass->packet == DC_NONE) /* useless to do anything if we haven't received packet type */ + if ((cp = startswith(ctx->path, dc_json_paths[DC_JSON_ME]))) { + if (!client->user) { + DC_MR(program->users); /* we don't need DC_IN_PROGRESS cause we have ref in cl */ + program->users[program->users_length] = client->user = dc_user_init(); + } + if (reason & LEJPCB_OBJECT_END) { + pass->api_io.type = DC_API_USER; + dc_api_stack(pass->api_io); /* inform api user */ + } + if (reason & LEJP_FLAG_CB_IS_VALUE) + switch (cp[0]) { /* email is already set from login */ + case 'u': /* sername */ + free(client->user->username); + client->user->username = strdup(ctx->buf); + break; + case 'i': /* d */ + client->user->id = strtoull(ctx->buf, NULL, 10); + break; + case 'd': /* iscriminator */ + client->user->discriminator = atoi(ctx->buf); + break; + } + } + if ((cp == startswith(ctx->path, dc_json_paths[DC_JSON_FRIEND]))) { + if (!client->user) /* for the client user */ + client->user = dc_user_init(); + struct dc_user * user = client->user->next; /* client->user->next is 1. friend */ + if (reason == LEJPCB_OBJECT_START) { /* DC_JSON_FRIEND may not be an object*/ + if (!pass->api_io.user) /* for the newly found friend (-; */ + pass->api_io.user = dc_user_init(); + pass->api_io.user->status &= ~(DC_IN_PROGRESS); /* if we never get here again */ + } else { + free(pass->api_io.user); /* just in case */ + pass->api_io.user = NULL; + } + if (reason == LEJPCB_OBJECT_END) { + while (user->next) + user = user->next; + DC_MR(program->users); + program->users[program->users_length++] = user = user->next = pass->api_io.user; + pass->api_io.user->status &= ~(DC_IN_PROGRESS); + pass->api_io.type = DC_API_USER; + dc_api_stack(pass->api_io); /* inform api user */ + } + if (reason & LEJP_FLAG_CB_IS_VALUE) + switch(cp[0]) { + case 'u': /* sername */ + free(pass->api_io.user->username); /* yup, we don't trust serv */ + pass->api_io.user->username = strdup(ctx->buf); + break; + case 'i': /* d */ + pass->api_io.user->id = strtoll(ctx->buf, NULL, 10); + break; + case 'd': /* iscriminator */ + pass->api_io.user->discriminator = atoi(ctx->buf); + break; /* yeah, we don't care about nicknames */ + } + } + if (pass->packet == DC_NONE) /* useless to do anything BELOW if we haven't recvd packet type */ return '\0'; - if (reason == LEJPCB_COMPLETE) { /* gr8, fin, call back to api */ + if (reason == LEJPCB_COMPLETE) { /* NOT USED FOR ANYTHING, REMOVE */ if (!pass->parsing_status) { /* some stuff is fully handled in switch (pass->pkt) */ pass->packet = DC_NONE; return '\0'; } *pass->parsing_status &= ~DC_IN_PROGRESS; pass->api_io.status |= DC_FROM_LWS; - // dc_api_io(pass->api_io); /* not implemented, still testing */ + // dc_api_io(pass->api_io); /* WE'RE NOT DOING IT THIS WAY */ pass->api_io.status &= ~DC_FROM_LWS; pass->parsing_status = NULL; pass->packet = DC_NONE; return '\0'; } -#define DC_IF_NO_INIT(m) if (!pass->api_io.m) if ((pass->api_io.m = dc_##m##_init()) && (pass->api_io.m->path = strdup(ctx->path)) && (cp = strrchr(pass->api_io.m->path, '.'))) cp[0] = '\0'; -#define DC_IF_PATH_MATCHES(m) if (pass->api_io.m && pass->api_io.m->path && strcpy(buf, ctx->path) && (cp = strrchr(buf, '.')) && (cp[0] = '\0') && !strcmp(pass->api_io.m->path, buf)) - if (reason & LEJP_FLAG_CB_IS_VALUE) { - if (strstr(ctx->path, ".username")) { /* checking properties of user objects */ - DC_IF_NO_INIT(user); - pass->api_io.user->username = strdup(ctx->buf); - } else if (strstr(ctx->path, ".discriminator")) { - DC_IF_NO_INIT(user); - pass->api_io.user->discriminator = atoi(ctx->buf); - } else DC_IF_PATH_MATCHES(user) { - if (strstr(ctx->path, ".id")) - pass->api_io.user->discriminator = strtoull(ctx->buf, NULL, 10); - } else if (strstr(ctx->path, "")) - } switch (pass->packet) { /* we fill in structs, set DC_INCOMPLETE and pass->parsing_status */ case DC_PING: dc_handle_ping(pass->api_io, pass /* this is just so it's not NULL */); diff --git a/src/h.c b/src/h.c index 3e47408..4463f01 100644 --- a/src/h.c +++ b/src/h.c @@ -155,12 +155,18 @@ enum dc_json_paths { /* lws reduces the following char array to uint8_t, so we c DC_JSON_OP, /* packet type */ DC_JSON_S, /* packet sequence number */ DC_JSON_PING, /* interval */ + DC_JSON_ME, /* never useful in path parser, but startswith() checks if we're in object */ + DC_JSON_FRIEND, /* never useful in path parser, but startswith() checks if we're in object */ + DC_JSON_DM, /* never useful in path parser, but startswith() checks if we're in object */ DC_JSON_PATHS_LENGTH }; char * dc_json_paths[] = { /* array of paths we are interested in */ "op", "s", - "d.heartbeat_interval" + "d.heartbeat_interval", + "d.user", + "d.relationships[].user", + "d.private_channels[]" }; struct dc_lws_pass { /* struct that is allocated for in dc_lws_cb unique per connection in void * us */ DC_STRUCT_PREFIX @@ -324,6 +330,7 @@ struct dc_user { short int discriminator; enum dc_status status; char * path; /* yesfree, internal, so parser knows what object this user is from */ + struct dc_user * next; /* nofree, next friend in ll of friends, first is client->user->next */ }; struct dc_user * dc_user_init () { struct dc_user * s = calloc(1, sizeof(*s)); diff --git a/src/lib.c b/src/lib.c index e8d54b2..07d339d 100644 --- a/src/lib.c +++ b/src/lib.c @@ -10,3 +10,8 @@ int smprintf (char ** str, const char * format, ...) { /* allocates automaticall va_end(aq); return len; } +char * startswith (char * testiranec, char * začetek) { + if (!strncmp(testiranec, začetek, strlen(začetek))) + return testiranec+strlen(začetek); + return NULL; +} -- cgit v1.2.3