kmadej_fast_excel_fork 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.travis.yml +28 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +70 -0
- data/Makefile +14 -0
- data/README.md +95 -0
- data/Rakefile +24 -0
- data/appveyor.yml +25 -0
- data/benchmarks/1k_rows.rb +59 -0
- data/benchmarks/20k_rows.rb +26 -0
- data/benchmarks/init.rb +59 -0
- data/benchmarks/memory.rb +49 -0
- data/examples/example.rb +42 -0
- data/examples/example_align.rb +23 -0
- data/examples/example_chart.rb +21 -0
- data/examples/example_colors.rb +37 -0
- data/examples/example_formula.rb +18 -0
- data/examples/example_image.rb +13 -0
- data/examples/example_styles.rb +27 -0
- data/examples/logo.png +0 -0
- data/extconf.rb +0 -0
- data/fast_excel.gemspec +20 -0
- data/lib/fast_excel.rb +600 -0
- data/lib/fast_excel/binding.rb +2819 -0
- data/lib/fast_excel/binding/chart.rb +2666 -0
- data/lib/fast_excel/binding/format.rb +1177 -0
- data/lib/fast_excel/binding/workbook.rb +338 -0
- data/lib/fast_excel/binding/worksheet.rb +1555 -0
- data/libxlsxwriter/.gitignore +49 -0
- data/libxlsxwriter/.indent.pro +125 -0
- data/libxlsxwriter/.travis.yml +25 -0
- data/libxlsxwriter/CONTRIBUTING.md +226 -0
- data/libxlsxwriter/Changes.txt +557 -0
- data/libxlsxwriter/LICENSE.txt +89 -0
- data/libxlsxwriter/Makefile +156 -0
- data/libxlsxwriter/Readme.md +78 -0
- data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +30 -0
- data/libxlsxwriter/cocoapods/libxlsxwriter.modulemap +7 -0
- data/libxlsxwriter/include/xlsxwriter.h +23 -0
- data/libxlsxwriter/include/xlsxwriter/app.h +79 -0
- data/libxlsxwriter/include/xlsxwriter/chart.h +3476 -0
- data/libxlsxwriter/include/xlsxwriter/common.h +372 -0
- data/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
- data/libxlsxwriter/include/xlsxwriter/core.h +51 -0
- data/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
- data/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
- data/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
- data/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
- data/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
- data/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
- data/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
- data/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
- data/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +214 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
- data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
- data/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
- data/libxlsxwriter/include/xlsxwriter/workbook.h +757 -0
- data/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
- data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
- data/libxlsxwriter/lib/.gitignore +0 -0
- data/libxlsxwriter/libxlsxwriter.podspec +47 -0
- data/libxlsxwriter/src/Makefile +130 -0
- data/libxlsxwriter/src/app.c +443 -0
- data/libxlsxwriter/src/chart.c +6346 -0
- data/libxlsxwriter/src/content_types.c +345 -0
- data/libxlsxwriter/src/core.c +293 -0
- data/libxlsxwriter/src/custom.c +224 -0
- data/libxlsxwriter/src/drawing.c +746 -0
- data/libxlsxwriter/src/format.c +729 -0
- data/libxlsxwriter/src/hash_table.c +223 -0
- data/libxlsxwriter/src/packager.c +948 -0
- data/libxlsxwriter/src/relationships.c +245 -0
- data/libxlsxwriter/src/shared_strings.c +266 -0
- data/libxlsxwriter/src/styles.c +1088 -0
- data/libxlsxwriter/src/theme.c +348 -0
- data/libxlsxwriter/src/utility.c +515 -0
- data/libxlsxwriter/src/workbook.c +1930 -0
- data/libxlsxwriter/src/worksheet.c +5022 -0
- data/libxlsxwriter/src/xmlwriter.c +355 -0
- data/libxlsxwriter/third_party/minizip/Makefile +44 -0
- data/libxlsxwriter/third_party/minizip/Makefile.am +45 -0
- data/libxlsxwriter/third_party/minizip/Makefile.orig +25 -0
- data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +6 -0
- data/libxlsxwriter/third_party/minizip/MiniZip64_info.txt +74 -0
- data/libxlsxwriter/third_party/minizip/README.txt +5 -0
- data/libxlsxwriter/third_party/minizip/configure.ac +32 -0
- data/libxlsxwriter/third_party/minizip/crypt.h +131 -0
- data/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
- data/libxlsxwriter/third_party/minizip/ioapi.h +208 -0
- data/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
- data/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
- data/libxlsxwriter/third_party/minizip/make_vms.com +25 -0
- data/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
- data/libxlsxwriter/third_party/minizip/miniunzip.1 +63 -0
- data/libxlsxwriter/third_party/minizip/minizip.1 +46 -0
- data/libxlsxwriter/third_party/minizip/minizip.c +520 -0
- data/libxlsxwriter/third_party/minizip/minizip.pc.in +12 -0
- data/libxlsxwriter/third_party/minizip/mztools.c +291 -0
- data/libxlsxwriter/third_party/minizip/mztools.h +37 -0
- data/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
- data/libxlsxwriter/third_party/minizip/unzip.h +437 -0
- data/libxlsxwriter/third_party/minizip/zip.c +2007 -0
- data/libxlsxwriter/third_party/minizip/zip.h +367 -0
- data/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
- data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
- data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
- data/libxlsxwriter/version.txt +1 -0
- data/test/date_test.rb +22 -0
- data/test/default_format_test.rb +19 -0
- data/test/format_test.rb +171 -0
- data/test/test_helper.rb +52 -0
- data/test/tmpfile_test.rb +23 -0
- data/test/worksheet_test.rb +86 -0
- metadata +182 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/*****************************************************************************
|
|
2
|
+
* relationships - A library for creating Excel XLSX relationships files.
|
|
3
|
+
*
|
|
4
|
+
* Used in conjunction with the libxlsxwriter library.
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#include <string.h>
|
|
11
|
+
#include "xlsxwriter/xmlwriter.h"
|
|
12
|
+
#include "xlsxwriter/relationships.h"
|
|
13
|
+
#include "xlsxwriter/utility.h"
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Forward declarations.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/*****************************************************************************
|
|
20
|
+
*
|
|
21
|
+
* Private functions.
|
|
22
|
+
*
|
|
23
|
+
****************************************************************************/
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* Create a new relationships object.
|
|
27
|
+
*/
|
|
28
|
+
lxw_relationships *
|
|
29
|
+
lxw_relationships_new()
|
|
30
|
+
{
|
|
31
|
+
lxw_relationships *rels = calloc(1, sizeof(lxw_relationships));
|
|
32
|
+
GOTO_LABEL_ON_MEM_ERROR(rels, mem_error);
|
|
33
|
+
|
|
34
|
+
rels->relationships = calloc(1, sizeof(struct lxw_rel_tuples));
|
|
35
|
+
GOTO_LABEL_ON_MEM_ERROR(rels->relationships, mem_error);
|
|
36
|
+
STAILQ_INIT(rels->relationships);
|
|
37
|
+
|
|
38
|
+
return rels;
|
|
39
|
+
|
|
40
|
+
mem_error:
|
|
41
|
+
lxw_free_relationships(rels);
|
|
42
|
+
return NULL;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* Free a relationships object.
|
|
47
|
+
*/
|
|
48
|
+
void
|
|
49
|
+
lxw_free_relationships(lxw_relationships *rels)
|
|
50
|
+
{
|
|
51
|
+
lxw_rel_tuple *relationship;
|
|
52
|
+
|
|
53
|
+
if (!rels)
|
|
54
|
+
return;
|
|
55
|
+
|
|
56
|
+
if (rels->relationships) {
|
|
57
|
+
while (!STAILQ_EMPTY(rels->relationships)) {
|
|
58
|
+
relationship = STAILQ_FIRST(rels->relationships);
|
|
59
|
+
STAILQ_REMOVE_HEAD(rels->relationships, list_pointers);
|
|
60
|
+
free(relationship->type);
|
|
61
|
+
free(relationship->target);
|
|
62
|
+
free(relationship->target_mode);
|
|
63
|
+
free(relationship);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
free(rels->relationships);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
free(rels);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/*****************************************************************************
|
|
73
|
+
*
|
|
74
|
+
* XML functions.
|
|
75
|
+
*
|
|
76
|
+
****************************************************************************/
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* Write the XML declaration.
|
|
80
|
+
*/
|
|
81
|
+
STATIC void
|
|
82
|
+
_relationships_xml_declaration(lxw_relationships *self)
|
|
83
|
+
{
|
|
84
|
+
lxw_xml_declaration(self->file);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/*
|
|
88
|
+
* Write the <Relationship> element.
|
|
89
|
+
*/
|
|
90
|
+
STATIC void
|
|
91
|
+
_write_relationship(lxw_relationships *self, const char *type,
|
|
92
|
+
const char *target, const char *target_mode)
|
|
93
|
+
{
|
|
94
|
+
struct xml_attribute_list attributes;
|
|
95
|
+
struct xml_attribute *attribute;
|
|
96
|
+
char r_id[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
|
|
97
|
+
|
|
98
|
+
self->rel_id++;
|
|
99
|
+
lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", self->rel_id);
|
|
100
|
+
|
|
101
|
+
LXW_INIT_ATTRIBUTES();
|
|
102
|
+
LXW_PUSH_ATTRIBUTES_STR("Id", r_id);
|
|
103
|
+
LXW_PUSH_ATTRIBUTES_STR("Type", type);
|
|
104
|
+
LXW_PUSH_ATTRIBUTES_STR("Target", target);
|
|
105
|
+
|
|
106
|
+
if (target_mode)
|
|
107
|
+
LXW_PUSH_ATTRIBUTES_STR("TargetMode", target_mode);
|
|
108
|
+
|
|
109
|
+
lxw_xml_empty_tag(self->file, "Relationship", &attributes);
|
|
110
|
+
|
|
111
|
+
LXW_FREE_ATTRIBUTES();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* Write the <Relationships> element.
|
|
116
|
+
*/
|
|
117
|
+
STATIC void
|
|
118
|
+
_write_relationships(lxw_relationships *self)
|
|
119
|
+
{
|
|
120
|
+
struct xml_attribute_list attributes;
|
|
121
|
+
struct xml_attribute *attribute;
|
|
122
|
+
lxw_rel_tuple *rel;
|
|
123
|
+
|
|
124
|
+
LXW_INIT_ATTRIBUTES();
|
|
125
|
+
LXW_PUSH_ATTRIBUTES_STR("xmlns", LXW_SCHEMA_PACKAGE);
|
|
126
|
+
|
|
127
|
+
lxw_xml_start_tag(self->file, "Relationships", &attributes);
|
|
128
|
+
|
|
129
|
+
STAILQ_FOREACH(rel, self->relationships, list_pointers) {
|
|
130
|
+
_write_relationship(self, rel->type, rel->target, rel->target_mode);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
LXW_FREE_ATTRIBUTES();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/*****************************************************************************
|
|
137
|
+
*
|
|
138
|
+
* XML file assembly functions.
|
|
139
|
+
*
|
|
140
|
+
****************************************************************************/
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
* Assemble and write the XML file.
|
|
144
|
+
*/
|
|
145
|
+
void
|
|
146
|
+
lxw_relationships_assemble_xml_file(lxw_relationships *self)
|
|
147
|
+
{
|
|
148
|
+
/* Write the XML declaration. */
|
|
149
|
+
_relationships_xml_declaration(self);
|
|
150
|
+
|
|
151
|
+
_write_relationships(self);
|
|
152
|
+
|
|
153
|
+
/* Close the relationships tag. */
|
|
154
|
+
lxw_xml_end_tag(self->file, "Relationships");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/*
|
|
158
|
+
* Add a generic container relationship to XLSX .rels xml files.
|
|
159
|
+
*/
|
|
160
|
+
STATIC void
|
|
161
|
+
_add_relationship(lxw_relationships *self, const char *schema,
|
|
162
|
+
const char *type, const char *target,
|
|
163
|
+
const char *target_mode)
|
|
164
|
+
{
|
|
165
|
+
lxw_rel_tuple *relationship;
|
|
166
|
+
|
|
167
|
+
if (!schema || !type || !target)
|
|
168
|
+
return;
|
|
169
|
+
|
|
170
|
+
relationship = calloc(1, sizeof(lxw_rel_tuple));
|
|
171
|
+
GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
|
|
172
|
+
|
|
173
|
+
relationship->type = calloc(1, LXW_MAX_ATTRIBUTE_LENGTH);
|
|
174
|
+
GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
|
|
175
|
+
|
|
176
|
+
/* Add the schema to the relationship type. */
|
|
177
|
+
lxw_snprintf(relationship->type, LXW_MAX_ATTRIBUTE_LENGTH, "%s%s",
|
|
178
|
+
schema, type);
|
|
179
|
+
|
|
180
|
+
relationship->target = lxw_strdup(target);
|
|
181
|
+
GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
|
|
182
|
+
|
|
183
|
+
if (target_mode) {
|
|
184
|
+
relationship->target_mode = lxw_strdup(target_mode);
|
|
185
|
+
GOTO_LABEL_ON_MEM_ERROR(relationship->target_mode, mem_error);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
STAILQ_INSERT_TAIL(self->relationships, relationship, list_pointers);
|
|
189
|
+
|
|
190
|
+
return;
|
|
191
|
+
|
|
192
|
+
mem_error:
|
|
193
|
+
if (relationship) {
|
|
194
|
+
free(relationship->type);
|
|
195
|
+
free(relationship->target);
|
|
196
|
+
free(relationship->target_mode);
|
|
197
|
+
free(relationship);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/*****************************************************************************
|
|
202
|
+
*
|
|
203
|
+
* Public functions.
|
|
204
|
+
*
|
|
205
|
+
****************************************************************************/
|
|
206
|
+
|
|
207
|
+
/*
|
|
208
|
+
* Add a document relationship to XLSX .rels xml files.
|
|
209
|
+
*/
|
|
210
|
+
void
|
|
211
|
+
lxw_add_document_relationship(lxw_relationships *self, const char *type,
|
|
212
|
+
const char *target)
|
|
213
|
+
{
|
|
214
|
+
_add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, NULL);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/*
|
|
218
|
+
* Add a package relationship to XLSX .rels xml files.
|
|
219
|
+
*/
|
|
220
|
+
void
|
|
221
|
+
lxw_add_package_relationship(lxw_relationships *self, const char *type,
|
|
222
|
+
const char *target)
|
|
223
|
+
{
|
|
224
|
+
_add_relationship(self, LXW_SCHEMA_PACKAGE, type, target, NULL);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* Add a MS schema package relationship to XLSX .rels xml files.
|
|
229
|
+
*/
|
|
230
|
+
void
|
|
231
|
+
lxw_add_ms_package_relationship(lxw_relationships *self, const char *type,
|
|
232
|
+
const char *target)
|
|
233
|
+
{
|
|
234
|
+
_add_relationship(self, LXW_SCHEMA_MS, type, target, NULL);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/*
|
|
238
|
+
* Add a worksheet relationship to sheet .rels xml files.
|
|
239
|
+
*/
|
|
240
|
+
void
|
|
241
|
+
lxw_add_worksheet_relationship(lxw_relationships *self, const char *type,
|
|
242
|
+
const char *target, const char *target_mode)
|
|
243
|
+
{
|
|
244
|
+
_add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, target_mode);
|
|
245
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/*****************************************************************************
|
|
2
|
+
* shared_strings - A library for creating Excel XLSX sst files.
|
|
3
|
+
*
|
|
4
|
+
* Used in conjunction with the libxlsxwriter library.
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#include "xlsxwriter/xmlwriter.h"
|
|
11
|
+
#include "xlsxwriter/shared_strings.h"
|
|
12
|
+
#include "xlsxwriter/utility.h"
|
|
13
|
+
#include <ctype.h>
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Forward declarations.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
STATIC int _element_cmp(struct sst_element *element1,
|
|
20
|
+
struct sst_element *element2);
|
|
21
|
+
|
|
22
|
+
#ifndef __clang_analyzer__
|
|
23
|
+
LXW_RB_GENERATE_ELEMENT(sst_rb_tree, sst_element, sst_tree_pointers,
|
|
24
|
+
_element_cmp);
|
|
25
|
+
#endif
|
|
26
|
+
|
|
27
|
+
/*****************************************************************************
|
|
28
|
+
*
|
|
29
|
+
* Private functions.
|
|
30
|
+
*
|
|
31
|
+
****************************************************************************/
|
|
32
|
+
|
|
33
|
+
/*
|
|
34
|
+
* Create a new SST SharedString object.
|
|
35
|
+
*/
|
|
36
|
+
lxw_sst *
|
|
37
|
+
lxw_sst_new()
|
|
38
|
+
{
|
|
39
|
+
/* Create the new shared string table. */
|
|
40
|
+
lxw_sst *sst = calloc(1, sizeof(lxw_sst));
|
|
41
|
+
RETURN_ON_MEM_ERROR(sst, NULL);
|
|
42
|
+
|
|
43
|
+
/* Add the sst RB tree. */
|
|
44
|
+
sst->rb_tree = calloc(1, sizeof(struct sst_rb_tree));
|
|
45
|
+
GOTO_LABEL_ON_MEM_ERROR(sst->rb_tree, mem_error);
|
|
46
|
+
|
|
47
|
+
/* Add a list for tracking the insertion order. */
|
|
48
|
+
sst->order_list = calloc(1, sizeof(struct sst_order_list));
|
|
49
|
+
GOTO_LABEL_ON_MEM_ERROR(sst->order_list, mem_error);
|
|
50
|
+
|
|
51
|
+
/* Initialize the order list. */
|
|
52
|
+
STAILQ_INIT(sst->order_list);
|
|
53
|
+
|
|
54
|
+
/* Initialize the RB tree. */
|
|
55
|
+
RB_INIT(sst->rb_tree);
|
|
56
|
+
|
|
57
|
+
return sst;
|
|
58
|
+
|
|
59
|
+
mem_error:
|
|
60
|
+
lxw_sst_free(sst);
|
|
61
|
+
return NULL;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
* Free a SST SharedString table object.
|
|
66
|
+
*/
|
|
67
|
+
void
|
|
68
|
+
lxw_sst_free(lxw_sst *sst)
|
|
69
|
+
{
|
|
70
|
+
struct sst_element *sst_element;
|
|
71
|
+
struct sst_element *sst_element_temp;
|
|
72
|
+
|
|
73
|
+
if (!sst)
|
|
74
|
+
return;
|
|
75
|
+
|
|
76
|
+
/* Free the sst_elements and their data using the ordered linked list. */
|
|
77
|
+
if (sst->order_list) {
|
|
78
|
+
STAILQ_FOREACH_SAFE(sst_element, sst->order_list, sst_order_pointers,
|
|
79
|
+
sst_element_temp) {
|
|
80
|
+
|
|
81
|
+
if (sst_element && sst_element->string)
|
|
82
|
+
free(sst_element->string);
|
|
83
|
+
if (sst_element)
|
|
84
|
+
free(sst_element);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
free(sst->order_list);
|
|
89
|
+
free(sst->rb_tree);
|
|
90
|
+
free(sst);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/*
|
|
94
|
+
* Comparator for the element structure
|
|
95
|
+
*/
|
|
96
|
+
STATIC int
|
|
97
|
+
_element_cmp(struct sst_element *element1, struct sst_element *element2)
|
|
98
|
+
{
|
|
99
|
+
return strcmp(element1->string, element2->string);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/*****************************************************************************
|
|
103
|
+
*
|
|
104
|
+
* XML functions.
|
|
105
|
+
*
|
|
106
|
+
****************************************************************************/
|
|
107
|
+
/*
|
|
108
|
+
* Write the XML declaration.
|
|
109
|
+
*/
|
|
110
|
+
STATIC void
|
|
111
|
+
_sst_xml_declaration(lxw_sst *self)
|
|
112
|
+
{
|
|
113
|
+
lxw_xml_declaration(self->file);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* Write the <t> element.
|
|
118
|
+
*/
|
|
119
|
+
STATIC void
|
|
120
|
+
_write_t(lxw_sst *self, char *string)
|
|
121
|
+
{
|
|
122
|
+
struct xml_attribute_list attributes;
|
|
123
|
+
struct xml_attribute *attribute;
|
|
124
|
+
|
|
125
|
+
LXW_INIT_ATTRIBUTES();
|
|
126
|
+
|
|
127
|
+
/* Add attribute to preserve leading or trailing whitespace. */
|
|
128
|
+
if (isspace((unsigned char) string[0])
|
|
129
|
+
|| isspace((unsigned char) string[strlen(string) - 1]))
|
|
130
|
+
LXW_PUSH_ATTRIBUTES_STR("xml:space", "preserve");
|
|
131
|
+
|
|
132
|
+
lxw_xml_data_element(self->file, "t", string, &attributes);
|
|
133
|
+
|
|
134
|
+
LXW_FREE_ATTRIBUTES();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/*
|
|
138
|
+
* Write the <si> element.
|
|
139
|
+
*/
|
|
140
|
+
STATIC void
|
|
141
|
+
_write_si(lxw_sst *self, char *string)
|
|
142
|
+
{
|
|
143
|
+
uint8_t escaped_string = LXW_FALSE;
|
|
144
|
+
|
|
145
|
+
lxw_xml_start_tag(self->file, "si", NULL);
|
|
146
|
+
|
|
147
|
+
/* Look for and escape control chars in the string. */
|
|
148
|
+
if (strpbrk(string, "\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C"
|
|
149
|
+
"\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16"
|
|
150
|
+
"\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F")) {
|
|
151
|
+
string = lxw_escape_control_characters(string);
|
|
152
|
+
escaped_string = LXW_TRUE;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* Write the t element. */
|
|
156
|
+
_write_t(self, string);
|
|
157
|
+
|
|
158
|
+
lxw_xml_end_tag(self->file, "si");
|
|
159
|
+
|
|
160
|
+
if (escaped_string)
|
|
161
|
+
free(string);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* Write the <sst> element.
|
|
166
|
+
*/
|
|
167
|
+
STATIC void
|
|
168
|
+
_write_sst(lxw_sst *self)
|
|
169
|
+
{
|
|
170
|
+
struct xml_attribute_list attributes;
|
|
171
|
+
struct xml_attribute *attribute;
|
|
172
|
+
char xmlns[] =
|
|
173
|
+
"http://schemas.openxmlformats.org/spreadsheetml/2006/main";
|
|
174
|
+
|
|
175
|
+
LXW_INIT_ATTRIBUTES();
|
|
176
|
+
LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
|
|
177
|
+
LXW_PUSH_ATTRIBUTES_INT("count", self->string_count);
|
|
178
|
+
LXW_PUSH_ATTRIBUTES_INT("uniqueCount", self->unique_count);
|
|
179
|
+
|
|
180
|
+
lxw_xml_start_tag(self->file, "sst", &attributes);
|
|
181
|
+
|
|
182
|
+
LXW_FREE_ATTRIBUTES();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*****************************************************************************
|
|
186
|
+
*
|
|
187
|
+
* XML file assembly functions.
|
|
188
|
+
*
|
|
189
|
+
****************************************************************************/
|
|
190
|
+
|
|
191
|
+
/*
|
|
192
|
+
* Assemble and write the XML file.
|
|
193
|
+
*/
|
|
194
|
+
STATIC void
|
|
195
|
+
_write_sst_strings(lxw_sst *self)
|
|
196
|
+
{
|
|
197
|
+
struct sst_element *sst_element;
|
|
198
|
+
|
|
199
|
+
STAILQ_FOREACH(sst_element, self->order_list, sst_order_pointers) {
|
|
200
|
+
/* Write the si element. */
|
|
201
|
+
_write_si(self, sst_element->string);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/*
|
|
206
|
+
* Assemble and write the XML file.
|
|
207
|
+
*/
|
|
208
|
+
void
|
|
209
|
+
lxw_sst_assemble_xml_file(lxw_sst *self)
|
|
210
|
+
{
|
|
211
|
+
/* Write the XML declaration. */
|
|
212
|
+
_sst_xml_declaration(self);
|
|
213
|
+
|
|
214
|
+
/* Write the sst element. */
|
|
215
|
+
_write_sst(self);
|
|
216
|
+
|
|
217
|
+
/* Write the sst strings. */
|
|
218
|
+
_write_sst_strings(self);
|
|
219
|
+
|
|
220
|
+
/* Close the sst tag. */
|
|
221
|
+
lxw_xml_end_tag(self->file, "sst");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/*****************************************************************************
|
|
225
|
+
*
|
|
226
|
+
* Public functions.
|
|
227
|
+
*
|
|
228
|
+
****************************************************************************/
|
|
229
|
+
/*
|
|
230
|
+
* Add to or find a string in the SST SharedString table and return it's index.
|
|
231
|
+
*/
|
|
232
|
+
struct sst_element *
|
|
233
|
+
lxw_get_sst_index(lxw_sst *sst, const char *string)
|
|
234
|
+
{
|
|
235
|
+
struct sst_element *element;
|
|
236
|
+
struct sst_element *existing_element;
|
|
237
|
+
|
|
238
|
+
/* Create an sst element to potentially add to the table. */
|
|
239
|
+
element = calloc(1, sizeof(struct sst_element));
|
|
240
|
+
if (!element)
|
|
241
|
+
return NULL;
|
|
242
|
+
|
|
243
|
+
/* Create potential new element with the string and its index. */
|
|
244
|
+
element->index = sst->unique_count;
|
|
245
|
+
element->string = lxw_strdup(string);
|
|
246
|
+
|
|
247
|
+
/* Try to insert it and see whether we already have that string. */
|
|
248
|
+
existing_element = RB_INSERT(sst_rb_tree, sst->rb_tree, element);
|
|
249
|
+
|
|
250
|
+
/* If existing_element is not NULL, then it already existed. */
|
|
251
|
+
/* Free new created element. */
|
|
252
|
+
if (existing_element) {
|
|
253
|
+
free(element->string);
|
|
254
|
+
free(element);
|
|
255
|
+
sst->string_count++;
|
|
256
|
+
return existing_element;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* If it didn't exist, also add it to the insertion order linked list. */
|
|
260
|
+
STAILQ_INSERT_TAIL(sst->order_list, element, sst_order_pointers);
|
|
261
|
+
|
|
262
|
+
/* Update SST string counts. */
|
|
263
|
+
sst->string_count++;
|
|
264
|
+
sst->unique_count++;
|
|
265
|
+
return element;
|
|
266
|
+
}
|