1 /**
2  * boot.c: Lotus 123 support for Gnumeric
3  *
4  * Authors:
5  *    See: README
6  *    Michael Meeks <mmeeks@gnu.org>
7  *    Morten Welinder (terra@gnome.org)
8  **/
9 #include <gnumeric-config.h>
10 #include <glib/gi18n-lib.h>
11 #include <gnumeric.h>
12 #include "lotus.h"
13 #include "lotus-formula.h"
14 #include "lotus-types.h"
15 
16 #include <goffice/goffice.h>
17 #include <workbook-view.h>
18 #include <gnm-plugin.h>
19 #include <gutils.h>
20 
21 #include <gsf/gsf-input.h>
22 #include <gsf/gsf-utils.h>
23 
24 GNM_PLUGIN_MODULE_HEADER;
25 
26 G_MODULE_EXPORT gboolean lotus_file_probe (GOFileOpener const *fo, GsfInput *input,
27                            GOFileProbeLevel pl);
28 G_MODULE_EXPORT void     lotus_file_open (GOFileOpener const *fo, GOIOContext *io_context,
29                           WorkbookView *wb_view, GsfInput *input);
30 
31 
32 gboolean
lotus_file_probe(GOFileOpener const * fo,GsfInput * input,GOFileProbeLevel pl)33 lotus_file_probe (GOFileOpener const *fo, GsfInput *input, GOFileProbeLevel pl)
34 {
35 	char const *h = NULL;
36 	int len;
37 	LotusVersion version;
38 
39 	if (!gsf_input_seek (input, 0, G_SEEK_SET))
40 		h = gsf_input_read (input, 6, NULL);
41 
42 	if (h == NULL ||
43 	    (GSF_LE_GET_GUINT16 (h + 0) != LOTUS_BOF &&
44 		GSF_LE_GET_GUINT16 (h + 0) != WORKS_BOF))
45 		return FALSE;
46 
47 	len = GSF_LE_GET_GUINT16 (h + 2);
48 	if (len < 2)
49 		return FALSE;
50 
51 	version = GSF_LE_GET_GUINT16 (h + 4);
52 	switch (version) {
53 	case LOTUS_VERSION_ORIG_123:
54 	case LOTUS_VERSION_SYMPHONY:
55 	case LOTUS_VERSION_SYMPHONY2:
56 		return len == 2;
57 
58 	case LOTUS_VERSION_123V4: /* Barely and crudely handled.  */
59 	case LOTUS_VERSION_123V6:
60 	case LOTUS_VERSION_123V7:
61 	case LOTUS_VERSION_123SS98:
62 		return len >= 19;
63 
64 	default:
65 		return FALSE;
66 	}
67 }
68 
69 void
lotus_file_open(GOFileOpener const * fo,GOIOContext * io_context,WorkbookView * wb_view,GsfInput * input)70 lotus_file_open (GOFileOpener const *fo, GOIOContext *io_context,
71                  WorkbookView *wb_view, GsfInput *input)
72 {
73 	LotusState state;
74 
75 	state.input	 = input;
76 	state.io_context = io_context;
77 	state.wbv	 = wb_view;
78 	state.wb	 = wb_view_get_workbook (wb_view);
79 	state.sheet	 = NULL;
80 	state.sheet_area_error = FALSE;
81 	state.style_pool = NULL;
82 	state.fonts      = NULL;
83 	state.works_conv = (GIConv)(-1);
84 
85 	if (!lotus_read (&state))
86 		go_io_error_string (io_context,
87 			_("Error while reading lotus workbook."));
88 
89 	if (state.style_pool)
90 		g_hash_table_destroy (state.style_pool);
91 	if (state.fonts)
92 		g_hash_table_destroy (state.fonts);
93 	if (state.works_conv != (GIConv)(-1))
94 		gsf_iconv_close (state.works_conv);
95 }
96 
97 
98 
99 G_MODULE_EXPORT void
go_plugin_init(G_GNUC_UNUSED GOPlugin * plugin,G_GNUC_UNUSED GOCmdContext * cc)100 go_plugin_init (G_GNUC_UNUSED GOPlugin *plugin,
101 		G_GNUC_UNUSED GOCmdContext *cc)
102 {
103 	lmbcs_init ();
104 	lotus_formula_init ();
105 }
106 
107 G_MODULE_EXPORT void
go_plugin_shutdown(G_GNUC_UNUSED GOPlugin * plugin,G_GNUC_UNUSED GOCmdContext * cc)108 go_plugin_shutdown (G_GNUC_UNUSED GOPlugin *plugin,
109 		    G_GNUC_UNUSED GOCmdContext *cc)
110 {
111 	lotus_formula_shutdown ();
112 	lmbcs_shutdown ();
113 }
114