Пример #1
0
static guint
json_parse_object (JsonParser   *parser,
                   JsonScanner  *scanner,
                   JsonNode    **node)
{
  JsonParserPrivate *priv = parser->priv;
  JsonObject *object;
  JsonNode *old_current;
  guint token;

  old_current = priv->current_node;
  priv->current_node = json_node_init_object (json_node_alloc (), NULL);

  object = json_object_new ();

  token = json_scanner_get_next_token (scanner);
  g_assert (token == G_TOKEN_LEFT_CURLY);

  g_signal_emit (parser, parser_signals[OBJECT_START], 0);

  while (token != G_TOKEN_RIGHT_CURLY)
    {
      guint next_token = json_scanner_peek_next_token (scanner);
      JsonNode *member = NULL;
      gchar *name;

      /* we need to abort here because empty objects do not
       * have member names
       */
      if (next_token == G_TOKEN_RIGHT_CURLY)
        break;

      /* parse the member's name */
      if (next_token != G_TOKEN_STRING)
        {
          JSON_NOTE (PARSER, "Missing object member name");

          priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD;

          json_object_unref (object);
          json_node_unref (priv->current_node);
          priv->current_node = old_current;

          return G_TOKEN_STRING;
        }

      /* member name */
      token = json_scanner_get_next_token (scanner);
      name = g_strdup (scanner->value.v_string);
      if (name == NULL)
        {
          JSON_NOTE (PARSER, "Empty object member name");

          priv->error_code = JSON_PARSER_ERROR_EMPTY_MEMBER_NAME;

          json_object_unref (object);
          json_node_unref (priv->current_node);
          priv->current_node = old_current;

          return G_TOKEN_STRING;
        }

      JSON_NOTE (PARSER, "Object member '%s'", name);

      /* a colon separates names from values */
      next_token = json_scanner_peek_next_token (scanner);
      if (next_token != ':')
        {
          JSON_NOTE (PARSER, "Missing object member name separator");

          priv->error_code = JSON_PARSER_ERROR_MISSING_COLON;

          g_free (name);
          json_object_unref (object);
          json_node_unref (priv->current_node);
          priv->current_node = old_current;

          return ':';
        }

      /* we swallow the ':' */
      token = json_scanner_get_next_token (scanner);
      g_assert (token == ':');
      next_token = json_scanner_peek_next_token (scanner);

      /* parse the member's value */
      switch (next_token)
        {
        case G_TOKEN_LEFT_BRACE:
          JSON_NOTE (PARSER, "Nested array at member %s", name);
          token = json_parse_array (parser, scanner, &member);
          break;

        case G_TOKEN_LEFT_CURLY:
          JSON_NOTE (PARSER, "Nested object at member %s", name);
          token = json_parse_object (parser, scanner, &member);
          break;

        default:
          /* once a member name is defined we need a value */
          token = json_scanner_get_next_token (scanner);
          token = json_parse_value (parser, scanner, token, &member);
          break;
        }

      if (token != G_TOKEN_NONE || member == NULL)
        {
          /* the json_parse_* functions will have set the error code */
          g_free (name);
          json_object_unref (object);
          json_node_unref (priv->current_node);
          priv->current_node = old_current;

          return token;
        }

      next_token = json_scanner_peek_next_token (scanner);
      if (next_token == G_TOKEN_COMMA)
        {
          token = json_scanner_get_next_token (scanner);
          next_token = json_scanner_peek_next_token (scanner);

          /* look for trailing commas */
          if (next_token == G_TOKEN_RIGHT_CURLY)
            {
              priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA;

              json_object_unref (object);
              json_node_unref (member);
              json_node_unref (priv->current_node);
              priv->current_node = old_current;

              return G_TOKEN_RIGHT_BRACE;
            }
        }
      else if (next_token == G_TOKEN_STRING)
        {
          priv->error_code = JSON_PARSER_ERROR_MISSING_COMMA;

          json_object_unref (object);
          json_node_unref (member);
          json_node_unref (priv->current_node);
          priv->current_node = old_current;

          return G_TOKEN_COMMA;
        }

      JSON_NOTE (PARSER, "Object member '%s' completed", name);
      json_node_set_parent (member, priv->current_node);
      if (priv->is_immutable)
        json_node_seal (member);
      json_object_set_member (object, name, member);

      g_signal_emit (parser, parser_signals[OBJECT_MEMBER], 0,
                     object,
                     name);

      g_free (name);

      token = next_token;
    }

  json_scanner_get_next_token (scanner);

  if (priv->is_immutable)
    json_object_seal (object);

  json_node_take_object (priv->current_node, object);
  if (priv->is_immutable)
    json_node_seal (priv->current_node);
  json_node_set_parent (priv->current_node, old_current);

  g_signal_emit (parser, parser_signals[OBJECT_END], 0, object);

  if (node != NULL && *node == NULL)
    *node = priv->current_node;

  priv->current_node = old_current;

  return G_TOKEN_NONE;
}
Пример #2
0
static guint
json_parse_object (JsonParser   *parser,
                   JsonScanner  *scanner,
                   JsonNode    **node)
{
  JsonParserPrivate *priv = parser->priv;
  JsonObject *object;
  JsonNode *old_current;
  guint token;

  old_current = priv->current_node;
  priv->current_node = json_node_new (JSON_NODE_OBJECT);

  object = json_object_new ();

  token = json_scanner_get_next_token (scanner);
  g_assert (token == G_TOKEN_LEFT_CURLY);

  g_signal_emit (parser, parser_signals[OBJECT_START], 0);

  while (token != G_TOKEN_RIGHT_CURLY)
    {
      guint next_token = json_scanner_peek_next_token (scanner);
      JsonNode *member = NULL;
      gchar *name;

      /* we need to abort here because empty objects do not
       * have member names
       */
      if (next_token == G_TOKEN_RIGHT_CURLY)
        break;

      /* parse the member's name */
      if (next_token != G_TOKEN_STRING)
        {
          json_object_unref (object);
          json_node_free (priv->current_node);
          priv->current_node = old_current;

          return G_TOKEN_STRING;
        }

      /* member name */
      token = json_scanner_get_next_token (scanner);
      name = g_strdup (scanner->value.v_string);

      /* a colon separates names from values */
      next_token = json_scanner_peek_next_token (scanner);
      if (next_token != ':')
        {
          g_free (name);
          json_object_unref (object);
          json_node_free (priv->current_node);
          priv->current_node = old_current;

          return ':';
        }

      /* we swallow the ':' */
      token = json_scanner_get_next_token (scanner);
      g_assert (token == ':');
      next_token = json_scanner_peek_next_token (scanner);

      /* parse the member's value */
      switch (next_token)
        {
        case G_TOKEN_LEFT_BRACE:
          token = json_parse_array (parser, scanner, &member);
          break;

        case G_TOKEN_LEFT_CURLY:
          token = json_parse_object (parser, scanner, &member);
          break;

        case G_TOKEN_INT:
        case G_TOKEN_FLOAT:
        case G_TOKEN_STRING:
        case '-':
        case JSON_TOKEN_TRUE:
        case JSON_TOKEN_FALSE:
        case JSON_TOKEN_NULL:
          token = json_scanner_get_next_token (scanner);
          token = json_parse_value (parser, scanner, token, &member);
          break;

        default:
          /* once a member name is defined we need a value */
          token = G_TOKEN_SYMBOL;
          break;
        }

      if (token != G_TOKEN_NONE || member == NULL)
        {
          /* the json_parse_* functions will have set the error code */
          g_free (name);
          json_object_unref (object);
          json_node_free (priv->current_node);
          priv->current_node = old_current;

          return token;
        }

      next_token = json_scanner_peek_next_token (scanner);
      if (next_token == G_TOKEN_COMMA)
        {
          token = json_scanner_get_next_token (scanner);
          next_token = json_scanner_peek_next_token (scanner);

          /* look for trailing commas */
          if (next_token == G_TOKEN_RIGHT_CURLY)
            {
              json_object_unref (object);
              json_node_free (member);
              json_node_free (priv->current_node);
              priv->current_node = old_current;

              return G_TOKEN_RIGHT_BRACE;
            }
        }
      else if (next_token == G_TOKEN_STRING)
        {
          json_object_unref (object);
          json_node_free (member);
          json_node_free (priv->current_node);
          priv->current_node = old_current;

          return G_TOKEN_COMMA;
        }

      json_node_set_parent (member, priv->current_node);
      json_object_set_member (object, name, member);

      g_signal_emit (parser, parser_signals[OBJECT_MEMBER], 0,
                     object,
                     name);

      g_free (name);

      token = next_token;
    }

  json_scanner_get_next_token (scanner);

  json_node_take_object (priv->current_node, object);
  json_node_set_parent (priv->current_node, old_current);

  g_signal_emit (parser, parser_signals[OBJECT_END], 0, object);

  if (node != NULL && *node == NULL)
    *node = priv->current_node;

  priv->current_node = old_current;

  return G_TOKEN_NONE;
}
Пример #3
0
JsonNode *
json_serialize_pspec (const GValue *real_value,
                      GParamSpec   *pspec)
{
  JsonNode *retval = NULL;
  JsonNodeType node_type;

  switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value)))
    {
    /* JSON native types */
    case G_TYPE_INT64:
      retval = json_node_init_int (json_node_alloc (), g_value_get_int64 (real_value));
      break;

    case G_TYPE_BOOLEAN:
      retval = json_node_init_boolean (json_node_alloc (), g_value_get_boolean (real_value));
      break;

    case G_TYPE_DOUBLE:
      retval = json_node_init_double (json_node_alloc (), g_value_get_double (real_value));
      break;

    case G_TYPE_STRING:
      retval = json_node_init_string (json_node_alloc (), g_value_get_string (real_value));
      break;

    /* auto-promoted types */
    case G_TYPE_INT:
      retval = json_node_init_int (json_node_alloc (), g_value_get_int (real_value));
      break;

    case G_TYPE_UINT:
      retval = json_node_init_int (json_node_alloc (), g_value_get_uint (real_value));
      break;

    case G_TYPE_LONG:
      retval = json_node_init_int (json_node_alloc (), g_value_get_long (real_value));
      break;

    case G_TYPE_ULONG:
      retval = json_node_init_int (json_node_alloc (), g_value_get_ulong (real_value));
      break;

    case G_TYPE_UINT64:
      retval = json_node_init_int (json_node_alloc (), g_value_get_uint64 (real_value));
      break;

    case G_TYPE_FLOAT:
      retval = json_node_init_double (json_node_alloc (), g_value_get_float (real_value));
      break;

    case G_TYPE_CHAR:
      retval = json_node_alloc ();
      json_node_init_int (retval, g_value_get_schar (real_value));
      break;

    case G_TYPE_UCHAR:
      retval = json_node_init_int (json_node_alloc (), g_value_get_uchar (real_value));
      break;

    case G_TYPE_ENUM:
      retval = json_node_init_int (json_node_alloc (), g_value_get_enum (real_value));
      break;

    case G_TYPE_FLAGS:
      retval = json_node_init_int (json_node_alloc (), g_value_get_flags (real_value));
      break;

    /* complex types */
    case G_TYPE_BOXED:
      if (G_VALUE_HOLDS (real_value, G_TYPE_STRV))
        {
          gchar **strv = g_value_get_boxed (real_value);
          gint i, strv_len;
          JsonArray *array;

          strv_len = g_strv_length (strv);
          array = json_array_sized_new (strv_len);

          for (i = 0; i < strv_len; i++)
            {
              JsonNode *str = json_node_new (JSON_NODE_VALUE);

              json_node_set_string (str, strv[i]);
              json_array_add_element (array, str);
            }

          retval = json_node_init_array (json_node_alloc (), array);
          json_array_unref (array);
        }
      else if (json_boxed_can_serialize (G_VALUE_TYPE (real_value), &node_type))
        {
          gpointer boxed = g_value_get_boxed (real_value);

          retval = json_boxed_serialize (G_VALUE_TYPE (real_value), boxed);
        }
      else
        g_warning ("Boxed type '%s' is not handled by JSON-GLib",
                   g_type_name (G_VALUE_TYPE (real_value)));
      break;

    case G_TYPE_OBJECT:
      {
        GObject *object = g_value_get_object (real_value);

        retval = json_node_alloc ();

        if (object != NULL)
          {
            json_node_init (retval, JSON_NODE_OBJECT);
            json_node_take_object (retval, json_gobject_dump (object));
          }
        else
          json_node_init_null (retval);
      }
      break;

    case G_TYPE_NONE:
      retval = json_node_new (JSON_NODE_NULL);
      break;

    default:
      g_warning ("Unsupported type `%s'", g_type_name (G_VALUE_TYPE (real_value)));
      break;
    }

  return retval;
}
int
main (int argc, char *argv[])
{
  GError *error = NULL;
  GOptionContext *context;
  JsonGenerator *gen;
  JsonNode *root;
  JsonObject *obj;
  JsonArray *array;
  int i;
  char *data;

  context = g_option_context_new ("- ISOM parsing test");
  g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
  g_option_context_add_group (context, gst_init_get_option_group ());
  if (!g_option_context_parse (context, &argc, &argv, &error)) {
    g_print ("option parsing failed: %s", error->message);
    exit (1);
  }
  g_option_context_free (context);

  if (argc < 2) {
    g_print ("need filename\n");
    exit (1);
  }

  array = json_array_new ();
  for (i = 1; i < argc; i++) {
    GssIsomParser *file;
    GssIsomTrack *video_track;
    GssIsomTrack *audio_track;
    JsonObject *object;
    JsonObject *o;
    gboolean ret;

    file = gss_isom_parser_new ();

    ret = gss_isom_parser_parse_file (file, argv[i]);
    if (!ret) {
      g_print ("parse failed");
      continue;
    }

    video_track = gss_isom_movie_get_video_track (file->movie);
    audio_track = gss_isom_movie_get_audio_track (file->movie);

    object = json_object_new ();
    json_object_set_string_member (object, "filename", argv[i]);
    if (video_track) {
      char *codec;

      o = json_object_new ();
      json_object_set_int_member (o, "track_id", video_track->tkhd.track_id);
      json_object_set_int_member (o, "bitrate", video_track->esds.avg_bitrate);
      codec = g_strdup_printf ("avc1.%02x%02x%02x",
          video_track->esds.codec_data[1],
          video_track->esds.codec_data[2], video_track->esds.codec_data[3]);
      json_object_set_string_member (o, "codec", codec);
      g_free (codec);
      json_object_set_string_member (o, "iv", random_iv_string ());
      json_object_set_object_member (object, "video", o);
    }
    if (audio_track) {
      o = json_object_new ();
      json_object_set_int_member (o, "track_id", audio_track->tkhd.track_id);
      json_object_set_int_member (o, "bitrate", audio_track->esds.avg_bitrate);
      json_object_set_string_member (o, "codec", "mp4a.40.2");  /* AAC LC */
      json_object_set_string_member (o, "iv", random_iv_string ());
      json_object_set_object_member (object, "audio", o);
    }

    json_array_add_object_element (array, object);

    gss_isom_parser_free (file);
  }

  obj = json_object_new ();
  json_object_set_int_member (obj, "version", 0);
  json_object_set_array_member (obj, "media", array);

  root = json_node_new (JSON_NODE_OBJECT);
  json_node_take_object (root, obj);
  gen = g_object_new (JSON_TYPE_GENERATOR,
      "root", root, "pretty", TRUE, "indent", 2, NULL);
  data = json_generator_to_data (gen, NULL);
  g_object_unref (gen);
  json_node_free (root);

  g_print ("%s\n", data);

  return 0;
}
static JsonNode *
gss_json_serialize_pspec (const GValue * real_value, GParamSpec * pspec)
{
  JsonNode *retval = NULL;
  GValue value = { 0, };
  JsonNodeType node_type;

  switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value))) {
    case G_TYPE_INT64:
    case G_TYPE_BOOLEAN:
    case G_TYPE_DOUBLE:
      /* JSON native types */
      retval = json_node_new (JSON_NODE_VALUE);
      g_value_init (&value, G_VALUE_TYPE (real_value));
      g_value_copy (real_value, &value);
      json_node_set_value (retval, &value);
      g_value_unset (&value);
      break;

    case G_TYPE_STRING:
      /* strings might be NULL, so we handle it differently */
      if (!g_value_get_string (real_value))
        retval = json_node_new (JSON_NODE_NULL);
      else {
        retval = json_node_new (JSON_NODE_VALUE);
        json_node_set_string (retval, g_value_get_string (real_value));
        break;
      }
      break;

    case G_TYPE_INT:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_int (retval, g_value_get_int (real_value));
      break;

    case G_TYPE_FLOAT:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_double (retval, g_value_get_float (real_value));
      break;

    case G_TYPE_BOXED:
      if (G_VALUE_HOLDS (real_value, G_TYPE_STRV)) {
        gchar **strv = g_value_get_boxed (real_value);
        gint i, strv_len;
        JsonArray *array;

        strv_len = g_strv_length (strv);
        array = json_array_sized_new (strv_len);

        for (i = 0; i < strv_len; i++) {
          JsonNode *str = json_node_new (JSON_NODE_VALUE);

          json_node_set_string (str, strv[i]);
          json_array_add_element (array, str);
        }

        retval = json_node_new (JSON_NODE_ARRAY);
        json_node_take_array (retval, array);
      } else if (json_boxed_can_serialize (G_VALUE_TYPE (real_value),
              &node_type)) {
        gpointer boxed = g_value_get_boxed (real_value);

        retval = json_boxed_serialize (G_VALUE_TYPE (real_value), boxed);
      } else
        g_warning ("Boxed type '%s' is not handled by JSON-GLib",
            g_type_name (G_VALUE_TYPE (real_value)));
      break;

    case G_TYPE_UINT:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_int (retval, g_value_get_uint (real_value));
      break;

    case G_TYPE_LONG:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_int (retval, g_value_get_long (real_value));
      break;

    case G_TYPE_ULONG:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_int (retval, g_value_get_long (real_value));
      break;

    case G_TYPE_CHAR:
      retval = json_node_new (JSON_NODE_VALUE);
#if GLIB_CHECK_VERSION (2, 31, 0)
      json_node_set_int (retval, g_value_get_schar (real_value));
#else
      json_node_set_int (retval, g_value_get_char (real_value));
#endif
      break;

    case G_TYPE_UCHAR:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_int (retval, g_value_get_uchar (real_value));
      break;

    case G_TYPE_ENUM:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_int (retval, g_value_get_enum (real_value));
      break;

    case G_TYPE_FLAGS:
      retval = json_node_new (JSON_NODE_VALUE);
      json_node_set_int (retval, g_value_get_flags (real_value));
      break;

    case G_TYPE_OBJECT:
    {
      GObject *object = g_value_get_object (real_value);

      if (object != NULL) {
        retval = json_node_new (JSON_NODE_OBJECT);
        json_node_take_object (retval, gss_json_gobject_dump (object));
      } else
        retval = json_node_new (JSON_NODE_NULL);
    }
      break;

    case G_TYPE_NONE:
      retval = json_node_new (JSON_NODE_NULL);
      break;

    default:
      g_warning ("Unsupported type `%s'",
          g_type_name (G_VALUE_TYPE (real_value)));
      break;
  }

  return retval;
}