Ejemplo n.º 1
0
int
main (int argc, char **argv)
{
    GConverter *converter;
    GFile *file;
    GFileInputStream *file_stream;
    GInputStream *stream;
    gchar buf[1024];
    gssize bytes;
        
    if (argc < 2) {
        g_printerr ("Usage: test-bz2 FILE\n");
        return 1;
    }

    file = g_file_new_for_path (argv[1]);
    file_stream = g_file_read (file, NULL, NULL);
    converter = G_CONVERTER (yelp_bz2_decompressor_new ());
    stream = g_converter_input_stream_new (G_INPUT_STREAM (file_stream),
                                           converter);

    while ((bytes = g_input_stream_read (stream, buf, 1024, NULL, NULL)) > 0) {
        gchar *out = g_strndup (buf, bytes);
        puts (out);
        g_free (out);
    }

    return 0;
}
Ejemplo n.º 2
0
/**
 * g_resource_open_stream:
 * @resource: A #GResource
 * @path: A pathname inside the resource
 * @lookup_flags: A #GResourceLookupFlags
 * @error: return location for a #GError, or %NULL
 *
 * Looks for a file at the specified @path in the resource and
 * returns a #GInputStream that lets you read the data.
 *
 * @lookup_flags controls the behaviour of the lookup.
 *
 * Returns: (transfer full): #GInputStream or %NULL on error.
 *     Free the returned object with g_object_unref()
 *
 * Since: 2.32
 **/
GInputStream *
g_resource_open_stream (GResource             *resource,
                        const gchar           *path,
                        GResourceLookupFlags   lookup_flags,
                        GError               **error)
{
  const void *data;
  gsize data_size;
  guint32 flags;
  GInputStream *stream, *stream2;

  if (!do_lookup (resource, path, lookup_flags, NULL, &flags, &data, &data_size, error))
    return NULL;

  stream = g_memory_input_stream_new_from_data (data, data_size, NULL);
  g_object_set_data_full (G_OBJECT (stream), "g-resource",
                          g_resource_ref (resource),
                          (GDestroyNotify)g_resource_unref);

  if (flags & G_RESOURCE_FLAGS_COMPRESSED)
    {
      GZlibDecompressor *decompressor =
        g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB);

      stream2 = g_converter_input_stream_new (stream, G_CONVERTER (decompressor));
      g_object_unref (decompressor);
      g_object_unref (stream);
      stream = stream2;
    }

  return stream;
}
Ejemplo n.º 3
0
/**
 * hwp_hwp3_parser_parse:
 * @parser: a #HwpHWP3Parser
 * @file: a #HwpHWP3File
 * @error: a #GError
 *
 * Since: 0.0.1
 */
void hwp_hwp3_parser_parse (HwpHWP3Parser *parser,
                            HwpHWP3File   *file,
                            GError       **error)
{
  g_return_if_fail (HWP_IS_HWP3_FILE (file));

  parser->stream = file->priv->stream;

  _hwp_hwp3_parser_parse_signature (parser, file, error);
  _hwp_hwp3_parser_parse_doc_info (parser, file, error);
  _hwp_hwp3_parser_parse_summary_info (parser, file, error);
  _hwp_hwp3_parser_parse_info_block (parser, file, error);

  if (file->is_compress) {
    GZlibDecompressor *zd;
    GInputStream      *cis;

    zd  = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW);
    cis = g_converter_input_stream_new (file->priv->stream, G_CONVERTER (zd));
    g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (cis),
                                                 TRUE);
    g_object_unref (file->priv->stream);
    file->priv->stream = g_object_ref (cis);
    g_object_unref (zd);
  }

  parser->stream = file->priv->stream;

  _hwp_hwp3_parser_parse_font_names (parser, file, error);
  _hwp_hwp3_parser_parse_styles (parser, file, error);
  _hwp_hwp3_parser_parse_paragraphs (parser, file, error);
  _hwp_hwp3_parser_parse_supplementary_info_block1 (parser, file, error);
  _hwp_hwp3_parser_parse_supplementary_info_block2 (parser, file, error);
}
Ejemplo n.º 4
0
GByteArray *
fb_util_zlib_inflate(const GByteArray *bytes, GError **error)
{
    GByteArray *ret;
    GZlibDecompressor *conv;

    conv = g_zlib_decompressor_new(G_ZLIB_COMPRESSOR_FORMAT_ZLIB);
    ret = fb_util_zlib_conv(G_CONVERTER(conv), bytes, error);
    g_object_unref(conv);
    return ret;
}
static GstBuffer *
create_overlay_buffer (void)
{
  GZlibDecompressor *decompress;
  GConverterResult decomp_res;
  guchar *gzipped_pixdata, *pixdata;
  gsize gzipped_size, bytes_read, pixdata_size;
  GstBuffer *logo_pixels;
  guint w, h, stride;

  gzipped_pixdata = g_base64_decode (gzipped_pixdata_base64, &gzipped_size);
  g_assert (gzipped_pixdata != NULL);

  pixdata = g_malloc (64 * 1024);

  decompress = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
  decomp_res = g_converter_convert (G_CONVERTER (decompress),
      gzipped_pixdata, gzipped_size, pixdata, 64 * 1024,
      G_CONVERTER_INPUT_AT_END, &bytes_read, &pixdata_size, NULL);
  g_assert (decomp_res == G_CONVERTER_FINISHED);
  g_assert (bytes_read == gzipped_size);
  g_free (gzipped_pixdata);
  g_object_unref (decompress);

  /* 0: Pixbuf magic (0x47646b50) */
  g_assert (GST_READ_UINT32_BE (pixdata) == 0x47646b50);

  /* 4: length incl. header */
  /* 8: pixdata_type */
  /* 12: rowstride (900) */
  stride = GST_READ_UINT32_BE (pixdata + 12);
  /* 16: width (225) */
  w = GST_READ_UINT32_BE (pixdata + 16);
  /* 20: height (57) */
  h = GST_READ_UINT32_BE (pixdata + 20);
  /* 24: pixel_data */
  GST_LOG ("%dx%d @ %d", w, h, stride);
  /* we assume that the last line also has padding at the end */
  g_assert (pixdata_size - 24 >= h * stride);

  logo_pixels = gst_buffer_new_and_alloc (h * stride);
  gst_buffer_fill (logo_pixels, 0, pixdata + 24, h * stride);
  gst_buffer_add_video_meta (logo_pixels, GST_VIDEO_FRAME_FLAG_NONE,
      GST_VIDEO_OVERLAY_COMPOSITION_FORMAT_RGB, w, h);

  g_free (pixdata);

  return logo_pixels;
}
Ejemplo n.º 6
0
/**
 * cockpit_web_response_gunzip:
 * @bytes: the compressed bytes
 * @error: place to put an error
 *
 * Perform gzip decompression on the @bytes.
 *
 * Returns: the uncompressed bytes, caller owns return value.
 */
GBytes *
cockpit_web_response_gunzip (GBytes *bytes,
                             GError **error)
{
  GConverter *converter;
  GConverterResult result;
  const guint8 *in;
  gsize inl, outl, read, written;
  GByteArray *out;

  converter = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));

  in = g_bytes_get_data (bytes, &inl);
  out = g_byte_array_new ();

  do
    {
      outl = out->len;
      g_byte_array_set_size (out, outl + inl);

      result = g_converter_convert (converter, in, inl, out->data + outl, inl,
                                    G_CONVERTER_INPUT_AT_END, &read, &written, error);
      if (result == G_CONVERTER_ERROR)
        break;

      g_byte_array_set_size (out, outl + written);
      in += read;
      inl -= read;
    }
  while (result != G_CONVERTER_FINISHED);

  g_object_unref (converter);

  if (result != G_CONVERTER_FINISHED)
    {
      g_byte_array_unref (out);
      return NULL;
    }
  else
    {
      return g_byte_array_free_to_bytes (out);
    }
}
Ejemplo n.º 7
0
static void
write_blob (int fd, struct eos_shard_writer_v1_blob_entry *blob)
{
  g_autoptr(GError) error = NULL;

  if (!blob->file)
    return;

  GFileInputStream *file_stream = g_file_read (blob->file, NULL, &error);
  if (!file_stream) {
    g_error ("Could not read from %s: %s", g_file_get_path (blob->file), error->message);
    return;
  }

  g_autoptr(GInputStream) stream;

  if (blob->flags & EOS_SHARD_BLOB_FLAG_COMPRESSED_ZLIB) {
    g_autoptr(GZlibCompressor) compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, -1);
    stream = g_converter_input_stream_new (G_INPUT_STREAM (file_stream), G_CONVERTER (compressor));
    g_object_unref (file_stream);
  } else {
    stream = G_INPUT_STREAM (file_stream);
  }

  blob->offs = lalign (fd);

  uint8_t buf[4096*4];
  int size, total_size = 0;
  g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256);
  while ((size = g_input_stream_read (stream, buf, sizeof (buf), NULL, NULL)) != 0) {
    g_assert (write (fd, buf, size) >= 0);
    g_checksum_update (checksum, buf, size);
    total_size += size;
  }
  size_t checksum_buf_len = sizeof (blob->checksum);
  g_checksum_get_digest (checksum, blob->checksum, &checksum_buf_len);
  g_assert (checksum_buf_len == sizeof (blob->checksum));

  blob->size = total_size;
}
Ejemplo n.º 8
0
bool gunzip_file(const char *path)
{
        GFile *in = NULL, *out = NULL;
        autofree(gchar) *newpath = NULL;
        autofree(GFileInputStream) *fis = NULL;
        autofree(GFileOutputStream) *fos = NULL;
        autofree(GOutputStream) *cos = NULL;
        autofree(GZlibDecompressor) *conv = NULL;
        gsize ret;

        newpath = g_strdup(path);

        if (g_str_has_suffix(newpath, ".gz")) {
                newpath = str_replace(newpath, ".gz", "");
        }

        in = g_file_new_for_path(path);
        out = g_file_new_for_path(newpath);

        fis = g_file_read(in, NULL, NULL);
        if (!fis) {
                return NULL;
        }
        fos = g_file_replace(out, NULL, FALSE, 0, NULL, NULL);
        if (!fos) {
                return NULL;
        }

        conv = g_zlib_decompressor_new(G_ZLIB_COMPRESSOR_FORMAT_GZIP);
        cos = g_converter_output_stream_new(G_OUTPUT_STREAM(fos), G_CONVERTER(conv));
        if (!cos) {
                return NULL;
        }
        ret = g_output_stream_splice(cos, G_INPUT_STREAM(fis), G_OUTPUT_STREAM_SPLICE_NONE, NULL, NULL);
        return (ret > 0 ? true : false );
}
static GCharsetConverter *
guess_encoding (GeditDocumentOutputStream *stream,
		const void                *inbuf,
		gsize                      inbuf_size)
{
	GCharsetConverter *conv = NULL;

	if (inbuf == NULL || inbuf_size == 0)
	{
		stream->priv->is_utf8 = TRUE;
		return NULL;
	}

	if (stream->priv->encodings != NULL &&
	    stream->priv->encodings->next == NULL)
	{
		stream->priv->use_first = TRUE;
	}

	/* We just check the first block */
	while (TRUE)
	{
		const GeditEncoding *enc;

		if (conv != NULL)
		{
			g_object_unref (conv);
			conv = NULL;
		}

		/* We get an encoding from the list */
		enc = get_encoding (stream);

		/* if it is NULL we didn't guess anything */
		if (enc == NULL)
		{
			break;
		}

		gedit_debug_message (DEBUG_UTILS, "trying charset: %s",
				     gedit_encoding_get_charset (stream->priv->current_encoding->data));

		if (enc == gedit_encoding_get_utf8 ())
		{
			gsize remainder;
			const gchar *end;
			
			if (g_utf8_validate (inbuf, inbuf_size, &end) ||
			    stream->priv->use_first)
			{
				stream->priv->is_utf8 = TRUE;
				break;
			}

			/* Check if the end is less than one char */
			remainder = inbuf_size - (end - (gchar *)inbuf);
			if (remainder < 6)
			{
				stream->priv->is_utf8 = TRUE;
				break;
			}

			continue;
		}

		conv = g_charset_converter_new ("UTF-8",
						gedit_encoding_get_charset (enc),
						NULL);

		/* If we tried all encodings we use the first one */
		if (stream->priv->use_first)
		{
			break;
		}

		/* Try to convert */
		if (try_convert (conv, inbuf, inbuf_size))
		{
			break;
		}
	}

	if (conv != NULL)
	{
		g_converter_reset (G_CONVERTER (conv));
	}

	return conv;
}
Ejemplo n.º 10
0
bool TextFileSaver::step()
{
    GOutputStream *stream = NULL;

    // Open the file.
    GFile *file = g_file_new_for_uri(uri());
    GFileOutputStream *fileStream = g_file_replace(file,
                                                   NULL,
                                                   TRUE,
                                                   G_FILE_CREATE_NONE,
                                                   NULL,
                                                   &m_error);
    if (!fileStream)
    {
        g_object_unref(file);
        return true;
    }

    // Open the encoding converter and setup the input stream.
    if (m_encoding == "UTF-8")
        stream = G_OUTPUT_STREAM(fileStream);
    else
    {
        GCharsetConverter *encodingConverter =
            g_charset_converter_new(m_encoding.c_str(), "UTF-8", &m_error);
        if (!encodingConverter)
        {
            g_object_unref(file);
            g_object_unref(fileStream);
            return true;
        }
        stream =
            g_converter_output_stream_new(G_OUTPUT_STREAM(fileStream),
                                          G_CONVERTER(encodingConverter));
        g_object_unref(fileStream);
        g_object_unref(encodingConverter);
    }

    // Convert and write.
    int size =
        g_output_stream_write(stream,
                              m_text.get(),
                              m_length == -1 ? strlen(m_text.get()) : m_length,
                              NULL,
                              &m_error);
    if (size == -1)
    {
        g_object_unref(file);
        g_object_unref(stream);
        return true;
    }

    if (!g_output_stream_close(stream, NULL, &m_error))
    {
        g_object_unref(file);
        g_object_unref(stream);
        return true;
    }
    g_object_unref(stream);

    // Get the time when the file was last modified.
    GFileInfo *fileInfo;
    fileInfo =
        g_file_query_info(file,
                          G_FILE_ATTRIBUTE_TIME_MODIFIED,
                          G_FILE_QUERY_INFO_NONE,
                          NULL,
                          &m_error);
    if (!fileInfo)
    {
        g_object_unref(file);
        return true;
    }
    m_modifiedTime.seconds = g_file_info_get_attribute_uint64(
        fileInfo,
        G_FILE_ATTRIBUTE_TIME_MODIFIED);
    g_object_unref(fileInfo);
    fileInfo =
        g_file_query_info(file,
                          G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
                          G_FILE_QUERY_INFO_NONE,
                          NULL,
                          &m_error);
    if (!fileInfo)
    {
        g_object_unref(file);
        return true;
    }
    m_modifiedTime.microSeconds = g_file_info_get_attribute_uint32(
        fileInfo,
        G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
    g_object_unref(fileInfo);
    g_object_unref(file);
    return true;
}
static GConverterResult
cedit_smart_charset_converter_convert (GConverter *converter,
				       const void *inbuf,
				       gsize       inbuf_size,
				       void       *outbuf,
				       gsize       outbuf_size,
				       GConverterFlags flags,
				       gsize      *bytes_read,
				       gsize      *bytes_written,
				       GError    **error)
{
	CeditSmartCharsetConverter *smart = CEDIT_SMART_CHARSET_CONVERTER (converter);

	/* Guess the encoding if we didn't make it yet */
	if (smart->priv->charset_conv == NULL &&
	    !smart->priv->is_utf8)
	{
		smart->priv->charset_conv = guess_encoding (smart, inbuf, inbuf_size);

		/* If we still have the previous case is that we didn't guess
		   anything */
		if (smart->priv->charset_conv == NULL &&
		    !smart->priv->is_utf8)
		{
			/* FIXME: Add a different domain when we kill cedit_convert */
			g_set_error_literal (error, CEDIT_DOCUMENT_ERROR,
					     CEDIT_DOCUMENT_ERROR_ENCODING_AUTO_DETECTION_FAILED,
					     _("It is not possible to detect the encoding automatically"));
			return G_CONVERTER_ERROR;
		}
	}

	/* Now if the encoding is utf8 just redirect the input to the output */
	if (smart->priv->is_utf8)
	{
		gsize size;
		GConverterResult ret;

		size = MIN (inbuf_size, outbuf_size);

		memcpy (outbuf, inbuf, size);
		*bytes_read = size;
		*bytes_written = size;

		ret = G_CONVERTER_CONVERTED;

		if (flags & G_CONVERTER_INPUT_AT_END)
			ret = G_CONVERTER_FINISHED;
		else if (flags & G_CONVERTER_FLUSH)
			ret = G_CONVERTER_FLUSHED;

		return ret;
	}

	/* If we reached here is because we need to convert the text so, we
	   convert it with the charset converter */
	return g_converter_convert (G_CONVERTER (smart->priv->charset_conv),
				    inbuf,
				    inbuf_size,
				    outbuf,
				    outbuf_size,
				    flags,
				    bytes_read,
				    bytes_written,
				    error);
}
Ejemplo n.º 12
0
/**
 * as_validator_validate_file:
 * @validator: An instance of #AsValidator.
 * @metadata_file: An AppStream XML file.
 *
 * Validate an AppStream XML file
 **/
gboolean
as_validator_validate_file (AsValidator *validator, GFile *metadata_file)
{
	g_autoptr(GFileInfo) info = NULL;
	g_autoptr(GInputStream) file_stream = NULL;
	g_autoptr(GInputStream) stream_data = NULL;
	g_autoptr(GConverter) conv = NULL;
	g_autoptr(GString) asxmldata = NULL;
	g_autofree gchar *fname = NULL;
	gssize len;
	const gsize buffer_size = 1024 * 32;
	g_autofree gchar *buffer = NULL;
	const gchar *content_type = NULL;
	g_autoptr(GError) tmp_error = NULL;
	gboolean ret;

	info = g_file_query_info (metadata_file,
				G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
				G_FILE_QUERY_INFO_NONE,
				NULL, NULL);
	if (info != NULL)
		content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);

	fname = g_file_get_basename (metadata_file);
	as_validator_set_current_fname (validator, fname);

	file_stream = G_INPUT_STREAM (g_file_read (metadata_file, NULL, &tmp_error));
	if (tmp_error != NULL) {
		as_validator_add_issue (validator, NULL,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_READ_ERROR,
					"Unable to read file: %s", tmp_error->message);
		return FALSE;
	}
	if (file_stream == NULL)
		return FALSE;

	if ((g_strcmp0 (content_type, "application/gzip") == 0) || (g_strcmp0 (content_type, "application/x-gzip") == 0)) {
		/* decompress the GZip stream */
		conv = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));
		stream_data = g_converter_input_stream_new (file_stream, conv);
	} else {
		stream_data = g_object_ref (file_stream);
	}

	asxmldata = g_string_new ("");
	buffer = g_malloc (buffer_size);
	while ((len = g_input_stream_read (stream_data, buffer, buffer_size, NULL, &tmp_error)) > 0) {
		g_string_append_len (asxmldata, buffer, len);
	}
	if (tmp_error != NULL) {
		as_validator_add_issue (validator, NULL,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_READ_ERROR,
					"Unable to read file: %s", tmp_error->message);
		return FALSE;
	}
	/* check if there was an error */
	if (len < 0)
		return FALSE;

	ret = as_validator_validate_data (validator, asxmldata->str);
	as_validator_clear_current_fname (validator);

	return ret;
}
Ejemplo n.º 13
0
static void
render_card_init (char *card_fname)
{
	int i;
	if (render_init) {
		for (i = 0; i < 52; i++)
			g_object_unref (card_pixbuf[i]);
		cairo_surface_destroy (grey_surface);
		render_init = 0;
	}

	/* gdk_pixbuf_new_from_file doesn't seem to support .svgz (while
	 * librsvg does), so decompress it here. Code from aisleriot
	 * src/lib/ar-svg.c */
	GFile *cf = g_file_new_for_path (card_fname);
	GFileInfo *info;
	GError *error = NULL;
	if (!(info = g_file_query_info (cf,
					G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE,
					G_FILE_QUERY_INFO_NONE,
					NULL,
					&error))) {
		printf ("%s: %s\n", card_fname, error->message);
		g_object_unref (cf);
		g_error_free (error);
		return;
	}

	const char *type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE);
	char *gz_type = g_content_type_from_mime_type ("application/x-gzip");
	gboolean is_gzip = (type != NULL && g_content_type_is_a (type, gz_type));
	g_free (gz_type);
	g_object_unref (info);

	GInputStream *stream;
	if (!(stream = G_INPUT_STREAM (g_file_read (cf, NULL, &error)))) {
		printf ("%s: %s\n", card_fname, error->message);
		g_object_unref (cf);
		g_error_free (error);
		return;
	}
	g_object_unref (cf);

	if (is_gzip) {
		GZlibDecompressor *decompressor;
		GInputStream *converter_stream;

		decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
		converter_stream = g_converter_input_stream_new (stream,
				G_CONVERTER (decompressor));
		g_object_unref (stream);
		stream = converter_stream;
	}

	/* file contains cards in 13 columns (A/2..10/J/Q/K) and 5 rows (C/D/H/S/Jokers) */
	/* actual card height is computed from resulting actual size */
	GdkPixbuf *pb = gdk_pixbuf_new_from_stream_at_scale (stream,
			card_width * 13, -1, TRUE, NULL, &error);
	g_object_unref (stream);
	if (!pb) {
		printf ("%s: %s.\n", card_fname, error->message);
		g_error_free (error);
		return;
	}
	int buf_width = gdk_pixbuf_get_width (pb);
	int buf_height = gdk_pixbuf_get_height (pb);
	card_width = ceil (gdk_pixbuf_get_width (pb) / 13.0);
	card_height = ceil (gdk_pixbuf_get_height (pb) / 5.0);
	for (i = 0; i < 52; i++) {
		card_pixbuf[i] = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, card_width, card_height);
		if (!card_pixbuf[i]) {
			printf ("%s: rendering card_pixbuf failed\n", card_fname);
			return;
		}
		int col = (i + 1) % 13;
		int row = i / 13;
		gdk_pixbuf_copy_area (pb, buf_width * col / 13.0, buf_height * row / 5.0,
		//gdk_pixbuf_copy_area (pb, card_width * col, card_height * row,
			card_width, card_height, card_pixbuf[i], 0, 0);
	}
	g_object_unref (pb);

	/* construct a alpha channel in card shape for greying out cards */
	grey_surface = cairo_image_surface_create (CAIRO_FORMAT_A8, card_width, card_height);
	cairo_t *ct = cairo_create (grey_surface);
	gdk_cairo_set_source_pixbuf (ct, card_pixbuf[0], 0, 0);
	cairo_paint_with_alpha (ct, 0.3);
	cairo_destroy (ct);

	render_init = 1;
}
Ejemplo n.º 14
0
/*
 * emer_gzip_compress:
 * @input_data: the data to compress.
 * @input_length: the length of the data to compress in bytes.
 * @compressed_length: (out): the length of the compressed data.
 * @error: (out) (optional): if compression failed, error will be set to a GError
 * describing the failure; otherwise it won't be modified. Pass NULL to ignore
 * this value.
 *
 * Compresses input_data with the gzip algorithm at compression level 9. Returns
 * NULL and sets error if compression fails. Sets compressed_length to the
 * length of the compressed data in bytes.
 *
 * Returns: the compressed data or NULL if compression fails. Free with g_free.
 */
gpointer
emer_gzip_compress (gconstpointer input_data,
                    gsize         input_length,
                    gsize        *compressed_length,
                    GError      **error)
{
  GZlibCompressor *zlib_compressor =
    g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, COMPRESSION_LEVEL);
  GConverter *converter = G_CONVERTER (zlib_compressor);

  gsize allocated_space = input_length + 1;
  GByteArray *byte_array = g_byte_array_sized_new (allocated_space);
  gsize total_bytes_read = 0;
  gsize total_bytes_written = 0;
  while (TRUE)
    {
      gsize bytes_left_in_buffer = allocated_space - total_bytes_written;
      if (bytes_left_in_buffer == 0)
        {
          allocated_space *= 2;
          g_byte_array_set_size (byte_array, allocated_space);
          continue;
        }

      gsize bytes_left_in_input = input_length - total_bytes_read;
      GConverterFlags conversion_flags = bytes_left_in_input > 0 ?
        G_CONVERTER_NO_FLAGS : G_CONVERTER_INPUT_AT_END;

      guint8 *curr_output = byte_array->data + total_bytes_written;
      const guint8 *curr_input =
        ((const guint8 *) input_data) + total_bytes_read;

      gsize curr_bytes_written, curr_bytes_read;
      GError *local_error = NULL;
      GConverterResult conversion_result =
        g_converter_convert (converter,
                             curr_input, bytes_left_in_input,
                             curr_output, bytes_left_in_buffer,
                             conversion_flags,
                             &curr_bytes_read, &curr_bytes_written,
                             &local_error);

      if (conversion_result == G_CONVERTER_ERROR)
        {
          if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NO_SPACE))
            {
              g_error_free (local_error);

              allocated_space *= 2;
              g_byte_array_set_size (byte_array, allocated_space);
              continue;
            }

          g_object_unref (zlib_compressor);
          g_byte_array_free (byte_array, TRUE);
          g_propagate_error (error, local_error);
          return NULL;
        }

      total_bytes_read += curr_bytes_read;
      total_bytes_written += curr_bytes_written;

      if (conversion_result == G_CONVERTER_FINISHED)
        break;

      /* Expand the byte array. */
      allocated_space *= 2;
      g_byte_array_set_size (byte_array, allocated_space);
    }

  g_object_unref (zlib_compressor);
  gpointer compressed_data = g_memdup (byte_array->data, total_bytes_written);
  g_byte_array_free (byte_array, TRUE);
  *compressed_length = total_bytes_written;
  return compressed_data;
}
String TextCodecGtk::decode(const char* bytes, size_t length, bool flush, bool stopOnError, bool& sawError)
{
    // Get a converter for the passed-in encoding.
    if (!m_iconvDecoder)
        createIConvDecoder();
    if (!m_iconvDecoder) {
        LOG_ERROR("Error creating IConv encoder even though encoding was in table.");
        return String();
    }

    Vector<UChar> result;

    gsize bytesRead = 0;
    gsize bytesWritten = 0;
    const gchar* input = bytes;
    gsize inputLength = length;
    gchar buffer[ConversionBufferSize];
    int flags = !length ? G_CONVERTER_INPUT_AT_END : G_CONVERTER_NO_FLAGS;
    if (flush)
        flags |= G_CONVERTER_FLUSH;

    bool bufferWasFull = false;
    char* prefixedBytes = 0;

    if (m_numBufferedBytes) {
        inputLength = length + m_numBufferedBytes;
        prefixedBytes = static_cast<char*>(fastMalloc(inputLength));
        memcpy(prefixedBytes, m_bufferedBytes, m_numBufferedBytes);
        memcpy(prefixedBytes + m_numBufferedBytes, bytes, length);

        input = prefixedBytes;

        // all buffered bytes are consumed now
        m_numBufferedBytes = 0;
    }

    do {
        GOwnPtr<GError> error;
        GConverterResult res = g_converter_convert(G_CONVERTER(m_iconvDecoder.get()),
                                                   input, inputLength,
                                                   buffer, sizeof(buffer),
                                                   static_cast<GConverterFlags>(flags),
                                                   &bytesRead, &bytesWritten,
                                                   &error.outPtr());
        input += bytesRead;
        inputLength -= bytesRead;

        if (res == G_CONVERTER_ERROR) {
            if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT)) {
                // There is not enough input to fully determine what the conversion should produce,
                // save it to a buffer to prepend it to the next input.
                memcpy(m_bufferedBytes, input, inputLength);
                m_numBufferedBytes = inputLength;
                inputLength = 0;
            } else if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_NO_SPACE))
                bufferWasFull = true;
            else if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_INVALID_DATA)) {
                if (stopOnError)
                    sawError = true;
                if (inputLength) {
                    // Ignore invalid character.
                    input += 1;
                    inputLength -= 1;
                }
            } else {
                sawError = true;
                LOG_ERROR("GIConv conversion error, Code %d: \"%s\"", error->code, error->message);
                m_numBufferedBytes = 0; // Reset state for subsequent calls to decode.
                fastFree(prefixedBytes);
                return String();
            }
        }

        result.append(reinterpret_cast<UChar*>(buffer), bytesWritten / sizeof(UChar));
    } while ((inputLength || bufferWasFull) && !sawError);

    fastFree(prefixedBytes);

    return String::adopt(result);
}
Ejemplo n.º 16
0
static void
end_element (GMarkupParseContext  *context,
	     const gchar          *element_name,
	     gpointer              user_data,
	     GError              **error)
{
  ParseState *state = user_data;
  GError *my_error = NULL;

  if (strcmp (element_name, "gresource") == 0)
    {
      g_free (state->prefix);
      state->prefix = NULL;
    }

  else if (strcmp (element_name, "file") == 0)
    {
      gchar *file, *real_file;
      gchar *key;
      FileData *data;
      char *tmp_file = NULL;
      char *tmp_file2 = NULL;

      file = state->string->str;
      key = file;
      if (state->alias)
	key = state->alias;

      if (state->prefix)
	key = g_build_path ("/", "/", state->prefix, key, NULL);
      else
	key = g_build_path ("/", "/", key, NULL);

      if (g_hash_table_lookup (state->table, key) != NULL)
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("File %s appears multiple times in the resource"),
		       key);
	  return;
	}

      data = g_new0 (FileData, 1);

      if (sourcedirs != NULL)
        {
	  real_file = find_file (file);
	  if (real_file == NULL)
	    {
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			     _("Failed to locate '%s' in any source directory"), file);
		return;
	    }
	}
      else
        {
	  gboolean exists;
	  exists = g_file_test (file, G_FILE_TEST_EXISTS);
	  if (!exists)
	    {
	      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			   _("Failed to locate '%s' in current directory"), file);
	      return;
	    }
	  real_file = g_strdup (file);
	}

      data->filename = g_strdup (real_file);
      if (!state->collect_data)
        goto done;

      if (state->preproc_options)
        {
          gchar **options;
          guint i;
          gboolean xml_stripblanks = FALSE;
          gboolean to_pixdata = FALSE;

          options = g_strsplit (state->preproc_options, ",", -1);

          for (i = 0; options[i]; i++)
            {
              if (!strcmp (options[i], "xml-stripblanks"))
                xml_stripblanks = TRUE;
              else if (!strcmp (options[i], "to-pixdata"))
                to_pixdata = TRUE;
              else
                {
                  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                               _("Unknown processing option \"%s\""), options[i]);
                  g_strfreev (options);
                  goto cleanup;
                }
            }
          g_strfreev (options);

          if (xml_stripblanks && xmllint != NULL)
            {
              gchar *argv[8];
              int status, fd, argc;

              tmp_file = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
                              g_strerror (errsv));
                  g_free (tmp_file);
                  tmp_file = NULL;
                  goto cleanup;
                }
              close (fd);

              argc = 0;
              argv[argc++] = (gchar *) xmllint;
              argv[argc++] = "--nonet";
              argv[argc++] = "--noblanks";
              argv[argc++] = "--output";
              argv[argc++] = tmp_file;
              argv[argc++] = real_file;
              argv[argc++] = NULL;
              g_assert (argc <= G_N_ELEMENTS (argv));

              if (!g_spawn_sync (NULL /* cwd */, argv, NULL /* envv */,
                                 G_SPAWN_STDOUT_TO_DEV_NULL |
                                 G_SPAWN_STDERR_TO_DEV_NULL,
                                 NULL, NULL, NULL, NULL, &status, &my_error))
                {
                  g_propagate_error (error, my_error);
                  goto cleanup;
                }
#ifdef HAVE_SYS_WAIT_H
              if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                      _("Error processing input file with xmllint"));
                  goto cleanup;
                }
#endif

              g_free (real_file);
              real_file = g_strdup (tmp_file);
            }

          if (to_pixdata)
            {
              gchar *argv[4];
              int status, fd, argc;

              if (gdk_pixbuf_pixdata == NULL)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                       "to-pixbuf preprocessing requested but GDK_PIXBUF_PIXDATA "
                                       "not set and gdk-pixbuf-pixdata not found in path");
                  goto cleanup;
                }

              tmp_file2 = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file2)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
			       g_strerror (errsv));
                  g_free (tmp_file2);
                  tmp_file2 = NULL;
                  goto cleanup;
                }
              close (fd);

              argc = 0;
              argv[argc++] = (gchar *) gdk_pixbuf_pixdata;
              argv[argc++] = real_file;
              argv[argc++] = tmp_file2;
              argv[argc++] = NULL;
              g_assert (argc <= G_N_ELEMENTS (argv));

              if (!g_spawn_sync (NULL /* cwd */, argv, NULL /* envv */,
                                 G_SPAWN_STDOUT_TO_DEV_NULL |
                                 G_SPAWN_STDERR_TO_DEV_NULL,
                                 NULL, NULL, NULL, NULL, &status, &my_error))
                {
                  g_propagate_error (error, my_error);
                  goto cleanup;
                }
#ifdef HAVE_SYS_WAIT_H
              if (!WIFEXITED (status) || WEXITSTATUS (status) != 0)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
				       _("Error processing input file with to-pixdata"));
                  goto cleanup;
                }
#endif

              g_free (real_file);
              real_file = g_strdup (tmp_file2);
            }
	}

      if (!g_file_get_contents (real_file, &data->content, &data->size, &my_error))
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("Error reading file %s: %s"),
		       real_file, my_error->message);
	  g_clear_error (&my_error);
	  goto cleanup;
	}
      /* Include zero termination in content_size for uncompressed files (but not in size) */
      data->content_size = data->size + 1;

      if (state->compressed)
	{
	  GOutputStream *out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
	  GZlibCompressor *compressor =
	    g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9);
	  GOutputStream *out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor));

	  if (!g_output_stream_write_all (out2, data->content, data->size,
					  NULL, NULL, NULL) ||
	      !g_output_stream_close (out2, NULL, NULL))
	    {
	      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Error compressing file %s"),
			   real_file);
	      goto cleanup;
	    }

	  g_free (data->content);
	  data->content_size = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (out));
	  data->content = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out));

	  g_object_unref (compressor);
	  g_object_unref (out);
	  g_object_unref (out2);

	  data->flags |= G_RESOURCE_FLAGS_COMPRESSED;
	}

    done:

      g_hash_table_insert (state->table, key, data);

    cleanup:
      /* Cleanup */

      g_free (state->alias);
      state->alias = NULL;
      g_string_free (state->string, TRUE);
      state->string = NULL;
      g_free (state->preproc_options);
      state->preproc_options = NULL;

      g_free (real_file);

      if (tmp_file)
        {
          unlink (tmp_file);
          g_free (tmp_file);
        }

      if (tmp_file2)
        {
          unlink (tmp_file2);
          g_free (tmp_file2);
        }
    }
}
CString TextCodecGtk::encode(const UChar* characters, size_t length, UnencodableHandling handling)
{
    if (!length)
        return "";

    if (!m_iconvEncoder)
        createIConvEncoder();
    if (!m_iconvEncoder) {
        LOG_ERROR("Error creating IConv encoder even though encoding was in table.");
        return CString();
    }

    gsize bytesRead = 0;
    gsize bytesWritten = 0;
    const gchar* input = reinterpret_cast<const char*>(characters);
    gsize inputLength = length * sizeof(UChar);
    gchar buffer[ConversionBufferSize];
    Vector<char> result;
    GOwnPtr<GError> error;

    size_t size = 0;
    do {
        g_converter_convert(G_CONVERTER(m_iconvEncoder.get()),
                            input, inputLength,
                            buffer, sizeof(buffer),
                            G_CONVERTER_INPUT_AT_END,
                            &bytesRead, &bytesWritten,
                            &error.outPtr());
        input += bytesRead;
        inputLength -= bytesRead;
        if (bytesWritten > 0) {
            result.grow(size + bytesWritten);
            memcpy(result.data() + size, buffer, bytesWritten);
            size += bytesWritten;
        }

        if (error && g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_INVALID_DATA)) {
            UChar codePoint = reinterpret_cast<const UChar*>(input)[0];
            UnencodableReplacementArray replacement;
            int replacementLength = TextCodec::getUnencodableReplacement(codePoint, handling, replacement);

            // Consume the invalid character.
            input += sizeof(UChar);
            inputLength -= sizeof(UChar);

            // Append replacement string to result buffer.
            result.grow(size + replacementLength);
            memcpy(result.data() + size, replacement, replacementLength);
            size += replacementLength;

            error.clear();
        }
    } while (inputLength && !error.get());

    if (error) {
        LOG_ERROR("GIConv conversion error, Code %d: \"%s\"", error->code, error->message);
        return CString();
    }

    return CString(result.data(), size);
}
Ejemplo n.º 18
0
static int
compress_blob_to_tmp (GInputStream *file_stream)
{
  char tmpl[] = "/tmp/shardXXXXXX";
  int fd = mkstemp (tmpl);
  unlink (tmpl);

  /* Compress the given GInputStream to the tmpfile. */

  g_autoptr(GZlibCompressor) compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, -1);
  g_autoptr(GInputStream) stream = g_converter_input_stream_new (G_INPUT_STREAM (file_stream), G_CONVERTER (compressor));

  uint8_t buf[4096*4];
  int size;
  while ((size = g_input_stream_read (stream, buf, sizeof (buf), NULL, NULL)) != 0) {
    g_assert (write (fd, buf, size) >= 0);
  }

  return fd;
}
Ejemplo n.º 19
0
static void
end_element (GMarkupParseContext  *context,
	     const gchar          *element_name,
	     gpointer              user_data,
	     GError              **error)
{
  ParseState *state = user_data;
  GError *my_error = NULL;

  if (strcmp (element_name, "gresource") == 0)
    {
      g_free (state->prefix);
      state->prefix = NULL;
    }

  else if (strcmp (element_name, "file") == 0)
    {
      gchar *file;
      gchar *real_file = NULL;
      gchar *key;
      FileData *data = NULL;
      char *tmp_file = NULL;
      char *tmp_file2 = NULL;

      file = state->string->str;
      key = file;
      if (state->alias)
	key = state->alias;

      if (state->prefix)
	key = g_build_path ("/", "/", state->prefix, key, NULL);
      else
	key = g_build_path ("/", "/", key, NULL);

      if (g_hash_table_lookup (state->table, key) != NULL)
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("File %s appears multiple times in the resource"),
		       key);
	  return;
	}

      if (sourcedirs != NULL)
        {
	  real_file = find_file (file);
	  if (real_file == NULL && state->collect_data)
	    {
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			     _("Failed to locate “%s” in any source directory"), file);
		return;
	    }
	}
      else
        {
	  gboolean exists;
	  exists = g_file_test (file, G_FILE_TEST_EXISTS);
	  if (!exists && state->collect_data)
	    {
	      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
			   _("Failed to locate “%s” in current directory"), file);
	      return;
	    }
	}

      if (real_file == NULL)
        real_file = g_strdup (file);

      data = g_new0 (FileData, 1);
      data->filename = g_strdup (real_file);
      if (!state->collect_data)
        goto done;

      if (state->preproc_options)
        {
          gchar **options;
          guint i;
          gboolean xml_stripblanks = FALSE;
          gboolean to_pixdata = FALSE;

          options = g_strsplit (state->preproc_options, ",", -1);

          for (i = 0; options[i]; i++)
            {
              if (!strcmp (options[i], "xml-stripblanks"))
                xml_stripblanks = TRUE;
              else if (!strcmp (options[i], "to-pixdata"))
                to_pixdata = TRUE;
              else
                {
                  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                               _("Unknown processing option “%s”"), options[i]);
                  g_strfreev (options);
                  goto cleanup;
                }
            }
          g_strfreev (options);

          if (xml_stripblanks && xmllint != NULL)
            {
              int fd;
	      GSubprocess *proc;

              tmp_file = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
                              g_strerror (errsv));
                  g_free (tmp_file);
                  tmp_file = NULL;
                  goto cleanup;
                }
              close (fd);

              proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
                                       xmllint, "--nonet", "--noblanks", "--output", tmp_file, real_file, NULL);
              g_free (real_file);
	      real_file = NULL;

	      if (!proc)
		goto cleanup;

	      if (!g_subprocess_wait_check (proc, NULL, error))
		{
		  g_object_unref (proc);
                  goto cleanup;
                }

	      g_object_unref (proc);

              real_file = g_strdup (tmp_file);
            }

          if (to_pixdata)
            {
              int fd;
	      GSubprocess *proc;

              if (gdk_pixbuf_pixdata == NULL)
                {
                  g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                                       "to-pixbuf preprocessing requested but GDK_PIXBUF_PIXDATA "
                                       "not set and gdk-pixbuf-pixdata not found in path");
                  goto cleanup;
                }

              tmp_file2 = g_strdup ("resource-XXXXXXXX");
              if ((fd = g_mkstemp (tmp_file2)) == -1)
                {
                  int errsv = errno;

                  g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
                               _("Failed to create temp file: %s"),
			       g_strerror (errsv));
                  g_free (tmp_file2);
                  tmp_file2 = NULL;
                  goto cleanup;
                }
              close (fd);

              proc = g_subprocess_new (G_SUBPROCESS_FLAGS_STDOUT_SILENCE, error,
                                       gdk_pixbuf_pixdata, real_file, tmp_file2, NULL);
              g_free (real_file);
              real_file = NULL;

	      if (!g_subprocess_wait_check (proc, NULL, error))
		{
		  g_object_unref (proc);
                  goto cleanup;
		}

	      g_object_unref (proc);

              real_file = g_strdup (tmp_file2);
            }
	}

      if (!g_file_get_contents (real_file, &data->content, &data->size, &my_error))
	{
	  g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
		       _("Error reading file %s: %s"),
		       real_file, my_error->message);
	  g_clear_error (&my_error);
	  goto cleanup;
	}
      /* Include zero termination in content_size for uncompressed files (but not in size) */
      data->content_size = data->size + 1;

      if (state->compressed)
	{
	  GOutputStream *out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
	  GZlibCompressor *compressor =
	    g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9);
	  GOutputStream *out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor));

	  if (!g_output_stream_write_all (out2, data->content, data->size,
					  NULL, NULL, NULL) ||
	      !g_output_stream_close (out2, NULL, NULL))
	    {
	      g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Error compressing file %s"),
			   real_file);
	      goto cleanup;
	    }

	  g_free (data->content);
	  data->content_size = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (out));
	  data->content = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (out));

	  g_object_unref (compressor);
	  g_object_unref (out);
	  g_object_unref (out2);

	  data->flags |= G_RESOURCE_FLAGS_COMPRESSED;
	}

done:
      g_hash_table_insert (state->table, key, data);
      data = NULL;

    cleanup:
      /* Cleanup */

      g_free (state->alias);
      state->alias = NULL;
      g_string_free (state->string, TRUE);
      state->string = NULL;
      g_free (state->preproc_options);
      state->preproc_options = NULL;

      g_free (real_file);

      if (tmp_file)
        {
          unlink (tmp_file);
          g_free (tmp_file);
        }

      if (tmp_file2)
        {
          unlink (tmp_file2);
          g_free (tmp_file2);
        }

      if (data != NULL)
        file_data_free (data);
    }
}
Ejemplo n.º 20
0
static gboolean
_gtr_po_load_ensure_utf8 (GtrPo * po, GError ** error)
{
  GMappedFile *mapped;
  const gchar *content;
  gboolean utf8_valid;
  gchar *filename;
  gsize size;
  GtrPoPrivate *priv = gtr_po_get_instance_private (po);

  filename = g_file_get_path (priv->location);
  mapped = g_mapped_file_new (filename, FALSE, error);
  g_free (filename);

  if (!mapped)
    return FALSE;

  content = g_mapped_file_get_contents (mapped);
  size = g_mapped_file_get_length (mapped);

  utf8_valid = g_utf8_validate (content, size, NULL);

  if (!_gtr_po_load (po, priv->location, error))
    {
      g_mapped_file_unref (mapped);
      return FALSE;
    }

  if (!utf8_valid &&
      priv->header)
    {
      gchar *charset = NULL;

      if (priv->header)
        charset = gtr_header_get_charset (priv->header);

      if (charset && *charset && strcmp (charset, "UTF-8") != 0)
        {
          GOutputStream *converter_stream, *stream;
          GCharsetConverter *converter;
          GIOStream *iostream;
          GFile *tmp;

          /* Store UTF-8 converted file in $TMP */
          converter = g_charset_converter_new ("UTF-8", charset, NULL);

          if (!converter)
            {
              g_set_error (error,
                           GTR_PO_ERROR,
                           GTR_PO_ERROR_ENCODING,
                           _("Could not convert from charset “%s” to UTF-8"),
                           charset);
              g_mapped_file_unref (mapped);
              g_free (charset);
              return FALSE;
            }

          g_free (charset);
          tmp = g_file_new_tmp ("gtranslator-XXXXXX.po",
                                (GFileIOStream **) &iostream,
                                NULL);

          if (!tmp)
            {
              g_set_error (error,
                           GTR_PO_ERROR,
                           GTR_PO_ERROR_ENCODING,
                           _("Could not store temporary "
                             "file for encoding conversion"));
              g_mapped_file_unref (mapped);
              g_object_unref (converter);
              return FALSE;
            }

          stream = g_io_stream_get_output_stream (iostream);
          converter_stream =
            g_converter_output_stream_new (stream,
                                           G_CONVERTER (converter));


          if (!g_output_stream_write_all (converter_stream,
                                          content, size, NULL,
                                          NULL, NULL))
            {
              g_set_error (error,
                           GTR_PO_ERROR,
                           GTR_PO_ERROR_ENCODING,
                           _("Could not store temporary "
                             "file for encoding conversion"));
              g_object_unref (converter_stream);
              g_object_unref (iostream);
              g_object_unref (converter);
              g_mapped_file_unref (mapped);
              return FALSE;
            }

          g_object_unref (converter_stream);
          g_object_unref (iostream);
          g_object_unref (converter);

          /* Now load again the converted file */
          if (!_gtr_po_load (po, tmp, error))
            {
              g_mapped_file_unref (mapped);
              return FALSE;
            }

          /* Ensure Content-Type is set correctly
           * in the header as per the content
           */
          if (priv->header)
            gtr_header_set_charset (priv->header, "UTF-8");

          utf8_valid = TRUE;
        }
    }

  g_mapped_file_unref (mapped);

  if (!utf8_valid)
    {
      g_set_error (error,
                   GTR_PO_ERROR,
                   GTR_PO_ERROR_ENCODING,
                   _("All attempt to convert the file to UTF-8 has failed, "
                     "use the msgconv or iconv command line tools before "
                     "opening this file with GNOME Translation Editor"));
      return FALSE;
    }

  return TRUE;
}
Ejemplo n.º 21
0
/**
 * as_node_from_file: (skip)
 * @file: file
 * @flags: #AsNodeFromXmlFlags, e.g. %AS_NODE_FROM_XML_FLAG_NONE
 * @cancellable: A #GCancellable, or %NULL
 * @error: A #GError or %NULL
 *
 * Parses an XML file into a DOM tree.
 *
 * Returns: (transfer none): A populated #AsNode tree
 *
 * Since: 0.1.0
 **/
AsNode *
as_node_from_file (GFile *file,
		   AsNodeFromXmlFlags flags,
		   GCancellable *cancellable,
		   GError **error)
{
	AsNodeToXmlHelper helper;
	GError *error_local = NULL;
	AsNode *root = NULL;
	const gchar *content_type = NULL;
	gboolean ret = TRUE;
	gsize chunk_size = 32 * 1024;
	gssize len;
	g_autofree gchar *data = NULL;
	g_autoptr(GMarkupParseContext) ctx = NULL;
	g_autoptr(GConverter) conv = NULL;
	g_autoptr(GFileInfo) info = NULL;
	g_autoptr(GInputStream) file_stream = NULL;
	g_autoptr(GInputStream) stream_data = NULL;
	const GMarkupParser parser = {
		as_node_start_element_cb,
		as_node_end_element_cb,
		as_node_text_cb,
		as_node_passthrough_cb,
		NULL };

	/* what kind of file is this */
	info = g_file_query_info (file,
				  G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
				  G_FILE_QUERY_INFO_NONE,
				  cancellable,
				  error);
	if (info == NULL)
		return NULL;

	/* decompress if required */
	file_stream = G_INPUT_STREAM (g_file_read (file, cancellable, error));
	if (file_stream == NULL)
		return NULL;
	content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
	if (g_strcmp0 (content_type, "application/gzip") == 0 ||
	    g_strcmp0 (content_type, "application/x-gzip") == 0) {
		conv = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP));
		stream_data = g_converter_input_stream_new (file_stream, conv);
	} else if (g_strcmp0 (content_type, "application/xml") == 0) {
		stream_data = g_object_ref (file_stream);
	} else {
		g_set_error (error,
			     AS_NODE_ERROR,
			     AS_NODE_ERROR_FAILED,
			     "cannot process file of type %s",
			     content_type);
		return NULL;
	}

	/* parse */
	root = as_node_new ();
	helper.flags = flags;
	helper.current = root;
	ctx = g_markup_parse_context_new (&parser,
					  G_MARKUP_PREFIX_ERROR_POSITION,
					  &helper,
					  NULL);

	data = g_malloc (chunk_size);
	while ((len = g_input_stream_read (stream_data,
					   data,
					   chunk_size,
					   cancellable,
					   error)) > 0) {
		ret = g_markup_parse_context_parse (ctx,
						    data,
						    len,
						    &error_local);
		if (!ret) {
			g_set_error_literal (error,
					     AS_NODE_ERROR,
					     AS_NODE_ERROR_FAILED,
					     error_local->message);
			g_error_free (error_local);
			as_node_unref (root);
			return NULL;
		}
	}
	if (len < 0) {
		as_node_unref (root);
		return NULL;
	}

	/* more opening than closing */
	if (root != helper.current) {
		g_set_error_literal (error,
				     AS_NODE_ERROR,
				     AS_NODE_ERROR_FAILED,
				     "Mismatched XML");
		as_node_unref (root);
		return NULL;
	}
	return root;
}
Ejemplo n.º 22
0
/**
 * gs_plugin_file_to_app:
 */
gboolean
gs_plugin_file_to_app (GsPlugin *plugin,
		       GList **list,
		       GFile *file,
		       GCancellable *cancellable,
		       GError **error)
{
	g_autofree gchar *content_type = NULL;
	g_autofree gchar *id_prefixed = NULL;
	g_autoptr(GBytes) appstream_gz = NULL;
	g_autoptr(GBytes) icon_data = NULL;
	g_autoptr(GBytes) metadata = NULL;
	g_autoptr(GsApp) app = NULL;
	g_autoptr(XdgAppBundleRef) xref_bundle = NULL;
	const gchar *mimetypes[] = {
		"application/vnd.xdgapp",
		NULL };

	/* does this match any of the mimetypes we support */
	content_type = gs_utils_get_content_type (file, cancellable, error);
	if (content_type == NULL)
		return FALSE;
	if (!g_strv_contains (mimetypes, content_type))
		return TRUE;

	/* load bundle */
	xref_bundle = xdg_app_bundle_ref_new (file, error);
	if (xref_bundle == NULL) {
		g_prefix_error (error, "error loading bundle: ");
		return FALSE;
	}

	/* create a virtual ID */
	id_prefixed = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref_bundle));

	/* load metadata */
	app = gs_app_new (id_prefixed);
	gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
	gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL);
	gs_app_set_size_installed (app, xdg_app_bundle_ref_get_installed_size (xref_bundle));
	gs_plugin_xdg_app_set_metadata (app, XDG_APP_REF (xref_bundle));
	metadata = xdg_app_bundle_ref_get_metadata (xref_bundle);
	if (!gs_plugin_xdg_app_set_app_metadata (app,
						 g_bytes_get_data (metadata, NULL),
						 g_bytes_get_size (metadata),
						 error))
		return FALSE;

	/* load AppStream */
	appstream_gz = xdg_app_bundle_ref_get_appstream (xref_bundle);
	if (appstream_gz != NULL) {
		g_autoptr(GZlibDecompressor) decompressor = NULL;
		g_autoptr(GInputStream) stream_gz = NULL;
		g_autoptr(GInputStream) stream_data = NULL;
		g_autoptr(GBytes) appstream = NULL;
		g_autoptr(AsStore) store = NULL;
		g_autofree gchar *id = NULL;
		AsApp *item;

		/* decompress data */
		decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
		stream_gz = g_memory_input_stream_new_from_bytes (appstream_gz);
		if (stream_gz == NULL)
			return FALSE;
		stream_data = g_converter_input_stream_new (stream_gz,
							    G_CONVERTER (decompressor));

		appstream = g_input_stream_read_bytes (stream_data,
						       0x100000, /* 1Mb */
						       cancellable,
						       error);
		if (appstream == NULL)
			return FALSE;
		store = as_store_new ();
		if (!as_store_from_bytes (store, appstream, cancellable, error))
			return FALSE;

		/* find app */
		id = g_strdup_printf ("%s.desktop", gs_app_get_xdgapp_name (app));
		item = as_store_get_app_by_id (store, id);
		if (item == NULL) {
			g_set_error (error,
				     GS_PLUGIN_ERROR,
				     GS_PLUGIN_ERROR_FAILED,
				     "application %s not found",
				     id);
			return FALSE;
		}

		/* copy details from AppStream to app */
		if (!gs_appstream_refine_app (plugin, app, item, error))
			return FALSE;
	}

	/* load icon */
	icon_data = xdg_app_bundle_ref_get_icon (xref_bundle,
						 64 * gs_plugin_get_scale (plugin));
	if (icon_data == NULL)
		icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64);
	if (icon_data != NULL) {
		g_autoptr(GInputStream) stream_icon = NULL;
		g_autoptr(GdkPixbuf) pixbuf = NULL;
		stream_icon = g_memory_input_stream_new_from_bytes (icon_data);
		pixbuf = gdk_pixbuf_new_from_stream (stream_icon, cancellable, error);
		if (pixbuf == NULL)
			return FALSE;
		gs_app_set_pixbuf (app, pixbuf);
	} else {
		g_autoptr(AsIcon) icon = NULL;
		icon = as_icon_new ();
		as_icon_set_kind (icon, AS_ICON_KIND_STOCK);
		as_icon_set_name (icon, "application-x-executable");
		gs_app_set_icon (app, icon);
	}

	/* not quite true: this just means we can update this specific app */
	if (xdg_app_bundle_ref_get_origin (xref_bundle))
		gs_app_add_quirk (app, AS_APP_QUIRK_HAS_SOURCE);

	g_debug ("created local app: %s", gs_app_to_string (app));
	gs_app_list_add (list, app);
	return TRUE;
}
Ejemplo n.º 23
0
static void
decompress_db (GFile *db, const char *path)
{
        GFile *db_decomp;
        GFile *db_decomp_tmp;
        GError *error = NULL;
        GZlibDecompressor *conv;
        GInputStream *instream;
        GInputStream *instream_conv;
        GOutputStream *outstream;
        char *tmp_db_path;

        instream = (GInputStream *) g_file_read (db, NULL, &error);
        if (!instream) {
                g_print ("Error opening file: %s", error->message);
                g_error_free (error);
                return;
        }

        conv = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
        instream_conv = (GInputStream *) g_converter_input_stream_new (instream, G_CONVERTER (conv));
        g_object_unref (instream);

        tmp_db_path = g_strdup_printf ("%s.%s", path, "tmp");
        db_decomp_tmp =  g_file_new_for_path (tmp_db_path);
        g_free (tmp_db_path);
        outstream = (GOutputStream *) g_file_replace (db_decomp_tmp,
                                                      NULL,
                                                      FALSE,
                                                      G_FILE_CREATE_NONE,
                                                      NULL,
                                                      &error);
        if (!outstream) {
                g_print ("Error creating file: %s\n", error->message);
                g_error_free (error);
                goto end;
        }

        if (g_output_stream_splice (outstream,
                                    instream_conv,
                                    0,
                                    NULL,
                                    &error) == -1) {
                g_print ("Error decompressing the database: %s\n", error->message);
                g_object_unref (outstream);
                g_error_free (error);
                goto end;
        }

        if (g_output_stream_close (outstream,
                                   NULL,
                                   &error) == FALSE) {
                g_print ("Error decompressing the database: %s\n", error->message);
                g_error_free (error);
        } else {
                db_decomp = g_file_new_for_path (path);
                if (g_file_move (db_decomp_tmp,
                                 db_decomp,
                                 G_FILE_COPY_OVERWRITE,
                                 NULL,
                                 NULL,
                                 NULL,
                                 &error) == FALSE) {
                        g_print ("Error moving the temporary database file to the" \
                                 " original database file: %s\n", error->message);
                        g_error_free (error);
                } else {
                        g_print ("Database updated\n");
                }

                g_object_unref (db_decomp);
        }
        g_object_unref (outstream);

end:
        g_object_unref (db_decomp_tmp);
        g_object_unref (conv);
        g_object_unref (instream_conv);
}
Ejemplo n.º 24
0
static gboolean
try_convert (GCharsetConverter *converter,
             const void        *inbuf,
             gsize              inbuf_size)
{
	GError *err;
	gsize bytes_read, nread;
	gsize bytes_written, nwritten;
	GConverterResult res;
	gchar *out;
	gboolean ret;
	gsize out_size;

	if (inbuf == NULL || inbuf_size == 0)
	{
		return FALSE;
	}

	err = NULL;
	nread = 0;
	nwritten = 0;
	out_size = inbuf_size * 4;
	out = g_malloc (out_size);

	do
	{
		res = g_converter_convert (G_CONVERTER (converter),
		                           (gchar *)inbuf + nread,
		                           inbuf_size - nread,
		                           (gchar *)out + nwritten,
		                           out_size - nwritten,
		                           G_CONVERTER_INPUT_AT_END,
		                           &bytes_read,
		                           &bytes_written,
		                           &err);

		nread += bytes_read;
		nwritten += bytes_written;
	} while (res != G_CONVERTER_FINISHED && res != G_CONVERTER_ERROR && err == NULL);

	if (err != NULL)
	{
		if (err->code == G_CONVERT_ERROR_PARTIAL_INPUT)
		{
			/* FIXME We can get partial input while guessing the
			   encoding because we just take some amount of text
			   to guess from. */
			ret = TRUE;
		}
		else
		{
			ret = FALSE;
		}

		g_error_free (err);
	}
	else
	{
		ret = TRUE;
	}

	/* FIXME: Check the remainder? */
	if (ret == TRUE && !g_utf8_validate (out, nwritten, NULL))
	{
		ret = FALSE;
	}

	g_free (out);

	return ret;
}
Ejemplo n.º 25
0
/**
 * g_resource_lookup_data:
 * @resource: A #GResource
 * @path: A pathname inside the resource
 * @lookup_flags: A #GResourceLookupFlags
 * @error: return location for a #GError, or %NULL
 *
 * Looks for a file at the specified @path in the resource and
 * returns a #GBytes that lets you directly access the data in
 * memory.
 *
 * The data is always followed by a zero byte, so you
 * can safely use the data as a C string. However, that byte
 * is not included in the size of the GBytes.
 *
 * For uncompressed resource files this is a pointer directly into
 * the resource bundle, which is typically in some readonly data section
 * in the program binary. For compressed files we allocate memory on
 * the heap and automatically uncompress the data.
 *
 * @lookup_flags controls the behaviour of the lookup.
 *
 * Returns: (transfer full): #GBytes or %NULL on error.
 *     Free the returned object with g_bytes_unref()
 *
 * Since: 2.32
 **/
GBytes *
g_resource_lookup_data (GResource             *resource,
                        const gchar           *path,
                        GResourceLookupFlags   lookup_flags,
                        GError               **error)
{
  const void *data;
  guint32 flags;
  gsize data_size;
  gsize size;

  if (!do_lookup (resource, path, lookup_flags, &size, &flags, &data, &data_size, error))
    return NULL;

  if (flags & G_RESOURCE_FLAGS_COMPRESSED)
    {
      char *uncompressed, *d;
      const char *s;
      GConverterResult res;
      gsize d_size, s_size;
      gsize bytes_read, bytes_written;


      GZlibDecompressor *decompressor =
        g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB);

      uncompressed = g_malloc (size + 1);

      s = data;
      s_size = data_size;
      d = uncompressed;
      d_size = size;

      do
        {
          res = g_converter_convert (G_CONVERTER (decompressor),
                                     s, s_size,
                                     d, d_size,
                                     G_CONVERTER_INPUT_AT_END,
                                     &bytes_read,
                                     &bytes_written,
                                     NULL);
          if (res == G_CONVERTER_ERROR)
            {
              g_free (uncompressed);
              g_object_unref (decompressor);

              g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL,
                           _("The resource at '%s' failed to decompress"),
                           path);
              return NULL;

            }
          s += bytes_read;
          s_size -= bytes_read;
          d += bytes_written;
          d_size -= bytes_written;
        }
      while (res != G_CONVERTER_FINISHED);

      uncompressed[size] = 0; /* Zero terminate */

      g_object_unref (decompressor);

      return g_bytes_new_take (uncompressed, size);
    }
  else
    return g_bytes_new_with_free_func (data, data_size, (GDestroyNotify)g_resource_unref, g_resource_ref (resource));
}
Ejemplo n.º 26
0
/**
 * as_get_yml_data_origin:
 *
 * Extract the data origin from the AppStream YAML file.
 * We don't use the #AsYAMLData loader, because it is much
 * slower than just loading the initial parts of the file and
 * extracting the origin manually.
 */
static gchar*
as_get_yml_data_origin (const gchar *fname)
{
	const gchar *data;
	GZlibDecompressor *zdecomp;
	g_autoptr(GFileInputStream) fistream = NULL;
	g_autoptr(GMemoryOutputStream) mem_os = NULL;
	g_autoptr(GInputStream) conv_stream = NULL;
	g_autoptr(GFile) file = NULL;
	g_autofree gchar *str = NULL;
	g_auto(GStrv) strv = NULL;
	GError *err;
	guint i;
	gchar *start, *end;
	gchar *origin = NULL;

	file = g_file_new_for_path (fname);
	fistream = g_file_read (file, NULL, &err);

	if (!fistream) {
		g_critical ("Unable to open file '%s' for reading: %s, skipping.", fname, err->message);
		g_error_free (err);
		return NULL;
	}

	mem_os = (GMemoryOutputStream*) g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
	zdecomp = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
	conv_stream = g_converter_input_stream_new (G_INPUT_STREAM (fistream), G_CONVERTER (zdecomp));
	g_object_unref (zdecomp);

	g_output_stream_splice (G_OUTPUT_STREAM (mem_os), conv_stream, 0, NULL, NULL);
	data = (const gchar*) g_memory_output_stream_get_data (mem_os);

	/* faster than a regular expression?
	 * Get the first YAML document, then extract the origin string.
	 */
	if (data == NULL)
		return NULL;
	/* start points to the start of the document, i.e. "File:" normally */
	start = g_strstr_len (data, 400, YAML_SEPARATOR) + YAML_SEPARATOR_LEN;
	if (start == NULL)
		return NULL;
	/* Find the end of the first document - can be NULL if there is only one,
	 * for example if we're given YAML for an empty archive */
	end = g_strstr_len (start, -1, YAML_SEPARATOR);
	str = g_strndup (start, strlen(start) - (end ? strlen(end) : 0));

	strv = g_strsplit (str, "\n", -1);
	for (i = 0; strv[i] != NULL; i++) {
		g_auto(GStrv) strv2 = NULL;
		if (!g_str_has_prefix (strv[i], "Origin:"))
			continue;

		strv2 = g_strsplit (strv[i], ":", 2);
		g_strstrip (strv2[1]);
		origin = g_strdup (strv2[1]);

		/* remove quotes, in case the string is quoted */
		if ((g_str_has_prefix (origin, "\"")) && (g_str_has_suffix (origin, "\""))) {
			g_autofree gchar *tmp = NULL;

			tmp = origin;
			origin = g_strndup (tmp + 1, strlen (tmp) - 2);
		}

		break;
	}

	return origin;
}
Ejemplo n.º 27
0
int
main (int argc, char *argv[])
{
  FlatpakInstallation *installation;
  FlatpakInstalledRef *app1;
  FlatpakInstalledRef *app2;
  FlatpakRemoteRef *remote_ref;
  g_autoptr(GPtrArray) remotes = NULL;
  GError *error = NULL;
  int i, j, k;

  installation = flatpak_installation_new_user (NULL, &error);
  if (installation == NULL)
    {
      g_print ("error: %s\n", error->message);
      return 1;
    }

  if (0)
    {
      const char *list[] = { "gnome-apps", "app/org.gnome.iagno/x86_64/stable",
                             "gnome", "runtime/org.gnome.Sdk/x86_64/3.20" };

      for (j = 0; j < G_N_ELEMENTS (list); j += 2)
        {
          g_print ("looking for related to ref: %s\n", list[j + 1]);

          for (k = 0; k < 2; k++)
            {
              g_autoptr(GError) error = NULL;
              g_autoptr(GPtrArray) related = NULL;


              if (k == 0)
                related = flatpak_installation_list_remote_related_refs_sync (installation,
                                                                              list[j],
                                                                              list[j + 1],
                                                                              NULL,
                                                                              &error);
              else
                related = flatpak_installation_list_installed_related_refs_sync (installation,
                                                                                 list[j],
                                                                                 list[j + 1],
                                                                                 NULL,
                                                                                 &error);

              if (related == NULL)
                {
                  g_warning ("Error: %s", error->message);
                  continue;
                }

              g_print ("%s related:\n", (k == 0) ? "remote" : "local");
              for (i = 0; i < related->len; i++)
                {
                  FlatpakRelatedRef *rel = g_ptr_array_index (related, i);
                  const char * const *subpaths = flatpak_related_ref_get_subpaths (rel);
                  g_autofree char *subpaths_str = NULL;

                  if (subpaths)
                    {
                      g_autofree char *subpaths_joined = g_strjoinv (",", (char **) subpaths);
                      subpaths_str = g_strdup_printf (" subpaths: %s", subpaths_joined);
                    }
                  else
                    subpaths_str = g_strdup ("");
                  g_print ("%d %s %s %s %s dl:%d del:%d%s\n",
                           flatpak_ref_get_kind (FLATPAK_REF (rel)),
                           flatpak_ref_get_name (FLATPAK_REF (rel)),
                           flatpak_ref_get_arch (FLATPAK_REF (rel)),
                           flatpak_ref_get_branch (FLATPAK_REF (rel)),
                           flatpak_ref_get_commit (FLATPAK_REF (rel)),
                           flatpak_related_ref_should_download (rel),
                           flatpak_related_ref_should_delete (rel),
                           subpaths_str);
                }
            }
        }

      return 0;
    }

  if (argc == 4)
    {
      GFileMonitor * monitor = flatpak_installation_create_monitor (installation, NULL, NULL);
      GMainLoop *main_loop;

      g_signal_connect (monitor, "changed", (GCallback) monitor_callback, NULL);
      main_loop = g_main_loop_new (NULL, FALSE);
      g_main_loop_run (main_loop);
    }

  if (argc == 3)
    {
      app1 = flatpak_installation_install (installation,
                                           argv[1],
                                           FLATPAK_REF_KIND_APP,
                                           argv[2],
                                           NULL, NULL,
                                           progress_cb, (gpointer) 0xdeadbeef,
                                           NULL, &error);
      if (app1 == NULL)
        g_print ("Error: %s\n", error->message);
      else
        g_print ("Installed %s: %s\n", argv[2],
                 flatpak_ref_get_commit (FLATPAK_REF (app1)));

      return 0;
    }

  if (argc == 2)
    {
      app1 = flatpak_installation_update (installation,
                                          FLATPAK_UPDATE_FLAGS_NONE,
                                          FLATPAK_REF_KIND_APP,
                                          argv[1],
                                          NULL, NULL,
                                          progress_cb, (gpointer) 0xdeadbeef,
                                          NULL, &error);
      if (app1 == NULL)
        g_print ("Error: %s\n", error->message);
      else
        g_print ("Updated %s: %s\n", argv[1],
                 flatpak_ref_get_commit (FLATPAK_REF (app1)));

      return 0;
    }

  g_print ("\n**** Loading bundle\n");
  {
    g_autoptr(GFile) f = g_file_new_for_commandline_arg ("tests/hello.pak");
    g_autoptr(FlatpakBundleRef) bundle = flatpak_bundle_ref_new (f, &error);
    if (bundle == NULL)
      {
        g_print ("Error loading bundle: %s\n", error->message);
        g_clear_error (&error);
      }
    else
      {
        g_autofree char *path = g_file_get_path (flatpak_bundle_ref_get_file (bundle));
        g_autoptr(GBytes) metadata = flatpak_bundle_ref_get_metadata (bundle);
        g_autoptr(GBytes) appdata = flatpak_bundle_ref_get_appstream (bundle);
        g_print ("%d %s %s %s %s %s %"G_GUINT64_FORMAT "\n%s\n",
                 flatpak_ref_get_kind (FLATPAK_REF (bundle)),
                 flatpak_ref_get_name (FLATPAK_REF (bundle)),
                 flatpak_ref_get_arch (FLATPAK_REF (bundle)),
                 flatpak_ref_get_branch (FLATPAK_REF (bundle)),
                 flatpak_ref_get_commit (FLATPAK_REF (bundle)),
                 path,
                 flatpak_bundle_ref_get_installed_size (bundle),
                 (char *) g_bytes_get_data (metadata, NULL));

        if (appdata != NULL)
          {
            g_autoptr(GZlibDecompressor) decompressor = NULL;
            g_autoptr(GOutputStream) out2 = NULL;
            g_autoptr(GOutputStream) out = NULL;

            out = g_unix_output_stream_new (1, FALSE);
            decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
            out2 = g_converter_output_stream_new (out, G_CONVERTER (decompressor));

            if (!g_output_stream_write_all (out2,
                                            g_bytes_get_data (appdata, NULL),
                                            g_bytes_get_size (appdata),
                                            NULL, NULL, &error))
              {
                g_print ("Error decompressing appdata: %s\n", error->message);
                g_clear_error (&error);
              }
          }
      }
  }

  g_print ("\n**** Checking for updates\n");
  {
    g_autoptr(GPtrArray) updates =
      flatpak_installation_list_installed_refs_for_update (installation,
                                                           NULL, &error);

    if (updates == NULL)
      {
        g_print ("check for updates error: %s\n", error->message);
        g_clear_error (&error);
      }
    else
      {
        for (i = 0; i < updates->len; i++)
          {
            FlatpakInstalledRef *ref = g_ptr_array_index (updates, i);
            g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT "\n",
                     flatpak_ref_get_kind (FLATPAK_REF (ref)),
                     flatpak_ref_get_name (FLATPAK_REF (ref)),
                     flatpak_ref_get_arch (FLATPAK_REF (ref)),
                     flatpak_ref_get_branch (FLATPAK_REF (ref)),
                     flatpak_ref_get_commit (FLATPAK_REF (ref)),
                     flatpak_installed_ref_get_latest_commit (ref),
                     flatpak_installed_ref_get_origin (ref),
                     flatpak_installed_ref_get_deploy_dir (ref),
                     flatpak_installed_ref_get_is_current (ref),
                     flatpak_installed_ref_get_installed_size (ref));
          }
      }
  }

  g_print ("\n**** Listing all installed refs\n");
  {
    g_autoptr(GPtrArray) refs = NULL;

    refs = flatpak_installation_list_installed_refs (installation,
                                                     NULL, NULL);

    for (i = 0; i < refs->len; i++)
      {
        FlatpakInstalledRef *ref = g_ptr_array_index (refs, i);
        g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT "\n",
                 flatpak_ref_get_kind (FLATPAK_REF (ref)),
                 flatpak_ref_get_name (FLATPAK_REF (ref)),
                 flatpak_ref_get_arch (FLATPAK_REF (ref)),
                 flatpak_ref_get_branch (FLATPAK_REF (ref)),
                 flatpak_ref_get_commit (FLATPAK_REF (ref)),
                 flatpak_installed_ref_get_latest_commit (ref),
                 flatpak_installed_ref_get_origin (ref),
                 flatpak_installed_ref_get_deploy_dir (ref),
                 flatpak_installed_ref_get_is_current (ref),
                 flatpak_installed_ref_get_installed_size (ref));
      }
  }

  g_print ("**** Listing all installed apps\n");
  {
    g_autoptr(GPtrArray) apps = NULL;

    apps = flatpak_installation_list_installed_refs_by_kind (installation,
                                                             FLATPAK_REF_KIND_APP,
                                                             NULL, NULL);

    for (i = 0; i < apps->len; i++)
      {
        FlatpakInstalledRef *app = g_ptr_array_index (apps, i);

        g_print ("%d %s %s %s %s %s %s %s %d %"G_GUINT64_FORMAT "\n",
                 flatpak_ref_get_kind (FLATPAK_REF (app)),
                 flatpak_ref_get_name (FLATPAK_REF (app)),
                 flatpak_ref_get_arch (FLATPAK_REF (app)),
                 flatpak_ref_get_branch (FLATPAK_REF (app)),
                 flatpak_ref_get_commit (FLATPAK_REF (app)),
                 flatpak_installed_ref_get_latest_commit (app),
                 flatpak_installed_ref_get_origin (app),
                 flatpak_installed_ref_get_deploy_dir (app),
                 flatpak_installed_ref_get_is_current (app),
                 flatpak_installed_ref_get_installed_size (app));
        g_print ("metadata:\n%s\n", (char *) g_bytes_get_data (flatpak_installed_ref_load_metadata (app, NULL, NULL), NULL));
      }
  }

  g_print ("\n**** Listing all installed runtimes\n");
  {
    g_autoptr(GPtrArray) runtimes = NULL;

    runtimes = flatpak_installation_list_installed_refs_by_kind (installation,
                                                                 FLATPAK_REF_KIND_RUNTIME,
                                                                 NULL, NULL);

    for (i = 0; i < runtimes->len; i++)
      {
        FlatpakInstalledRef *runtime = g_ptr_array_index (runtimes, i);
        g_print ("%d %s %s %s %s %s %s %d\n",
                 flatpak_ref_get_kind (FLATPAK_REF (runtime)),
                 flatpak_ref_get_name (FLATPAK_REF (runtime)),
                 flatpak_ref_get_arch (FLATPAK_REF (runtime)),
                 flatpak_ref_get_branch (FLATPAK_REF (runtime)),
                 flatpak_ref_get_commit (FLATPAK_REF (runtime)),
                 flatpak_installed_ref_get_origin (runtime),
                 flatpak_installed_ref_get_deploy_dir (runtime),
                 flatpak_installed_ref_get_is_current (runtime));
      }
  }

  g_print ("\n**** Getting installed gedit master\n");
  app1 = flatpak_installation_get_installed_ref (installation,
                                                 FLATPAK_REF_KIND_APP,
                                                 "org.gnome.gedit",
                                                 NULL, "master", NULL, NULL);
  if (app1)
    {
      g_print ("gedit master: %d %s %s %s %s %s %s %d\n",
               flatpak_ref_get_kind (FLATPAK_REF (app1)),
               flatpak_ref_get_name (FLATPAK_REF (app1)),
               flatpak_ref_get_arch (FLATPAK_REF (app1)),
               flatpak_ref_get_branch (FLATPAK_REF (app1)),
               flatpak_ref_get_commit (FLATPAK_REF (app1)),
               flatpak_installed_ref_get_origin (app1),
               flatpak_installed_ref_get_deploy_dir (app1),
               flatpak_installed_ref_get_is_current (app1));
    }
  if (!flatpak_installation_launch (installation,
                                    "org.gnome.gedit",
                                    NULL, NULL, NULL,
                                    NULL, &error))
    {
      g_print ("launch gedit error: %s\n", error->message);
      g_clear_error (&error);
    }

  g_print ("\n**** Getting current installed gedit\n");
  app2 = flatpak_installation_get_current_installed_app (installation,
                                                         "org.gnome.gedit",
                                                         NULL, NULL);
  if (app2)
    {
      g_print ("gedit current: %d %s %s %s %s %s %s %d\n",
               flatpak_ref_get_kind (FLATPAK_REF (app2)),
               flatpak_ref_get_name (FLATPAK_REF (app2)),
               flatpak_ref_get_arch (FLATPAK_REF (app2)),
               flatpak_ref_get_branch (FLATPAK_REF (app2)),
               flatpak_ref_get_commit (FLATPAK_REF (app2)),
               flatpak_installed_ref_get_origin (app2),
               flatpak_installed_ref_get_deploy_dir (app2),
               flatpak_installed_ref_get_is_current (app2));
    }


  g_print ("\n**** Listing remotes\n");
  remotes = flatpak_installation_list_remotes (installation,
                                               NULL, NULL);

  for (i = 0; i < remotes->len; i++)
    {
      FlatpakRemote *remote = g_ptr_array_index (remotes, i);
      g_autoptr(GPtrArray) refs = NULL;
      const char *collection_id = NULL;

      collection_id = flatpak_remote_get_collection_id (remote);

      g_print ("\nRemote: %s %u %d %s %s %s %s %d %d %s\n",
               flatpak_remote_get_name (remote),
               flatpak_remote_get_remote_type (remote),
               flatpak_remote_get_prio (remote),
               flatpak_remote_get_url (remote),
               collection_id,
               flatpak_remote_get_title (remote),
               flatpak_remote_get_default_branch (remote),
               flatpak_remote_get_gpg_verify (remote),
               flatpak_remote_get_noenumerate (remote),
               g_file_get_path (flatpak_remote_get_appstream_dir (remote, NULL)));

      g_print ("\n**** Listing remote refs on %s\n", flatpak_remote_get_name (remote));
      refs = flatpak_installation_list_remote_refs_sync (installation, flatpak_remote_get_name (remote),
                                                         NULL, NULL);
      if (refs)
        {
          for (j = 0; j < refs->len; j++)
            {
              FlatpakRemoteRef *ref = g_ptr_array_index (refs, j);
              g_print ("%d %s %s %s %s %s\n",
                       flatpak_ref_get_kind (FLATPAK_REF (ref)),
                       flatpak_ref_get_name (FLATPAK_REF (ref)),
                       flatpak_ref_get_arch (FLATPAK_REF (ref)),
                       flatpak_ref_get_branch (FLATPAK_REF (ref)),
                       flatpak_ref_get_commit (FLATPAK_REF (ref)),
                       flatpak_remote_ref_get_remote_name (ref));

              if (j == 0)
                {
                  guint64 download_size;
                  guint64 installed_size;

                  if (!flatpak_installation_fetch_remote_size_sync (installation,
                                                                    flatpak_remote_get_name (remote),
                                                                    FLATPAK_REF (ref),
                                                                    &download_size,
                                                                    &installed_size,
                                                                    NULL, &error))
                    {
                      g_print ("error fetching sizes: %s\n", error->message);
                      g_clear_error (&error);
                    }
                  else
                    {
                      g_print ("Download size: %"G_GUINT64_FORMAT " Installed size: %"G_GUINT64_FORMAT "\n",
                               download_size, installed_size);
                    }
                }
            }
        }

      g_print ("\n**** Getting remote platform 3.20 on %s\n", flatpak_remote_get_name (remote));
      error = NULL;
      remote_ref = flatpak_installation_fetch_remote_ref_sync (installation, flatpak_remote_get_name (remote),
                                                               FLATPAK_REF_KIND_RUNTIME,
                                                               "org.gnome.Platform", NULL, "3.20",
                                                               NULL, &error);
      if (remote_ref)
        {
          GBytes *metadata;

          g_print ("%d %s %s %s %s %s\n",
                   flatpak_ref_get_kind (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_name (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_arch (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_branch (FLATPAK_REF (remote_ref)),
                   flatpak_ref_get_commit (FLATPAK_REF (remote_ref)),
                   flatpak_remote_ref_get_remote_name (remote_ref));

          metadata = flatpak_installation_fetch_remote_metadata_sync (installation, flatpak_remote_get_name (remote),
                                                                      FLATPAK_REF (remote_ref), NULL, &error);
          if (metadata)
            {
              g_print ("metadata: %s\n", (char *) g_bytes_get_data (metadata, NULL));
            }
          else
            {
              g_print ("fetch error\n");
              g_print ("error: %s\n", error->message);
              g_clear_error (&error);
            }
        }
      else
        {
          g_print ("error: %s\n", error->message);
          g_clear_error (&error);
        }
    }
  return 0;
}