static void gsf_open_pkg_write_content_override (GsfOutfileOpenPkg const *open_pkg, char const *base, GsfXMLOut *xml) { GsfOutfileOpenPkg const *child; char *path; GSList *ptr; for (ptr = open_pkg->children ; ptr != NULL ; ptr = ptr->next) { child = ptr->data; if (child->is_dir) { path = g_strconcat (base, gsf_output_name (GSF_OUTPUT (child)), "/", NULL); gsf_open_pkg_write_content_override (child, path, xml); } else { path = g_strconcat (base, gsf_output_name (GSF_OUTPUT (child)), NULL); /* rels files do need content types, the defaults handle them */ if (NULL != child->content_type) { gsf_xml_out_start_element (xml, "Override"); gsf_xml_out_add_cstr (xml, "PartName", path); gsf_xml_out_add_cstr (xml, "ContentType", child->content_type); gsf_xml_out_end_element (xml); /* </Override> */ } } g_free (path); } }
static GsfOutput * gsf_outfile_open_pkg_new_child (GsfOutfile *parent, char const *name, gboolean is_dir, char const *first_property_name, va_list args) { GsfOutfileOpenPkg *child, *open_pkg = GSF_OUTFILE_OPEN_PKG (parent); GsfOutput *sink; if (!open_pkg->is_dir) return NULL; child = (GsfOutfileOpenPkg *)g_object_new_valist ( GSF_OUTFILE_OPEN_PKG_TYPE, first_property_name, args); gsf_output_set_name (GSF_OUTPUT (child), name); gsf_output_set_container (GSF_OUTPUT (child), parent); child->is_dir = is_dir; sink = gsf_outfile_new_child (GSF_OUTFILE (open_pkg->sink), name, is_dir); gsf_outfile_open_pkg_set_sink (child, sink); g_object_unref (sink); /* * Holding a ref here is not ideal. It means we won't release any of the * children until the package is closed. */ open_pkg->children = g_slist_prepend (open_pkg->children, g_object_ref (child)); return GSF_OUTPUT (child); }
static GsfOutput * gsf_outfile_open_pkg_new_child (GsfOutfile *parent, char const *name, gboolean is_dir, char const *first_property_name, va_list args) { GsfOutfileOpenPkg *child, *open_pkg = GSF_OUTFILE_OPEN_PKG (parent); GsfOutput *sink; if (!open_pkg->is_dir) return NULL; child = (GsfOutfileOpenPkg *)g_object_new_valist ( GSF_OUTFILE_OPEN_PKG_TYPE, first_property_name, args); gsf_output_set_name (GSF_OUTPUT (child), name); gsf_output_set_container (GSF_OUTPUT (child), parent); child->is_dir = is_dir; sink = gsf_outfile_new_child (GSF_OUTFILE (open_pkg->sink), name, is_dir); gsf_outfile_open_pkg_set_sink (child, sink); g_object_unref (sink); open_pkg->children = g_slist_prepend (open_pkg->children, child); g_object_ref (child); return GSF_OUTPUT (child); }
static GSList * xlsx_write_pivots (XLSXWriteState *state, GsfOutfile *wb_part) { GHashTable *caches = excel_collect_pivot_caches (state->base.wb); GHashTableIter iter; GSList *refs = NULL; gpointer key, value; char const *cache_def_id; if (caches == NULL) return NULL; state->date_fmt = xlsx_pivot_date_fmt (); state->pivotCache.count = state->pivotTable.count = 0; state->pivotCache.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "pivotCache", TRUE); state->pivotTable.dir = (GsfOutfile *)gsf_outfile_new_child (state->xl_dir, "pivotTable", TRUE); g_hash_table_iter_init (&iter, caches); while (g_hash_table_iter_next (&iter, &key, &value)) if (NULL != key) { cache_def_id = xlsx_write_pivot_cache_definition (state, wb_part, key, GPOINTER_TO_UINT(value)); refs = g_slist_prepend (refs, (gpointer)cache_def_id); } gsf_output_close (GSF_OUTPUT (state->pivotCache.dir)); gsf_output_close (GSF_OUTPUT (state->pivotTable.dir)); g_hash_table_destroy (caches); go_format_unref (state->date_fmt); return g_slist_reverse (refs); }
uint32_t FileWriterI::close() { if (baseOutfile == NULL) { WARNING << "ops::msole::FileWriterI::close() : file already closed"; return RET_ERR; } // close all opened files. vector <GsfOutput*> :: iterator iter; for ( uint32_t i = 0 ; i < openFileHandler.size() ; i++) { GsfOutput * output = openFileHandler[i]; if (output != NULL) { gsf_output_close (GSF_OUTPUT (output)); g_object_unref (G_OBJECT (output)); } } openFileHandler.clear(); // close all opened directories. map <std::string, GsfOutput*> :: reverse_iterator rIter; for ( rIter = openDirList.rbegin( ) ; rIter != openDirList.rend( ) ; rIter++) { GsfOutput * output = openDirList[rIter->first]; gsf_output_close (GSF_OUTPUT (output)); g_object_unref (G_OBJECT (output)); } openDirList.clear(); baseOutfile = NULL; DEBUG << "ops::msole::FileWriterI::close() : file closed"; return RET_OK; }
static void gsf_output_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { /* gsf_off_t is typedef'd to gint64 */ switch (property_id) { case PROP_NAME: g_value_set_string (value, gsf_output_name (GSF_OUTPUT (object))); break; case PROP_SIZE: g_value_set_int64 (value, gsf_output_size (GSF_OUTPUT (object))); break; case PROP_POS: g_value_set_int64 (value, gsf_output_tell (GSF_OUTPUT (object))); break; case PROP_CLOSED: g_value_set_boolean (value, gsf_output_is_closed (GSF_OUTPUT (object))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
/** * gsf_output_stdio_new_FILE: (skip) * @filename: The filename corresponding to @file. * @file: (transfer full): an existing stdio <type>FILE</type> * * @keep_open: Should @file be closed when the wrapper is closed * * Assumes ownership of @file. If @keep_open is true, ownership reverts * to caller when the GsfOutput is closed. * * Returns: a new GsfOutput wrapper for @file. Warning: the result will be * seekable only if @file is seekable. If it is seekable, the resulting * GsfOutput object will seek relative to @file's beginning, not its * current location at the time the GsfOutput object is created. **/ GsfOutput * gsf_output_stdio_new_FILE (char const *filename, FILE *file, gboolean keep_open) { GsfOutputStdio *stdio; g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (file != NULL, NULL); stdio = g_object_new (GSF_OUTPUT_STDIO_TYPE, NULL); stdio->file = file; stdio->keep_open = keep_open; stdio->real_filename = stdio->temp_filename = NULL; gsf_output_set_name_from_filename (GSF_OUTPUT (stdio), filename); return GSF_OUTPUT (stdio); }
/* write the metadata (dirents, small block, xbats) and close the sink */ static gboolean gsf_outfile_msole_close_root (GsfOutfileMSOle *ole) { GsfOutfile *tmp; guint8 buf [OLE_HEADER_SIZE]; guint32 sbat_start, num_sbat, sb_data_start, sb_data_size, sb_data_blocks; guint32 bat_start, num_bat, dirent_start, num_dirent_blocks, next, child_index; unsigned i, j, blocks, num_xbat, xbat_pos; gsf_off_t data_size; unsigned metabat_size = ole->bb.size / BAT_INDEX_SIZE - 1; GPtrArray *elem = ole->root->content.dir.root_order; /* write small block data */ blocks = 0; sb_data_start = ole_cur_block (ole); data_size = gsf_output_tell (ole->sink); for (i = 0 ; i < elem->len ; i++) { GsfOutfileMSOle *child = g_ptr_array_index (elem, i); if (child->type == MSOLE_SMALL_BLOCK) { gsf_off_t size = gsf_output_size (GSF_OUTPUT (child)); if (size > 0) { child->blocks = ((size - 1) >> ole->sb.shift) + 1; gsf_output_write (ole->sink, child->blocks << ole->sb.shift, child->content.small_block.buf); child->first_block = blocks; blocks += child->blocks; } else {
uint32_t FileWriterI::mkdir(string inpath) { // check if writer is ready if (baseOutfile == NULL) { ERROR << "ops::msole::FileWriterI::writeAllImpl() : file not opened"; return RET_ERR; } // split inpath vector<string> pathElements = ops::tools::split(inpath, '/'); // go into subdirs size_t currentPathIndex = 0; string partialInpath = "/"; GsfOutput * output = GSF_OUTPUT(baseOutfile); for (; currentPathIndex < pathElements.size() ; currentPathIndex++) { partialInpath += pathElements[currentPathIndex] + "/"; if (openDirList.find(partialInpath) != openDirList.end()) { output = openDirList[partialInpath]; } else { // create new child ans store it output = gsf_outfile_new_child(GSF_OUTFILE(output), pathElements[currentPathIndex].c_str(), true); openDirList[partialInpath] = output; } } DEBUG << "ops::msole::FileWriterI::writeAllImpl() : " + inpath + " created"; return RET_OK; }
uint32_t FileWriterI::open(string filepath) { GError * err = NULL; // open file GsfOutput * output = gsf_output_stdio_new (filepath.c_str(), &err); if (output == NULL) { ERROR << "ops::msole::FileWriterI::open() : can't open " + filepath + " : " + err->message; g_error_free (err); return RET_ERR; } baseOutfile = gsf_outfile_msole_new (output); g_object_unref (G_OBJECT (output)); if (baseOutfile == NULL) { ERROR << "ops::msole::FileWriterI::open() : can't create OLE file :" + filepath + " : " + err->message; g_error_free (err); return RET_ERR; } // create map for keeping open directories openDirList["/"] = GSF_OUTPUT(baseOutfile); DEBUG << "ops::msole::FileWriterI::open() : " + filepath + " opened"; return RET_OK; }
/** * gsf_output_bzip_new : * @sink : The underlying data source. * @err : optionally %NULL. * * Adds a reference to @sink. * * Returns: a new file or %NULL. **/ GsfOutput * gsf_output_bzip_new (GsfOutput *sink, GError **err) { #ifdef HAVE_BZ2 GsfOutputBzip *bzip; g_return_val_if_fail (GSF_IS_OUTPUT (sink), NULL); bzip = g_object_new (GSF_OUTPUT_BZIP_TYPE, NULL); if (G_UNLIKELY (NULL == bzip)) return NULL; g_object_ref (G_OBJECT (sink)); bzip->sink = sink; if (!init_bzip (bzip, err)) { g_object_unref (G_OBJECT (bzip)); return NULL; } return GSF_OUTPUT (bzip); #else (void)sink; if (err) *err = g_error_new (gsf_output_error_id (), 0, "BZ2 support not enabled"); return NULL; #endif }
/* Decompress infile in dest_dir. */ static void decompress_infile (GsfInfile *infile, gchar *dest_dir) { GError *err = (GError *) NULL; int j = 0; for (j = 0; j < gsf_infile_num_children (infile); j++) { GsfInput *child = gsf_infile_child_by_index (infile, j); char const* filename = gsf_input_name (child); gboolean is_dir = gsf_infile_num_children (GSF_INFILE (child)) >= 0; if (is_dir) { gchar *dir_path = g_build_filename (dest_dir, filename, (gchar *) 0); decompress_infile (GSF_INFILE (child), dir_path); g_free (dir_path); } else { gchar *file_path = g_build_filename (dest_dir, filename, (gchar *) 0); GsfOutput *output = GSF_OUTPUT (gsf_output_stdio_new (file_path, &err)); gsf_input_copy (child, output); gsf_output_close (output); g_object_unref (output); g_free (file_path); } g_object_unref (G_OBJECT (child)); } }
static int test (char *argv[]) { GsfInfile *infile; GsfOutfile *outfile; GsfOutput *output; GError *err = NULL; fprintf (stderr, "%s\n", argv [1]); infile = gsf_infile_stdio_new (argv[1], &err); if (infile == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' error: %s", argv[1], err->message); g_error_free (err); return 1; } output = gsf_output_stdio_new (argv[2], &err); if (output == NULL) { g_return_val_if_fail (err != NULL, 1); g_warning ("'%s' error: %s", argv[2], err->message); g_error_free (err); g_object_unref (G_OBJECT (infile)); return 1; } outfile = gsf_outfile_msole_new (output); g_object_unref (G_OBJECT (output)); clone (GSF_INPUT (infile), GSF_OUTPUT (outfile)); return 0; }
static void gsf_output_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GsfOutput *output = GSF_OUTPUT (object); /* gsf_off_t is typedef'd to gint64 */ switch (property_id) { case PROP_NAME: g_value_set_string (value, gsf_output_name (output)); break; case PROP_SIZE: g_value_set_int64 (value, gsf_output_size (output)); break; case PROP_CLOSED: g_value_set_boolean (value, gsf_output_is_closed (output)); break; case PROP_POS: g_value_set_int64 (value, gsf_output_tell (output)); break; case PROP_MODTIME: g_value_set_boxed (value, gsf_output_get_modtime (output)); break; case PROP_CONTAINER: g_value_set_object (value, output->container); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
static void gsf_outfile_msole_finalize (GObject *obj) { GsfOutfileMSOle *ole = GSF_OUTFILE_MSOLE (obj); GsfOutput *output = GSF_OUTPUT (obj); if (!gsf_output_is_closed (output)) gsf_output_close (output); if (ole->sink != NULL) { g_object_unref (G_OBJECT (ole->sink)); ole->sink = NULL; } switch (ole->type) { case MSOLE_DIR: g_slist_free (ole->content.dir.children); ole->content.dir.children = NULL; if (ole->content.dir.root_order != NULL) g_warning ("Finalizing a MSOle Outfile without closing it."); break; case MSOLE_SMALL_BLOCK: g_free (ole->content.small_block.buf); ole->content.small_block.buf = NULL; break; case MSOLE_BIG_BLOCK: break; default : g_warning ("Unknown file type"); } parent_class->finalize (obj); }
static gboolean zip_close_root (GsfOutput *output) { GsfOutfileZip *zip = GSF_OUTFILE_ZIP (output); GsfOutfileZip *child; gsf_off_t dirpos = gsf_output_tell (zip->sink); GPtrArray *elem = zip->root_order; unsigned entries = elem->len; unsigned i; /* Check that children are closed */ for (i = 0 ; i < elem->len ; i++) { child = g_ptr_array_index (elem, i); if (!gsf_output_is_closed (GSF_OUTPUT (child))) { g_warning ("Child still open"); return FALSE; } } /* Write directory */ for (i = 0 ; i < entries ; i++) { child = g_ptr_array_index (elem, i); if (!zip_dirent_write (zip->sink, child->vdir->dirent)) return FALSE; } disconnect_children (zip); return zip_trailer_write (zip, entries, dirpos); }
UT_Error AbiCollabSessionManager::serializeDocument(const PD_Document* pDoc, std::string& document, bool encodeBase64) { UT_return_val_if_fail(pDoc, false); // Don't put this auto-save in the most recent list. XAP_App::getApp()->getPrefs()->setIgnoreNextRecent(); // maskExport(); GsfOutputMemory* sink = GSF_OUTPUT_MEMORY(gsf_output_memory_new()); GsfOutput* gzSink = gsf_output_gzip_new(GSF_OUTPUT(sink), NULL); bool bAuthor = pDoc->isExportAuthorAtts(); const_cast<PD_Document *>(pDoc)->setExportAuthorAtts(true); UT_Error result = const_cast<PD_Document*>(pDoc)->saveAs(GSF_OUTPUT(gzSink), IE_Exp::fileTypeForSuffix(".abw"), true); const_cast<PD_Document *>(pDoc)->setExportAuthorAtts(bAuthor); gsf_output_close(GSF_OUTPUT(gzSink)); // unmaskExport(); if (result == UT_OK) { guint32 size = gsf_output_size (GSF_OUTPUT(sink)); const guint8* zabwBuf = gsf_output_memory_get_bytes (sink); if (encodeBase64) { // this would be more efficient if we had a GsfOutputBase64.. ah well, this will do for now guint8* base64zabwBuf = gsf_base64_encode_simple(zabwBuf, size); document += (char*)base64zabwBuf; g_free(base64zabwBuf); } else { // just copy raw zipped data into string document.resize( size ); memcpy( &document[0], zabwBuf, size ); } } else { UT_DEBUGMSG(("Failed to export! Handle this gracefully!\n")); } g_object_unref(G_OBJECT(gzSink)); g_object_unref(G_OBJECT(sink)); return result; }
static GsfOutput * gsf_outfile_zip_new_child (GsfOutfile *parent, char const *name, gboolean is_dir, char const *first_property_name, va_list args) { GsfOutfileZip *zip_parent = (GsfOutfileZip *)parent; GsfOutfileZip *child; size_t n_params = 0; GParameter *params = NULL; char *display_name; g_return_val_if_fail (zip_parent != NULL, NULL); g_return_val_if_fail (zip_parent->vdir, NULL); g_return_val_if_fail (zip_parent->vdir->is_directory, NULL); g_return_val_if_fail (name && *name, NULL); gsf_property_settings_collect (GSF_OUTFILE_ZIP_TYPE, ¶ms, &n_params, "sink", zip_parent->sink, "entry-name", name, NULL); gsf_property_settings_collect_valist (GSF_OUTFILE_ZIP_TYPE, ¶ms, &n_params, first_property_name, args); child = (GsfOutfileZip *)g_object_newv (GSF_OUTFILE_ZIP_TYPE, n_params, params); gsf_property_settings_free (params, n_params); child->vdir = gsf_vdir_new (name, is_dir, NULL); /* FIXME: It isn't clear what encoding name is in. */ display_name = g_filename_display_name (name); gsf_output_set_name (GSF_OUTPUT (child), display_name); g_free (display_name); gsf_output_set_container (GSF_OUTPUT (child), parent); gsf_vdir_add_child (zip_parent->vdir, child->vdir); root_register_child (zip_parent->root, child); return GSF_OUTPUT (child); }
static gboolean close_file_helper (GsfOutputStdio *stdio, gboolean seterr) { gboolean res = (0 == fclose (stdio->file)); stdio->file = NULL; if (!res && seterr) gsf_output_set_error (GSF_OUTPUT (stdio), errno, "Failed to close file: %s", g_strerror (errno)); return res; }
static GObject * gsf_outfile_zip_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_params) { GsfOutfileZip *zip =(GsfOutfileZip *) (parent_class->constructor (type, n_construct_properties, construct_params)); if (!zip->entry_name) { zip->vdir = gsf_vdir_new ("", TRUE, NULL); zip->root_order = g_ptr_array_new (); zip->root = zip; /* The names are the same */ gsf_output_set_name (GSF_OUTPUT (zip), gsf_output_name (zip->sink)); gsf_output_set_container (GSF_OUTPUT (zip), NULL); } return (GObject *)zip; }
static gboolean soi_gdk_pixbuf_save (gchar const *buf, gsize count, GError **error, gpointer data) { GsfOutput *output = GSF_OUTPUT (data); gboolean ok = gsf_output_write (output, count, buf); if (!ok && error) *error = g_error_copy (gsf_output_error (output)); return ok; }
static void gsf_output_init (GObject *obj) { GsfOutput *output = GSF_OUTPUT (obj); output->cur_offset = 0; output->cur_size = 0; output->name = NULL; output->wrapped_by = NULL; output->container = NULL; output->err = NULL; output->is_closed = FALSE; output->printf_buf = NULL; output->printf_buf_size = 0; }
HRESULT STDMETHODCALLTYPE OMGSFIStorage::StgCreateStorageEx( const TCHAR FAR* in_filename, OMFile::OMAccessMode in_accessMode, void **out_storage, ULONG in_sectorSize) { TRACE("OMGSFIStorage::StgCreateStorageEx"); PRECONDITION("Valid access mode", in_accessMode == OMFile::writeOnlyMode); GsfStorage *storage = 0; *out_storage = 0; char storageName[FILENAME_MAX]; #ifndef OM_UNICODE_APIS strncpy (storageName, in_filename, sizeof(storageName) -1); storageName[sizeof(storageName) -1] = '\0'; #else convertWideStringToString (storageName, in_filename, FILENAME_MAX); #endif int status = GSTG_OK; GError *err; GsfOutput *output = GSF_OUTPUT (gsf_output_stdio_new (storageName, &err)); if (output != NULL) { storage = GSF_OUTFILE (gsf_outfile_msole_new_full ( output, in_sectorSize, // sector size - 512 or 4096 bytes 64)); // mini-sector size always 64 bytes g_object_unref (G_OBJECT (output)); } else status = GSTG_ERROR; if (status == GSTG_OK) { OMGSFIStorage *newStorage = new OMGSFIStorage (storage, GSF_WRITE, storageName); *out_storage = newStorage; } return makeStatus(status); }
ULONG STDMETHODCALLTYPE OMGSFIStorage::Release(void) { TRACE("OMGSFIStorage::Release"); ULONG result = --_referenceCount; if (_referenceCount == 0) { if (_storage != 0) { if (GSF_IS_OUTPUT(_storage)) { gsf_output_close (GSF_OUTPUT(_storage)); } g_object_unref (G_OBJECT(_storage)); _storage = 0; } delete this; } return result; }
static void gsf_output_dispose (GObject *obj) { GsfOutput *output = GSF_OUTPUT (obj); if (!output->is_closed) { /* g_warning ("Disposing of an unclosed stream"); */ gsf_output_close (output); } gsf_output_set_container (output, NULL); gsf_output_set_name (output, NULL); g_free (output->printf_buf); output->printf_buf = NULL; g_clear_error (&output->err); parent_class->dispose (obj); }
int32_t FileWriterI::fileOpen(std::string inpath) { int32_t handler = -1; // check if writer is ready if (baseOutfile == NULL) { ERROR << "ops::msole::FileWriterI::fileOpen() : file not opened"; return RET_ERR; } // split inpath vector<string> pathElements = ops::tools::split(inpath, '/'); // go into subdirs size_t currentPathIndex = 0; string partialInpath = "/"; GsfOutput * output = GSF_OUTPUT(baseOutfile); for (; currentPathIndex < pathElements.size() ; currentPathIndex++) { if (currentPathIndex < pathElements.size() - 1) { partialInpath += pathElements[currentPathIndex] + "/"; if (openDirList.find(partialInpath) != openDirList.end()) { output = openDirList[partialInpath]; } else { // create new child ans store it output = gsf_outfile_new_child(GSF_OUTFILE(output), pathElements[currentPathIndex].c_str(), true); openDirList[partialInpath] = output; } } else { // last path, so it's a plain file output = gsf_outfile_new_child(GSF_OUTFILE(output), pathElements[currentPathIndex].c_str(), false); // store file and return handler handler = openFileHandler.size(); openFileHandler.push_back(output); } } DEBUG << "ops::msole::FileWriterI::fileOpen() : " + inpath + " opened"; return handler; }
static void stream_name_write_to_buf (GsfOutfileZip *zip, GString *res) { GsfOutput *output = GSF_OUTPUT (zip); GsfOutfile *container; if (zip == zip->root) return; container = gsf_output_container (output); if (container) { stream_name_write_to_buf (GSF_OUTFILE_ZIP (container), res); if (res->len) { /* Forward slash is specified by the format. */ g_string_append_c (res, '/'); } } if (zip->entry_name) g_string_append (res, zip->entry_name); }
static void gsf_output_set_property (GObject *object, guint property_id, GValue const *value, GParamSpec *pspec) { GsfOutput *output = GSF_OUTPUT (object); switch (property_id) { case PROP_NAME: gsf_output_set_name (output, g_value_get_string (value)); break; case PROP_MODTIME: gsf_output_set_modtime (output, g_value_get_boxed (value)); break; case PROP_CONTAINER: gsf_output_set_container (output, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } }
/** * gsf_outfile_open_pkg_relate: * @child: #GsfOutfileOpenPkg * @parent: #GsfOutfileOpenPkg * @type: target type * * Create a relationship between @child and @parent of @type. * * Returns: (transfer none): the relID which the caller does not own * but will live as long as @parent. **/ char const * gsf_outfile_open_pkg_relate (GsfOutfileOpenPkg *child, GsfOutfileOpenPkg *parent, char const *type) { GString *path; int up = -1; GsfOutfile *child_dir, *parent_dir; /* Calculate the path from @child to @parent */ parent_dir = parent->is_dir ? GSF_OUTFILE (parent) : gsf_output_container (GSF_OUTPUT (parent)); do { up++; child_dir = GSF_OUTFILE (child); while (NULL != (child_dir = gsf_output_container (GSF_OUTPUT (child_dir)))) if (child_dir == parent_dir) goto found; /* break out of both loops */ } while (NULL != (parent_dir = gsf_output_container (GSF_OUTPUT (parent_dir)))); found: /* yes prepend is slow, this will never be preformance critical */ path = g_string_new (gsf_output_name (GSF_OUTPUT (child))); child_dir = GSF_OUTFILE (child); while (NULL != (child_dir = gsf_output_container (GSF_OUTPUT (child_dir))) && NULL != gsf_output_name (GSF_OUTPUT (child_dir)) && child_dir != parent_dir) { g_string_prepend_c (path, '/'); g_string_prepend (path, gsf_output_name (GSF_OUTPUT (child_dir))); } while (up--) g_string_prepend (path, "../"); return gsf_outfile_open_pkg_create_rel (parent, g_string_free (path, FALSE), type, FALSE); }
/** * be sure to unref the result if it is non-NULL * * TODO : this is really overkill for now. * only wmf/emf will require regenerating the pixbuf for different scale * factors. And even then we should cache them. */ static GdkPixbuf * soi_get_pixbuf (SheetObjectImage *soi, double scale) { GError *err = NULL; guint8 *data; guint32 data_len; GdkPixbufLoader *loader = NULL; GdkPixbuf *pixbuf = NULL; gboolean ret; g_return_val_if_fail (IS_SHEET_OBJECT_IMAGE (soi), NULL); data = soi->bytes.data; data_len = soi->bytes.len; if (data == NULL || data_len == 0) return pixbuf; if (soi->type != NULL && !strcmp (soi->type, "wmf")) loader = gdk_pixbuf_loader_new_with_type (soi->type, &err); else loader = gdk_pixbuf_loader_new (); if (soi->type == NULL || strlen (soi->type) == 0) g_signal_connect (loader, "size-prepared", G_CALLBACK (soi_info_cb), soi); if (loader) { ret = gdk_pixbuf_loader_write (loader, soi->bytes.data, soi->bytes.len, &err); /* Close in any case. But don't let error during closing * shadow error from loader_write. */ gdk_pixbuf_loader_close (loader, ret ? &err : NULL); if (ret) pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); if (pixbuf) { g_object_ref (G_OBJECT (pixbuf)); d (printf ("pixbuf width=%d, height=%d\n", gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf))); if (soi->crop_top != 0.0 || soi->crop_bottom != 0.0 || soi->crop_left != 0.0 || soi->crop_right != 0.0) { d (printf ("crop rect top=%g, bottom=%g, " "left=%g, right=%g\n", soi->crop_top, soi->crop_bottom, soi->crop_left, soi->crop_right)); pixbuf = soi_get_cropped_pixbuf (soi, pixbuf); } } g_object_unref (G_OBJECT (loader)); } if (!pixbuf) { if (!soi->dumped) { static int count = 0; char *filename = g_strdup_printf ("unknown%d.%s", count++, soi->type); #if 0 GsfOutput *file = gsf_output_stdio_new (filename, NULL); if (file) { gsf_output_write (GSF_OUTPUT (file), soi->bytes.len, soi->bytes.data); gsf_output_close (GSF_OUTPUT (file)); g_object_unref (file); } #endif g_free (filename); soi->dumped = TRUE; } if (err != NULL) { g_warning ("%s", err->message); g_error_free (err); err = NULL; } else { g_warning ("Unable to display image"); } } return pixbuf; }