/**
 * json_parser_load_from_data:
 * @parser: a #JsonParser
 * @data: the buffer to parse
 * @length: the length of the buffer, or -1
 * @error: return location for a #GError, or %NULL
 *
 * Loads a JSON stream from a buffer and parses it. You can call this function
 * multiple times with the same #JsonParser object, but the contents of the
 * parser will be destroyed each time.
 *
 * Return value: %TRUE if the buffer was succesfully parser. In case
 *   of error, @error is set accordingly and %FALSE is returned
 */
gboolean
json_parser_load_from_data (JsonParser   *parser,
                            const gchar  *data,
                            gssize        length,
                            GError      **error)
{
  JsonParserPrivate *priv;
  GError *internal_error;
  gboolean retval = TRUE;

  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
  g_return_val_if_fail (data != NULL, FALSE);

  priv = parser->priv;

  if (length < 0)
    length = strlen (data);

  priv->is_filename = FALSE;
  g_free (priv->filename);
  priv->filename = NULL;

  internal_error = NULL;
  if (!json_parser_load (parser, data, length, &internal_error))
    {
      g_propagate_error (error, internal_error);
      retval = FALSE;
    }

  return retval;
}
Exemple #2
0
/**
 * json_parser_load_from_stream_finish:
 * @parser: a #JsonParser
 * @result: a #GAsyncResult
 * @error: the return location for a #GError or %NULL
 *
 * Finishes an asynchronous stream loading started with
 * json_parser_load_from_stream_async().
 *
 * Return value: %TRUE if the content of the stream was successfully retrieves
 *   and parsed, and %FALSE otherwise. In case of error, the #GError will be
 *   filled accordingly.
 *
 * Since: 0.12
 */
gboolean
json_parser_load_from_stream_finish (JsonParser    *parser,
                                     GAsyncResult  *result,
                                     GError       **error)
{
  gboolean res;

  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
  g_return_val_if_fail (g_task_is_valid (result, parser), FALSE);

  res = g_task_propagate_boolean (G_TASK (result), error);
  if (res)
    {
      LoadData *data = g_task_get_task_data (G_TASK (result));
      GError *internal_error = NULL;

      /* We need to do this inside the finis() function because JsonParser will emit
       * signals, and we need to ensure that the signals are emitted in the right
       * context; it's easier to do that if we just rely on the async callback being
       * called in the right context, even if it means making the finish() function
       * necessary to complete the async operation.
       */
      res = json_parser_load (parser, (const gchar *) data->content->data, data->pos, &internal_error);
      if (internal_error != NULL)
        g_propagate_error (error, internal_error);
    }

  return res;
}
/**
 * json_parser_load_from_stream:
 * @parser: a #JsonParser
 * @stream: an open #GInputStream
 * @cancellable: (allow-none): a #GCancellable, or %NULL
 * @error: the return location for a #GError, or %NULL
 *
 * Loads the contents of an input stream and parses them.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by
 * triggering the @cancellable object from another thread. If the
 * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be set
 * on the passed @error.
 *
 * Return value: %TRUE if the data stream was successfully read and
 *   parsed, and %FALSE otherwise
 *
 * Since: 0.12
 */
gboolean
json_parser_load_from_stream (JsonParser    *parser,
                              GInputStream  *stream,
                              GCancellable  *cancellable,
                              GError       **error)
{
  GByteArray *content;
  gsize pos;
  gssize res;
  gboolean retval = FALSE;
  GError *internal_error;

  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
  g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return FALSE;

  content = g_byte_array_new ();
  pos = 0;

  g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1);
  while ((res = g_input_stream_read (stream, content->data + pos,
                                     GET_DATA_BLOCK_SIZE,
                                     cancellable, error)) > 0)
    {
      pos += res;
      g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1);
    }

  if (res < 0)
    {
      /* error has already been set */
      retval = FALSE;
      goto out;
    }

  /* zero-terminate the content; we allocated an extra byte for this */
  content->data[pos] = 0;

  internal_error = NULL;
  retval = json_parser_load (parser, (const gchar *) content->data, content->len, &internal_error);

  if (internal_error != NULL)
    g_propagate_error (error, internal_error);

out:
  g_byte_array_free (content, TRUE);

  return retval;
}
/**
 * json_parser_load_from_stream_finish:
 * @parser: a #JsonParser
 * @result: a #GAsyncResult
 * @error: the return location for a #GError or %NULL
 *
 * Finishes an asynchronous stream loading started with
 * json_parser_load_from_stream_async().
 *
 * Return value: %TRUE if the content of the stream was successfully retrieves
 *   and parsed, and %FALSE otherwise. In case of error, the #GError will be
 *   filled accordingly.
 *
 * Since: 0.12
 */
gboolean
json_parser_load_from_stream_finish (JsonParser    *parser,
                                     GAsyncResult  *result,
                                     GError       **error)
{
  GSimpleAsyncResult *simple;
  GError *internal_error;
  LoadStreamData *data;
  gboolean res;

  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
  g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);

  simple = G_SIMPLE_ASYNC_RESULT (result);

  if (g_simple_async_result_propagate_error (simple, error))
    return FALSE;

  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == json_parser_load_from_stream_async);

  data = g_simple_async_result_get_op_res_gpointer (simple);

  if (data->error)
    {
      g_propagate_error (error, data->error);
      data->error = NULL;
      return FALSE;
    }

  g_byte_array_set_size (data->content, data->pos + 1);
  data->content->data[data->pos] = 0;

  internal_error = NULL;
  res = json_parser_load (parser, (const gchar *) data->content->data, data->content->len, &internal_error);

  if (internal_error != NULL)
    g_propagate_error (error, internal_error);

  return res;
}
/**
 * json_parser_load_from_file:
 * @parser: a #JsonParser
 * @filename: the path for the file to parse
 * @error: return location for a #GError, or %NULL
 *
 * Loads a JSON stream from the content of @filename and parses it. See
 * json_parser_load_from_data().
 *
 * Return value: %TRUE if the file was successfully loaded and parsed.
 *   In case of error, @error is set accordingly and %FALSE is returned
 */
gboolean
json_parser_load_from_file (JsonParser   *parser,
                            const gchar  *filename,
                            GError      **error)
{
  JsonParserPrivate *priv;
  GError *internal_error;
  gchar *data;
  gsize length;
  gboolean retval = TRUE;

  g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE);
  g_return_val_if_fail (filename != NULL, FALSE);

  priv = parser->priv;

  internal_error = NULL;
  if (!g_file_get_contents (filename, &data, &length, &internal_error))
    {
      g_propagate_error (error, internal_error);
      return FALSE;
    }

  g_free (priv->filename);

  priv->is_filename = TRUE;
  priv->filename = g_strdup (filename);

  if (!json_parser_load (parser, data, length, &internal_error))
    {
      g_propagate_error (error, internal_error);
      retval = FALSE;
    }

  g_free (data);

  return retval;
}