Exemplo n.º 1
0
static int unpack(scanner_t *s, json_t *root, va_list *ap)
{
    switch(s->token)
    {
        case '{':
            return unpack_object(s, root, ap);

        case '[':
            return unpack_array(s, root, ap);

        case 's':
            if(!json_is_string(root)) {
                set_error(s, "<validation>", "Expected string, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY)) {
                const char **str;

                str = va_arg(*ap, const char **);
                if(!str) {
                    set_error(s, "<args>", "NULL string argument");
                    return -1;
                }

                *str = json_string_value(root);
            }
            return 0;

        case 'i':
            if(!json_is_integer(root)) {
                set_error(s, "<validation>", "Expected integer, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY))
                *va_arg(*ap, int*) = (int) json_integer_value(root);

            return 0;

        case 'I':
            if(!json_is_integer(root)) {
                set_error(s, "<validation>", "Expected integer, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY))
                *va_arg(*ap, json_int_t*) = json_integer_value(root);

            return 0;

        case 'b':
            if(!json_is_boolean(root)) {
                set_error(s, "<validation>", "Expected true or false, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY))
                *va_arg(*ap, int*) = json_is_true(root);

            return 0;

        case 'f':
            if(!json_is_real(root)) {
                set_error(s, "<validation>", "Expected real, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY))
                *va_arg(*ap, double*) = json_real_value(root);

            return 0;

        case 'F':
            if(!json_is_number(root)) {
                set_error(s, "<validation>", "Expected real or integer, got %s",
                          type_name(root));
                return -1;
            }

            if(!(s->flags & JSON_VALIDATE_ONLY))
                *va_arg(*ap, double*) = json_number_value(root);

            return 0;

        case 'O':
            if(!(s->flags & JSON_VALIDATE_ONLY))
                json_incref(root);
            /* Fall through */

        case 'o':
            if(!(s->flags & JSON_VALIDATE_ONLY))
                *va_arg(*ap, json_t**) = root;

            return 0;

        case 'n':
            /* Never assign, just validate */
            if(!json_is_null(root)) {
                set_error(s, "<validation>", "Expected null, got %s",
                          type_name(root));
                return -1;
            }
            return 0;

        default:
            set_error(s, "<format>", "Unexpected format character '%c'",
                      s->token);
            return -1;
    }
}
Exemplo n.º 2
0
int VtUrlDist_parse(struct VtUrlDist* url_dist,
                    void (*cb)(const char *url, unsigned long long timestamp, int total, int positives, json_t *raw_json, void *data),
                    void *user_data) {
  json_t *resp_json, *url_obj;
  json_t *url_str_json, *timestamp_json, *total_json, *positives_json;
  unsigned int index;

  if (!url_dist || !url_dist->response) {
    VT_ERROR("No data recieved\n");
    return -1;
  }

  resp_json =  VtResponse_getJanssonObj(url_dist->response);

  if (!json_is_array(resp_json)) {
    VT_ERROR("JSON is not array\n");
    return -1;
  }

  json_array_foreach(resp_json, index, url_obj) {

    if (!json_is_object(url_obj)) {
      VT_ERROR("Parse error not a URL object\n");
      return -1;
    }

    url_str_json = json_object_get(url_obj, "url");
    if (!url_str_json || !json_is_string(url_str_json)) {
      VT_ERROR("Parse error: url string\n");
      return -1;
    }

    timestamp_json = json_object_get(url_obj, "timestamp");
    if (!timestamp_json || !json_is_integer(timestamp_json)) {
      VT_ERROR("JSON parse error timestamp\n");
      return -1;
    }

    total_json = json_object_get(url_obj, "total");
    if (!total_json || !json_is_integer(total_json)) {
      VT_ERROR("JSON parse error total\n");
      return -1;
    }

    positives_json = json_object_get(url_obj, "positives");
    if (!positives_json || !json_is_integer(positives_json)) {
      VT_ERROR("JSON parse error positives\n");
      return -1;
    }

    // set the after value, so if we do another query, we will not repeat the same data
    url_dist->after = json_integer_value(timestamp_json);

    // Call user defined callback function
    if (cb)
      cb(json_string_value(url_str_json), json_integer_value(timestamp_json),
         (int) json_integer_value(total_json), (int) json_integer_value(positives_json),
         url_obj, user_data);

  }

  return 0;
}
Exemplo n.º 3
0
/* Call the simple functions not covered by other tests of the public API */
static void run_tests()
{
    json_t *value;

    value = json_boolean(1);
    if(!json_is_true(value))
        fail("json_boolean(1) failed");
    json_decref(value);

    value = json_boolean(-123);
    if(!json_is_true(value))
        fail("json_boolean(-123) failed");
    json_decref(value);

    value = json_boolean(0);
    if(!json_is_false(value))
        fail("json_boolean(0) failed");
    json_decref(value);


    value = json_integer(1);
    if(json_typeof(value) != JSON_INTEGER)
        fail("json_typeof failed");

    if(json_is_object(value))
        fail("json_is_object failed");

    if(json_is_array(value))
        fail("json_is_array failed");

    if(json_is_string(value))
        fail("json_is_string failed");

    if(!json_is_integer(value))
        fail("json_is_integer failed");

    if(json_is_real(value))
        fail("json_is_real failed");

    if(!json_is_number(value))
        fail("json_is_number failed");

    if(json_is_true(value))
        fail("json_is_true failed");

    if(json_is_false(value))
        fail("json_is_false failed");

    if(json_is_boolean(value))
        fail("json_is_boolean failed");

    if(json_is_null(value))
        fail("json_is_null failed");

    json_decref(value);


    value = json_string("foo");
    if(!value)
        fail("json_string failed");
    if(strcmp(json_string_value(value), "foo"))
        fail("invalid string value");

    if(json_string_set(value, "bar"))
        fail("json_string_set failed");
    if(strcmp(json_string_value(value), "bar"))
        fail("invalid string value");

    json_decref(value);

    value = json_string(NULL);
    if(value)
        fail("json_string(NULL) failed");

    /* invalid UTF-8  */
    value = json_string("a\xefz");
    if(value)
        fail("json_string(<invalid utf-8>) failed");

    value = json_string_nocheck("foo");
    if(!value)
        fail("json_string_nocheck failed");
    if(strcmp(json_string_value(value), "foo"))
        fail("invalid string value");

    if(json_string_set_nocheck(value, "bar"))
        fail("json_string_set_nocheck failed");
    if(strcmp(json_string_value(value), "bar"))
        fail("invalid string value");

    json_decref(value);

    /* invalid UTF-8 */
    value = json_string_nocheck("qu\xff");
    if(!value)
        fail("json_string_nocheck failed");
    if(strcmp(json_string_value(value), "qu\xff"))
        fail("invalid string value");

    if(json_string_set_nocheck(value, "\xfd\xfe\xff"))
        fail("json_string_set_nocheck failed");
    if(strcmp(json_string_value(value), "\xfd\xfe\xff"))
        fail("invalid string value");

    json_decref(value);


    value = json_integer(123);
    if(!value)
        fail("json_integer failed");
    if(json_integer_value(value) != 123)
        fail("invalid integer value");
    if(json_number_value(value) != 123.0)
        fail("invalid number value");

    if(json_integer_set(value, 321))
        fail("json_integer_set failed");
    if(json_integer_value(value) != 321)
        fail("invalid integer value");
    if(json_number_value(value) != 321.0)
        fail("invalid number value");

    json_decref(value);

    value = json_real(123.123);
    if(!value)
        fail("json_real failed");
    if(json_real_value(value) != 123.123)
        fail("invalid integer value");
    if(json_number_value(value) != 123.123)
        fail("invalid number value");

    if(json_real_set(value, 321.321))
        fail("json_real_set failed");
    if(json_real_value(value) != 321.321)
        fail("invalid real value");
    if(json_number_value(value) != 321.321)
        fail("invalid number value");

    json_decref(value);

    value = json_true();
    if(!value)
        fail("json_true failed");
    json_decref(value);

    value = json_false();
    if(!value)
        fail("json_false failed");
    json_decref(value);

    value = json_null();
    if(!value)
        fail("json_null failed");
    json_decref(value);

    /* Test reference counting on singletons (true, false, null) */
    value = json_true();
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting true works incorrectly");

    value = json_false();
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting false works incorrectly");

    value = json_null();
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
    json_decref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
    json_incref(value);
    if(value->refcount != (size_t)-1)
      fail("refcounting null works incorrectly");
}
Exemplo n.º 4
0
void get_data(const char *recording, double start, double duration)
/*===============================================================*/
{
  int CHUNKSIZE = 10000 ;

  double *data = NULL ;
  int channels = 0 ;
  json_t *siguris = NULL ;

  const char *DATAFORMAT = STREAM_DOUBLE ;


  // Setup stream, set options (e.g. block size), add signals, etc,
  // then bsml_stream_start(strm)
  bsml_streamdata *strm = bsml_streamdata_request(recording, start, duration, DATAFORMAT, CHUNKSIZE) ;

  bsml_streamblock *sb ;
  int frameno = 0 ;

  while ((sb = bsml_streamdata_read(strm)) != NULL) {
#ifdef LOG_HEADER
    fprintf(stderr, "%s Block %c: %d\n  ", run_id, sb->type, sb->length) ;
    json_dumpf(sb->header, stderr, JSON_ENSURE_ASCII) ;
    fprintf(stderr, "\n") ;
#endif
    if      (sb->type == BSML_STREAM_ERROR_BLOCK) {
      fprintf(stderr, "ERROR: %-*s\n", sb->length, sb->content) ;
      }

    else if (sb->type == BSML_STREAM_INFO_BLOCK) {
      if (siguris) json_decref(siguris) ;
      siguris = json_object_get(sb->header, "signals") ;
      // Also have "channels" field (plus "rates" and "units").
      if (siguris && json_is_array(siguris)) {
        size_t n = json_array_size(siguris) ;
        json_incref(siguris) ;
        if (channels != n) {
          channels = n ;
          if (data) free(data) ;
          data = calloc(sizeof(double), channels*CHUNKSIZE) ;
          }
        }
      }

    else if (sb->type == BSML_STREAM_RDF_BLOCK) {

      }

    else if (sb->type == BSML_STREAM_DATA_BLOCK) {
      // Need to check rates match...
      // Or have rates in Info block and check when it's received...
      // What about signals where the rate changes??
      json_t *info = json_object_get(sb->header, "info") ;
      if (info && json_is_integer(info)) {
        int chan = json_integer_value(info) ;
        double *dp = data + chan ;
        double *cp = (double *)sb->content ;
        int l = sb->length/sizeof(double) ;
        while (l > 0) {
          *dp = *cp ;
          dp += channels ;
          ++cp ;
          --l ;
          }
        if (chan == (channels-1)) {
          double *dp = data ;
          int i ;
          l = sb->length/sizeof(double) ;
          while (l > 0) {
            printf("%d ", frameno) ;
            for (i = 0 ;  i < channels ;  ++i) {
              if (i > 0) printf(" ") ;
              printf("%8g", *dp) ;
              ++dp ;
              }
            printf("\n") ;
            ++frameno ;
            --l ;
            }
          }
        }
      // get dtype from sb->header
      // JSON *header ;
//      dtype *buffer = calloc(sb->length, sizeof(dtype)) ;
//      memcpy(buffer, (double *)sb->content, sb->length*sizeof(dtype)) ;
      }
    bsml_streamblock_free(sb) ;
    }

  if (strm->error != BSML_STREAM_ERROR_NONE)  // Always check for errors...
    fprintf(stderr, "ERROR %d: %s\n", strm->error, bsml_stream_error_text(strm->error)) ;


  bsml_streamdata_free(strm) ;
  if (data) free(data) ;
  if (siguris) json_decref(siguris) ;
  }
Exemplo n.º 5
0
/* Main Code */
int main(int argc, char *argv[])
{
	janus_log_init(FALSE, TRUE, NULL);

	/* Check the JANUS_PPREC_DEBUG environment variable for the debugging level */
	if(g_getenv("JANUS_PPREC_DEBUG") != NULL) {
		int val = atoi(g_getenv("JANUS_PPREC_DEBUG"));
		if(val > 0 && val < LOG_MAX)
			janus_log_level = val;
		JANUS_LOG(LOG_INFO, "Logging level: %d\n", janus_log_level);
	}
	
	/* Evaluate arguments */
	if(argc != 3) {
		JANUS_LOG(LOG_INFO, "Usage: %s source.mjr destination.[opus|webm]\n", argv[0]);
		JANUS_LOG(LOG_INFO, "       %s --header source.mjr (only parse header)\n", argv[0]);
		JANUS_LOG(LOG_INFO, "       %s --parse source.mjr (only parse and re-order packets)\n", argv[0]);
		return -1;
	}
	char *source = NULL, *destination = NULL;
	gboolean header_only = !strcmp(argv[1], "--header");
	gboolean parse_only = !strcmp(argv[1], "--parse");
	if(header_only || parse_only) {
		/* Only parse the .mjr header and/or re-order the packets, no processing */
		source = argv[2];
	} else {
		/* Post-process the .mjr recording */
		source = argv[1];
		destination = argv[2];
		JANUS_LOG(LOG_INFO, "%s --> %s\n", source, destination);
	}
	FILE *file = fopen(source, "rb");
	if(file == NULL) {
		JANUS_LOG(LOG_ERR, "Could not open file %s\n", source);
		return -1;
	}
	fseek(file, 0L, SEEK_END);
	long fsize = ftell(file);
	fseek(file, 0L, SEEK_SET);
	JANUS_LOG(LOG_INFO, "File is %zu bytes\n", fsize);

	/* Pre-parse */
	JANUS_LOG(LOG_INFO, "Pre-parsing file to generate ordered index...\n");
	gboolean parsed_header = FALSE;
	int video = 0;
	gint64 c_time = 0, w_time = 0;
	int bytes = 0, skip = 0;
	long offset = 0;
	uint16_t len = 0, count = 0;
	uint32_t last_ts = 0, reset = 0;
	int times_resetted = 0;
	uint32_t post_reset_pkts = 0;
	char prebuffer[1500];
	memset(prebuffer, 0, 1500);
	/* Let's look for timestamp resets first */
	while(offset < fsize) {
		if(header_only && parsed_header) {
			/* We only needed to parse the header */
			exit(0);
		}
		/* Read frame header */
		skip = 0;
		fseek(file, offset, SEEK_SET);
		bytes = fread(prebuffer, sizeof(char), 8, file);
		if(bytes != 8 || prebuffer[0] != 'M') {
			JANUS_LOG(LOG_WARN, "Invalid header at offset %ld (%s), the processing will stop here...\n",
				offset, bytes != 8 ? "not enough bytes" : "wrong prefix");
			break;
		}
		if(prebuffer[1] == 'E') {
			/* Either the old .mjr format header ('MEETECHO' header followed by 'audio' or 'video'), or a frame */
			offset += 8;
			bytes = fread(&len, sizeof(uint16_t), 1, file);
			len = ntohs(len);
			offset += 2;
			if(len == 5 && !parsed_header) {
				/* This is the main header */
				parsed_header = TRUE;
				JANUS_LOG(LOG_WARN, "Old .mjr header format\n");
				bytes = fread(prebuffer, sizeof(char), 5, file);
				if(prebuffer[0] == 'v') {
					JANUS_LOG(LOG_INFO, "This is a video recording, assuming VP8\n");
					video = 1;
				} else if(prebuffer[0] == 'a') {
					JANUS_LOG(LOG_INFO, "This is an audio recording, assuming Opus\n");
					video = 0;
				} else {
					JANUS_LOG(LOG_WARN, "Unsupported recording media type...\n");
					exit(1);
				}
				offset += len;
				continue;
			} else if(len < 12) {
				/* Not RTP, skip */
				JANUS_LOG(LOG_VERB, "Skipping packet (not RTP?)\n");
				offset += len;
				continue;
			}
		} else if(prebuffer[1] == 'J') {
			/* New .mjr format, the header may contain useful info */
			offset += 8;
			bytes = fread(&len, sizeof(uint16_t), 1, file);
			len = ntohs(len);
			offset += 2;
			if(len > 0 && !parsed_header) {
				/* This is the info header */
				JANUS_LOG(LOG_WARN, "New .mjr header format\n");
				bytes = fread(prebuffer, sizeof(char), len, file);
				parsed_header = TRUE;
				prebuffer[len] = '\0';
				json_error_t error;
				json_t *info = json_loads(prebuffer, 0, &error);
				if(!info) {
					JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
					JANUS_LOG(LOG_WARN, "Error parsing info header...\n");
					exit(1);
				}
				/* Is it audio or video? */
				json_t *type = json_object_get(info, "t");
				if(!type || !json_is_string(type)) {
					JANUS_LOG(LOG_WARN, "Missing/invalid recording type in info header...\n");
					exit(1);
				}
				const char *t = json_string_value(type);
				if(!strcasecmp(t, "v")) {
					video = 1;
				} else if(!strcasecmp(t, "a")) {
					video = 0;
				} else {
					JANUS_LOG(LOG_WARN, "Unsupported recording type '%s' in info header...\n", t);
					exit(1);
				}
				/* What codec was used? */
				json_t *codec = json_object_get(info, "c");
				if(!codec || !json_is_string(codec)) {
					JANUS_LOG(LOG_WARN, "Missing recording codec in info header...\n");
					exit(1);
				}
				const char *c = json_string_value(codec);
				if(video && strcasecmp(c, "vp8")) {
					JANUS_LOG(LOG_WARN, "The post-processor only suupports VP8 video for now (was '%s')...\n", c);
					exit(1);
				} else if(!video && strcasecmp(c, "opus")) {
					JANUS_LOG(LOG_WARN, "The post-processor only suupports Opus audio for now (was '%s')...\n", c);
					exit(1);
				}
				/* When was the file created? */
				json_t *created = json_object_get(info, "s");
				if(!created || !json_is_integer(created)) {
					JANUS_LOG(LOG_WARN, "Missing recording created time in info header...\n");
					exit(1);
				}
				c_time = json_integer_value(created);
				/* When was the first frame written? */
				json_t *written = json_object_get(info, "u");
				if(!written || !json_is_integer(written)) {
					JANUS_LOG(LOG_WARN, "Missing recording written time in info header...\n");
					exit(1);
				}
				w_time = json_integer_value(written);
				/* Summary */
				JANUS_LOG(LOG_INFO, "This is %s recording:\n", video ? "a video" : "an audio");
				JANUS_LOG(LOG_INFO, "  -- Codec:   %s\n", c);
				JANUS_LOG(LOG_INFO, "  -- Created: %"SCNi64"\n", c_time);
				JANUS_LOG(LOG_INFO, "  -- Written: %"SCNi64"\n", w_time);
			}
		} else {
			JANUS_LOG(LOG_ERR, "Invalid header...\n");
			exit(1);
		}
		/* Only read RTP header */
		bytes = fread(prebuffer, sizeof(char), 16, file);
		janus_pp_rtp_header *rtp = (janus_pp_rtp_header *)prebuffer;
		if(last_ts > 0) {
			/* Is the new timestamp smaller than the next one, and if so, is it a timestamp reset or simply out of order? */
			if(ntohl(rtp->timestamp) < last_ts && (last_ts-ntohl(rtp->timestamp) > 2*1000*1000*1000)) {
				reset = ntohl(rtp->timestamp);
				JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
				times_resetted++;
				post_reset_pkts = 0;
			} else if(ntohl(rtp->timestamp) < reset) {
				if(post_reset_pkts < 1000) {
					JANUS_LOG(LOG_WARN, "Updating latest timestamp reset: %"SCNu32" (was %"SCNu32")\n", ntohl(rtp->timestamp), reset);
					reset = ntohl(rtp->timestamp);
				} else {
					reset = ntohl(rtp->timestamp);
					JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
					times_resetted++;
					post_reset_pkts = 0;
				}
			}
		}
		last_ts = ntohl(rtp->timestamp);
		post_reset_pkts++;
		/* Skip data for now */
		offset += len;
	}
	JANUS_LOG(LOG_WARN, "Counted %d timestamp resets\n", times_resetted);
	/* Now let's parse the frames and order them */
	offset = 0;
	/* Timestamp reset related stuff */
	last_ts = 0;
	reset = 0;
	times_resetted = 0;
	post_reset_pkts = 0;
	uint64_t max32 = UINT32_MAX;
	/* Start loop */
	while(offset < fsize) {
		/* Read frame header */
		skip = 0;
		fseek(file, offset, SEEK_SET);
		bytes = fread(prebuffer, sizeof(char), 8, file);
		if(bytes != 8 || prebuffer[0] != 'M') {
			/* Broken packet? Stop here */
			break;
		}
		prebuffer[8] = '\0';
		JANUS_LOG(LOG_VERB, "Header: %s\n", prebuffer);
		offset += 8;
		bytes = fread(&len, sizeof(uint16_t), 1, file);
		len = ntohs(len);
		JANUS_LOG(LOG_VERB, "  -- Length: %"SCNu16"\n", len);
		offset += 2;
		if(prebuffer[1] == 'J' || len < 12) {
			/* Not RTP, skip */
			JANUS_LOG(LOG_VERB, "  -- Not RTP, skipping\n");
			offset += len;
			continue;
		}
		if(len > 2000) {
			/* Way too large, very likely not RTP, skip */
			JANUS_LOG(LOG_VERB, "  -- Too large packet (%d bytes), skipping\n", len);
			offset += len;
			continue;
		}
		/* Only read RTP header */
		bytes = fread(prebuffer, sizeof(char), 16, file);
		janus_pp_rtp_header *rtp = (janus_pp_rtp_header *)prebuffer;
		JANUS_LOG(LOG_VERB, "  -- RTP packet (ssrc=%"SCNu32", pt=%"SCNu16", ext=%"SCNu16", seq=%"SCNu16", ts=%"SCNu32")\n",
				ntohl(rtp->ssrc), rtp->type, rtp->extension, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
		if(rtp->extension) {
			janus_pp_rtp_header_extension *ext = (janus_pp_rtp_header_extension *)(prebuffer+12);
		JANUS_LOG(LOG_VERB, "  -- -- RTP extension (type=%"SCNu16", length=%"SCNu16")\n",
				ntohs(ext->type), ntohs(ext->length)); 
			skip = 4 + ntohs(ext->length)*4;
		}
		/* Generate frame packet and insert in the ordered list */
		janus_pp_frame_packet *p = g_malloc0(sizeof(janus_pp_frame_packet));
		if(p == NULL) {
			JANUS_LOG(LOG_ERR, "Memory error!\n");
			return -1;
		}
		p->seq = ntohs(rtp->seq_number);
		/* Due to resets, we need to mess a bit with the original timestamps */
		if(last_ts == 0) {
			/* Simple enough... */
			p->ts = ntohl(rtp->timestamp);
		} else {
			/* Is the new timestamp smaller than the next one, and if so, is it a timestamp reset or simply out of order? */
			if(ntohl(rtp->timestamp) < last_ts && (last_ts-ntohl(rtp->timestamp) > 2*1000*1000*1000)) {
				reset = ntohl(rtp->timestamp);
				JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
				times_resetted++;
				post_reset_pkts = 0;
			} else if(ntohl(rtp->timestamp) < reset) {
				if(post_reset_pkts < 1000) {
					JANUS_LOG(LOG_WARN, "Updating latest timestamp reset: %"SCNu32" (was %"SCNu32")\n", ntohl(rtp->timestamp), reset);
					reset = ntohl(rtp->timestamp);
				} else {
					reset = ntohl(rtp->timestamp);
					JANUS_LOG(LOG_WARN, "Timestamp reset: %"SCNu32"\n", reset);
					times_resetted++;
					post_reset_pkts = 0;
				}
			}
			/* Take into account the number of resets when setting the internal, 64-bit, timestamp */
			p->ts = (times_resetted*max32)+ntohl(rtp->timestamp);
		}
		p->len = len;
		p->drop = 0;
		if(rtp->padding) {
			/* There's padding data, let's check the last byte to see how much data we should skip */
			fseek(file, offset + len - 1, SEEK_SET);
			fread(prebuffer, sizeof(char), 1, file);
			uint8_t padlen = (uint8_t)prebuffer[0];
			JANUS_LOG(LOG_VERB, "Padding at sequence number %hu: %d/%d\n",
				ntohs(rtp->seq_number), padlen, p->len);
			p->len -= padlen;
			if((p->len - skip - 12) <= 0) {
				/* Only padding, take note that we should drop the packet later */
				p->drop = 1;
				JANUS_LOG(LOG_VERB, "  -- All padding, marking packet as dropped\n");
			}
		}
		last_ts = ntohl(rtp->timestamp);
		post_reset_pkts++;
		/* Fill in the rest of the details */
		p->offset = offset;
		p->skip = skip;
		p->next = NULL;
		p->prev = NULL;
		if(list == NULL) {
			/* First element becomes the list itself (and the last item), at least for now */
			list = p;
			last = p;
		} else {
			/* Check where we should insert this, starting from the end */
			int added = 0;
			janus_pp_frame_packet *tmp = last;
			while(tmp) {
				if(tmp->ts < p->ts) {
					/* The new timestamp is greater than the last one we have, append */
					added = 1;
					if(tmp->next != NULL) {
						/* We're inserting */
						tmp->next->prev = p;
						p->next = tmp->next;
					} else {
						/* Update the last packet */
						last = p;
					}
					tmp->next = p;
					p->prev = tmp;
					break;
				} else if(tmp->ts == p->ts) {
					/* Same timestamp, check the sequence number */
					if(tmp->seq < p->seq && (abs(tmp->seq - p->seq) < 10000)) {
						/* The new sequence number is greater than the last one we have, append */
						added = 1;
						if(tmp->next != NULL) {
							/* We're inserting */
							tmp->next->prev = p;
							p->next = tmp->next;
						} else {
							/* Update the last packet */
							last = p;
						}
						tmp->next = p;
						p->prev = tmp;
						break;
					} else if(tmp->seq > p->seq && (abs(tmp->seq - p->seq) > 10000)) {
						/* The new sequence number (resetted) is greater than the last one we have, append */
						added = 1;
						if(tmp->next != NULL) {
							/* We're inserting */
							tmp->next->prev = p;
							p->next = tmp->next;
						} else {
							/* Update the last packet */
							last = p;
						}
						tmp->next = p;
						p->prev = tmp;
						break;
					}
				}
				/* If either the timestamp ot the sequence number we just got is smaller, keep going back */
				tmp = tmp->prev;
			}
			if(!added) {
				/* We reached the start */
				p->next = list;
				list->prev = p;
				list = p;
			}
		}
		/* Skip data for now */
		offset += len;
		count++;
	}
	
	JANUS_LOG(LOG_INFO, "Counted %"SCNu16" RTP packets\n", count);
	janus_pp_frame_packet *tmp = list;
	count = 0;
	while(tmp) {
		count++;
		JANUS_LOG(LOG_VERB, "[%10lu][%4d] seq=%"SCNu16", ts=%"SCNu64", time=%"SCNu64"s\n", tmp->offset, tmp->len, tmp->seq, tmp->ts, (tmp->ts-list->ts)/90000);
		tmp = tmp->next;
	}
	JANUS_LOG(LOG_INFO, "Counted %"SCNu16" frame packets\n", count);

	if(parse_only) {
		/* We only needed to parse and re-order the packets, we're done here */
		exit(0);
	}

	if(!video) {
		/* We don't need any pre-parsing for audio */
		if(janus_pp_opus_create(destination) < 0) {
			JANUS_LOG(LOG_ERR, "Error creating .opus file...\n");
			exit(1);
		}
	} else {
		/* Look for maximum width and height, and for the mean framerate */
		if(janus_pp_webm_preprocess(file, list) < 0) {
			JANUS_LOG(LOG_ERR, "Error pre-processing VP8 RTP frames...\n");
			exit(1);
		}
		/* Now we can write the WebM file */
		if(janus_pp_webm_create(destination) < 0) {
			JANUS_LOG(LOG_ERR, "Error creating .webm file...\n");
			exit(1);
		}
	}
	
	/* Handle SIGINT */
	signal(SIGINT, janus_pp_handle_signal);

	/* Loop */
	working = 1;
	if(!video) {
		if(janus_pp_opus_process(file, list, &working) < 0) {
			JANUS_LOG(LOG_ERR, "Error processing Opus RTP frames...\n");
		}
	} else {
		if(janus_pp_webm_process(file, list, &working) < 0) {
			JANUS_LOG(LOG_ERR, "Error processing VP8 RTP frames...\n");
		}
	}

	/* Clean up */
	if(video) {
		janus_pp_webm_close();
	} else {
		janus_pp_opus_close();
	}
	fclose(file);
	
	file = fopen(destination, "rb");
	if(file == NULL) {
		JANUS_LOG(LOG_INFO, "No destination file %s??\n", destination);
	} else {
		fseek(file, 0L, SEEK_END);
		fsize = ftell(file);
		fseek(file, 0L, SEEK_SET);
		JANUS_LOG(LOG_INFO, "%s is %zu bytes\n", destination, fsize);
		fclose(file);
	}
	janus_pp_frame_packet *temp = list, *next = NULL;
	while(temp) {
		next = temp->next;
		g_free(temp);
		temp = next;
	}

	JANUS_LOG(LOG_INFO, "Bye!\n");

	janus_log_destroy();

	return 0;
}
Exemplo n.º 6
0
static int
avro_schema_from_json_t(json_t *json, avro_schema_t *schema,
			st_table *named_schemas)
{
#ifdef _WIN32
 #pragma message("#warning: Bug: '0' is not of type avro_type_t.")
#else
 #warning "Bug: '0' is not of type avro_type_t."
#endif
  /* We should really have an "AVRO_INVALID" type in
   * avro_type_t. Suppress warning below in which we set type to 0.
   */
	avro_type_t type = (avro_type_t) 0;
	unsigned int i;
	avro_schema_t named_type = NULL;

	if (avro_type_from_json_t(json, &type, named_schemas, &named_type)) {
		return EINVAL;
	}

	switch (type) {
	case AVRO_LINK:
		*schema = avro_schema_link(named_type);
		break;

	case AVRO_STRING:
		*schema = avro_schema_string();
		break;

	case AVRO_BYTES:
		*schema = avro_schema_bytes();
		break;

	case AVRO_INT32:
		*schema = avro_schema_int();
		break;

	case AVRO_INT64:
		*schema = avro_schema_long();
		break;

	case AVRO_FLOAT:
		*schema = avro_schema_float();
		break;

	case AVRO_DOUBLE:
		*schema = avro_schema_double();
		break;

	case AVRO_BOOLEAN:
		*schema = avro_schema_boolean();
		break;

	case AVRO_NULL:
		*schema = avro_schema_null();
		break;

	case AVRO_RECORD:
		{
			json_t *json_name = json_object_get(json, "name");
			json_t *json_namespace =
			    json_object_get(json, "namespace");
			json_t *json_fields = json_object_get(json, "fields");
			unsigned int num_fields;
			const char *record_name;
			const char *record_namespace;

			if (!json_is_string(json_name)) {
				avro_set_error("Record type must have a \"name\"");
				return EINVAL;
			}
			if (!json_is_array(json_fields)) {
				avro_set_error("Record type must have \"fields\"");
				return EINVAL;
			}
			num_fields = json_array_size(json_fields);
			if (num_fields == 0) {
				avro_set_error("Record type must have at least one field");
				return EINVAL;
			}
			record_name = json_string_value(json_name);
			if (!record_name) {
				avro_set_error("Record type must have a \"name\"");
				return EINVAL;
			}
			if (json_is_string(json_namespace)) {
				record_namespace =
				    json_string_value(json_namespace);
			} else {
				record_namespace = NULL;
			}
			*schema =
			    avro_schema_record(record_name, record_namespace);
			if (save_named_schemas(record_name, *schema, named_schemas)) {
				avro_set_error("Cannot save record schema");
				return ENOMEM;
			}
			for (i = 0; i < num_fields; i++) {
				json_t *json_field =
				    json_array_get(json_fields, i);
				json_t *json_field_name;
				json_t *json_field_type;
				json_t *json_field_default;
				avro_schema_t json_field_type_schema;
				int field_rval;

				if (!json_is_object(json_field)) {
					avro_set_error("Record field %d must be an object", i);
					avro_schema_decref(*schema);
					return EINVAL;
				}
				json_field_name =
				    json_object_get(json_field, "name");
				if (!json_field_name) {
					avro_set_error("Record field %d must have a \"name\"", i);
					avro_schema_decref(*schema);
					return EINVAL;
				}
				json_field_type =
				    json_object_get(json_field, "type");
				if (!json_field_type) {
					avro_set_error("Record field %d must have a \"type\"", i);
					avro_schema_decref(*schema);
					return EINVAL;
				}
				json_field_default =
				    json_object_get(json_field, "default");
				field_rval =
				    avro_schema_from_json_t(json_field_type,
							    &json_field_type_schema,
							    named_schemas);
				if (field_rval) {
					avro_schema_decref(*schema);
					return field_rval;
				}
				field_rval =
				    avro_schema_record_field_append(*schema,
								    json_string_value
								    (json_field_name),
								    json_field_type_schema);
				if (field_rval) {
					avro_schema_decref(*schema);
					return field_rval;
				}
                                if (json_field_default) {
                                    field_rval =
                                        avro_schema_record_field_default_set_by_index(*schema,
                                                                                      i,
                                                                                      json_field_default);
                                }
				avro_schema_decref(json_field_type_schema);
				if (field_rval != 0) {
					avro_schema_decref(*schema);
					return field_rval;
				}
			}
		}
		break;

	case AVRO_ENUM:
		{
			json_t *json_name = json_object_get(json, "name");
			json_t *json_symbols = json_object_get(json, "symbols");
			const char *name;
			unsigned int num_symbols;

			if (!json_is_string(json_name)) {
				avro_set_error("Enum type must have a \"name\"");
				return EINVAL;
			}
			if (!json_is_array(json_symbols)) {
				avro_set_error("Enum type must have \"symbols\"");
				return EINVAL;
			}

			name = json_string_value(json_name);
			if (!name) {
				avro_set_error("Enum type must have a \"name\"");
				return EINVAL;
			}
			num_symbols = json_array_size(json_symbols);
			if (num_symbols == 0) {
				avro_set_error("Enum type must have at least one symbol");
				return EINVAL;
			}
			*schema = avro_schema_enum(name);
			if (save_named_schemas(name, *schema, named_schemas)) {
				avro_set_error("Cannot save enum schema");
				return ENOMEM;
			}
			for (i = 0; i < num_symbols; i++) {
				int enum_rval;
				json_t *json_symbol =
				    json_array_get(json_symbols, i);
				const char *symbol;
				if (!json_is_string(json_symbol)) {
					avro_set_error("Enum symbol %d must be a string", i);
					avro_schema_decref(*schema);
					return EINVAL;
				}
				symbol = json_string_value(json_symbol);
				enum_rval =
				    avro_schema_enum_symbol_append(*schema,
								   symbol);
				if (enum_rval != 0) {
					avro_schema_decref(*schema);
					return enum_rval;
				}
			}
		}
		break;

	case AVRO_ARRAY:
		{
			int items_rval;
			json_t *json_items = json_object_get(json, "items");
			avro_schema_t items_schema;
			if (!json_items) {
				avro_set_error("Array type must have \"items\"");
				return EINVAL;
			}
			items_rval =
			    avro_schema_from_json_t(json_items, &items_schema,
						    named_schemas);
			if (items_rval) {
				return items_rval;
			}
			*schema = avro_schema_array(items_schema);
			avro_schema_decref(items_schema);
		}
		break;

	case AVRO_MAP:
		{
			int values_rval;
			json_t *json_values = json_object_get(json, "values");
			avro_schema_t values_schema;

			if (!json_values) {
				avro_set_error("Map type must have \"values\"");
				return EINVAL;
			}
			values_rval =
			    avro_schema_from_json_t(json_values, &values_schema,
						    named_schemas);
			if (values_rval) {
				return values_rval;
			}
			*schema = avro_schema_map(values_schema);
			avro_schema_decref(values_schema);
		}
		break;

	case AVRO_UNION:
		{
			unsigned int num_schemas = json_array_size(json);
			avro_schema_t s;
			if (num_schemas == 0) {
				avro_set_error("Union type must have at least one branch");
				return EINVAL;
			}
			*schema = avro_schema_union();
			for (i = 0; i < num_schemas; i++) {
				int schema_rval;
				json_t *schema_json = json_array_get(json, i);
				if (!schema_json) {
					avro_set_error("Cannot retrieve branch JSON");
					return EINVAL;
				}
				schema_rval =
				    avro_schema_from_json_t(schema_json, &s,
							    named_schemas);
				if (schema_rval != 0) {
					avro_schema_decref(*schema);
					return schema_rval;
				}
				schema_rval =
				    avro_schema_union_append(*schema, s);
				avro_schema_decref(s);
				if (schema_rval != 0) {
					avro_schema_decref(*schema);
					return schema_rval;
				}
			}
		}
		break;

	case AVRO_FIXED:
		{
			json_t *json_size = json_object_get(json, "size");
			json_t *json_name = json_object_get(json, "name");
			json_int_t size;
			const char *name;
			if (!json_is_integer(json_size)) {
				avro_set_error("Fixed type must have a \"size\"");
				return EINVAL;
			}
			if (!json_is_string(json_name)) {
				avro_set_error("Fixed type must have a \"name\"");
				return EINVAL;
			}
			size = json_integer_value(json_size);
			name = json_string_value(json_name);
			*schema = avro_schema_fixed(name, (int64_t) size);
			if (save_named_schemas(name, *schema, named_schemas)) {
				avro_set_error("Cannot save fixed schema");
				return ENOMEM;
			}
		}
		break;

	default:
		avro_set_error("Unknown schema type");
		return EINVAL;
	}
	return 0;
}
Exemplo n.º 7
0
static void test_misc()
{
    json_t *object, *string, *other_string, *value;

    object = json_object();
    string = json_string("test");
    other_string = json_string("other");

    if(!object)
        fail("unable to create object");
    if(!string || !other_string)
        fail("unable to create string");

    if(json_object_get(object, "a"))
        fail("value for nonexisting key");

    if(json_object_set(object, "a", string))
        fail("unable to set value");

    if(!json_object_set(object, NULL, string))
        fail("able to set NULL key");

    if(!json_object_set(object, "a", NULL))
        fail("able to set NULL value");

    /* invalid UTF-8 in key */
    if(!json_object_set(object, "a\xefz", string))
        fail("able to set invalid unicode key");

    value = json_object_get(object, "a");
    if(!value)
        fail("no value for existing key");
    if(value != string)
        fail("got different value than what was added");

    /* "a", "lp" and "px" collide in a five-bucket hashtable */
    if(json_object_set(object, "b", string) ||
            json_object_set(object, "lp", string) ||
            json_object_set(object, "px", string))
        fail("unable to set value");

    value = json_object_get(object, "a");
    if(!value)
        fail("no value for existing key");
    if(value != string)
        fail("got different value than what was added");

    if(json_object_set(object, "a", other_string))
        fail("unable to replace an existing key");

    value = json_object_get(object, "a");
    if(!value)
        fail("no value for existing key");
    if(value != other_string)
        fail("got different value than what was set");

    if(!json_object_del(object, "nonexisting"))
        fail("able to delete a nonexisting key");

    if(json_object_del(object, "px"))
        fail("unable to delete an existing key");

    if(json_object_del(object, "a"))
        fail("unable to delete an existing key");

    if(json_object_del(object, "lp"))
        fail("unable to delete an existing key");


    /* add many keys to initiate rehashing */

    if(json_object_set(object, "a", string))
        fail("unable to set value");

    if(json_object_set(object, "lp", string))
        fail("unable to set value");

    if(json_object_set(object, "px", string))
        fail("unable to set value");

    if(json_object_set(object, "c", string))
        fail("unable to set value");

    if(json_object_set(object, "d", string))
        fail("unable to set value");

    if(json_object_set(object, "e", string))
        fail("unable to set value");


    if(json_object_set_new(object, "foo", json_integer(123)))
        fail("unable to set new value");

    value = json_object_get(object, "foo");
    if(!json_is_integer(value) || json_integer_value(value) != 123)
        fail("json_object_set_new works incorrectly");

    if(!json_object_set_new(object, NULL, json_integer(432)))
        fail("able to set_new NULL key");

    if(!json_object_set_new(object, "foo", NULL))
        fail("able to set_new NULL value");

    json_decref(string);
    json_decref(other_string);
    json_decref(object);
}
Exemplo n.º 8
0
Arquivo: pull.c Projeto: Memeo/lounge
int la_pull_run(la_pull_t *puller)
{
    CURLcode ret;
    json_t *changes;
    json_error_t json_error;
    long status;
    int i, len;

    if (init_changes_feed(puller) != 0)
        return -1;
    
    ret = curl_easy_perform(puller->curl);
    if (ret != CURLE_OK)
    {
        debug("curl_easy_perform %d\n", ret);
        return -1;
    }
    
    if (curl_easy_getinfo(puller->curl, CURLINFO_RESPONSE_CODE, &status) != CURLE_OK)
    {
        return -1;
    }
    curl_easy_cleanup(puller->curl);
       
    if (status != 200)
    {
        debug("got response code %ld\n", status);
        return -1;
    }
        
    changes = json_loadb(la_buffer_data(puller->buffer), la_buffer_size(puller->buffer), 0, &json_error);
    la_buffer_clear(puller->buffer);
    if (changes == NULL || !json_is_object(changes))
        return -1;
    
    if (puller->last_seq != NULL)
        free(puller->last_seq);
    puller->last_seq = NULL;
    json_t *last_seq = json_object_get(changes, "last_seq");
    if (last_seq != NULL)
        puller->last_seq = json_dumps(last_seq, 0);
    
    json_t *results = json_object_get(changes, "results");
    if (results == NULL || !json_is_array(results))
    {
        json_decref(changes);
        return -1;
    }

    len = json_array_size(results);
    debug("got %d changes\n", len);
    for (i = 0; i < len; i++)
    {
        la_codec_error_t codec_error;
        la_db_get_result ret;
        la_rev_t rev, thatrev;
        json_t *key, *changes_array, *change_obj, *revobj, *seq;
        json_t *change = json_array_get(results, i);
        if (change == NULL || !json_is_object(change))
            continue;
        key = json_object_get(change, "id");
        if (key == NULL || !json_is_string(key))
            continue;
        debug("handling document %s\n", json_string_value(key));
        seq = json_object_get(change, "seq");
        if (seq == NULL || (!json_is_integer(seq) && !json_is_string(seq)))
            continue;
        changes_array = json_object_get(change, "changes");
        if (changes_array == NULL || !json_is_array(changes_array) || json_array_size(changes_array) == 0)
            continue;
        change_obj = json_array_get(changes_array, 0);
        if (change_obj == NULL || !json_is_object(change_obj))
            continue;
        revobj = json_object_get(change_obj, "rev");
        if (revobj == NULL || !json_is_string(revobj))
            continue;
        debug("changed revision %s\n", json_string_value(revobj));
        la_rev_scan(json_string_value(revobj), &thatrev);
        ret = la_db_get(puller->db, json_string_value(key), NULL, NULL, &rev, &codec_error);
        if (ret == LA_DB_GET_ERROR)
            continue;
        debug("get local result %d rev %s\n", ret, ret == LA_DB_GET_OK ? la_rev_string(rev) : "");
        if (ret == LA_DB_GET_NOT_FOUND || memcmp(&rev.rev.rev, &thatrev.rev.rev, LA_OBJECT_REVISION_LEN) != 0)
        {
            // Rev is missing, fetch it.
            la_codec_error_t codec_error;
            la_buffer_t *urlbuf = la_buffer_new(256);
            char *path = url_encode(json_string_value(key));
            la_buffer_appendf(urlbuf, "%s/%s?revs=true&rev=%s", puller->urlbase, path, json_string_value(revobj));
            char *url = la_buffer_string(urlbuf);
            free(path);
            
            debug("fetching %s\n", url);
            la_buffer_destroy(urlbuf);
            CURL *fetch = curl_easy_init();
            la_storage_rev_t *remote_revs = NULL;
            la_storage_rev_t *local_revs = NULL;
            uint64_t mystart;
            int j, revslen;
            
            if (fetch == NULL)
            {
                free(url);
                continue;
            }
            
            if (curl_easy_setopt(fetch, CURLOPT_URL, url) != CURLE_OK)
            {
                free(url);
                curl_easy_cleanup(fetch);
                continue;
            }
            free(url);
            if (puller->user != NULL)
            {
                if (curl_easy_setopt(fetch, CURLOPT_USERNAME, puller->user) != CURLE_OK)
                {
                    curl_easy_cleanup(fetch);
                    continue;
                }
            }
            if (puller->password != NULL)
            {
                if (curl_easy_setopt(fetch, CURLOPT_USERPWD, puller->password) != CURLE_OK)
                {
                    curl_easy_cleanup(fetch);
                    continue;
                }
            }
            curl_easy_setopt(fetch, CURLOPT_WRITEFUNCTION, pull_write_cb);
            curl_easy_setopt(fetch, CURLOPT_WRITEDATA, puller);
            if (curl_easy_perform(fetch) != CURLE_OK)
            {
                curl_easy_cleanup(fetch);
                continue;
            }
            curl_easy_cleanup(fetch);
            
            json_t *object = json_loadb(la_buffer_data(puller->buffer), la_buffer_size(puller->buffer), 0, &json_error);
            la_buffer_clear(puller->buffer);
            if (object == NULL || !json_is_object(object))
            {
                debug("didn't get object back from server %p %d\n", object, object ? json_typeof(object) : -1);
                debug("%s", json_error.text);
                continue;
            }
            
            json_t *_revisions = json_object_get(object, "_revisions");
            if (_revisions == NULL || !json_is_object(_revisions))
            {
                debug("didn't find _revisions\n");
                json_decref(object);
                continue;
            }
            json_incref(_revisions);
            json_object_del(object, "_revisions");
            
            json_t *_revisions_start = json_object_get(_revisions, "start");
            if (_revisions_start == NULL || !json_is_integer(_revisions_start))
            {
                debug("didn't find revisions/start\n");
                json_decref(_revisions);
                json_decref(object);
                continue;
            }
            
            json_t *_revisions_ids = json_object_get(_revisions, "ids");
            if (_revisions_ids == NULL || !json_is_array(_revisions_ids))
            {
                debug("didn't find revisions/ids\n");
                json_decref(_revisions);
                json_decref(object);
                continue;
            }
            
            revslen = json_array_size(_revisions_ids);
            debug("%d remote revisions\n", revslen);
            remote_revs = malloc(sizeof(la_storage_rev_t) * revslen);
            if (remote_revs == NULL)
            {
                json_decref(_revisions);
                json_decref(object);
                continue;
            }
            for (j = 0; j < revslen; j++)
            {
                la_storage_scan_rev(json_string_value(json_array_get(_revisions_ids, j)), &remote_revs[j]);
            }

            // Fetch local revisions of the object, if it exists.
            int myrevcount = 0;
            if (ret == LA_DB_GET_OK)
            {
                myrevcount = la_db_get_allrevs(puller->db, json_string_value(key), &mystart, &local_revs);
                
                if (myrevcount > 0 && local_revs != NULL)
                {
                    la_storage_rev_t *r = realloc(local_revs, (myrevcount + 1) * sizeof(la_storage_rev_t));
                    if (r == NULL)
                    {
                        json_decref(_revisions);
                        json_decref(object);
                        free(local_revs);
                        continue;
                    }
                    local_revs = r;
                    memmove(&local_revs[1], local_revs, sizeof(la_storage_rev_t) * myrevcount);
                    myrevcount++;
                }
                else
                {
                    local_revs = malloc(sizeof(la_storage_rev_t));
                    if (local_revs == NULL)
                    {
                        json_decref(object);
                        continue;
                    }
                    myrevcount = 1;
                }
                memcpy(&local_revs[0], &rev.rev, sizeof(la_storage_rev_t));
            }
            else
            {
                // If it doesn't exist, just set it.
                debug("value never there, just adding it\n");
                la_codec_value_t *value = la_codec_from_json(object);
                la_db_put_result putresult = la_db_replace(puller->db, json_string_value(key), &thatrev, value, &remote_revs[1], revslen - 1);
                if (putresult != LA_DB_PUT_OK)
                {
                    debug("failed to add the doc %d\n", putresult);
                }
                la_codec_decref(value);
                json_decref(object);
                json_decref(_revisions);
                continue;
            }
            
            // There will be three cases:
            //
            //  1. Our current version is part of the history of the remote version (we are behind).
            //     To resolve, take the remote version and the history.
            //
            //  2. Our history contains (some of) the remote history (we are ahead).
            //     To resolve, do nothing.
            //
            //  3. Our history diverges (we have a fork).
            //     To resolve, invoke the conflict handler.
            
            if (la_storage_revs_overlap(local_revs, myrevcount, remote_revs, revslen))
            {
                debug("overwriting local version\n");
                free(local_revs);
                // Just insert the document and revision history.
                la_codec_value_t *value = la_codec_from_json(object);
                la_db_replace(puller->db, json_string_value(key), &thatrev, value, &remote_revs[1], revslen - 1);
                la_codec_decref(value);
            }
            else if (!la_storage_revs_overlap(remote_revs, revslen, local_revs, myrevcount))
            {
                debug("handling conflict...\n");
                free(local_revs);
                // We are conflicting.
                la_codec_value_t *myvalue;
                if (la_db_get(puller->db, json_string_value(key), NULL, &myvalue, NULL, &codec_error) != LA_DB_GET_OK)
                {
                    la_codec_decref(myvalue);
                    json_decref(_revisions);
                    json_decref(object);
                    continue;
                }
                la_codec_value_t *theirvalue = la_codec_from_json(object);
                la_codec_value_t *mergedvalue = NULL;
                
                switch (puller->resolver(json_string_value(key), myvalue, theirvalue, &mergedvalue, puller->resolver_baton))
                {
                    case LA_PULL_RESOLVE_TAKE_MINE:
                        break; // Nothing
                        
                    case LA_PULL_RESOLVE_TAKE_THEIRS:
                        la_db_replace(puller->db, json_string_value(key), &thatrev, theirvalue, &remote_revs[1], revslen - 1);
                        break;
                        
                    case LA_PULL_RESOLVE_TAKE_MERGED:
                        la_db_put(puller->db, json_string_value(key), &rev, mergedvalue, NULL);
                        break;
                }
                
                la_codec_decref(myvalue);
                la_codec_decref(theirvalue);
                if (mergedvalue != NULL)
                    la_codec_decref(mergedvalue);
                free(remote_revs);
            }
            else
            {
                debug("doing nothing, we are ahead of the server");
            }
            // Otherwise, we are ahead. Do nothing.
        }
    }
    json_decref(changes);
 
    if ((puller->options & LA_PULL_CONTINUOUS) != 0)
    {
        init_changes_feed(puller);
    }
    return 0;
}
Exemplo n.º 9
0
bool ParamComboBox :: SetValueFromJSON (const json_t * const value_p)
{
	bool success_flag  = false;

	switch (bpw_param_p -> pa_type)
		{
			case PT_STRING:
			case PT_FILE_TO_READ:
			case PT_FILE_TO_WRITE:
			case PT_DIRECTORY:
				{
					if (json_is_string (value_p))
						{
							const char *value_s = json_string_value (value_p);

							pcb_combo_box_p -> setCurrentText (value_s);
							success_flag  = true;
						}
				}
				break;

			case PT_CHAR:
				{
					if (json_is_string (value_p))
						{
							const char *value_s = json_string_value (value_p);
							char c [2];

							*c = *value_s;
							* (c + 1) = '\0';

							pcb_combo_box_p -> setCurrentText (c);
							success_flag  = true;
						}
				}
				break;

			case PT_BOOLEAN:
				{
					if (json_is_true (value_p))
						{
							pcb_combo_box_p -> setCurrentText ("true");
						}
					else if (json_is_true (value_p))
						{
							pcb_combo_box_p -> setCurrentText ("false");
						}
				}
				break;

			case PT_SIGNED_INT:
			case PT_UNSIGNED_INT:
				{
					if (json_is_integer (value_p))
						{
							QString s;
							int value = json_integer_value (value_p);

							s.setNum (value);
							pcb_combo_box_p -> setCurrentText (s);

							success_flag = true;
						}
				}
				break;

			case PT_SIGNED_REAL:
			case PT_UNSIGNED_REAL:
				{
					if (json_is_number (value_p))
						{
							QString s;
							double value = json_number_value (value_p);

							s.setNum (value);
							pcb_combo_box_p -> setCurrentText (s);

							success_flag = true;
						}
				}
				break;

			default:
				break;
		}


	return success_flag;
}
Exemplo n.º 10
0
/* Thread to handle incoming messages */
static void *janus_echotest_handler(void *data) {
	JANUS_LOG(LOG_VERB, "Joining EchoTest handler thread\n");
	janus_echotest_message *msg = NULL;
	int error_code = 0;
	char *error_cause = g_malloc0(512);
	if(error_cause == NULL) {
		JANUS_LOG(LOG_FATAL, "Memory error!\n");
		return NULL;
	}
	json_t *root = NULL;
	while(g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
		msg = g_async_queue_pop(messages);
		if(msg == NULL)
			continue;
		if(msg == &exit_message)
			break;
		if(msg->handle == NULL) {
			janus_echotest_message_free(msg);
			continue;
		}
		janus_echotest_session *session = NULL;
		janus_mutex_lock(&sessions_mutex);
		if(g_hash_table_lookup(sessions, msg->handle) != NULL ) {
			session = (janus_echotest_session *)msg->handle->plugin_handle;
		}
		janus_mutex_unlock(&sessions_mutex);
		if(!session) {
			JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
			janus_echotest_message_free(msg);
			continue;
		}
		if(session->destroyed) {
			janus_echotest_message_free(msg);
			continue;
		}
		/* Handle request */
		error_code = 0;
		root = NULL;
		JANUS_LOG(LOG_VERB, "Handling message: %s\n", msg->message);
		if(msg->message == NULL) {
			JANUS_LOG(LOG_ERR, "No message??\n");
			error_code = JANUS_ECHOTEST_ERROR_NO_MESSAGE;
			g_snprintf(error_cause, 512, "%s", "No message??");
			goto error;
		}
		json_error_t error;
		root = json_loads(msg->message, 0, &error);
		if(!root) {
			JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
			error_code = JANUS_ECHOTEST_ERROR_INVALID_JSON;
			g_snprintf(error_cause, 512, "JSON error: on line %d: %s", error.line, error.text);
			goto error;
		}
		if(!json_is_object(root)) {
			JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
			error_code = JANUS_ECHOTEST_ERROR_INVALID_JSON;
			g_snprintf(error_cause, 512, "JSON error: not an object");
			goto error;
		}
		/* Parse request */
		json_t *audio = json_object_get(root, "audio");
		if(audio && !json_is_boolean(audio)) {
			JANUS_LOG(LOG_ERR, "Invalid element (audio should be a boolean)\n");
			error_code = JANUS_ECHOTEST_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (audio should be a boolean)");
			goto error;
		}
		json_t *video = json_object_get(root, "video");
		if(video && !json_is_boolean(video)) {
			JANUS_LOG(LOG_ERR, "Invalid element (video should be a boolean)\n");
			error_code = JANUS_ECHOTEST_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (video should be a boolean)");
			goto error;
		}
		json_t *bitrate = json_object_get(root, "bitrate");
		if(bitrate && (!json_is_integer(bitrate) || json_integer_value(bitrate) < 0)) {
			JANUS_LOG(LOG_ERR, "Invalid element (bitrate should be a positive integer)\n");
			error_code = JANUS_ECHOTEST_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (bitrate should be a positive integer)");
			goto error;
		}
		json_t *record = json_object_get(root, "record");
		if(record && !json_is_boolean(record)) {
			JANUS_LOG(LOG_ERR, "Invalid element (record should be a boolean)\n");
			error_code = JANUS_ECHOTEST_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (record should be a boolean)");
			goto error;
		}
		json_t *recfile = json_object_get(root, "filename");
		if(recfile && !json_is_string(recfile)) {
			JANUS_LOG(LOG_ERR, "Invalid element (filename should be a string)\n");
			error_code = JANUS_ECHOTEST_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (filename should be a string)");
			goto error;
		}
		/* Enforce request */
		if(audio) {
			session->audio_active = json_is_true(audio);
			JANUS_LOG(LOG_VERB, "Setting audio property: %s\n", session->audio_active ? "true" : "false");
		}
		if(video) {
			if(!session->video_active && json_is_true(video)) {
				/* Send a PLI */
				JANUS_LOG(LOG_VERB, "Just (re-)enabled video, sending a PLI to recover it\n");
				char buf[12];
				memset(buf, 0, 12);
				janus_rtcp_pli((char *)&buf, 12);
				gateway->relay_rtcp(session->handle, 1, buf, 12);
			}
			session->video_active = json_is_true(video);
			JANUS_LOG(LOG_VERB, "Setting video property: %s\n", session->video_active ? "true" : "false");
		}
		if(bitrate) {
			session->bitrate = json_integer_value(bitrate);
			JANUS_LOG(LOG_VERB, "Setting video bitrate: %"SCNu64"\n", session->bitrate);
			if(session->bitrate > 0) {
				/* FIXME Generate a new REMB (especially useful for Firefox, which doesn't send any we can cap later) */
				char buf[24];
				memset(buf, 0, 24);
				janus_rtcp_remb((char *)&buf, 24, session->bitrate);
				JANUS_LOG(LOG_VERB, "Sending REMB\n");
				gateway->relay_rtcp(session->handle, 1, buf, 24);
				/* FIXME How should we handle a subsequent "no limit" bitrate? */
			}
		}
		if(record) {
			if(msg->sdp) {
				session->has_audio = (strstr(msg->sdp, "m=audio") != NULL);
				session->has_video = (strstr(msg->sdp, "m=video") != NULL);
			}
			gboolean recording = json_is_true(record);
			const char *recording_base = json_string_value(recfile);
			JANUS_LOG(LOG_VERB, "Recording %s (base filename: %s)\n", recording ? "enabled" : "disabled", recording_base ? recording_base : "not provided");
			if(!recording) {
				/* Not recording (anymore?) */
				if(session->arc) {
					janus_recorder_close(session->arc);
					JANUS_LOG(LOG_INFO, "Closed audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
					janus_recorder_free(session->arc);
				}
				session->arc = NULL;
				if(session->vrc) {
					janus_recorder_close(session->vrc);
					JANUS_LOG(LOG_INFO, "Closed video recording %s\n", session->vrc->filename ? session->vrc->filename : "??");
					janus_recorder_free(session->vrc);
				}
				session->vrc = NULL;
			} else {
				/* We've started recording, send a PLI and go on */
				char filename[255];
				gint64 now = janus_get_real_time();
				if(session->has_audio) {
					/* FIXME We assume we're recording Opus, here */
					memset(filename, 0, 255);
					if(recording_base) {
						/* Use the filename and path we have been provided */
						g_snprintf(filename, 255, "%s-audio", recording_base);
						session->arc = janus_recorder_create(NULL, "opus", filename);
						if(session->arc == NULL) {
							/* FIXME We should notify the fact the recorder could not be created */
							JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this EchoTest user!\n");
						}
					} else {
						/* Build a filename */
						g_snprintf(filename, 255, "echotest-%p-%"SCNi64"-audio", session, now);
						session->arc = janus_recorder_create(NULL, "opus", filename);
						if(session->arc == NULL) {
							/* FIXME We should notify the fact the recorder could not be created */
							JANUS_LOG(LOG_ERR, "Couldn't open an audio recording file for this EchoTest user!\n");
						}
					}
				}
				if(session->has_video) {
					/* FIXME We assume we're recording VP8, here */
					memset(filename, 0, 255);
					if(recording_base) {
						/* Use the filename and path we have been provided */
						g_snprintf(filename, 255, "%s-video", recording_base);
						session->vrc = janus_recorder_create(NULL, "vp8", filename);
						if(session->vrc == NULL) {
							/* FIXME We should notify the fact the recorder could not be created */
							JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this EchoTest user!\n");
						}
					} else {
						/* Build a filename */
						g_snprintf(filename, 255, "echotest-%p-%"SCNi64"-video", session, now);
						session->vrc = janus_recorder_create(NULL, "vp8", filename);
						if(session->vrc == NULL) {
							/* FIXME We should notify the fact the recorder could not be created */
							JANUS_LOG(LOG_ERR, "Couldn't open an video recording file for this EchoTest user!\n");
						}
					}
					/* Send a PLI */
					JANUS_LOG(LOG_VERB, "Recording video, sending a PLI to kickstart it\n");
					char buf[12];
					memset(buf, 0, 12);
					janus_rtcp_pli((char *)&buf, 12);
					gateway->relay_rtcp(session->handle, 1, buf, 12);
				}
			}
		}
		/* Any SDP to handle? */
		if(msg->sdp) {
			JANUS_LOG(LOG_VERB, "This is involving a negotiation (%s) as well:\n%s\n", msg->sdp_type, msg->sdp);
			session->has_audio = (strstr(msg->sdp, "m=audio") != NULL);
			session->has_video = (strstr(msg->sdp, "m=video") != NULL);
		}

		if(!audio && !video && !bitrate && !record && !msg->sdp) {
			JANUS_LOG(LOG_ERR, "No supported attributes (audio, video, bitrate, record, jsep) found\n");
			error_code = JANUS_ECHOTEST_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Message error: no supported attributes (audio, video, bitrate, record, jsep) found");
			goto error;
		}

		json_decref(root);
		/* Prepare JSON event */
		json_t *event = json_object();
		json_object_set_new(event, "echotest", json_string("event"));
		json_object_set_new(event, "result", json_string("ok"));
		char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
		json_decref(event);
		JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
		if(!msg->sdp) {
			int ret = gateway->push_event(msg->handle, &janus_echotest_plugin, msg->transaction, event_text, NULL, NULL);
			JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
		} else {
			/* Forward the same offer to the gateway, to start the echo test */
			const char *type = NULL;
			if(!strcasecmp(msg->sdp_type, "offer"))
				type = "answer";
			if(!strcasecmp(msg->sdp_type, "answer"))
				type = "offer";
			/* Any media direction that needs to be fixed? */
			char *sdp = g_strdup(msg->sdp);
			if(strstr(sdp, "a=recvonly")) {
				/* Turn recvonly to inactive, as we simply bounce media back */
				sdp = janus_string_replace(sdp, "a=recvonly", "a=inactive");
			} else if(strstr(sdp, "a=sendonly")) {
				/* Turn sendonly to recvonly */
				sdp = janus_string_replace(sdp, "a=sendonly", "a=recvonly");
				/* FIXME We should also actually not echo this media back, though... */
			}
			/* Make also sure we get rid of ULPfec, red, etc. */
			if(strstr(sdp, "ulpfec")) {
				/* FIXME This really needs some better code */
				sdp = janus_string_replace(sdp, "a=rtpmap:116 red/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:117 ulpfec/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:96 rtx/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=fmtp:96 apt=100\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:97 rtx/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=fmtp:97 apt=101\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:98 rtx/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=fmtp:98 apt=116\r\n", "");
				sdp = janus_string_replace(sdp, " 116", "");
				sdp = janus_string_replace(sdp, " 117", "");
				sdp = janus_string_replace(sdp, " 96", "");
				sdp = janus_string_replace(sdp, " 97", "");
				sdp = janus_string_replace(sdp, " 98", "");
			}
			/* How long will the gateway take to push the event? */
			g_atomic_int_set(&session->hangingup, 0);
			gint64 start = janus_get_monotonic_time();
			int res = gateway->push_event(msg->handle, &janus_echotest_plugin, msg->transaction, event_text, type, sdp);
			JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (took %"SCNu64" us)\n",
				res, janus_get_monotonic_time()-start);
			g_free(sdp);
		}
		g_free(event_text);
		janus_echotest_message_free(msg);
		continue;
		
error:
		{
			if(root != NULL)
				json_decref(root);
			/* Prepare JSON error event */
			json_t *event = json_object();
			json_object_set_new(event, "echotest", json_string("event"));
			json_object_set_new(event, "error_code", json_integer(error_code));
			json_object_set_new(event, "error", json_string(error_cause));
			char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
			json_decref(event);
			JANUS_LOG(LOG_VERB, "Pushing event: %s\n", event_text);
			int ret = gateway->push_event(msg->handle, &janus_echotest_plugin, msg->transaction, event_text, NULL, NULL);
			JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
			g_free(event_text);
			janus_echotest_message_free(msg);
		}
	}
	g_free(error_cause);
	JANUS_LOG(LOG_VERB, "Leaving EchoTest handler thread\n");
	return NULL;
}
Exemplo n.º 11
0
/**
 * Loads the settings for a specific account using the given key
 * If no settings file exists for the given user, defaults are created
 *
 * @param login         Access to the account sync dir
 * @param ppSettings    Location to store ptr to allocated settings (caller must free)
 * @param pError        A pointer to the location to store the error if there is one
 */
tABC_CC ABC_AccountSettingsLoad(const Login &login,
                                tABC_AccountSettings **ppSettings,
                                tABC_Error *pError)
{
    tABC_CC cc = ABC_CC_Ok;
    AutoCoreLock lock(gCoreMutex);

    tABC_AccountSettings *pSettings = NULL;
    json_t *pJSON_Root = NULL;
    json_t *pJSON_Value = NULL;
    bool bExists = false;
    auto filename = login.syncDir() + ACCOUNT_SETTINGS_FILENAME;

    ABC_CHECK_NULL(ppSettings);

    ABC_CHECK_RET(ABC_FileIOFileExists(filename.c_str(), &bExists, pError));
    if (true == bExists)
    {
        // load and decrypted the file into a json object
        ABC_CHECK_RET(ABC_CryptoDecryptJSONFileObject(filename.c_str(),
            toU08Buf(login.dataKey()), &pJSON_Root, pError));
        //ABC_DebugLog("Loaded settings JSON:\n%s\n", json_dumps(pJSON_Root, JSON_INDENT(4) | JSON_PRESERVE_ORDER));

        // allocate the new settings object
        ABC_NEW(pSettings, tABC_AccountSettings);
        pSettings->szFirstName = NULL;
        pSettings->szLastName = NULL;
        pSettings->szNickname = NULL;

        // get the first name
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_FIRST_NAME_FIELD);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT(json_is_string(pJSON_Value), ABC_CC_JSONError, "Error parsing JSON string value");
            ABC_STRDUP(pSettings->szFirstName, json_string_value(pJSON_Value));
        }

        // get the last name
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_LAST_NAME_FIELD);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT(json_is_string(pJSON_Value), ABC_CC_JSONError, "Error parsing JSON string value");
            ABC_STRDUP(pSettings->szLastName, json_string_value(pJSON_Value));
        }

        // get the nickname
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_NICKNAME_FIELD);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT(json_is_string(pJSON_Value), ABC_CC_JSONError, "Error parsing JSON string value");
            ABC_STRDUP(pSettings->szNickname, json_string_value(pJSON_Value));
        }

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_PIN_FIELD);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT(json_is_string(pJSON_Value), ABC_CC_JSONError, "Error parsing JSON string value");
            ABC_STRDUP(pSettings->szPIN, json_string_value(pJSON_Value));
        }

        // get name on payments option
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_NAME_ON_PAYMENTS_FIELD);
        ABC_CHECK_ASSERT((pJSON_Value && json_is_boolean(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON boolean value");
        pSettings->bNameOnPayments = json_is_true(pJSON_Value) ? true : false;

        // get minutes auto logout
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_MINUTES_AUTO_LOGOUT_FIELD);
        ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON integer value");
        pSettings->minutesAutoLogout = (int) json_integer_value(pJSON_Value);

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_RECOVERY_REMINDER_COUNT);
        if (pJSON_Value) {
            ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON integer value");
            pSettings->recoveryReminderCount = (int) json_integer_value(pJSON_Value);
        } else {
            pSettings->recoveryReminderCount = 0;
        }

        // get language
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_LANGUAGE_FIELD);
        ABC_CHECK_ASSERT((pJSON_Value && json_is_string(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON string value");
        ABC_STRDUP(pSettings->szLanguage, json_string_value(pJSON_Value));

        // get currency num
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_NUM_CURRENCY_FIELD);
        ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON integer value");
        pSettings->currencyNum = (int) json_integer_value(pJSON_Value);

        // get advanced features
        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_ADVANCED_FEATURES_FIELD);
        ABC_CHECK_ASSERT((pJSON_Value && json_is_boolean(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON boolean value");
        pSettings->bAdvancedFeatures = json_is_true(pJSON_Value) ? true : false;

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_DAILY_SPEND_LIMIT_ENABLED);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT((pJSON_Value && json_is_boolean(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON boolean value");
            pSettings->bDailySpendLimit = json_is_true(pJSON_Value) ? true : false;
        }
        else
        {
            pSettings->bDailySpendLimit = false;
        }

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_DAILY_SPEND_LIMIT_SATOSHIS);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON daily spend satoshi value");
            pSettings->dailySpendLimitSatoshis = (int64_t) json_integer_value(pJSON_Value);
        }
        else
        {
            pSettings->dailySpendLimitSatoshis = 0;
        }

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_SPEND_REQUIRE_PIN_ENABLED);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT((pJSON_Value && json_is_boolean(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON boolean value");
            pSettings->bSpendRequirePin = json_is_true(pJSON_Value) ? true : false;
        }
        else
        {
            // Default to PIN required
            pSettings->bSpendRequirePin = true;
        }

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_DISABLE_PIN_LOGIN);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT((pJSON_Value && json_is_boolean(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON boolean value");
            pSettings->bDisablePINLogin = json_is_true(pJSON_Value) ? true : false;
        }
        else
        {
            // Default to PIN login allowed
            pSettings->bDisablePINLogin = false;
        }

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_PIN_LOGIN_COUNT);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON pin login count");
            pSettings->pinLoginCount = json_integer_value(pJSON_Value);
        }
        else
        {
            // Default to PIN login allowed
            pSettings->pinLoginCount = 0;
        }

        pJSON_Value = json_object_get(pJSON_Root, JSON_ACCT_SPEND_REQUIRE_PIN_SATOSHIS);
        if (pJSON_Value)
        {
            ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON daily spend satoshi value");
            pSettings->spendRequirePinSatoshis = (int64_t) json_integer_value(pJSON_Value);
        }
        else
        {
            // Default PIN requirement to 50mb
            pSettings->spendRequirePinSatoshis = DEF_REQUIRE_PIN_SATOSHIS;
        }


        // get the denomination object
        json_t *pJSON_Denom = json_object_get(pJSON_Root, JSON_ACCT_BITCOIN_DENOMINATION_FIELD);
        ABC_CHECK_ASSERT((pJSON_Denom && json_is_object(pJSON_Denom)), ABC_CC_JSONError, "Error parsing JSON object value");

        // get denomination satoshi display size (e.g., 100,000 would be milli-bit coin)
        pJSON_Value = json_object_get(pJSON_Denom, JSON_ACCT_SATOSHI_FIELD);
        ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON integer value");
        pSettings->bitcoinDenomination.satoshi = json_integer_value(pJSON_Value);

        // get denomination type
        pJSON_Value = json_object_get(pJSON_Denom, JSON_ACCT_LABEL_TYPE);
        ABC_CHECK_ASSERT((pJSON_Value && json_is_integer(pJSON_Value)), ABC_CC_JSONError, "Error parsing JSON integer value");
        pSettings->bitcoinDenomination.denominationType = json_integer_value(pJSON_Value);

        // get the exchange rates array
        json_t *pJSON_Sources = json_object_get(pJSON_Root, JSON_ACCT_EX_RATE_SOURCES_FIELD);
        ABC_CHECK_ASSERT((pJSON_Sources && json_is_array(pJSON_Sources)), ABC_CC_JSONError, "Error parsing JSON array value");

        // get the number of elements in the array
        pSettings->exchangeRateSources.numSources = (int) json_array_size(pJSON_Sources);
        if (pSettings->exchangeRateSources.numSources > 0)
        {
            ABC_ARRAY_NEW(pSettings->exchangeRateSources.aSources,
                          pSettings->exchangeRateSources.numSources, tABC_ExchangeRateSource*);
        }
Exemplo n.º 12
0
void read_config(void)
{
	json_t *jcfg, *cred_expire;
	json_error_t err;
	const char *tmp_str, *rpcuser, *rpcpass;
	char *file_data;

	file_data = read_commented_file(srv.config);
	if (!file_data)
		exit(1);

	jcfg = json_loads(file_data, &err);

	free(file_data);

	if (!jcfg) {
		applog(LOG_ERR, "%s: JSON parse failed", srv.config);
		exit(1);
	}

	if (!json_is_object(jcfg)) {
		applog(LOG_ERR, "top-level JSON value not an object");
		exit(1);
	}

	parse_listen(json_object_get(jcfg, "listen"));
	parse_database(json_object_get(jcfg, "database"));
	parse_memcached(json_object_get(jcfg, "memcached"));

	if (elist_empty(&srv.listeners)) {
		applog(LOG_ERR, "error: no listen addresses specified");
		exit(1);
	}

	tmp_str = json_string_value(json_object_get(jcfg, "pid"));
	if (tmp_str)
		srv.pid_file = strdup(tmp_str);

	tmp_str = json_string_value(json_object_get(jcfg, "forcehost"));
	if (tmp_str)
		srv.ourhost = strdup(tmp_str);

	tmp_str = json_string_value(json_object_get(jcfg, "log.requests"));
	if (tmp_str) {
		srv.req_log = strdup(tmp_str);
		srv.req_fd = open(srv.req_log,
				  O_WRONLY | O_CREAT | O_APPEND, 0666);
		if (srv.req_fd < 0) {
			syslogerr(srv.req_log);
			exit(1);
		}
	}

	tmp_str = json_string_value(json_object_get(jcfg, "log.shares"));
	if (tmp_str) {
		srv.share_log = strdup(tmp_str);
		srv.share_fd = open(srv.share_log,
				  O_WRONLY | O_CREAT | O_APPEND, 0666);
		if (srv.share_fd < 0) {
			syslogerr(srv.share_log);
			exit(1);
		}
	}

	if (json_is_true(json_object_get(jcfg, "longpoll.disable")))
		srv.disable_lp = true;

	cred_expire = json_object_get(jcfg, "auth.cred_cache.expire");
	if (json_is_integer(cred_expire))
		srv.cred_expire = json_integer_value(cred_expire);

	tmp_str = json_string_value(json_object_get(jcfg, "rpc.url"));
	if (!tmp_str) {
		applog(LOG_ERR, "error: no RPC URL specified");
		exit(1);
	}
	srv.rpc_url = strdup(tmp_str);

	rpcuser = json_string_value(json_object_get(jcfg, "rpc.user"));
	rpcpass = json_string_value(json_object_get(jcfg, "rpc.pass"));
	if (!rpcuser || !rpcpass) {
		applog(LOG_ERR, "error: no RPC user and/or password specified");
		exit(1);
	}
	if (asprintf(&srv.rpc_userpass, "%s:%s", rpcuser, rpcpass) < 0) {
		applog(LOG_ERR, "OOM");
		exit(1);
	}

	if (json_is_true(json_object_get(jcfg, "rpc.target.rewrite")))
		srv.easy_target = json_string(EASY_TARGET);

	if (!srv.pid_file) {
		if (!(srv.pid_file = strdup("/var/run/pushpoold.pid"))) {
			applog(LOG_ERR, "no core");
			exit(1);
		}
	}

	json_decref(jcfg);
}
Exemplo n.º 13
0
static void parse_database(const json_t *db_obj)
{
	const json_t *tmp;
	const char *db_host, *db_name, *db_un, *db_pw, *db_st_pwdb, *db_st_sharelog, *tmp_str;
	int db_port = -1;

	if (!json_is_object(db_obj))
		return;

	tmp_str = json_string_value(json_object_get(db_obj, "engine"));
	if (tmp_str) {
		if (0) {
#ifdef HAVE_SQLITE3 /**/
		} else if (!strcmp(tmp_str, "sqlite3")) {
			srv.db_eng = SDB_SQLITE;
			srv.db_ops = &sqlite_db_ops;
#endif
#ifdef HAVE_MYSQL
		} else if (!strcmp(tmp_str, "mysql")) {
			srv.db_eng = SDB_MYSQL;
			srv.db_ops = &mysql_db_ops;
#endif
#ifdef HAVE_POSTGRESQL
		} else if (!strcmp(tmp_str, "postgresql")) {
			srv.db_eng = SDB_POSTGRESQL;
			srv.db_ops = &postgresql_db_ops;
#endif
		} else {
			applog(LOG_ERR, "invalid database.engine");
			exit(1);
		}
	}

	db_host = json_string_value(json_object_get(db_obj, "host"));
	tmp = json_object_get(db_obj, "port");
	if (json_is_integer(tmp)) {
		db_port = json_integer_value(tmp);
		if (db_port < 1 || db_port > 65535) {
			applog(LOG_ERR, "invalid database port");
			exit(1);
		}
	}

	db_name = json_string_value(json_object_get(db_obj, "name"));
	db_un = json_string_value(json_object_get(db_obj, "username"));
	db_pw = json_string_value(json_object_get(db_obj, "password"));
	srv.db_sharelog = (json_is_true(json_object_get(db_obj, "sharelog"))) ?
		true : false;

	switch (srv.db_eng) {

	case SDB_SQLITE:
		if (db_host || db_port >= 0 || db_un || db_pw) {
			applog(LOG_ERR, "sqlite does not support database host"
			       ", port, username or password");
			exit(1);
		}
		if (!db_name || (*db_name != '/')) {
			applog(LOG_ERR, "missing or invalid database.name");
			exit(1);
		}

		srv.db_name = strdup(db_name);
		break;

	default:
		if (!db_host)
			db_host = "localhost";
		if (db_port < 0)
			db_port = -1;
		if (!db_name || !db_un || !db_pw) {
			applog(LOG_ERR, "missing database name, user or pass");
			exit(1);
		}

		srv.db_host = strdup(db_host);
		srv.db_port = db_port;
		srv.db_name = strdup(db_name);
		srv.db_username = strdup(db_un);
		srv.db_password = strdup(db_pw);
		break;
	}

	db_st_pwdb = json_string_value(json_object_get(db_obj, "stmt.pwdb"));
	if (db_st_pwdb)
		srv.db_stmt_pwdb = strdup(db_st_pwdb);
	db_st_sharelog = json_string_value(
		json_object_get(db_obj, "stmt.sharelog"));
	if (db_st_sharelog)
		srv.db_stmt_sharelog = strdup(db_st_sharelog);
}
Exemplo n.º 14
0
static json_t *
cmd_update_screen(json_t * params, int display_only)
{
    static struct nh_dbuf_entry dbuf[ROWNO][COLNO];
    int ux, uy;
    int x, y, effect, bg, trap, obj, obj_mn, mon, monflags, branding, invis,
        visible;
    json_t *jdbuf, *col, *elem;

    if (json_unpack(params, "{si,si,so!}", "ux", &ux, "uy", &uy, "dbuf", &jdbuf)
        == -1) {
        print_error("Incorrect parameters in cmd_update_screen");
        return NULL;
    }

    if (json_is_integer(jdbuf)) {
        if (json_integer_value(jdbuf) == 0) {
            memset(dbuf, 0, sizeof (struct nh_dbuf_entry) * ROWNO * COLNO);
            cur_wndprocs.win_update_screen(dbuf, ux, uy);
        } else
            print_error("Incorrect parameter in cmd_update_screen");
        return NULL;
    }

    if (!json_is_array(jdbuf)) {
        print_error("Incorrect parameter in cmd_update_screen");
        return NULL;
    }

    if (json_array_size(jdbuf) != COLNO)
        print_error("Wrong number of columns in cmd_update_screen");
    for (x = 0; x < COLNO; x++) {
        col = json_array_get(jdbuf, x);
        if (json_is_integer(col)) {
            if (json_integer_value(col) == 0) {
                for (y = 0; y < ROWNO; y++)
                    memset(&dbuf[y][x], 0, sizeof (struct nh_dbuf_entry));
            } else if (json_integer_value(col) != 1)
                print_error("Strange column value in cmd_update_screen");
            continue;
        }

        if (!json_is_array(col) || json_array_size(col) != ROWNO) {
            print_error("Wrong column data type in cmd_update_screen");
            continue;
        }

        for (y = 0; y < ROWNO; y++) {
            elem = json_array_get(col, y);

            if (json_is_integer(elem)) {
                if (json_integer_value(elem) == 0)
                    memset(&dbuf[y][x], 0, sizeof (struct nh_dbuf_entry));
                else if (json_integer_value(elem) != 1)
                    print_error("Strange element value in cmd_update_screen");
                continue;
            }

            if (json_unpack
                (elem, "[i,i,i,i,i,i,i,i,i,i!]", &effect, &bg, &trap, &obj,
                 &obj_mn, &mon, &monflags, &branding, &invis, &visible) == -1)
                print_error("Strange element data in cmd_update_screen");
            dbuf[y][x].effect = effect;
            dbuf[y][x].bg = bg;
            dbuf[y][x].trap = trap;
            dbuf[y][x].obj = obj;
            dbuf[y][x].obj_mn = obj_mn;
            dbuf[y][x].mon = mon;
            dbuf[y][x].monflags = monflags;
            dbuf[y][x].branding = branding;
            dbuf[y][x].invis = invis;
            dbuf[y][x].visible = visible;
        }
    }

    cur_wndprocs.win_update_screen(dbuf, ux, uy);
    return NULL;
}
Exemplo n.º 15
0
int jt_stats_unpacker(json_t *root, void **data)
{
	json_t *params;
	json_t *iface, *samples, *err_mean, *err_max, *err_sd;
	json_t *mts, *tv_sec, *tv_nsec;

	struct jt_msg_stats *stats;

	params = json_object_get(root, "p");
	assert(params);
	assert(JSON_OBJECT == json_typeof(params));
	assert(0 < json_object_size(params));

	stats = malloc(sizeof(struct jt_msg_stats));

	/* FIXME: this json_get_object() inteface sucks bricks,
	 * but the unpack API doesn't seem to work right now (jansson-2.7). :(
	 */
	iface = json_object_get(params, "iface");
	if (!json_is_string(iface)) {
		goto unpack_fail;
	}
	snprintf(stats->iface, MAX_IFACE_LEN, "%s", json_string_value(iface));

	samples = json_object_get(params, "s");
	if (!json_is_array(samples)) {
		goto unpack_fail;
	}

	stats->sample_count = json_array_size(samples);
	stats->samples =
	    malloc(stats->sample_count * sizeof(struct stats_sample));

	int i;
	for (i = 0; i < stats->sample_count; i++) {
		json_t *s = json_array_get(samples, i);
		assert(json_is_object(s));
		json_t *t;

		t = json_object_get(s, "rx");
		assert(json_is_integer(t));
		stats->samples[i].rx = json_integer_value(t);

		t = json_object_get(s, "tx");
		assert(json_is_integer(t));
		stats->samples[i].tx = json_integer_value(t);

		t = json_object_get(s, "rxP");
		assert(json_is_integer(t));
		stats->samples[i].rxPkt = json_integer_value(t);

		t = json_object_get(s, "txP");
		assert(json_is_integer(t));
		stats->samples[i].txPkt = json_integer_value(t);
	}

	/* get the stats sampling time error */
	err_mean = json_object_get(params, "whoosh_err_mean");
	if (!json_is_integer(err_mean)) {
		goto unpack_fail_free_samples;
	}
	stats->err.mean = json_integer_value(err_mean);

	err_max = json_object_get(params, "whoosh_err_max");
	if (!json_is_integer(err_max)) {
		goto unpack_fail_free_samples;
	}
	stats->err.max = json_integer_value(err_max);

	err_sd = json_object_get(params, "whoosh_err_sd");
	if (!json_is_integer(err_sd)) {
		goto unpack_fail_free_samples;
	}
	stats->err.sd = json_integer_value(err_sd);

	/* get the message timestamp */
	mts = json_object_get(params, "t");
	if (!json_is_object(mts)) {
		goto unpack_fail_free_samples;
	}

	tv_sec = json_object_get(mts, "tv_sec");
	if (!json_is_integer(tv_sec)) {
		goto unpack_fail_free_samples;
	}
	stats->mts.tv_sec = json_integer_value(tv_sec);

	tv_nsec = json_object_get(mts, "tv_nsec");
	if (!json_is_integer(tv_nsec)) {
		goto unpack_fail_free_samples;
	}
	stats->mts.tv_nsec = json_integer_value(tv_nsec);

	*data = stats;
	json_object_clear(params);
	return 0;

unpack_fail_free_samples:
	free(stats->samples);
unpack_fail:
	free(stats);
	return -1;
}
Exemplo n.º 16
0
 /* --------------------------------------------------------------------------------------------
  * See whether the managed value is integer.
 */
 bool IsInteger() const
 {
     return json_is_integer(m_Ptr);
 }
Exemplo n.º 17
0
int CouchWorkingMemory::get( char *data ){
  json_t *sign = get_json_t( data );
  int ret = (sign && json_is_integer(sign)) ? json_integer_value(sign) : 0;
  json_decref( CouchWorkingMemory::S_Root );
  return ret;
}
Exemplo n.º 18
0
static void test_misc(void)
{
    json_t *array, *five, *seven, *value;
    size_t i;

    array = json_array();
    five = json_integer(5);
    seven = json_integer(7);

    if(!array)
        fail("unable to create array");
    if(!five || !seven)
        fail("unable to create integer");

    if(json_array_size(array) != 0)
        fail("empty array has nonzero size");

    if(!json_array_append(array, NULL))
        fail("able to append NULL");

    if(json_array_append(array, five))
        fail("unable to append");

    if(json_array_size(array) != 1)
        fail("wrong array size");

    value = json_array_get(array, 0);
    if(!value)
        fail("unable to get item");
    if(value != five)
        fail("got wrong value");

    if(json_array_append(array, seven))
        fail("unable to append value");

    if(json_array_size(array) != 2)
        fail("wrong array size");

    value = json_array_get(array, 1);
    if(!value)
        fail("unable to get item");
    if(value != seven)
        fail("got wrong value");

    if(json_array_set(array, 0, seven))
        fail("unable to set value");

    if(!json_array_set(array, 0, NULL))
        fail("able to set NULL");

    if(json_array_size(array) != 2)
        fail("wrong array size");

    value = json_array_get(array, 0);
    if(!value)
        fail("unable to get item");
    if(value != seven)
        fail("got wrong value");

    if(json_array_get(array, 2) != NULL)
        fail("able to get value out of bounds");

    if(!json_array_set(array, 2, seven))
        fail("able to set value out of bounds");

    for(i = 2; i < 30; i++) {
        if(json_array_append(array, seven))
            fail("unable to append value");

        if(json_array_size(array) != i + 1)
            fail("wrong array size");
    }

    for(i = 0; i < 30; i++) {
        value = json_array_get(array, i);
        if(!value)
            fail("unable to get item");
        if(value != seven)
            fail("got wrong value");
    }

    if(json_array_set_new(array, 15, json_integer(123)))
        fail("unable to set new value");

    value = json_array_get(array, 15);
    if(!json_is_integer(value) || json_integer_value(value) != 123)
        fail("json_array_set_new works incorrectly");

    if(!json_array_set_new(array, 15, NULL))
        fail("able to set_new NULL value");

    if(json_array_append_new(array, json_integer(321)))
        fail("unable to append new value");

    value = json_array_get(array, json_array_size(array) - 1);
    if(!json_is_integer(value) || json_integer_value(value) != 321)
        fail("json_array_append_new works incorrectly");

    if(!json_array_append_new(array, NULL))
        fail("able to append_new NULL value");

    json_decref(five);
    json_decref(seven);
    json_decref(array);
}
Exemplo n.º 19
0
avro_schema_t avro_schema_string(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_STRING,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_bytes(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_BYTES,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_int(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_INT32,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_long(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_INT64,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_float(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_FLOAT,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_double(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_DOUBLE,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_boolean(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_BOOLEAN,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_null(void)
{
	static struct avro_obj_t obj = {
		.type = AVRO_NULL,
		.class_type = AVRO_SCHEMA,
		.refcount = 1
	};
	return &obj;
}

avro_schema_t avro_schema_fixed(const char *name, const int64_t size)
{
	struct avro_fixed_schema_t *fixed =
	    malloc(sizeof(struct avro_fixed_schema_t));
	if (!fixed) {
		return NULL;
	}
	if (!is_avro_id(name)) {
		return NULL;
	}
	fixed->name = strdup(name);
	fixed->size = size;
	avro_schema_init(&fixed->obj, AVRO_FIXED);
	return &fixed->obj;
}

avro_schema_t avro_schema_union(void)
{
	struct avro_union_schema_t *schema =
	    malloc(sizeof(struct avro_union_schema_t));
	if (!schema) {
		return NULL;
	}
	schema->branches = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
	if (!schema->branches) {
		free(schema);
		return NULL;
	}

	avro_schema_init(&schema->obj, AVRO_UNION);
	return &schema->obj;
}

int
avro_schema_union_append(const avro_schema_t union_schema,
			 const avro_schema_t schema)
{
	struct avro_union_schema_t *unionp;
	if (!union_schema || !schema || !is_avro_union(union_schema)) {
		return EINVAL;
	}
	unionp = avro_schema_to_union(union_schema);
	st_insert(unionp->branches, unionp->branches->num_entries,
		  (st_data_t) schema);
	avro_schema_incref(schema);
	return 0;
}

avro_schema_t avro_schema_array(const avro_schema_t items)
{
	struct avro_array_schema_t *array =
	    malloc(sizeof(struct avro_array_schema_t));
	if (!array) {
		return NULL;
	}
	array->items = avro_schema_incref(items);
	avro_schema_init(&array->obj, AVRO_ARRAY);
	return &array->obj;
}

avro_schema_t avro_schema_map(const avro_schema_t values)
{
	struct avro_map_schema_t *map =
	    malloc(sizeof(struct avro_map_schema_t));
	if (!map) {
		return NULL;
	}
	map->values = avro_schema_incref(values);
	avro_schema_init(&map->obj, AVRO_MAP);
	return &map->obj;
}

avro_schema_t avro_schema_enum(const char *name)
{
	struct avro_enum_schema_t *enump;

	if (!is_avro_id(name)) {
		return NULL;
	}
	enump = malloc(sizeof(struct avro_enum_schema_t));
	if (!enump) {
		return NULL;
	}
	enump->name = strdup(name);
	if (!enump->name) {
		free(enump);
		return NULL;
	}
	enump->symbols = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
	if (!enump->symbols) {
		free(enump->name);
		free(enump);
		return NULL;
	}
	enump->symbols_byname = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
	if (!enump->symbols_byname) {
		st_free_table(enump->symbols);
		free(enump->name);
		free(enump);
		return NULL;
	}
	avro_schema_init(&enump->obj, AVRO_ENUM);
	return &enump->obj;
}

int
avro_schema_enum_symbol_append(const avro_schema_t enum_schema,
			       const char *symbol)
{
	struct avro_enum_schema_t *enump;
	char *sym;
	long idx;
	if (!enum_schema || !symbol || !is_avro_enum(enum_schema)) {
		return EINVAL;
	}
	enump = avro_schema_to_enum(enum_schema);
	sym = strdup(symbol);
	if (!sym) {
		return ENOMEM;
	}
	idx = enump->symbols->num_entries;
	st_insert(enump->symbols, (st_data_t) idx, (st_data_t) sym);
	st_insert(enump->symbols_byname, (st_data_t) sym, (st_data_t) idx);
	return 0;
}

int
avro_schema_record_field_append(const avro_schema_t record_schema,
				const char *field_name,
				const avro_schema_t field_schema)
{
	struct avro_record_schema_t *record;
	struct avro_record_field_t *new_field;
	if (!field_name || !field_schema || !is_avro_schema(record_schema)
	    || !is_avro_record(record_schema) || record_schema == field_schema
	    || !is_avro_id(field_name)) {
		return EINVAL;
	}
	record = avro_schema_to_record(record_schema);
	new_field = malloc(sizeof(struct avro_record_field_t));
	if (!new_field) {
		return ENOMEM;
	}
	new_field->name = strdup(field_name);
	new_field->type = avro_schema_incref(field_schema);
	st_insert(record->fields, record->fields->num_entries,
		  (st_data_t) new_field);
	st_insert(record->fields_byname, (st_data_t) new_field->name,
		  (st_data_t) new_field);
	return 0;
}

avro_schema_t avro_schema_record(const char *name, const char *space)
{
	struct avro_record_schema_t *record;
	if (!is_avro_id(name)) {
		return NULL;
	}
	record = malloc(sizeof(struct avro_record_schema_t));
	if (!record) {
		return NULL;
	}
	record->name = strdup(name);
	if (!record->name) {
		free(record);
		return NULL;
	}
	record->space = space ? strdup(space) : NULL;
	if (space && !record->space) {
		free(record->name);
		free(record);
		return NULL;
	}
	record->fields = st_init_numtable_with_size(DEFAULT_TABLE_SIZE);
	if (!record->fields) {
		if (record->space) {
			free(record->space);
		}
		free(record->name);
		free(record);
		return NULL;
	}
	record->fields_byname = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
	if (!record->fields_byname) {
		st_free_table(record->fields);
		free(record->name);
		free(record);
		return NULL;
	}

	avro_schema_init(&record->obj, AVRO_RECORD);
	return &record->obj;
}

static int
save_named_schemas(const char *name, avro_schema_t schema,
		   avro_schema_error_t * error)
{
	st_table *st = (*error)->named_schemas;
	return st_insert(st, (st_data_t) name, (st_data_t) schema);
}

static avro_schema_t
find_named_schemas(const char *name, avro_schema_error_t * error)
{
	st_table *st = (*error)->named_schemas;
	union {
		avro_schema_t schema;
		st_data_t data;
	} val;
	if (st_lookup(st, (st_data_t) name, &(val.data))) {
		return val.schema;
	}
	return NULL;
};

avro_schema_t avro_schema_link(avro_schema_t to)
{
	struct avro_link_schema_t *link;
	if (!is_avro_named_type(to)) {
		return NULL;
	}
	link = malloc(sizeof(struct avro_link_schema_t));
	if (!link) {
		return NULL;
	}
	link->to = avro_schema_incref(to);
	avro_schema_init(&link->obj, AVRO_LINK);
	return &link->obj;
}

static int
avro_type_from_json_t(json_t * json, avro_type_t * type,
		      avro_schema_error_t * error, avro_schema_t * named_type)
{
	json_t *json_type;
	const char *type_str;

	if (json_is_array(json)) {
		*type = AVRO_UNION;
		return 0;
	} else if (json_is_object(json)) {
		json_type = json_object_get(json, "type");
	} else {
		json_type = json;
	}
	if (!json_is_string(json_type)) {
		return EINVAL;
	}
	type_str = json_string_value(json_type);
	if (!type_str) {
		return EINVAL;
	}
	/*
	 * TODO: gperf/re2c this 
	 */
	if (strcmp(type_str, "string") == 0) {
		*type = AVRO_STRING;
	} else if (strcmp(type_str, "bytes") == 0) {
		*type = AVRO_BYTES;
	} else if (strcmp(type_str, "int") == 0) {
		*type = AVRO_INT32;
	} else if (strcmp(type_str, "long") == 0) {
		*type = AVRO_INT64;
	} else if (strcmp(type_str, "float") == 0) {
		*type = AVRO_FLOAT;
	} else if (strcmp(type_str, "double") == 0) {
		*type = AVRO_DOUBLE;
	} else if (strcmp(type_str, "boolean") == 0) {
		*type = AVRO_BOOLEAN;
	} else if (strcmp(type_str, "null") == 0) {
		*type = AVRO_NULL;
	} else if (strcmp(type_str, "record") == 0) {
		*type = AVRO_RECORD;
	} else if (strcmp(type_str, "enum") == 0) {
		*type = AVRO_ENUM;
	} else if (strcmp(type_str, "array") == 0) {
		*type = AVRO_ARRAY;
	} else if (strcmp(type_str, "map") == 0) {
		*type = AVRO_MAP;
	} else if (strcmp(type_str, "fixed") == 0) {
		*type = AVRO_FIXED;
	} else if ((*named_type = find_named_schemas(type_str, error))) {
		*type = AVRO_LINK;
	} else {
		return EINVAL;
	}
	return 0;
}

static int
avro_schema_from_json_t(json_t * json, avro_schema_t * schema,
			avro_schema_error_t * error)
{
	avro_type_t type = 0;
	unsigned int i;
	avro_schema_t named_schemas = NULL;

	if (avro_type_from_json_t(json, &type, error, &named_schemas)) {
		return EINVAL;
	}

	switch (type) {
	case AVRO_LINK:
		*schema = avro_schema_link(named_schemas);
		break;

	case AVRO_STRING:
		*schema = avro_schema_string();
		break;

	case AVRO_BYTES:
		*schema = avro_schema_bytes();
		break;

	case AVRO_INT32:
		*schema = avro_schema_int();
		break;

	case AVRO_INT64:
		*schema = avro_schema_long();
		break;

	case AVRO_FLOAT:
		*schema = avro_schema_float();
		break;

	case AVRO_DOUBLE:
		*schema = avro_schema_double();
		break;

	case AVRO_BOOLEAN:
		*schema = avro_schema_boolean();
		break;

	case AVRO_NULL:
		*schema = avro_schema_null();
		break;

	case AVRO_RECORD:
		{
			json_t *json_name = json_object_get(json, "name");
			json_t *json_namespace =
			    json_object_get(json, "namespace");
			json_t *json_fields = json_object_get(json, "fields");
			unsigned int num_fields;
			const char *record_name;
			const char *record_namespace;

			if (!json_is_string(json_name)) {
				return EINVAL;
			}
			if (!json_is_array(json_fields)) {
				return EINVAL;
			}
			num_fields = json_array_size(json_fields);
			if (num_fields == 0) {
				return EINVAL;
			}
			record_name = json_string_value(json_name);
			if (!record_name) {
				return EINVAL;
			}
			if (json_is_string(json_namespace)) {
				record_namespace =
				    json_string_value(json_namespace);
			} else {
				record_namespace = NULL;
			}
			*schema =
			    avro_schema_record(record_name, record_namespace);
			if (save_named_schemas(record_name, *schema, error)) {
				return ENOMEM;
			}
			for (i = 0; i < num_fields; i++) {
				json_t *json_field =
				    json_array_get(json_fields, i);
				json_t *json_field_name;
				json_t *json_field_type;
				avro_schema_t json_field_type_schema;
				int field_rval;

				if (!json_is_object(json_field)) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				json_field_name =
				    json_object_get(json_field, "name");
				if (!json_field_name) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				json_field_type =
				    json_object_get(json_field, "type");
				if (!json_field_type) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				field_rval =
				    avro_schema_from_json_t(json_field_type,
							    &json_field_type_schema,
							    error);
				if (field_rval) {
					avro_schema_decref(*schema);
					return field_rval;
				}
				field_rval =
				    avro_schema_record_field_append(*schema,
								    json_string_value
								    (json_field_name),
								    json_field_type_schema);
				avro_schema_decref(json_field_type_schema);
				if (field_rval != 0) {
					avro_schema_decref(*schema);
					return field_rval;
				}
			}
		}
		break;

	case AVRO_ENUM:
		{
			json_t *json_name = json_object_get(json, "name");
			json_t *json_symbols = json_object_get(json, "symbols");
			const char *name;
			unsigned int num_symbols;

			if (!json_is_string(json_name)) {
				return EINVAL;
			}
			if (!json_is_array(json_symbols)) {
				return EINVAL;
			}

			name = json_string_value(json_name);
			if (!name) {
				return EINVAL;
			}
			num_symbols = json_array_size(json_symbols);
			if (num_symbols == 0) {
				return EINVAL;
			}
			*schema = avro_schema_enum(name);
			if (save_named_schemas(name, *schema, error)) {
				return ENOMEM;
			}
			for (i = 0; i < num_symbols; i++) {
				int enum_rval;
				json_t *json_symbol =
				    json_array_get(json_symbols, i);
				const char *symbol;
				if (!json_is_string(json_symbol)) {
					avro_schema_decref(*schema);
					return EINVAL;
				}
				symbol = json_string_value(json_symbol);
				enum_rval =
				    avro_schema_enum_symbol_append(*schema,
								   symbol);
				if (enum_rval != 0) {
					avro_schema_decref(*schema);
					return enum_rval;
				}
			}
		}
		break;

	case AVRO_ARRAY:
		{
			int items_rval;
			json_t *json_items = json_object_get(json, "items");
			avro_schema_t items_schema;
			if (!json_items) {
				return EINVAL;
			}
			items_rval =
			    avro_schema_from_json_t(json_items, &items_schema,
						    error);
			if (items_rval) {
				return items_rval;
			}
			*schema = avro_schema_array(items_schema);
			avro_schema_decref(items_schema);
		}
		break;

	case AVRO_MAP:
		{
			int values_rval;
			json_t *json_values = json_object_get(json, "values");
			avro_schema_t values_schema;

			if (!json_values) {
				return EINVAL;
			}
			values_rval =
			    avro_schema_from_json_t(json_values, &values_schema,
						    error);
			if (values_rval) {
				return values_rval;
			}
			*schema = avro_schema_map(values_schema);
			avro_schema_decref(values_schema);
		}
		break;

	case AVRO_UNION:
		{
			unsigned int num_schemas = json_array_size(json);
			avro_schema_t s;
			if (num_schemas == 0) {
				return EINVAL;
			}
			*schema = avro_schema_union();
			for (i = 0; i < num_schemas; i++) {
				int schema_rval;
				json_t *schema_json = json_array_get(json, i);
				if (!schema_json) {
					return EINVAL;
				}
				schema_rval =
				    avro_schema_from_json_t(schema_json, &s,
							    error);
				if (schema_rval != 0) {
					avro_schema_decref(*schema);
					return schema_rval;
				}
				schema_rval =
				    avro_schema_union_append(*schema, s);
				avro_schema_decref(s);
				if (schema_rval != 0) {
					avro_schema_decref(*schema);
					return schema_rval;
				}
			}
		}
		break;

	case AVRO_FIXED:
		{
			json_t *json_size = json_object_get(json, "size");
			json_t *json_name = json_object_get(json, "name");
			int size;
			const char *name;
			if (!json_is_integer(json_size)) {
				return EINVAL;
			}
			if (!json_is_string(json_name)) {
				return EINVAL;
			}
			size = json_integer_value(json_size);
			name = json_string_value(json_name);
			*schema = avro_schema_fixed(name, size);
			if (save_named_schemas(name, *schema, error)) {
				return ENOMEM;
			}
		}
		break;

	default:
		return EINVAL;
	}
	return 0;
}

int
avro_schema_from_json(const char *jsontext, const int32_t len,
		      avro_schema_t * schema, avro_schema_error_t * e)
{
	json_t *root;
	int rval = 0;
	avro_schema_error_t error;

	AVRO_UNUSED(len);

	if (!jsontext || !schema) {
		return EINVAL;
	}

	error = malloc(sizeof(struct avro_schema_error_t_));
	if (!error) {
		return ENOMEM;
	}
	*e = error;

	error->named_schemas = st_init_strtable_with_size(DEFAULT_TABLE_SIZE);
	if (!error->named_schemas) {
		free(error);
		return ENOMEM;
	}

	root = json_loads(jsontext, &error->json_error);
	if (!root) {
		st_free_table(error->named_schemas);
		free(error);
		return EINVAL;
	}

	/*
	 * json_dumpf(root, stderr, 0); 
	 */
	rval = avro_schema_from_json_t(root, schema, e);
	json_decref(root);
	st_free_table(error->named_schemas);
	if (rval == 0) {
		/* no need for an error return */
		free(error);
	}
	return rval;
}

avro_schema_t avro_schema_copy(avro_schema_t schema)
{
	long i;
	avro_schema_t new_schema = NULL;
	if (!schema) {
		return NULL;
	}
	switch (avro_typeof(schema)) {
	case AVRO_STRING:
	case AVRO_BYTES:
	case AVRO_INT32:
	case AVRO_INT64:
	case AVRO_FLOAT:
	case AVRO_DOUBLE:
	case AVRO_BOOLEAN:
	case AVRO_NULL:
		/*
		 * No need to copy primitives since they're static 
		 */
		new_schema = schema;
		break;

	case AVRO_RECORD:
		{
			struct avro_record_schema_t *record_schema =
			    avro_schema_to_record(schema);
			new_schema =
			    avro_schema_record(record_schema->name,
					       record_schema->space);
			for (i = 0; i < record_schema->fields->num_entries; i++) {
				union {
					st_data_t data;
					struct avro_record_field_t *field;
				} val;
				st_lookup(record_schema->fields, i, &val.data);
				avro_schema_t type_copy =
				    avro_schema_copy(val.field->type);
				avro_schema_record_field_append(new_schema,
								val.field->name,
								type_copy);
			}
		}
		break;

	case AVRO_ENUM:
		{
			struct avro_enum_schema_t *enum_schema =
			    avro_schema_to_enum(schema);
			new_schema = avro_schema_enum(enum_schema->name);
			for (i = 0; i < enum_schema->symbols->num_entries; i++) {
				union {
					st_data_t data;
					char *sym;
				} val;
				st_lookup(enum_schema->symbols, i, &val.data);
				avro_schema_enum_symbol_append(new_schema,
							       val.sym);
			}
		}
		break;

	case AVRO_FIXED:
		{
			struct avro_fixed_schema_t *fixed_schema =
			    avro_schema_to_fixed(schema);
			new_schema =
			    avro_schema_fixed(fixed_schema->name,
					      fixed_schema->size);
		}
		break;

	case AVRO_MAP:
		{
			struct avro_map_schema_t *map_schema =
			    avro_schema_to_map(schema);
			avro_schema_t values_copy =
			    avro_schema_copy(map_schema->values);
			if (!values_copy) {
				return NULL;
			}
			new_schema = avro_schema_map(values_copy);
		}
		break;

	case AVRO_ARRAY:
		{
			struct avro_array_schema_t *array_schema =
			    avro_schema_to_array(schema);
			avro_schema_t items_copy =
			    avro_schema_copy(array_schema->items);
			if (!items_copy) {
				return NULL;
			}
			new_schema = avro_schema_array(items_copy);
		}
		break;

	case AVRO_UNION:
		{
			struct avro_union_schema_t *union_schema =
			    avro_schema_to_union(schema);

			new_schema = avro_schema_union();
			for (i = 0; i < union_schema->branches->num_entries;
			     i++) {
				avro_schema_t schema_copy;
				union {
					st_data_t data;
					avro_schema_t schema;
				} val;
				st_lookup(union_schema->branches, i, &val.data);
				schema_copy = avro_schema_copy(val.schema);
				if (avro_schema_union_append
				    (new_schema, schema_copy)) {
					avro_schema_decref(new_schema);
					return NULL;
				}
			}
		}
		break;

	case AVRO_LINK:
		{
			struct avro_link_schema_t *link_schema =
			    avro_schema_to_link(schema);
			/*
			 * TODO: use an avro_schema_copy of to instead of pointing to
			 * the same reference 
			 */
			avro_schema_incref(link_schema->to);
			new_schema = avro_schema_link(link_schema->to);
		}
		break;

	default:
		return NULL;
	}
	return new_schema;
}

const char *avro_schema_name(const avro_schema_t schema)
{
	if (is_avro_record(schema)) {
		return (avro_schema_to_record(schema))->name;
	} else if (is_avro_enum(schema)) {
		return (avro_schema_to_enum(schema))->name;
	} else if (is_avro_fixed(schema)) {
		return (avro_schema_to_fixed(schema))->name;
	}
	return NULL;
}

/* simple helper for writing strings */
static int avro_write_str(avro_writer_t out, const char *str)
{
	return avro_write(out, (char *)str, strlen(str));
}

static int write_field(avro_writer_t out, struct avro_record_field_t *field)
{
	int rval;
	check(rval, avro_write_str(out, "{\"name\":\""));
	check(rval, avro_write_str(out, field->name));
	check(rval, avro_write_str(out, "\",\"type\":"));
	check(rval, avro_schema_to_json(field->type, out));
	return avro_write_str(out, "}");
}

static int write_record(avro_writer_t out, struct avro_record_schema_t *record)
{
	int rval;
	long i;

	check(rval, avro_write_str(out, "{\"type\":\"record\",\"name\":\""));
	check(rval, avro_write_str(out, record->name));
	check(rval, avro_write_str(out, "\","));
	if (record->space) {
		check(rval, avro_write_str(out, "\"namespace\":\""));
		check(rval, avro_write_str(out, record->space));
		check(rval, avro_write_str(out, "\","));
	}
	check(rval, avro_write_str(out, "\"fields\":["));
	for (i = 0; i < record->fields->num_entries; i++) {
		union {
			st_data_t data;
			struct avro_record_field_t *field;
		} val;
		st_lookup(record->fields, i, &val.data);
		if (i) {
			check(rval, avro_write_str(out, ","));
		}
		check(rval, write_field(out, val.field));
	}
	return avro_write_str(out, "]}");
}
Exemplo n.º 20
0
static void test_insert(void)
{
    json_t *array, *five, *seven, *eleven, *value;
    int i;

    array = json_array();
    five = json_integer(5);
    seven = json_integer(7);
    eleven = json_integer(11);

    if(!array)
        fail("unable to create array");
    if(!five || !seven || !eleven)
        fail("unable to create integer");


    if(!json_array_insert(array, 1, five))
        fail("able to insert value out of bounds");


    if(json_array_insert(array, 0, five))
        fail("unable to insert value in an empty array");

    if(json_array_get(array, 0) != five)
        fail("json_array_insert works incorrectly");

    if(json_array_size(array) != 1)
        fail("array size is invalid after insertion");


    if(json_array_insert(array, 1, seven))
        fail("unable to insert value at the end of an array");

    if(json_array_get(array, 0) != five)
        fail("json_array_insert works incorrectly");

    if(json_array_get(array, 1) != seven)
        fail("json_array_insert works incorrectly");

    if(json_array_size(array) != 2)
        fail("array size is invalid after insertion");


    if(json_array_insert(array, 1, eleven))
        fail("unable to insert value in the middle of an array");

    if(json_array_get(array, 0) != five)
        fail("json_array_insert works incorrectly");

    if(json_array_get(array, 1) != eleven)
        fail("json_array_insert works incorrectly");

    if(json_array_get(array, 2) != seven)
        fail("json_array_insert works incorrectly");

    if(json_array_size(array) != 3)
        fail("array size is invalid after insertion");


    if(json_array_insert_new(array, 2, json_integer(123)))
        fail("unable to insert value in the middle of an array");

    value = json_array_get(array, 2);
    if(!json_is_integer(value) || json_integer_value(value) != 123)
        fail("json_array_insert_new works incorrectly");

    if(json_array_size(array) != 4)
        fail("array size is invalid after insertion");


    for(i = 0; i < 20; i++) {
        if(json_array_insert(array, 0, seven))
            fail("unable to insert value at the begining of an array");
    }

    for(i = 0; i < 20; i++) {
        if(json_array_get(array, i) != seven)
            fail("json_aray_insert works incorrectly");
    }

    if(json_array_size(array) != 24)
        fail("array size is invalid after loop insertion");

    json_decref(five);
    json_decref(seven);
    json_decref(eleven);
    json_decref(array);
}
Exemplo n.º 21
0
static size_t http_write_callback(void *ptr, size_t size, size_t nmemb, void *userdata) {
    json_t *response, *value, *in;
    json_error_t error;
    const char *etcd_value;
    const char *errmsg;
    struct etcd_data *data;
    int val;

    data = userdata;

    response = json_loads(ptr, 0, &error);
    if (!json_is_object(response)) {
        strcpy(data->errmsg, "'response' returned is not a json object");
        goto error;
    }

    in = json_object_get(response, "index");
    if (json_is_integer(in)) {
        data->index = json_integer_value(in);
    }

    value = json_object_get(response, "value");
    if (!json_is_string(value)) {
        value = json_object_get(response, "action");
        etcd_value = "";
        if (json_is_string(value)) {
            etcd_value = json_string_value(value);
        }
        if (strcmp(etcd_value, DELETE_KEY) == 0) {
            value = json_object_get(response, "key");
            etcd_value = json_string_value(value);
            strcpy(data->value, ++etcd_value);
            data->response = ETCD_SUCCESS;

            json_decref(response);
            return size * nmemb;

        } else {
            value = json_object_get(response, "errorCode");
            if (!json_is_integer(value)) {
                strcpy(data->errmsg, "Invalid error message.");
                goto error;
            }
            val = json_integer_value(value);

            value = json_object_get(response, "message");
            if (!json_is_string(value)) {
                strcpy(data->errmsg, "Invalid error message.");
                goto error;
            }

            errmsg = json_string_value(value);
            sprintf(data->errmsg, "%d:%s", val, errmsg);
            goto error;
        }
    }
    etcd_value = json_string_value(value);
    memcpy(data->value, etcd_value, strlen(etcd_value) + 1);
    data->response = ETCD_SUCCESS;

    json_decref(response);
    return size * nmemb;

error:
    json_decref(response);
    data->value = NULL;
    data->response = ETCD_FAILURE;
    return size * nmemb;
}
Exemplo n.º 22
0
struct ps_plugin_result * ps_gstsink_handle_message (ps_plugin_session * handle, char * transaction, char * message, char * sdp_type, char * sdp) {
	if(g_atomic_int_get(&stopping) || !g_atomic_int_get(&initialized))
		return ps_plugin_result_new(PS_PLUGIN_ERROR, g_atomic_int_get(&stopping) ? "Shutting down" : "Plugin not initialized");
	
	int error_code = 0;
	char error_cause[512];
	json_t * root = NULL;
	json_t * response = NULL;
	
	if (message == NULL) {
		PS_LOG (LOG_ERR, "No message??\n");
		error_code = PS_GSTSINK_ERROR_NO_MESSAGE;
		g_snprintf (error_cause, 512, "%s", "No message");
		goto error;
	}
	PS_LOG (LOG_VERB, "Handling message: %s\n", message);
	ps_gstsink_session * session = (ps_gstsink_session *) handle->plugin_handle;
	
	if(!session) {
		PS_LOG(LOG_ERR, "No session associated with this handle...\n");
		error_code = PS_GSTSINK_ERROR_UNKNOWN_ERROR;
		g_snprintf(error_cause, 512, "%s", "session associated with this handle...");
		goto error;
	}
	if(session->destroyed) {
		PS_LOG(LOG_ERR, "Session has already been destroyed...\n");
		error_code = PS_GSTSINK_ERROR_UNKNOWN_ERROR;
		g_snprintf(error_cause, 512, "%s", "Session has already been destroyed...");
		goto error;
	}
	json_error_t error;
	root = json_loads(message, 0, &error);
	if(!root) {
		PS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
		error_code = PS_GSTSINK_ERROR_INVALID_JSON;
		g_snprintf(error_cause, 512, "JSON error: on line %d: %s", error.line, error.text);
		goto error;
	}
	if(!json_is_object(root)) {
		PS_LOG(LOG_ERR, "JSON error: not an object\n");
		error_code = PS_GSTSINK_ERROR_INVALID_JSON;
		g_snprintf(error_cause, 512, "JSON error: not an object");
		goto error;
	}
	
	json_t * request = json_object_get (root, "request");
	if (!request) {
		PS_LOG (LOG_ERR, "Missing element (request)\n");
		error_code = PS_GSTSINK_ERROR_MISSING_ELEMENT;
		g_snprintf (error_cause, 512, "Missing element (request)");
		goto error;
	}
	if (!json_is_string(request)) {
		PS_LOG (LOG_ERR, "Invalid element (request should be a string)\n");
		error_code = PS_GSTSINK_ERROR_INVALID_ELEMENT;
		g_snprintf (error_cause, 512, "Invalid element (request should be a string)");
		goto error;
	}
	
	const char * request_text = json_string_value (request);
	if (!strcasecmp(request_text, "list")) {
		json_t * list = json_array();
		PS_LOG(LOG_VERB, "Request for list of recordings\n");
		json_t * ml = json_object();
		json_object_set_new(ml, "id", json_integer(100));
		json_object_set_new(ml, "name", json_string("test"));
		json_object_set_new(ml, "date", json_string("06/06/2016"));
		json_object_set_new(ml, "audio", json_string("true"));
		json_object_set_new(ml, "video", json_string("true"));
		json_array_append_new(list, ml);
		response = json_object();
		json_object_set_new(response, "recordplay", json_string("list"));
		json_object_set_new(response, "list", list);
		goto plugin_response;
	} else if(!strcasecmp(request_text, "configure")) {
		json_t *video_bitrate_max = json_object_get(root, "video-bitrate-max");
		if(video_bitrate_max) {
			if(!json_is_integer(video_bitrate_max) || json_integer_value(video_bitrate_max) < 0) {
				PS_LOG(LOG_ERR, "Invalid element (video-bitrate-max should be a positive integer)\n");
				error_code = PS_GSTSINK_ERROR_INVALID_ELEMENT;
				g_snprintf(error_cause, 512, "Invalid element (video-bitrate-max should be a positive integer)");
				goto error;
			}
			session->video_bitrate = json_integer_value(video_bitrate_max);
			PS_LOG(LOG_VERB, "Video bitrate has been set to %"SCNu64"\n", session->video_bitrate);
		}
		json_t *video_keyframe_interval= json_object_get(root, "video-keyframe-interval");
		if(video_keyframe_interval) {
			if(!json_is_integer(video_keyframe_interval) || json_integer_value(video_keyframe_interval) < 0) {
				PS_LOG(LOG_ERR, "Invalid element (video-keyframe-interval should be a positive integer)\n");
				error_code = PS_GSTSINK_ERROR_INVALID_ELEMENT;
				g_snprintf(error_cause, 512, "Invalid element (video-keyframe-interval should be a positive integer)");
				goto error;
			}
			session->video_keyframe_interval = json_integer_value(video_keyframe_interval);
			PS_LOG(LOG_VERB, "Video keyframe interval has been set to %u\n", session->video_keyframe_interval);
		}
		response = json_object();
		json_object_set_new(response, "recordplay", json_string("configure"));
		json_object_set_new(response, "status", json_string("ok"));
		/* Return a success, and also let the client be aware of what changed, to allow crosschecks */
		json_t *settings = json_object();
		json_object_set_new(settings, "video-keyframe-interval", json_integer(session->video_keyframe_interval)); 
		json_object_set_new(settings, "video-bitrate-max", json_integer(session->video_bitrate)); 
		json_object_set_new(response, "settings", settings); 
		goto plugin_response;
	} else if (!strcasecmp(request_text, "start") || !strcasecmp(request_text,"stop")) {
		ps_gstsink_message * msg = g_malloc0(sizeof(ps_gstsink_message));
		if (msg==NULL) {
			PS_LOG (LOG_FATAL, "Memory Error!\n");
			error_code = PS_GSTSINK_ERROR_UNKNOWN_ERROR;
			g_snprintf (error_cause, 512, "Memory Error");
			goto error;
		}
		g_free (message);
		msg->handle = handle;
		msg->transaction = transaction;
		msg->message = root;
		msg->sdp_type = sdp_type;
		msg->sdp = sdp;
		
		g_async_queue_push (messages, msg);
		
		return ps_plugin_result_new (PS_PLUGIN_OK_WAIT, NULL);
	} else {
		PS_LOG (LOG_VERB, "Unknown request '%s'\n", request_text);
		error_code = PS_GSTSINK_ERROR_INVALID_REQUEST;
		g_snprintf (error_cause, 512, "Unknown request '%s'",request_text);
		goto error;
	}

plugin_response:
	{
		if(!response) {
			error_code = PS_GSTSINK_ERROR_UNKNOWN_ERROR;
			g_snprintf(error_cause, 512, "Invalid response");
			goto error;
		}
		if(root != NULL)
			json_decref(root);
		g_free(transaction);
		g_free(message);
		g_free(sdp_type);
		g_free(sdp);

		char *response_text = json_dumps(response, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
		json_decref(response);
		ps_plugin_result *result = ps_plugin_result_new(PS_PLUGIN_OK, response_text);
		g_free(response_text);
		return result;
	}
		
error:
	{
		if (root != NULL) json_decref(root);
		g_free(transaction);
		g_free(message);
		g_free(sdp_type);
		g_free(sdp);
		
		json_t * event = json_object();
		json_object_set_new(event, "recordplay", json_string("event"));
		json_object_set_new(event, "error_code", json_integer(error_code));
		json_object_set_new(event, "error", json_string(error_cause));
		char *event_text = json_dumps(event, JSON_INDENT(3) | JSON_PRESERVE_ORDER);
		json_decref(event);
		ps_plugin_result *result = ps_plugin_result_new(PS_PLUGIN_OK, event_text);
		g_free(event_text);
		return result;
	}
	
}
Exemplo n.º 23
0
static void run_tests()
{
    json_t *value;
    int i;
    char buffer[4] = {'t', 'e', 's', 't'};
    json_error_t error;

    /*
     * Simple, valid json_pack cases
     */
    /* true */
    value = json_pack("b", 1);
    if(!json_is_true(value))
        fail("json_pack boolean failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack boolean refcount failed");
    json_decref(value);

    /* false */
    value = json_pack("b", 0);
    if(!json_is_false(value))
        fail("json_pack boolean failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack boolean refcount failed");
    json_decref(value);

    /* null */
    value = json_pack("n");
    if(!json_is_null(value))
        fail("json_pack null failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack null refcount failed");
    json_decref(value);

    /* integer */
    value = json_pack("i", 1);
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack integer failed");
    if(value->refcount != (size_t)1)
        fail("json_pack integer refcount failed");
    json_decref(value);

    /* integer from json_int_t */
    value = json_pack("I", (json_int_t)555555);
    if(!json_is_integer(value) || json_integer_value(value) != 555555)
        fail("json_pack json_int_t failed");
    if(value->refcount != (size_t)1)
        fail("json_pack integer refcount failed");
    json_decref(value);

    /* real */
    value = json_pack("f", 1.0);
    if(!json_is_real(value) || json_real_value(value) != 1.0)
        fail("json_pack real failed");
    if(value->refcount != (size_t)1)
        fail("json_pack real refcount failed");
    json_decref(value);

    /* string */
    value = json_pack("s", "test");
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string refcount failed");
    json_decref(value);

    /* nullable string (defined case) */
    value = json_pack("s?", "test");
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack nullable string (defined case) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack nullable string (defined case) refcount failed");
    json_decref(value);

    /* nullable string (NULL case) */
    value = json_pack("s?", NULL);
    if(!json_is_null(value))
        fail("json_pack nullable string (NULL case) failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack nullable string (NULL case) refcount failed");
    json_decref(value);

    /* string and length (int) */
    value = json_pack("s#", "test asdf", 4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length refcount failed");
    json_decref(value);

    /* string and length (size_t) */
    value = json_pack("s%", "test asdf", (size_t)4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length refcount failed");
    json_decref(value);

    /* string and length (int), non-NUL terminated string */
    value = json_pack("s#", buffer, 4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length (int) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length (int) refcount failed");
    json_decref(value);

    /* string and length (size_t), non-NUL terminated string */
    value = json_pack("s%", buffer, (size_t)4);
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string and length (size_t) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string and length (size_t) refcount failed");
    json_decref(value);

    /* string concatenation */
    value = json_pack("s++", "te", "st", "ing");
    if(!json_is_string(value) || strcmp("testing", json_string_value(value)))
        fail("json_pack string concatenation failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string concatenation refcount failed");
    json_decref(value);

    /* string concatenation and length (int) */
    value = json_pack("s#+#+", "test", 1, "test", 2, "test");
    if(!json_is_string(value) || strcmp("ttetest", json_string_value(value)))
        fail("json_pack string concatenation and length (int) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string concatenation and length (int) refcount failed");
    json_decref(value);

    /* string concatenation and length (size_t) */
    value = json_pack("s%+%+", "test", (size_t)1, "test", (size_t)2, "test");
    if(!json_is_string(value) || strcmp("ttetest", json_string_value(value)))
        fail("json_pack string concatenation and length (size_t) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack string concatenation and length (size_t) refcount failed");
    json_decref(value);

    /* empty object */
    value = json_pack("{}", 1.0);
    if(!json_is_object(value) || json_object_size(value) != 0)
        fail("json_pack empty object failed");
    if(value->refcount != (size_t)1)
        fail("json_pack empty object refcount failed");
    json_decref(value);

    /* empty list */
    value = json_pack("[]", 1.0);
    if(!json_is_array(value) || json_array_size(value) != 0)
        fail("json_pack empty list failed");
    if(value->refcount != (size_t)1)
        fail("json_pack empty list failed");
    json_decref(value);

    /* non-incref'd object */
    value = json_pack("o", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack object failed");
    if(value->refcount != (size_t)1)
        fail("json_pack integer refcount failed");
    json_decref(value);

    /* non-incref'd nullable object (defined case) */
    value = json_pack("o?", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack nullable object (defined case) failed");
    if(value->refcount != (size_t)1)
        fail("json_pack nullable object (defined case) refcount failed");
    json_decref(value);

    /* non-incref'd nullable object (NULL case) */
    value = json_pack("o?", NULL);
    if(!json_is_null(value))
        fail("json_pack nullable object (NULL case) failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack nullable object (NULL case) refcount failed");
    json_decref(value);

    /* incref'd object */
    value = json_pack("O", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack object failed");
    if(value->refcount != (size_t)2)
        fail("json_pack integer refcount failed");
    json_decref(value);
    json_decref(value);

    /* incref'd nullable object (defined case) */
    value = json_pack("O?", json_integer(1));
    if(!json_is_integer(value) || json_integer_value(value) != 1)
        fail("json_pack incref'd nullable object (defined case) failed");
    if(value->refcount != (size_t)2)
        fail("json_pack incref'd nullable object (defined case) refcount failed");
    json_decref(value);
    json_decref(value);

    /* incref'd nullable object (NULL case) */
    value = json_pack("O?", NULL);
    if(!json_is_null(value))
        fail("json_pack incref'd nullable object (NULL case) failed");
    if(value->refcount != (size_t)-1)
        fail("json_pack incref'd nullable object (NULL case) refcount failed");

    /* simple object */
    value = json_pack("{s:[]}", "foo");
    if(!json_is_object(value) || json_object_size(value) != 1)
        fail("json_pack array failed");
    if(!json_is_array(json_object_get(value, "foo")))
        fail("json_pack array failed");
    if(json_object_get(value, "foo")->refcount != (size_t)1)
        fail("json_pack object refcount failed");
    json_decref(value);

    /* object with complex key */
    value = json_pack("{s+#+: []}", "foo", "barbar", 3, "baz");
    if(!json_is_object(value) || json_object_size(value) != 1)
        fail("json_pack array failed");
    if(!json_is_array(json_object_get(value, "foobarbaz")))
        fail("json_pack array failed");
    if(json_object_get(value, "foobarbaz")->refcount != (size_t)1)
        fail("json_pack object refcount failed");
    json_decref(value);

    /* simple array */
    value = json_pack("[i,i,i]", 0, 1, 2);
    if(!json_is_array(value) || json_array_size(value) != 3)
        fail("json_pack object failed");
    for(i=0; i<3; i++)
    {
        if(!json_is_integer(json_array_get(value, i)) ||
           json_integer_value(json_array_get(value, i)) != i)

            fail("json_pack integer array failed");
    }
    json_decref(value);

    /* Whitespace; regular string */
    value = json_pack(" s ", "test");
    if(!json_is_string(value) || strcmp("test", json_string_value(value)))
        fail("json_pack string (with whitespace) failed");
    json_decref(value);

    /* Whitespace; empty array */
    value = json_pack("[ ]");
    if(!json_is_array(value) || json_array_size(value) != 0)
        fail("json_pack empty array (with whitespace) failed");
    json_decref(value);

    /* Whitespace; array */
    value = json_pack("[ i , i,  i ] ", 1, 2, 3);
    if(!json_is_array(value) || json_array_size(value) != 3)
        fail("json_pack array (with whitespace) failed");
    json_decref(value);

    /*
     * Invalid cases
     */

    /* newline in format string */
    if(json_pack_ex(&error, 0, "{\n\n1"))
        fail("json_pack failed to catch invalid format '1'");
    check_error("Expected format 's', got '1'", "<format>", 3, 1, 4);

    /* mismatched open/close array/object */
    if(json_pack_ex(&error, 0, "[}"))
        fail("json_pack failed to catch mismatched '}'");
    check_error("Unexpected format character '}'", "<format>", 1, 2, 2);

    if(json_pack_ex(&error, 0, "{]"))
        fail("json_pack failed to catch mismatched ']'");
    check_error("Expected format 's', got ']'", "<format>", 1, 2, 2);

    /* missing close array */
    if(json_pack_ex(&error, 0, "["))
        fail("json_pack failed to catch missing ']'");
    check_error("Unexpected end of format string", "<format>", 1, 2, 2);

    /* missing close object */
    if(json_pack_ex(&error, 0, "{"))
        fail("json_pack failed to catch missing '}'");
    check_error("Unexpected end of format string", "<format>", 1, 2, 2);

    /* garbage after format string */
    if(json_pack_ex(&error, 0, "[i]a", 42))
        fail("json_pack failed to catch garbage after format string");
    check_error("Garbage after format string", "<format>", 1, 4, 4);

    if(json_pack_ex(&error, 0, "ia", 42))
        fail("json_pack failed to catch garbage after format string");
    check_error("Garbage after format string", "<format>", 1, 2, 2);

    /* NULL string */
    if(json_pack_ex(&error, 0, "s", NULL))
        fail("json_pack failed to catch null argument string");
    check_error("NULL string argument", "<args>", 1, 1, 1);

    /* + on its own */
    if(json_pack_ex(&error, 0, "+", NULL))
        fail("json_pack failed to a lone +");
    check_error("Unexpected format character '+'", "<format>", 1, 1, 1);

    /* NULL format */
    if(json_pack_ex(&error, 0, NULL))
        fail("json_pack failed to catch NULL format string");
    check_error("NULL or empty format string", "<format>", -1, -1, 0);

    /* NULL key */
    if(json_pack_ex(&error, 0, "{s:i}", NULL, 1))
        fail("json_pack failed to catch NULL key");
    check_error("NULL string argument", "<args>", 1, 2, 2);

    /* More complicated checks for row/columns */
    if(json_pack_ex(&error, 0, "{ {}: s }", "foo"))
        fail("json_pack failed to catch object as key");
    check_error("Expected format 's', got '{'", "<format>", 1, 3, 3);

    /* Complex object */
    if(json_pack_ex(&error, 0, "{ s: {},  s:[ii{} }", "foo", "bar", 12, 13))
        fail("json_pack failed to catch missing ]");
    check_error("Unexpected format character '}'", "<format>", 1, 19, 19);

    /* Complex array */
    if(json_pack_ex(&error, 0, "[[[[[   [[[[[  [[[[ }]]]] ]]]] ]]]]]"))
        fail("json_pack failed to catch extra }");
    check_error("Unexpected format character '}'", "<format>", 1, 21, 21);

    /* Invalid UTF-8 in object key */
    if(json_pack_ex(&error, 0, "{s:i}", "\xff\xff", 42))
        fail("json_pack failed to catch invalid UTF-8 in an object key");
    check_error("Invalid UTF-8 object key", "<args>", 1, 2, 2);

    /* Invalid UTF-8 in a string */
    if(json_pack_ex(&error, 0, "{s:s}", "foo", "\xff\xff"))
        fail("json_pack failed to catch invalid UTF-8 in a string");
    check_error("Invalid UTF-8 string", "<args>", 1, 4, 4);
}
Exemplo n.º 24
0
int janssonmod_set(unsigned int append, struct sip_msg* msg, char* type_in,
		 char* path_in, char* value_in, char* result_in)
{
	str type_s;
	str value_s;
	str path_s;

	pv_spec_t* result_pv;
	pv_value_t result_val;

	if (fixup_get_svalue(msg, (gparam_p)type_in, &type_s) != 0){
		ERR("cannot get type string value\n");
		return -1;
	}

	if (fixup_get_svalue(msg, (gparam_p)value_in, &value_s) != 0){
		ERR("cannot get value string\n");
		return -1;
	}

	if (fixup_get_svalue(msg, (gparam_p)path_in, &path_s) != 0){
		ERR("cannot get path string value\n");
		return -1;
	}

	result_pv = (pv_spec_t *)result_in;

	if(pv_get_spec_value(msg, result_pv, &result_val)!=0
			|| result_val.flags != PV_VAL_STR) {
		result_val.flags = PV_VAL_STR;
		result_val.rs.s = "{}";
		result_val.rs.len = strlen("{}");
	}

/*
	ALERT("type is: %.*s\n", type_s.len, type_s.s);
	ALERT("path is: %.*s\n", path_s.len, path_s.s);
	ALERT("value is: %.*s\n", value_s.len, value_s.s);
	ALERT("result is: %.*s\n", result_val.rs.len, result_val.rs.s);
*/

	char* result = result_val.rs.s;

	json_t* result_json = NULL;
	json_t* value = NULL;
	char* freeme = NULL;
	json_error_t parsing_error = {0};
	char* endptr;

	/* check the type */
	if(STR_EQ_STATIC(type_s, "object") || STR_EQ_STATIC(type_s, "obj")){
		value = json_loads(value_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
		if(value && !json_is_object(value)) {
			ERR("value to add is not an object - \"%s\"\n", path_s.s);
			goto fail;
		}

	}else if(STR_EQ_STATIC(type_s, "array")) {
		value = json_loads(value_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
		if(value && !json_is_array(value)) {
			ERR("value to add is not an array - \"%s\"\n", path_s.s);
			goto fail;
		}

	}else if(STR_EQ_STATIC(type_s, "string")
				|| STR_EQ_STATIC(type_s, "str")) {
		value = json_string(value_s.s);
		if(!value || !json_is_string(value)) {
			ERR("value to add is not a string - \"%s\"\n", path_s.s);
			goto fail;
		}

	}else if(STR_EQ_STATIC(type_s, "integer")
				|| STR_EQ_STATIC(type_s, "int")) {
		long long i = strtoll(value_s.s, &endptr, 10);
		if(*endptr != '\0') {
			ERR("parsing int failed for \"%s\" - \"%s\"\n", path_s.s, value_s.s);
			goto fail;
		}
		value = json_integer(i);
		if(!value || !json_is_integer(value)) {
			ERR("value to add is not an integer \"%s\"\n", path_s.s);
			goto fail;
		}

	}else if(STR_EQ_STATIC(type_s, "real")) {
		double d = strtod(value_s.s, &endptr);
		if(*endptr != '\0') {
			ERR("parsing real failed for \"%s\" - \"%s\"\n", path_s.s, value_s.s);
			goto fail;
		}
		value = json_real(d);
		if(!value || !json_is_real(value)) {
			ERR("value to add is not a real \"%s\"\n", path_s.s);
			goto fail;
		}

	}else if(STR_EQ_STATIC(type_s, "true")) {
		value = json_true();

	}else if(STR_EQ_STATIC(type_s, "false")) {
		value = json_false();

	}else if(STR_EQ_STATIC(type_s, "null")) {
		value = json_null();

	} else {
		ERR("unrecognized input type\n");
		goto fail;
	}

	if(!value) {
		ERR("parsing failed for \"%s\"\n", value_s.s);
		ERR("value error at line %d: %s\n",
				parsing_error.line, parsing_error.text);
		goto fail;
	}

	char* path = path_s.s;

	result_json = json_loads(result, JSON_REJECT_DUPLICATES, &parsing_error);

	if(!result_json) {
		ERR("result has json error at line %d: %s\n",
				parsing_error.line, parsing_error.text);
		goto fail;
	}

	if(json_path_set(result_json, path, value, append)<0) {
		goto fail;
	}

	if(jansson_to_val(&result_val, &freeme, result_json)<0) goto fail;

	result_pv->setf(msg, &result_pv->pvp, (int)EQ_T, &result_val);

	if(freeme) free(freeme);
	json_decref(result_json);
	return 1;

fail:
	if(freeme) free(freeme);
	json_decref(result_json);
	return -1;
}
Exemplo n.º 25
0
bool TwitPic::parseJSON(const string& json, TwitPicResult& result) {
	printf("result:\n%s\n", json.c_str());
	json_t* root;
	json_error_t error;
	
	root = json_loads(json.c_str(), 0, &error);
	if(!root) {
		printf("Error: on line: %d, %s\n", error.line, error.text);
		json_decref(root);
		return false;
	}
	
	// id
	json_t* node = json_object_get(root, "id");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no id found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.id_str = json_string_value(node);
	}
	
	// text
	node = json_object_get(root, "text");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no text found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.text = json_string_value(node);
	}

	// url
	node = json_object_get(root, "url");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no url found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.url = json_string_value(node);
	}
	
	// width
	node = json_object_get(root, "width");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no width found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_integer(node)) {
		result.width = json_integer_value(node);
	}

	// height
	node = json_object_get(root, "height");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no height found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_integer(node)) {
		result.height = json_integer_value(node);
	}
	
	// size
	node = json_object_get(root, "size");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no size found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_integer(node)) {
		result.size = json_integer_value(node);
	}

	// type
	node = json_object_get(root, "type");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no type found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.type = json_string_value(node);
	}
	
	// timestamp
	node = json_object_get(root, "timestamp");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no timestamp found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_string(node)) {
		result.timestamp = json_string_value(node);
	}
	
	// user
	// --------------
	json_t* subnode = json_object_get(root, "user");
	if(node == NULL) {
		printf("Error: cannot parse twitpic result, no user found.\n");
		json_decref(root);
		return false;
	}
	if(json_is_object(subnode)) {
		// user_id
		node = json_object_get(subnode, "id");
		if(node == NULL) {
			printf("Error: cannot parse twitpic result, no user id found.\n");
			json_decref(root);
			return false;
		}
		if(json_is_integer(node)) {
			result.user_id = json_integer_value(node);
		}
		
		// user_screen_name
		node = json_object_get(subnode, "screen_name");
		if(node == NULL) {
			printf("Error: cannot parse twitpic result, no user screen_name found.\n");
			json_decref(root);
			return false;
		}
		if(json_is_string(node)) {
			result.user_screen_name = json_string_value(node);
		}
	}
	result.print();
	return true;
}
/* Thread to handle incoming messages */
static void *janus_source_handler(void *data) {
	JANUS_LOG(LOG_VERB, "Joining SourcePlugin handler thread\n");
	janus_source_message *msg = NULL;
	int error_code = 0;
	char *error_cause = g_malloc0(512);
	json_t *root = NULL;
	while (g_atomic_int_get(&initialized) && !g_atomic_int_get(&stopping)) {
		msg = g_async_queue_pop(messages);
		if (msg == NULL)
			continue;
		if (msg == &exit_message)
			break;
		if (msg->handle == NULL) {
			janus_source_message_free(msg);
			continue;
		}
		janus_source_session *session = NULL;
		janus_mutex_lock(&sessions_mutex);
		if (g_hash_table_lookup(sessions, msg->handle) != NULL) {
			session = (janus_source_session *)msg->handle->plugin_handle;
		}
		janus_mutex_unlock(&sessions_mutex);
		if (!session) {
			JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
			janus_source_message_free(msg);
			continue;
		}
		if (session->destroyed) {
			janus_source_message_free(msg);
			continue;
		}
		/* Handle request */
		error_code = 0;
		root = msg->message;
		if (msg->message == NULL) {
			JANUS_LOG(LOG_ERR, "No message??\n");
			error_code = JANUS_SOURCE_ERROR_NO_MESSAGE;
			g_snprintf(error_cause, 512, "%s", "No message??");
			goto error;
		}
		if (!json_is_object(root)) {
			JANUS_LOG(LOG_ERR, "JSON error: not an object\n");
			error_code = JANUS_SOURCE_ERROR_INVALID_JSON;
			g_snprintf(error_cause, 512, "JSON error: not an object");
			goto error;
		}
		/* Parse request */
		const char *msg_sdp_type = json_string_value(json_object_get(msg->jsep, "type"));
		const char *msg_sdp = json_string_value(json_object_get(msg->jsep, "sdp"));
		json_t *audio = json_object_get(root, "audio");
		if (audio && !json_is_boolean(audio)) {
			JANUS_LOG(LOG_ERR, "Invalid element (audio should be a boolean)\n");
			error_code = JANUS_SOURCE_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (audio should be a boolean)");
			goto error;
		}
		json_t *video = json_object_get(root, "video");
		if (video && !json_is_boolean(video)) {
			JANUS_LOG(LOG_ERR, "Invalid element (video should be a boolean)\n");
			error_code = JANUS_SOURCE_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (video should be a boolean)");
			goto error;
		}
		json_t *bitrate = json_object_get(root, "bitrate");
		if (bitrate && (!json_is_integer(bitrate) || json_integer_value(bitrate) < 0)) {
			JANUS_LOG(LOG_ERR, "Invalid element (bitrate should be a positive integer)\n");
			error_code = JANUS_SOURCE_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (bitrate should be a positive integer)");
			goto error;
		}
		json_t *record = json_object_get(root, "record");
		if (record && !json_is_boolean(record)) {
			JANUS_LOG(LOG_ERR, "Invalid element (record should be a boolean)\n");
			error_code = JANUS_SOURCE_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (record should be a boolean)");
			goto error;
		}
		json_t *recfile = json_object_get(root, "filename");
		if (recfile && !json_is_string(recfile)) {
			JANUS_LOG(LOG_ERR, "Invalid element (filename should be a string)\n");
			error_code = JANUS_SOURCE_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Invalid value (filename should be a string)");
			goto error;
		}
		
		json_t *id = json_object_get(root, "id");
		if(id && !json_is_string(id)) {
				JANUS_LOG(LOG_ERR, "Invalid element (id should be a string)\n");
				error_code = JANUS_SOURCE_ERROR_INVALID_ELEMENT;
				g_snprintf(error_cause, 512, "Invalid value (id should be positive string)");
				goto error;
		}
		/* Enforce request */
		if (audio) {
			session->audio_active = json_is_true(audio);
			JANUS_LOG(LOG_VERB, "Setting audio property: %s\n", session->audio_active ? "true" : "false");
		}
		if (video) {
			if (!session->video_active && json_is_true(video)) {
				/* Send a PLI */
				JANUS_LOG(LOG_VERB, "Just (re-)enabled video, sending a PLI to recover it\n");
				char buf[12];
				memset(buf, 0, 12);
				janus_rtcp_pli((char *)&buf, 12);
				gateway->relay_rtcp(session->handle, 1, buf, 12);
			}
			session->video_active = json_is_true(video);
			JANUS_LOG(LOG_VERB, "Setting video property: %s\n", session->video_active ? "true" : "false");
		}
		if (bitrate) {
			session->bitrate = json_integer_value(bitrate);
			JANUS_LOG(LOG_VERB, "Setting video bitrate: %"SCNu64"\n", session->bitrate);
			if (session->bitrate > 0) {
				/* FIXME Generate a new REMB (especially useful for Firefox, which doesn't send any we can cap later) */
				char buf[24];
				memset(buf, 0, 24);
				janus_rtcp_remb((char *)&buf, 24, session->bitrate);
				JANUS_LOG(LOG_VERB, "Sending REMB\n");
				gateway->relay_rtcp(session->handle, 1, buf, 24);
				/* FIXME How should we handle a subsequent "no limit" bitrate? */
			}
		}
		if(id) {
			session->id = g_strdup(json_string_value(id));			
		}


		if (!audio && !video && !bitrate && !record && !id && !msg_sdp) {
			JANUS_LOG(LOG_ERR, "No supported attributes (audio, video, bitrate, record, id, jsep) found\n");
			error_code = JANUS_SOURCE_ERROR_INVALID_ELEMENT;
			g_snprintf(error_cause, 512, "Message error: no supported attributes (audio, video, bitrate, record, id, jsep) found");
			goto error;
		}

		/* Prepare JSON event */
		json_t *event = json_object();
		json_object_set_new(event, "source", json_string("event"));
		json_object_set_new(event, "result", json_string("ok"));
		if(!msg_sdp) {
			int ret = gateway->push_event(msg->handle, &janus_source_plugin, msg->transaction, event, NULL);
			JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
			json_decref(event);
		}
		else {
			/* Forward the same offer to the gateway, to start the source plugin */
			const char *type = NULL;
			if (!strcasecmp(msg_sdp_type, "offer"))
				type = "answer";
			if (!strcasecmp(msg_sdp_type, "answer"))
				type = "offer";
			/* Any media direction that needs to be fixed? */
			char *sdp = g_strdup(msg_sdp);
			if (strstr(sdp, "a=recvonly")) {
				/* Turn recvonly to inactive, as we simply bounce media back */
				sdp = janus_string_replace(sdp, "a=recvonly", "a=inactive");
			}
			else if (strstr(sdp, "a=sendonly")) {
				/* Turn sendonly to recvonly */
				sdp = janus_string_replace(sdp, "a=sendonly", "a=recvonly");
				/* FIXME We should also actually not echo this media back, though... */
			}
			/* Make also sure we get rid of ULPfec, red, etc. */
			if (strstr(sdp, "ulpfec")) {
				/* FIXME This really needs some better code */
				sdp = janus_string_replace(sdp, "a=rtpmap:116 red/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:117 ulpfec/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:96 rtx/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=fmtp:96 apt=100\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:97 rtx/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=fmtp:97 apt=101\r\n", "");
				sdp = janus_string_replace(sdp, "a=rtpmap:98 rtx/90000\r\n", "");
				sdp = janus_string_replace(sdp, "a=fmtp:98 apt=116\r\n", "");
				sdp = janus_string_replace(sdp, " 116", "");
				sdp = janus_string_replace(sdp, " 117", "");
				sdp = janus_string_replace(sdp, " 96", "");
				sdp = janus_string_replace(sdp, " 97", "");
				sdp = janus_string_replace(sdp, " 98", "");
			}
			json_t *jsep = json_pack("{ssss}", "type", type, "sdp", sdp);
			sdp = janus_source_do_codec_negotiation(session, sdp);
			
			/* How long will the gateway take to push the event? */
			g_atomic_int_set(&session->hangingup, 0);
			gint64 start = janus_get_monotonic_time();
			int res = gateway->push_event(msg->handle, &janus_source_plugin, msg->transaction, event, jsep);
			JANUS_LOG(LOG_VERB, "  >> Pushing event: %d (took %"SCNu64" us)\n",
				res, janus_get_monotonic_time() - start);
			g_free(sdp);
			/* We don't need the event and jsep anymore */
			json_decref(event);
			json_decref(jsep);
		}
		janus_source_message_free(msg);
		continue;

	error:
		{
			/* Prepare JSON error event */
			json_t *event = json_object();
			json_object_set_new(event, "source", json_string("event"));
			json_object_set_new(event, "error_code", json_integer(error_code));
			json_object_set_new(event, "error", json_string(error_cause));
			int ret = gateway->push_event(msg->handle, &janus_source_plugin, msg->transaction, event, NULL);
			JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
			janus_source_message_free(msg);
			/* We don't need the event anymore */
			json_decref(event);
		}
	}
	g_free(error_cause);
	JANUS_LOG(LOG_VERB, "Leaving SourcePlugin handler thread\n");
	return NULL;
}
Exemplo n.º 27
0
bool TrafficNetwork::loadFromFile(const string fileName){
	int nbBands;
	long currentNode,otherNode;
	string roadName;
	double roadLength;
	double roadSpeedLimit;
	int metric;

	json_t *root;
	json_error_t error;

	root = json_load_file(fileName.c_str(), 0, &error);

	if(!root){
		std::cout<<std::endl<<"ERROR: while opening "<<fileName<<" at line "<<error.line<<" - "<<error.text<<std::endl;
		return false;
	}

	if(!json_is_object(root)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - expected root to be an object"<<std::endl;
		json_decref(root);
		return false;
	}

	json_t *_metric, *_roads, *_nodes;
	_metric = json_object_get(root,"metric");

	if(!json_is_integer(_metric)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'metric' field not present or wrong type"<<std::endl;
		json_decref(root);
		return false;
	}
	metric = json_integer_value(_metric);

	_nodes = json_object_get(root,"nodes");
	if(!json_is_array(_nodes)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'nodes' field not present or not an array"<<std::endl;
		json_decref(root);
		return false;
	}

	size_t n = json_array_size(_nodes);
	nbNodes = n;
	nodes = NodeVec(nbNodes);
	json_t *nodeId,*_node, *nodeType;
	for(size_t i = 0; i < n; i++){
		_node = json_array_get(_nodes,i);
		if(!json_is_object(_node)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - expected node "<<i<<" to be an object"<<std::endl;
			json_decref(root);
			return false;
		}
		nodeId = json_object_get(_node,"id");
		if(!json_is_integer(nodeId)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'id' field of node "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		nodeType = json_object_get(_node,"type");
		if(json_is_integer(nodeType)){
			nodes[i] = new Node(json_integer_value(nodeId),json_integer_value(nodeType));
		}else{
			nodes[i] = new Node(json_integer_value(nodeId));
		}

	}

	_roads = json_object_get(root,"roads");
	if(!json_is_array(_roads)){
		std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'roads' field not present or not an array"<<std::endl;
		json_decref(root);
		return false;
	}

	n = json_array_size(_roads);
	json_t *_roadName,*_roadSpeedLimit,*_roadNbBands,*_roadLength,*_road,*startId,*endId;
	for(size_t i = 0; i < n; i++){
		_road = json_array_get(_roads,i);
		if(!json_is_object(_road)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - expected road "<<i<<" to be an object"<<std::endl;
			json_decref(root);
			return false;
		}

		_roadName = json_object_get(_road,"name");
		if(!json_is_string(_roadName)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'name' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		roadName = json_string_value(_roadName);

		_roadSpeedLimit = json_object_get(_road,"speedLimit");
		if(!json_is_integer(_roadSpeedLimit)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'speedLimit' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		roadSpeedLimit = formatSpeedLimit(json_integer_value(_roadSpeedLimit),metric);

		_roadLength = json_object_get(_road,"length");
		if(!json_is_real(_roadLength)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'length' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		roadLength = formatLength(json_real_value(_roadLength),metric);

		_roadNbBands = json_object_get(_road,"nbBands");
		if(!json_is_integer(_roadNbBands)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'nbBands' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		nbBands = json_integer_value(_roadNbBands);

		startId = json_object_get(_road,"startId");
		if(!json_is_integer(startId)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'startId' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		currentNode = json_integer_value(startId);

		endId = json_object_get(_road,"endId");
		if(!json_is_integer(endId)){
			std::cout<<std::endl<<"ERROR: input file "<<fileName<<" has not the correct structure - 'endId' field of road "<<i<<" not present or wrong type"<<std::endl;
			json_decref(root);
			return false;
		}
		otherNode = json_integer_value(endId);
		addRoad(currentNode, otherNode, roadName, roadLength, roadSpeedLimit,nbBands);
	}
	//clean up
	json_array_clear(_nodes);
	json_object_clear(_road);
	json_array_clear(_roads);
	json_object_clear(root);
	json_decref(root);
	return true;
}
Exemplo n.º 28
0
CCObject* NDKHelper::GetCCObjectFromJson(json_t *obj)
{
    if (obj == NULL)
        return NULL;
    
    if (json_is_object(obj))
    {
        CCDictionary *dictionary = new CCDictionary();
        //CCDictionary::create();
        
        const char *key;
        json_t *value;
        
        void *iter = json_object_iter(obj);
        while(iter)
        {
            key = json_object_iter_key(iter);
            value = json_object_iter_value(iter);
            
            dictionary->setObject(NDKHelper::GetCCObjectFromJson(value)->autorelease(), string(key));
            
            iter = json_object_iter_next(obj, iter);
        }
        
        return dictionary;
    }
    else if (json_is_array(obj))
    {
        size_t sizeArray = json_array_size(obj);
        CCArray *array = new CCArray();
        //CCArray::createWithCapacity(sizeArray);
        
        for (unsigned int i = 0; i < sizeArray; i++)
        {
            array->addObject(NDKHelper::GetCCObjectFromJson(json_array_get(obj, i))->autorelease());
        }
        
        return array;
    }
    else if (json_is_boolean(obj))
    {
        stringstream str;
        if (json_is_true(obj))
            str << true;
        else if (json_is_false(obj))
            str << false;
        
        CCString *ccString = new CCString(str.str());
        //CCString::create(str.str());
        return ccString;
    }
    else if (json_is_integer(obj))
    {
        stringstream str;
        str << json_integer_value(obj);
        
        CCString *ccString = new CCString(str.str());
        //CCString::create(str.str());
        return ccString;
    }
    else if (json_is_real(obj))
    {
        stringstream str;
        str << json_real_value(obj);
        
        CCString *ccString = new CCString(str.str());
        //CCString::create(str.str());
        return ccString;
    }
    else if (json_is_string(obj))
    {
        stringstream str;
        str << json_string_value(obj);
        
        CCString *ccString = new CCString(str.str());
        //CCString::create(str.str());
        return ccString;
    }
    
    return NULL;
}
Exemplo n.º 29
0
static void send_json(char* str, size_t len)
{
	json_t* root, *cmd, *data, *data_len, *ip, *port;
	json_error_t error;
	root = json_loads(str, 0, &error);

	if(!root || !json_is_object(root))
	{
		fprintf(stderr, "JSON: Error on line %d: %s\n", error.line, error.text);
		return;
	}
	cmd = json_object_get(root, "cmd");
	if(!json_is_integer(cmd))
	{
		fprintf(stderr, "JSON: cmd is not an integer\n");
		json_decref(root);
		return;
	}
	data = json_object_get(root, "data");
	if(!json_is_null(data) && !json_is_string(data))
	{
		fprintf(stderr, "JSON: data is not a string\n");
		json_decref(root);
		return;
	}
	data_len = json_object_get(root, "data_len");
	if(!json_is_integer(cmd))
	{
		fprintf(stderr, "JSON: data_len is not an integer\n");
		json_decref(root);
		return;
	}

	ip = json_object_get(root, "ip");
	if(!ip || !json_is_string(ip))
	{
		json_decref(ip);
		ip=NULL;
	}

	port = json_object_get(root, "port");
	if(!port || !json_is_integer(port))
	{
		json_decref(port);
		port=NULL;
	}

	int t_int = json_integer_value(cmd);
	if(t_int == -1)
	{
		welcome_message_sent=0;
		json_decref(root);
		return;
	}
	EventType t=(EventType)t_int;
	int datalen=json_integer_value(data_len);
	printf("Got: %s\n", str);
	if(ip && port)
	{
		event_send_simple_to_addr(t, datalen ? json_string_value(data) : NULL, datalen, json_string_value(ip), json_integer_value(port), corefd);
	}
	else
	{
		event_send_simple(t, datalen ? json_string_value(data) : NULL, datalen, corefd);
	}
	json_decref(root);
	// TODO: Does other json_t* variables need to be decref'd?
	return;
}
Exemplo n.º 30
0
/*
 ******************************************************************************
 * dgadmin_rest_sync_version_resp_parser --                                   *//**
 *
 * \brief This routine parses response of version GET request
 *
 * \param [in]	body_buf	A pointer to a version response buffer. 
 *
 * \param [out]	version		The version.
 * \param [out]	target_uri	The URI of the HTTP request.
 * \param [out]	operation	The operation which acts on the URI. Now
 * 				support GET and DELETE.
 *
 * \retval 0 	Success
 * \retval >0 	Failure
 *
 *****************************************************************************/
static int dgadmin_rest_sync_version_resp_parser(char *body_buf, int *version, char *target_uri, int *operation)
{
	json_t *js_root = NULL;
	json_t *js_version = NULL, *js_uri = NULL, *js_operation = NULL;
	json_error_t jerror;
	const char *uri, *operation_str;
	int ret = DOVE_STATUS_ERROR;

	do
	{
		js_root = json_loads(body_buf, 0, &jerror);
		if (!js_root)
		{
			log_notice(ServiceUtilLogLevel,"JSON body NULL");
			break;
		}

		/* Borrowed reference, no need to decref */
		js_version = json_object_get(js_root, "next_change");
		if (!json_is_integer(js_version))
		{
            log_notice(ServiceUtilLogLevel,"ERROR");
			break;
		}
		*version = json_integer_value(js_version);

		js_uri = json_object_get(js_root, "uri");
		if (!json_is_string(js_uri))
		{
            log_notice(ServiceUtilLogLevel,"ERROR");
			break;
		}
		if ((uri = json_string_value(js_uri)) == NULL)
		{
            log_notice(ServiceUtilLogLevel,"ERROR");
			break;
		}
		strcpy(target_uri, uri);

		js_operation = json_object_get(js_root, "method");
		if (!json_is_string(js_operation))
		{
            log_notice(ServiceUtilLogLevel,"ERROR");
			break;
		}
		if ((operation_str = json_string_value(js_operation)) == NULL)
		{
            log_notice(ServiceUtilLogLevel,"ERROR");
			break;
		}
		if (!strcmp(operation_str, "GET"))
		{
			*operation = DGADMIN_REST_SYNC_OPERATION_GET;
		}
		else if (!strcmp(operation_str, "DELETE"))
		{
			*operation = DGADMIN_REST_SYNC_OPERATION_DELETE;
		}
		else
		{
            if(uri && (strlen(uri)))
            {
                log_notice(ServiceUtilLogLevel,"ERROR");
			    break;
            }
		}

		ret = DOVE_STATUS_OK;
	} while(0);


	if (js_root)
	{
		json_decref(js_root);
	}

	return ret;
}