const char * AbiWordperfectInputStream::subStreamName(unsigned id) { if (!m_ole) m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL)); if (!m_ole) m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL)); if (m_ole) { if ((int)id >= gsf_infile_num_children(m_ole)) { return 0; } std::map<unsigned, std::string>::iterator i = m_substreams.lower_bound(id); if (i == m_substreams.end() || m_substreams.key_comp()(id, i->first)) { std::string name = gsf_infile_name_by_index(m_ole, (int)id); i = m_substreams.insert(i, std::map<unsigned, std::string>::value_type(id, name)); } return i->second.c_str(); } return 0; }
static void clone_dir (GsfInfile *in, GsfOutfile *out) { GsfInput *new_input; GsfOutput *new_output; gboolean is_dir; int i; for (i = 0 ; i < gsf_infile_num_children (in) ; i++) { new_input = gsf_infile_child_by_index (in, i); /* In theory, if new_file is a regular file (not directory), * it should be GsfInput only, not GsfInfile, as it is not * structured. However, having each Infile define a 2nd class * that only inherited from Input was cumbersome. So in * practice, the convention is that new_input is always * GsfInfile, but regular file is distinguished by having -1 * children. */ is_dir = GSF_IS_INFILE (new_input) && gsf_infile_num_children (GSF_INFILE (new_input)) >= 0; new_output = gsf_outfile_new_child (out, gsf_infile_name_by_index (in, i), is_dir); clone (new_input, new_output); } /* An observation: when you think about the explanation to is_dir * above, you realize that clone_dir is called even for regular files. * But nothing bad happens, as the loop is never entered. */ }
static void clone (GsfInput *input, GsfOutput *output) { guint8 const *data; size_t len; int i; if (gsf_input_size (input) > 0) { while ((len = gsf_input_remaining (input)) > 0) { /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read (input, len, NULL))) { g_warning ("error reading ?"); return; } if (!gsf_output_write (output, len, data)) { g_warning ("error writing ?"); return; } } } /* See test-cp-msole.c for explanation how to distinct directories * from regular files. */ if (GSF_IS_INFILE (input) && gsf_infile_num_children (GSF_INFILE (input)) > 0) { GsfInfile *in = GSF_INFILE (input); GsfOutfile *out = GSF_OUTFILE (output); GsfInput *src; GsfOutput *dst; gboolean is_dir; for (i = 0 ; i < gsf_infile_num_children (in) ; i++) { src = gsf_infile_child_by_index (in, i); is_dir = GSF_IS_INFILE (src) && gsf_infile_num_children (GSF_INFILE (src)) >= 0; dst = gsf_outfile_new_child (out, gsf_infile_name_by_index (in, i), is_dir); clone (src, dst); } } gsf_output_close (output); g_object_unref (G_OBJECT (output)); g_object_unref (G_OBJECT (input)); }
static void clone_ (GsfInfile *in, GsfOutfile *out) { GsfInput *input = GSF_INPUT (in); GsfOutput *output = GSF_OUTPUT (out); if (gsf_input_size (input) > 0) { size_t len; while ((len = gsf_input_remaining (input)) > 0) { guint8 const *data; /* copy in odd sized chunks to exercise system */ if (len > 314) len = 314; if (NULL == (data = gsf_input_read (input, len, NULL))) { g_warning ("error reading ?"); break; } if (!gsf_output_write (output, len, data)) { g_warning ("error writing ?"); break; } } } else { int i, n = gsf_infile_num_children (in); for (i = 0 ; i < n; i++) { int level; gboolean is_dir; char const *name = gsf_infile_name_by_index (in, i); char *display_name = name ? g_filename_display_name (name) : NULL; input = gsf_infile_child_by_index (in, i); if (NULL == input) { g_print ("Error opening '%s, index = %d\n", display_name ? display_name : "?", i); g_free (display_name); continue; } is_dir = gsf_infile_num_children (GSF_INFILE (input)) >= 0; g_object_get (G_OBJECT (input), "compression-level", &level, NULL); g_print ("%s: size=%ld, level=%d, %s\n", display_name ? display_name : "?", (long)gsf_input_size (input), level, is_dir ? "directory" : "file"); g_free (display_name); output = gsf_outfile_new_child_full (out, name, is_dir, "compression-level", level, NULL); clone_ (GSF_INFILE (input), GSF_OUTFILE (output)); } } gsf_output_close (GSF_OUTPUT (out)); g_object_unref (G_OBJECT (out)); g_object_unref (G_OBJECT (in)); }