xlsxwriter 0.0.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.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +40 -0
  3. data/ext/xlsxwriter/chart.c +105 -0
  4. data/ext/xlsxwriter/chart.h +27 -0
  5. data/ext/xlsxwriter/extconf.rb +14 -0
  6. data/ext/xlsxwriter/format.c +67 -0
  7. data/ext/xlsxwriter/format.h +9 -0
  8. data/ext/xlsxwriter/libxlsxwriter/LICENSE.txt +89 -0
  9. data/ext/xlsxwriter/libxlsxwriter/Makefile +141 -0
  10. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter.h +23 -0
  11. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/app.h +79 -0
  12. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/chart.h +1093 -0
  13. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/common.h +336 -0
  14. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
  15. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/core.h +51 -0
  16. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
  17. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
  18. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
  19. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
  20. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
  21. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
  22. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
  23. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
  24. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
  25. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +215 -0
  26. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
  27. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
  28. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
  29. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
  30. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
  31. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/workbook.h +751 -0
  32. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
  33. data/ext/xlsxwriter/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
  34. data/ext/xlsxwriter/libxlsxwriter/lib/.gitignore +0 -0
  35. data/ext/xlsxwriter/libxlsxwriter/src/Makefile +125 -0
  36. data/ext/xlsxwriter/libxlsxwriter/src/app.c +439 -0
  37. data/ext/xlsxwriter/libxlsxwriter/src/chart.c +3420 -0
  38. data/ext/xlsxwriter/libxlsxwriter/src/content_types.c +341 -0
  39. data/ext/xlsxwriter/libxlsxwriter/src/core.c +293 -0
  40. data/ext/xlsxwriter/libxlsxwriter/src/custom.c +224 -0
  41. data/ext/xlsxwriter/libxlsxwriter/src/drawing.c +746 -0
  42. data/ext/xlsxwriter/libxlsxwriter/src/format.c +728 -0
  43. data/ext/xlsxwriter/libxlsxwriter/src/hash_table.c +223 -0
  44. data/ext/xlsxwriter/libxlsxwriter/src/packager.c +877 -0
  45. data/ext/xlsxwriter/libxlsxwriter/src/relationships.c +242 -0
  46. data/ext/xlsxwriter/libxlsxwriter/src/shared_strings.c +264 -0
  47. data/ext/xlsxwriter/libxlsxwriter/src/styles.c +1086 -0
  48. data/ext/xlsxwriter/libxlsxwriter/src/theme.c +348 -0
  49. data/ext/xlsxwriter/libxlsxwriter/src/utility.c +512 -0
  50. data/ext/xlsxwriter/libxlsxwriter/src/workbook.c +1895 -0
  51. data/ext/xlsxwriter/libxlsxwriter/src/worksheet.c +4992 -0
  52. data/ext/xlsxwriter/libxlsxwriter/src/xmlwriter.c +355 -0
  53. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/Makefile +44 -0
  54. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/crypt.h +131 -0
  55. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
  56. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/ioapi.h +209 -0
  57. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
  58. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
  59. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
  60. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/minizip.c +520 -0
  61. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/mztools.c +291 -0
  62. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/mztools.h +37 -0
  63. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
  64. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/unzip.h +437 -0
  65. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.c +2007 -0
  66. data/ext/xlsxwriter/libxlsxwriter/third_party/minizip/zip.h +367 -0
  67. data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
  68. data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
  69. data/ext/xlsxwriter/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
  70. data/ext/xlsxwriter/workbook.c +257 -0
  71. data/ext/xlsxwriter/workbook.h +42 -0
  72. data/ext/xlsxwriter/workbook_properties.c +103 -0
  73. data/ext/xlsxwriter/workbook_properties.h +10 -0
  74. data/ext/xlsxwriter/worksheet.c +1064 -0
  75. data/ext/xlsxwriter/worksheet.h +74 -0
  76. data/ext/xlsxwriter/xlsxwriter.c +239 -0
  77. data/lib/xlsxwriter.rb +6 -0
  78. data/lib/xlsxwriter/version.rb +3 -0
  79. data/lib/xlsxwriter/worksheet.rb +72 -0
  80. data/test/run-test.rb +11 -0
  81. data/test/support/xlsx_comparable.rb +109 -0
  82. data/test/test-array-formula.rb +33 -0
  83. data/test/test-autofilter.rb +70 -0
  84. data/test/test-chart-area.rb +25 -0
  85. data/test/test-data.rb +65 -0
  86. data/test/test-default-row.rb +25 -0
  87. data/test/test-defined-name.rb +46 -0
  88. data/test/test-escapes.rb +33 -0
  89. data/test/test-fit-to-pages.rb +21 -0
  90. data/test/test-formatting.rb +137 -0
  91. data/test/test-gridlines.rb +15 -0
  92. data/test/test-hyperlink.rb +67 -0
  93. data/test/test-image.rb +84 -0
  94. data/test/test-merge-range.rb +18 -0
  95. data/test/test-misc.rb +29 -0
  96. data/test/test-optimize.rb +32 -0
  97. data/test/test-page-breaks.rb +13 -0
  98. data/test/test-page-setup.rb +28 -0
  99. data/test/test-panes.rb +45 -0
  100. data/test/test-print-area.rb +19 -0
  101. data/test/test-print-options.rb +61 -0
  102. data/test/test-print-scale.rb +12 -0
  103. data/test/test-properties.rb +51 -0
  104. data/test/test-protect.rb +27 -0
  105. data/test/test-repeat.rb +23 -0
  106. data/test/test-row-col-format.rb +35 -0
  107. data/test/test-set-selection.rb +13 -0
  108. data/test/test-set-start-page.rb +13 -0
  109. data/test/test-simple.rb +62 -0
  110. data/test/test-types.rb +17 -0
  111. data/test/xlsx-func-testcase.rb +36 -0
  112. metadata +228 -0
@@ -0,0 +1,242 @@
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
+ while (!STAILQ_EMPTY(rels->relationships)) {
57
+ relationship = STAILQ_FIRST(rels->relationships);
58
+ STAILQ_REMOVE_HEAD(rels->relationships, list_pointers);
59
+ free(relationship->type);
60
+ free(relationship->target);
61
+ free(relationship->target_mode);
62
+ free(relationship);
63
+ }
64
+
65
+ free(rels->relationships);
66
+ free(rels);
67
+ }
68
+
69
+ /*****************************************************************************
70
+ *
71
+ * XML functions.
72
+ *
73
+ ****************************************************************************/
74
+
75
+ /*
76
+ * Write the XML declaration.
77
+ */
78
+ STATIC void
79
+ _relationships_xml_declaration(lxw_relationships *self)
80
+ {
81
+ lxw_xml_declaration(self->file);
82
+ }
83
+
84
+ /*
85
+ * Write the <Relationship> element.
86
+ */
87
+ STATIC void
88
+ _write_relationship(lxw_relationships *self, const char *type,
89
+ const char *target, const char *target_mode)
90
+ {
91
+ struct xml_attribute_list attributes;
92
+ struct xml_attribute *attribute;
93
+ char r_id[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 };
94
+
95
+ self->rel_id++;
96
+ lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", self->rel_id);
97
+
98
+ LXW_INIT_ATTRIBUTES();
99
+ LXW_PUSH_ATTRIBUTES_STR("Id", r_id);
100
+ LXW_PUSH_ATTRIBUTES_STR("Type", type);
101
+ LXW_PUSH_ATTRIBUTES_STR("Target", target);
102
+
103
+ if (target_mode)
104
+ LXW_PUSH_ATTRIBUTES_STR("TargetMode", target_mode);
105
+
106
+ lxw_xml_empty_tag(self->file, "Relationship", &attributes);
107
+
108
+ LXW_FREE_ATTRIBUTES();
109
+ }
110
+
111
+ /*
112
+ * Write the <Relationships> element.
113
+ */
114
+ STATIC void
115
+ _write_relationships(lxw_relationships *self)
116
+ {
117
+ struct xml_attribute_list attributes;
118
+ struct xml_attribute *attribute;
119
+ lxw_rel_tuple *rel;
120
+
121
+ LXW_INIT_ATTRIBUTES();
122
+ LXW_PUSH_ATTRIBUTES_STR("xmlns", LXW_SCHEMA_PACKAGE);
123
+
124
+ lxw_xml_start_tag(self->file, "Relationships", &attributes);
125
+
126
+ STAILQ_FOREACH(rel, self->relationships, list_pointers) {
127
+ _write_relationship(self, rel->type, rel->target, rel->target_mode);
128
+ }
129
+
130
+ LXW_FREE_ATTRIBUTES();
131
+ }
132
+
133
+ /*****************************************************************************
134
+ *
135
+ * XML file assembly functions.
136
+ *
137
+ ****************************************************************************/
138
+
139
+ /*
140
+ * Assemble and write the XML file.
141
+ */
142
+ void
143
+ lxw_relationships_assemble_xml_file(lxw_relationships *self)
144
+ {
145
+ /* Write the XML declaration. */
146
+ _relationships_xml_declaration(self);
147
+
148
+ _write_relationships(self);
149
+
150
+ /* Close the relationships tag. */
151
+ lxw_xml_end_tag(self->file, "Relationships");
152
+ }
153
+
154
+ /*
155
+ * Add a generic container relationship to XLSX .rels xml files.
156
+ */
157
+ STATIC void
158
+ _add_relationship(lxw_relationships *self, const char *schema,
159
+ const char *type, const char *target,
160
+ const char *target_mode)
161
+ {
162
+ lxw_rel_tuple *relationship;
163
+
164
+ if (!schema || !type || !target)
165
+ return;
166
+
167
+ relationship = calloc(1, sizeof(lxw_rel_tuple));
168
+ GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error);
169
+
170
+ relationship->type = calloc(1, LXW_MAX_ATTRIBUTE_LENGTH);
171
+ GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error);
172
+
173
+ /* Add the schema to the relationship type. */
174
+ lxw_snprintf(relationship->type, LXW_MAX_ATTRIBUTE_LENGTH, "%s%s",
175
+ schema, type);
176
+
177
+ relationship->target = lxw_strdup(target);
178
+ GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error);
179
+
180
+ if (target_mode) {
181
+ relationship->target_mode = lxw_strdup(target_mode);
182
+ GOTO_LABEL_ON_MEM_ERROR(relationship->target_mode, mem_error);
183
+ }
184
+
185
+ STAILQ_INSERT_TAIL(self->relationships, relationship, list_pointers);
186
+
187
+ return;
188
+
189
+ mem_error:
190
+ if (relationship) {
191
+ free(relationship->type);
192
+ free(relationship->target);
193
+ free(relationship->target_mode);
194
+ free(relationship);
195
+ }
196
+ }
197
+
198
+ /*****************************************************************************
199
+ *
200
+ * Public functions.
201
+ *
202
+ ****************************************************************************/
203
+
204
+ /*
205
+ * Add a document relationship to XLSX .rels xml files.
206
+ */
207
+ void
208
+ lxw_add_document_relationship(lxw_relationships *self, const char *type,
209
+ const char *target)
210
+ {
211
+ _add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, NULL);
212
+ }
213
+
214
+ /*
215
+ * Add a package relationship to XLSX .rels xml files.
216
+ */
217
+ void
218
+ lxw_add_package_relationship(lxw_relationships *self, const char *type,
219
+ const char *target)
220
+ {
221
+ _add_relationship(self, LXW_SCHEMA_PACKAGE, type, target, NULL);
222
+ }
223
+
224
+ /*
225
+ * Add a MS schema package relationship to XLSX .rels xml files.
226
+ */
227
+ void
228
+ lxw_add_ms_package_relationship(lxw_relationships *self, const char *type,
229
+ const char *target)
230
+ {
231
+ _add_relationship(self, LXW_SCHEMA_MS, type, target, NULL);
232
+ }
233
+
234
+ /*
235
+ * Add a worksheet relationship to sheet .rels xml files.
236
+ */
237
+ void
238
+ lxw_add_worksheet_relationship(lxw_relationships *self, const char *type,
239
+ const char *target, const char *target_mode)
240
+ {
241
+ _add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, target_mode);
242
+ }
@@ -0,0 +1,264 @@
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
+ LXW_RB_GENERATE_ELEMENT(sst_rb_tree, sst_element, sst_tree_pointers,
23
+ _element_cmp);
24
+
25
+ /*****************************************************************************
26
+ *
27
+ * Private functions.
28
+ *
29
+ ****************************************************************************/
30
+
31
+ /*
32
+ * Create a new SST SharedString object.
33
+ */
34
+ lxw_sst *
35
+ lxw_sst_new()
36
+ {
37
+ /* Create the new shared string table. */
38
+ lxw_sst *sst = calloc(1, sizeof(lxw_sst));
39
+ RETURN_ON_MEM_ERROR(sst, NULL);
40
+
41
+ /* Add the sst RB tree. */
42
+ sst->rb_tree = calloc(1, sizeof(struct sst_rb_tree));
43
+ GOTO_LABEL_ON_MEM_ERROR(sst->rb_tree, mem_error);
44
+
45
+ /* Add a list for tracking the insertion order. */
46
+ sst->order_list = calloc(1, sizeof(struct sst_order_list));
47
+ GOTO_LABEL_ON_MEM_ERROR(sst->order_list, mem_error);
48
+
49
+ /* Initialize the order list. */
50
+ STAILQ_INIT(sst->order_list);
51
+
52
+ /* Initialize the RB tree. */
53
+ RB_INIT(sst->rb_tree);
54
+
55
+ return sst;
56
+
57
+ mem_error:
58
+ lxw_sst_free(sst);
59
+ return NULL;
60
+ }
61
+
62
+ /*
63
+ * Free a SST SharedString table object.
64
+ */
65
+ void
66
+ lxw_sst_free(lxw_sst *sst)
67
+ {
68
+ struct sst_element *sst_element;
69
+ struct sst_element *sst_element_temp;
70
+
71
+ if (!sst)
72
+ return;
73
+
74
+ /* Free the sst_elements and their data using the ordered linked list. */
75
+ if (sst->order_list) {
76
+ STAILQ_FOREACH_SAFE(sst_element, sst->order_list, sst_order_pointers,
77
+ sst_element_temp) {
78
+
79
+ if (sst_element && sst_element->string)
80
+ free(sst_element->string);
81
+ if (sst_element)
82
+ free(sst_element);
83
+ }
84
+ }
85
+
86
+ free(sst->order_list);
87
+ free(sst->rb_tree);
88
+ free(sst);
89
+ }
90
+
91
+ /*
92
+ * Comparator for the element structure
93
+ */
94
+ STATIC int
95
+ _element_cmp(struct sst_element *element1, struct sst_element *element2)
96
+ {
97
+ return strcmp(element1->string, element2->string);
98
+ }
99
+
100
+ /*****************************************************************************
101
+ *
102
+ * XML functions.
103
+ *
104
+ ****************************************************************************/
105
+ /*
106
+ * Write the XML declaration.
107
+ */
108
+ STATIC void
109
+ _sst_xml_declaration(lxw_sst *self)
110
+ {
111
+ lxw_xml_declaration(self->file);
112
+ }
113
+
114
+ /*
115
+ * Write the <t> element.
116
+ */
117
+ STATIC void
118
+ _write_t(lxw_sst *self, char *string)
119
+ {
120
+ struct xml_attribute_list attributes;
121
+ struct xml_attribute *attribute;
122
+
123
+ LXW_INIT_ATTRIBUTES();
124
+
125
+ /* Add attribute to preserve leading or trailing whitespace. */
126
+ if (isspace((unsigned char) string[0])
127
+ || isspace((unsigned char) string[strlen(string) - 1]))
128
+ LXW_PUSH_ATTRIBUTES_STR("xml:space", "preserve");
129
+
130
+ lxw_xml_data_element(self->file, "t", string, &attributes);
131
+
132
+ LXW_FREE_ATTRIBUTES();
133
+ }
134
+
135
+ /*
136
+ * Write the <si> element.
137
+ */
138
+ STATIC void
139
+ _write_si(lxw_sst *self, char *string)
140
+ {
141
+ uint8_t escaped_string = LXW_FALSE;
142
+
143
+ lxw_xml_start_tag(self->file, "si", NULL);
144
+
145
+ /* Look for and escape control chars in the string. */
146
+ if (strpbrk(string, "\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C"
147
+ "\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16"
148
+ "\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F")) {
149
+ string = lxw_escape_control_characters(string);
150
+ escaped_string = LXW_TRUE;
151
+ }
152
+
153
+ /* Write the t element. */
154
+ _write_t(self, string);
155
+
156
+ lxw_xml_end_tag(self->file, "si");
157
+
158
+ if (escaped_string)
159
+ free(string);
160
+ }
161
+
162
+ /*
163
+ * Write the <sst> element.
164
+ */
165
+ STATIC void
166
+ _write_sst(lxw_sst *self)
167
+ {
168
+ struct xml_attribute_list attributes;
169
+ struct xml_attribute *attribute;
170
+ char xmlns[] =
171
+ "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
172
+
173
+ LXW_INIT_ATTRIBUTES();
174
+ LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
175
+ LXW_PUSH_ATTRIBUTES_INT("count", self->string_count);
176
+ LXW_PUSH_ATTRIBUTES_INT("uniqueCount", self->unique_count);
177
+
178
+ lxw_xml_start_tag(self->file, "sst", &attributes);
179
+
180
+ LXW_FREE_ATTRIBUTES();
181
+ }
182
+
183
+ /*****************************************************************************
184
+ *
185
+ * XML file assembly functions.
186
+ *
187
+ ****************************************************************************/
188
+
189
+ /*
190
+ * Assemble and write the XML file.
191
+ */
192
+ STATIC void
193
+ _write_sst_strings(lxw_sst *self)
194
+ {
195
+ struct sst_element *sst_element;
196
+
197
+ STAILQ_FOREACH(sst_element, self->order_list, sst_order_pointers) {
198
+ /* Write the si element. */
199
+ _write_si(self, sst_element->string);
200
+ }
201
+ }
202
+
203
+ /*
204
+ * Assemble and write the XML file.
205
+ */
206
+ void
207
+ lxw_sst_assemble_xml_file(lxw_sst *self)
208
+ {
209
+ /* Write the XML declaration. */
210
+ _sst_xml_declaration(self);
211
+
212
+ /* Write the sst element. */
213
+ _write_sst(self);
214
+
215
+ /* Write the sst strings. */
216
+ _write_sst_strings(self);
217
+
218
+ /* Close the sst tag. */
219
+ lxw_xml_end_tag(self->file, "sst");
220
+ }
221
+
222
+ /*****************************************************************************
223
+ *
224
+ * Public functions.
225
+ *
226
+ ****************************************************************************/
227
+ /*
228
+ * Add to or find a string in the SST SharedString table and return it's index.
229
+ */
230
+ struct sst_element *
231
+ lxw_get_sst_index(lxw_sst *sst, const char *string)
232
+ {
233
+ struct sst_element *element;
234
+ struct sst_element *existing_element;
235
+
236
+ /* Create an sst element to potentially add to the table. */
237
+ element = calloc(1, sizeof(struct sst_element));
238
+ if (!element)
239
+ return NULL;
240
+
241
+ /* Create potential new element with the string and its index. */
242
+ element->index = sst->unique_count;
243
+ element->string = lxw_strdup(string);
244
+
245
+ /* Try to insert it and see whether we already have that string. */
246
+ existing_element = RB_INSERT(sst_rb_tree, sst->rb_tree, element);
247
+
248
+ /* If existing_element is not NULL, then it already existed. */
249
+ /* Free new created element. */
250
+ if (existing_element) {
251
+ free(element->string);
252
+ free(element);
253
+ sst->string_count++;
254
+ return existing_element;
255
+ }
256
+
257
+ /* If it didn't exist, also add it to the insertion order linked list. */
258
+ STAILQ_INSERT_TAIL(sst->order_list, element, sst_order_pointers);
259
+
260
+ /* Update SST string counts. */
261
+ sst->string_count++;
262
+ sst->unique_count++;
263
+ return element;
264
+ }