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; }
/** * 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; }
/** * 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); }
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; }
/** * 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); } }
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; }
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; }
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); }
/** * 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; }
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; }
/* * 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); }
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); }
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; }
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); } }
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; }
/** * 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; }
/** * 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; }
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); }
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; }
/** * 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)); }
/** * 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; }
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; }