kmadej_fast_excel_fork 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +28 -0
  4. data/CHANGELOG.md +13 -0
  5. data/Gemfile +17 -0
  6. data/Gemfile.lock +70 -0
  7. data/Makefile +14 -0
  8. data/README.md +95 -0
  9. data/Rakefile +24 -0
  10. data/appveyor.yml +25 -0
  11. data/benchmarks/1k_rows.rb +59 -0
  12. data/benchmarks/20k_rows.rb +26 -0
  13. data/benchmarks/init.rb +59 -0
  14. data/benchmarks/memory.rb +49 -0
  15. data/examples/example.rb +42 -0
  16. data/examples/example_align.rb +23 -0
  17. data/examples/example_chart.rb +21 -0
  18. data/examples/example_colors.rb +37 -0
  19. data/examples/example_formula.rb +18 -0
  20. data/examples/example_image.rb +13 -0
  21. data/examples/example_styles.rb +27 -0
  22. data/examples/logo.png +0 -0
  23. data/extconf.rb +0 -0
  24. data/fast_excel.gemspec +20 -0
  25. data/lib/fast_excel.rb +600 -0
  26. data/lib/fast_excel/binding.rb +2819 -0
  27. data/lib/fast_excel/binding/chart.rb +2666 -0
  28. data/lib/fast_excel/binding/format.rb +1177 -0
  29. data/lib/fast_excel/binding/workbook.rb +338 -0
  30. data/lib/fast_excel/binding/worksheet.rb +1555 -0
  31. data/libxlsxwriter/.gitignore +49 -0
  32. data/libxlsxwriter/.indent.pro +125 -0
  33. data/libxlsxwriter/.travis.yml +25 -0
  34. data/libxlsxwriter/CONTRIBUTING.md +226 -0
  35. data/libxlsxwriter/Changes.txt +557 -0
  36. data/libxlsxwriter/LICENSE.txt +89 -0
  37. data/libxlsxwriter/Makefile +156 -0
  38. data/libxlsxwriter/Readme.md +78 -0
  39. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +30 -0
  40. data/libxlsxwriter/cocoapods/libxlsxwriter.modulemap +7 -0
  41. data/libxlsxwriter/include/xlsxwriter.h +23 -0
  42. data/libxlsxwriter/include/xlsxwriter/app.h +79 -0
  43. data/libxlsxwriter/include/xlsxwriter/chart.h +3476 -0
  44. data/libxlsxwriter/include/xlsxwriter/common.h +372 -0
  45. data/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
  46. data/libxlsxwriter/include/xlsxwriter/core.h +51 -0
  47. data/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
  48. data/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
  49. data/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
  50. data/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
  51. data/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
  52. data/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
  53. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
  54. data/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
  55. data/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
  56. data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +214 -0
  57. data/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
  58. data/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
  59. data/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
  60. data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
  61. data/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
  62. data/libxlsxwriter/include/xlsxwriter/workbook.h +757 -0
  63. data/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
  64. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
  65. data/libxlsxwriter/lib/.gitignore +0 -0
  66. data/libxlsxwriter/libxlsxwriter.podspec +47 -0
  67. data/libxlsxwriter/src/Makefile +130 -0
  68. data/libxlsxwriter/src/app.c +443 -0
  69. data/libxlsxwriter/src/chart.c +6346 -0
  70. data/libxlsxwriter/src/content_types.c +345 -0
  71. data/libxlsxwriter/src/core.c +293 -0
  72. data/libxlsxwriter/src/custom.c +224 -0
  73. data/libxlsxwriter/src/drawing.c +746 -0
  74. data/libxlsxwriter/src/format.c +729 -0
  75. data/libxlsxwriter/src/hash_table.c +223 -0
  76. data/libxlsxwriter/src/packager.c +948 -0
  77. data/libxlsxwriter/src/relationships.c +245 -0
  78. data/libxlsxwriter/src/shared_strings.c +266 -0
  79. data/libxlsxwriter/src/styles.c +1088 -0
  80. data/libxlsxwriter/src/theme.c +348 -0
  81. data/libxlsxwriter/src/utility.c +515 -0
  82. data/libxlsxwriter/src/workbook.c +1930 -0
  83. data/libxlsxwriter/src/worksheet.c +5022 -0
  84. data/libxlsxwriter/src/xmlwriter.c +355 -0
  85. data/libxlsxwriter/third_party/minizip/Makefile +44 -0
  86. data/libxlsxwriter/third_party/minizip/Makefile.am +45 -0
  87. data/libxlsxwriter/third_party/minizip/Makefile.orig +25 -0
  88. data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +6 -0
  89. data/libxlsxwriter/third_party/minizip/MiniZip64_info.txt +74 -0
  90. data/libxlsxwriter/third_party/minizip/README.txt +5 -0
  91. data/libxlsxwriter/third_party/minizip/configure.ac +32 -0
  92. data/libxlsxwriter/third_party/minizip/crypt.h +131 -0
  93. data/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
  94. data/libxlsxwriter/third_party/minizip/ioapi.h +208 -0
  95. data/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
  96. data/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
  97. data/libxlsxwriter/third_party/minizip/make_vms.com +25 -0
  98. data/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
  99. data/libxlsxwriter/third_party/minizip/miniunzip.1 +63 -0
  100. data/libxlsxwriter/third_party/minizip/minizip.1 +46 -0
  101. data/libxlsxwriter/third_party/minizip/minizip.c +520 -0
  102. data/libxlsxwriter/third_party/minizip/minizip.pc.in +12 -0
  103. data/libxlsxwriter/third_party/minizip/mztools.c +291 -0
  104. data/libxlsxwriter/third_party/minizip/mztools.h +37 -0
  105. data/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
  106. data/libxlsxwriter/third_party/minizip/unzip.h +437 -0
  107. data/libxlsxwriter/third_party/minizip/zip.c +2007 -0
  108. data/libxlsxwriter/third_party/minizip/zip.h +367 -0
  109. data/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
  110. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
  111. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
  112. data/libxlsxwriter/version.txt +1 -0
  113. data/test/date_test.rb +22 -0
  114. data/test/default_format_test.rb +19 -0
  115. data/test/format_test.rb +171 -0
  116. data/test/test_helper.rb +52 -0
  117. data/test/tmpfile_test.rb +23 -0
  118. data/test/worksheet_test.rb +86 -0
  119. metadata +182 -0
@@ -0,0 +1,178 @@
1
+ /*
2
+ * libxlsxwriter
3
+ *
4
+ * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
5
+ *
6
+ * xmlwriter - A libxlsxwriter library for creating Excel XLSX
7
+ * XML files.
8
+ *
9
+ * The xmlwriter library is used to create the XML sub-components files
10
+ * in the Excel XLSX file format.
11
+ *
12
+ * This library is used in preference to a more generic XML library to allow
13
+ * for customization and optimization for the XLSX file format.
14
+ *
15
+ * The xmlwriter functions are only used internally and do not need to be
16
+ * called directly by the end user.
17
+ *
18
+ */
19
+ #ifndef __XMLWRITER_H__
20
+ #define __XMLWRITER_H__
21
+
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+ #include <stdint.h>
25
+ #include "common.h"
26
+
27
+ #define LXW_MAX_ATTRIBUTE_LENGTH 256
28
+ #define LXW_ATTR_32 32
29
+
30
+ #define LXW_ATTRIBUTE_COPY(dst, src) \
31
+ do{ \
32
+ strncpy(dst, src, LXW_MAX_ATTRIBUTE_LENGTH -1); \
33
+ dst[LXW_MAX_ATTRIBUTE_LENGTH - 1] = '\0'; \
34
+ } while (0)
35
+
36
+
37
+ /* *INDENT-OFF* */
38
+ #ifdef __cplusplus
39
+ extern "C" {
40
+ #endif
41
+ /* *INDENT-ON* */
42
+
43
+ /* Attribute used in XML elements. */
44
+ struct xml_attribute {
45
+ char key[LXW_MAX_ATTRIBUTE_LENGTH];
46
+ char value[LXW_MAX_ATTRIBUTE_LENGTH];
47
+
48
+ /* Make the struct a queue.h list element. */
49
+ STAILQ_ENTRY (xml_attribute) list_entries;
50
+ };
51
+
52
+ /* Use queue.h macros to define the xml_attribute_list type. */
53
+ STAILQ_HEAD(xml_attribute_list, xml_attribute);
54
+
55
+ /* Create a new attribute struct to add to a xml_attribute_list. */
56
+ struct xml_attribute *lxw_new_attribute_str(const char *key,
57
+ const char *value);
58
+ struct xml_attribute *lxw_new_attribute_int(const char *key, uint32_t value);
59
+ struct xml_attribute *lxw_new_attribute_dbl(const char *key, double value);
60
+
61
+ /* Macro to initialize the xml_attribute_list pointers. */
62
+ #define LXW_INIT_ATTRIBUTES() \
63
+ STAILQ_INIT(&attributes)
64
+
65
+ /* Macro to add attribute string elements to xml_attribute_list. */
66
+ #define LXW_PUSH_ATTRIBUTES_STR(key, value) \
67
+ do { \
68
+ attribute = lxw_new_attribute_str((key), (value)); \
69
+ STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \
70
+ } while (0)
71
+
72
+ /* Macro to add attribute int values to xml_attribute_list. */
73
+ #define LXW_PUSH_ATTRIBUTES_INT(key, value) \
74
+ do { \
75
+ attribute = lxw_new_attribute_int((key), (value)); \
76
+ STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \
77
+ } while (0)
78
+
79
+ /* Macro to add attribute double values to xml_attribute_list. */
80
+ #define LXW_PUSH_ATTRIBUTES_DBL(key, value) \
81
+ do { \
82
+ attribute = lxw_new_attribute_dbl((key), (value)); \
83
+ STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \
84
+ } while (0)
85
+
86
+ /* Macro to free xml_attribute_list and attribute. */
87
+ #define LXW_FREE_ATTRIBUTES() \
88
+ while (!STAILQ_EMPTY(&attributes)) { \
89
+ attribute = STAILQ_FIRST(&attributes); \
90
+ STAILQ_REMOVE_HEAD(&attributes, list_entries); \
91
+ free(attribute); \
92
+ }
93
+
94
+ /**
95
+ * Create the XML declaration in an XML file.
96
+ *
97
+ * @param xmlfile A FILE pointer to the output XML file.
98
+ */
99
+ void lxw_xml_declaration(FILE * xmlfile);
100
+
101
+ /**
102
+ * Write an XML start tag with optional attributes.
103
+ *
104
+ * @param xmlfile A FILE pointer to the output XML file.
105
+ * @param tag The XML tag to write.
106
+ * @param attributes An optional list of attributes to add to the tag.
107
+ */
108
+ void lxw_xml_start_tag(FILE * xmlfile,
109
+ const char *tag,
110
+ struct xml_attribute_list *attributes);
111
+
112
+ /**
113
+ * Write an XML start tag with optional un-encoded attributes.
114
+ * This is a minor optimization for attributes that don't need encoding.
115
+ *
116
+ * @param xmlfile A FILE pointer to the output XML file.
117
+ * @param tag The XML tag to write.
118
+ * @param attributes An optional list of attributes to add to the tag.
119
+ */
120
+ void lxw_xml_start_tag_unencoded(FILE * xmlfile,
121
+ const char *tag,
122
+ struct xml_attribute_list *attributes);
123
+
124
+ /**
125
+ * Write an XML end tag.
126
+ *
127
+ * @param xmlfile A FILE pointer to the output XML file.
128
+ * @param tag The XML tag to write.
129
+ */
130
+ void lxw_xml_end_tag(FILE * xmlfile, const char *tag);
131
+
132
+ /**
133
+ * Write an XML empty tag with optional attributes.
134
+ *
135
+ * @param xmlfile A FILE pointer to the output XML file.
136
+ * @param tag The XML tag to write.
137
+ * @param attributes An optional list of attributes to add to the tag.
138
+ */
139
+ void lxw_xml_empty_tag(FILE * xmlfile,
140
+ const char *tag,
141
+ struct xml_attribute_list *attributes);
142
+
143
+ /**
144
+ * Write an XML empty tag with optional un-encoded attributes.
145
+ * This is a minor optimization for attributes that don't need encoding.
146
+ *
147
+ * @param xmlfile A FILE pointer to the output XML file.
148
+ * @param tag The XML tag to write.
149
+ * @param attributes An optional list of attributes to add to the tag.
150
+ */
151
+ void lxw_xml_empty_tag_unencoded(FILE * xmlfile,
152
+ const char *tag,
153
+ struct xml_attribute_list *attributes);
154
+
155
+ /**
156
+ * Write an XML element containing data and optional attributes.
157
+ *
158
+ * @param xmlfile A FILE pointer to the output XML file.
159
+ * @param tag The XML tag to write.
160
+ * @param data The data section of the XML element.
161
+ * @param attributes An optional list of attributes to add to the tag.
162
+ */
163
+ void lxw_xml_data_element(FILE * xmlfile,
164
+ const char *tag,
165
+ const char *data,
166
+ struct xml_attribute_list *attributes);
167
+
168
+ char *lxw_escape_control_characters(const char *string);
169
+
170
+ char *lxw_escape_data(const char *data);
171
+
172
+ /* *INDENT-OFF* */
173
+ #ifdef __cplusplus
174
+ }
175
+ #endif
176
+ /* *INDENT-ON* */
177
+
178
+ #endif /* __XMLWRITER_H__ */
File without changes
@@ -0,0 +1,47 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = "libxlsxwriter"
3
+ s.version = "0.6.9"
4
+ s.summary = "Libxlsxwriter: A C library for creating Excel XLSX files."
5
+ s.ios.deployment_target = "6.0"
6
+ s.osx.deployment_target = "10.8"
7
+
8
+ s.description = <<-DESC
9
+ Libxlsxwriter is a C library that can be used to write text, numbers, formulas and hyperlinks to multiple worksheets in an Excel 2007+ XLSX file.
10
+
11
+ It supports features such as:
12
+
13
+ * 100% compatible Excel XLSX files.
14
+ * Full Excel formatting.
15
+ * Merged cells.
16
+ * Defined names.
17
+ * Autofilters.
18
+ * Charts.
19
+ * Worksheet PNG/JPEG images.
20
+ * Memory optimisation mode for writing large files.
21
+ * Source code available on [GitHub](https://github.com/jmcnamara/libxlsxwriter).
22
+ * FreeBSD license.
23
+ * ANSI C.
24
+ * Works with GCC, Clang, Xcode, MSVC 2015, ICC, TCC, MinGW, MingGW-w64/32.
25
+ * Works on Linux, FreeBSD, OpenBSD, OS X, iOS and Windows. Also works on MSYS/MSYS2 and Cygwin.
26
+ * Compiles for 32 and 64 bit.
27
+ * The only dependency is on `zlib`.
28
+ DESC
29
+
30
+ s.homepage = "http://libxlsxwriter.github.io"
31
+ s.documentation_url = "http://libxlsxwriter.github.io"
32
+ s.license = "FreeBSD"
33
+ s.author = { "John McNamara" => "jmcnamara@cpan.org" }
34
+
35
+ s.source = { :git => "https://github.com/jmcnamara/libxlsxwriter.git", :tag => "RELEASE_" + s.version.to_s }
36
+ s.source_files = "src/**/*.c", "third_party/**/{zip.c,ioapi.c,tmpfileplus.c}", "include/**/*.h"
37
+
38
+ s.header_dir = "xlsxwriter"
39
+ s.header_mappings_dir = "include/xlsxwriter"
40
+ s.library = "z"
41
+ s.compiler_flags = "-DNOCRYPT=1", "-DNOUNCRYPT=1"
42
+ s.pod_target_xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '${PODS_ROOT}/libxlsxwriter/include' }
43
+ s.module_map = "cocoapods/libxlsxwriter.modulemap"
44
+ s.prepare_command = <<-CMD
45
+ cp cocoapods/libxlsxwriter-umbrella.h include/xlsxwriter/libxlsxwriter-umbrella.h
46
+ CMD
47
+ end
@@ -0,0 +1,130 @@
1
+ ###############################################################################
2
+ #
3
+ # Makefile for libxlsxwriter library.
4
+ #
5
+ # Copyright 2014-2017, John McNamara, jmcnamara@cpan.org
6
+ #
7
+
8
+ # Keep the output quiet by default.
9
+ Q=@
10
+ ifdef V
11
+ Q=
12
+ endif
13
+
14
+ # Directory variables.
15
+ OBJS_DIR = .
16
+ INC_DIR = ../include
17
+
18
+ # The minizip directory.
19
+ MINIZIP_DIR = ../third_party/minizip
20
+
21
+
22
+ ifdef USE_STANDARD_TMPFILE
23
+ # Use standard/C tmpfile().
24
+ CFLAGS += -DUSE_STANDARD_TMPFILE
25
+ else
26
+ # Use tmpfileplus (the default).
27
+ TMPFILEPLUS_DIR = ../third_party/tmpfileplus
28
+ TMPFILEPLUS_OBJ = $(TMPFILEPLUS_DIR)/tmpfileplus.o
29
+ TMPFILEPLUS_SO = $(TMPFILEPLUS_DIR)/tmpfileplus.so
30
+ endif
31
+
32
+ # Flags passed to compiler.
33
+ CFLAGS += -g -O3 -Wall -Wextra -pedantic -ansi
34
+
35
+ # Ignore icc remarks about inlining limits.
36
+ ifeq ($(CC),icc)
37
+ CFLAGS +=-diag-disable=11074,11076
38
+ endif
39
+
40
+ # Library names.
41
+ LIBXLSXWRITER_A = libxlsxwriter.a
42
+ LIBXLSXWRITER_SO = libxlsxwriter.so
43
+
44
+ # Library with additional non-static functions for testing.
45
+ LIBXLSXWRITER_TO = libxlsxwriter_test.a
46
+
47
+ # Flags passed to static linker.
48
+ ARFLAGS = rc
49
+
50
+ # Flags passed to dynamic linker.
51
+ FPIC = -fPIC
52
+ SOFLAGS = -shared $(FPIC)
53
+
54
+ # Get Env/OS name.
55
+ UNAME := $(shell uname)
56
+
57
+ # Change make options on OS X.
58
+ ifeq ($(UNAME), Darwin)
59
+ LIBXLSXWRITER_SO = libxlsxwriter.dylib
60
+ SOFLAGS = -dynamiclib $(FPIC) -install_name /usr/lib/$(LIBXLSXWRITER_SO)
61
+ endif
62
+
63
+ # Check for MinGW/MinGW64/Cygwin environments.
64
+ ifneq (,$(findstring MINGW, $(UNAME)))
65
+ MING_LIKE = y
66
+ endif
67
+ ifneq (,$(findstring MSYS, $(UNAME)))
68
+ MING_LIKE = y
69
+ endif
70
+ ifneq (,$(findstring CYGWIN, $(UNAME)))
71
+ MING_LIKE = y
72
+ endif
73
+
74
+ # Change make options on MinGW/MinGW64/Cygwin.
75
+ ifdef MING_LIKE
76
+ LIBXLSXWRITER_SO = libxlsxwriter.dll
77
+ FPIC =
78
+ CC = gcc
79
+ CFLAGS += -Wno-char-subscripts -Wno-long-long
80
+ endif
81
+
82
+ # Headers as dependecies.
83
+ HDRS = $(wildcard ../include/xlsxwriter/*.h)
84
+
85
+ # Ojects to compile.
86
+ SRCS = $(wildcard *.c)
87
+ OBJS = $(patsubst %.c,%.o,$(SRCS))
88
+ SOBJS = $(patsubst %.c,%.so,$(SRCS))
89
+ TOBJS = $(patsubst %.c,%.to,$(SRCS))
90
+ # End of OBJS
91
+
92
+ # Build the object files and the libraries.
93
+ all : $(LIBXLSXWRITER_A) $(LIBXLSXWRITER_SO)
94
+ $(Q)cp $(LIBXLSXWRITER_A) $(LIBXLSXWRITER_SO) ../lib
95
+
96
+ test_lib : libxlsxwriter_test.a
97
+
98
+ # The static library.
99
+ $(LIBXLSXWRITER_A) : $(OBJS)
100
+ $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_DIR)/ioapi.o $(MINIZIP_DIR)/zip.o $(TMPFILEPLUS_OBJ) $^
101
+
102
+ # The dynamic library.
103
+ ifeq ($(findstring m32,$(CFLAGS)),m32)
104
+ ARCH = -m32
105
+ endif
106
+
107
+ $(LIBXLSXWRITER_SO) : $(SOBJS)
108
+ $(Q)$(CC) $(SOFLAGS) $(ARCH) -o $@ $(MINIZIP_DIR)/ioapi.so $(MINIZIP_DIR)/zip.so $(TMPFILEPLUS_SO) $^ -lz
109
+
110
+ # The test library.
111
+ $(LIBXLSXWRITER_TO) : $(TOBJS)
112
+ $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_DIR)/ioapi.o $(MINIZIP_DIR)/zip.o $(TMPFILEPLUS_OBJ) $^
113
+
114
+ # Minimal target for quick compile without creating the libs.
115
+ test_compile : $(OBJS)
116
+
117
+ # Targets for the object files.
118
+ %.o : %.c $(HDRS)
119
+ $(Q)$(CC) -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) -c $<
120
+
121
+ %.so : %.c $(HDRS)
122
+ $(Q)$(CC) $(FPIC) -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
123
+
124
+ %.to : %.c $(HDRS)
125
+ $(Q)$(CC) -g -O3 -DTESTING -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
126
+
127
+
128
+ # Clean up any temp/build files.
129
+ clean :
130
+ $(Q)rm -f *.o *.a *.so *.to *.dylib *.dll
@@ -0,0 +1,443 @@
1
+ /*****************************************************************************
2
+ * app - A library for creating Excel XLSX app 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/app.h"
12
+ #include "xlsxwriter/utility.h"
13
+
14
+ /*
15
+ * Forward declarations.
16
+ */
17
+
18
+ /*****************************************************************************
19
+ *
20
+ * Private functions.
21
+ *
22
+ ****************************************************************************/
23
+
24
+ /*
25
+ * Create a new app object.
26
+ */
27
+ lxw_app *
28
+ lxw_app_new()
29
+ {
30
+ lxw_app *app = calloc(1, sizeof(lxw_app));
31
+ GOTO_LABEL_ON_MEM_ERROR(app, mem_error);
32
+
33
+ app->heading_pairs = calloc(1, sizeof(struct lxw_heading_pairs));
34
+ GOTO_LABEL_ON_MEM_ERROR(app->heading_pairs, mem_error);
35
+ STAILQ_INIT(app->heading_pairs);
36
+
37
+ app->part_names = calloc(1, sizeof(struct lxw_part_names));
38
+ GOTO_LABEL_ON_MEM_ERROR(app->part_names, mem_error);
39
+ STAILQ_INIT(app->part_names);
40
+
41
+ return app;
42
+
43
+ mem_error:
44
+ lxw_app_free(app);
45
+ return NULL;
46
+ }
47
+
48
+ /*
49
+ * Free a app object.
50
+ */
51
+ void
52
+ lxw_app_free(lxw_app *app)
53
+ {
54
+ lxw_heading_pair *heading_pair;
55
+ lxw_part_name *part_name;
56
+
57
+ if (!app)
58
+ return;
59
+
60
+ /* Free the lists in the App object. */
61
+ if (app->heading_pairs) {
62
+ while (!STAILQ_EMPTY(app->heading_pairs)) {
63
+ heading_pair = STAILQ_FIRST(app->heading_pairs);
64
+ STAILQ_REMOVE_HEAD(app->heading_pairs, list_pointers);
65
+ free(heading_pair->key);
66
+ free(heading_pair->value);
67
+ free(heading_pair);
68
+ }
69
+ free(app->heading_pairs);
70
+ }
71
+
72
+ if (app->part_names) {
73
+ while (!STAILQ_EMPTY(app->part_names)) {
74
+ part_name = STAILQ_FIRST(app->part_names);
75
+ STAILQ_REMOVE_HEAD(app->part_names, list_pointers);
76
+ free(part_name->name);
77
+ free(part_name);
78
+ }
79
+ free(app->part_names);
80
+ }
81
+
82
+ free(app);
83
+ }
84
+
85
+ /*****************************************************************************
86
+ *
87
+ * XML functions.
88
+ *
89
+ ****************************************************************************/
90
+
91
+ /*
92
+ * Write the XML declaration.
93
+ */
94
+ STATIC void
95
+ _app_xml_declaration(lxw_app *self)
96
+ {
97
+ lxw_xml_declaration(self->file);
98
+ }
99
+
100
+ /*
101
+ * Write the <Properties> element.
102
+ */
103
+ STATIC void
104
+ _write_properties(lxw_app *self)
105
+ {
106
+ struct xml_attribute_list attributes;
107
+ struct xml_attribute *attribute;
108
+ char xmlns[] = LXW_SCHEMA_OFFICEDOC "/extended-properties";
109
+ char xmlns_vt[] = LXW_SCHEMA_OFFICEDOC "/docPropsVTypes";
110
+
111
+ LXW_INIT_ATTRIBUTES();
112
+ LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns);
113
+ LXW_PUSH_ATTRIBUTES_STR("xmlns:vt", xmlns_vt);
114
+
115
+ lxw_xml_start_tag(self->file, "Properties", &attributes);
116
+
117
+ LXW_FREE_ATTRIBUTES();
118
+ }
119
+
120
+ /*
121
+ * Write the <Application> element.
122
+ */
123
+ STATIC void
124
+ _write_application(lxw_app *self)
125
+ {
126
+ lxw_xml_data_element(self->file, "Application", "Microsoft Excel", NULL);
127
+ }
128
+
129
+ /*
130
+ * Write the <DocSecurity> element.
131
+ */
132
+ STATIC void
133
+ _write_doc_security(lxw_app *self)
134
+ {
135
+ lxw_xml_data_element(self->file, "DocSecurity", "0", NULL);
136
+ }
137
+
138
+ /*
139
+ * Write the <ScaleCrop> element.
140
+ */
141
+ STATIC void
142
+ _write_scale_crop(lxw_app *self)
143
+ {
144
+ lxw_xml_data_element(self->file, "ScaleCrop", "false", NULL);
145
+ }
146
+
147
+ /*
148
+ * Write the <vt:lpstr> element.
149
+ */
150
+ STATIC void
151
+ _write_vt_lpstr(lxw_app *self, const char *str)
152
+ {
153
+ lxw_xml_data_element(self->file, "vt:lpstr", str, NULL);
154
+ }
155
+
156
+ /*
157
+ * Write the <vt:i4> element.
158
+ */
159
+ STATIC void
160
+ _write_vt_i4(lxw_app *self, const char *value)
161
+ {
162
+ lxw_xml_data_element(self->file, "vt:i4", value, NULL);
163
+ }
164
+
165
+ /*
166
+ * Write the <vt:variant> element.
167
+ */
168
+ STATIC void
169
+ _write_vt_variant(lxw_app *self, const char *key, const char *value)
170
+ {
171
+ /* Write the vt:lpstr element. */
172
+ lxw_xml_start_tag(self->file, "vt:variant", NULL);
173
+ _write_vt_lpstr(self, key);
174
+ lxw_xml_end_tag(self->file, "vt:variant");
175
+
176
+ /* Write the vt:i4 element. */
177
+ lxw_xml_start_tag(self->file, "vt:variant", NULL);
178
+ _write_vt_i4(self, value);
179
+ lxw_xml_end_tag(self->file, "vt:variant");
180
+ }
181
+
182
+ /*
183
+ * Write the <vt:vector> element for the heading pairs.
184
+ */
185
+ STATIC void
186
+ _write_vt_vector_heading_pairs(lxw_app *self)
187
+ {
188
+ struct xml_attribute_list attributes;
189
+ struct xml_attribute *attribute;
190
+ lxw_heading_pair *heading_pair;
191
+
192
+ LXW_INIT_ATTRIBUTES();
193
+ LXW_PUSH_ATTRIBUTES_INT("size", self->num_heading_pairs * 2);
194
+ LXW_PUSH_ATTRIBUTES_STR("baseType", "variant");
195
+
196
+ lxw_xml_start_tag(self->file, "vt:vector", &attributes);
197
+
198
+ STAILQ_FOREACH(heading_pair, self->heading_pairs, list_pointers) {
199
+ _write_vt_variant(self, heading_pair->key, heading_pair->value);
200
+ }
201
+
202
+ lxw_xml_end_tag(self->file, "vt:vector");
203
+
204
+ LXW_FREE_ATTRIBUTES();
205
+ }
206
+
207
+ /*
208
+ * Write the <vt:vector> element for the named parts.
209
+ */
210
+ STATIC void
211
+ _write_vt_vector_lpstr_named_parts(lxw_app *self)
212
+ {
213
+ struct xml_attribute_list attributes;
214
+ struct xml_attribute *attribute;
215
+ lxw_part_name *part_name;
216
+
217
+ LXW_INIT_ATTRIBUTES();
218
+ LXW_PUSH_ATTRIBUTES_INT("size", self->num_part_names);
219
+ LXW_PUSH_ATTRIBUTES_STR("baseType", "lpstr");
220
+
221
+ lxw_xml_start_tag(self->file, "vt:vector", &attributes);
222
+
223
+ STAILQ_FOREACH(part_name, self->part_names, list_pointers) {
224
+ _write_vt_lpstr(self, part_name->name);
225
+ }
226
+
227
+ lxw_xml_end_tag(self->file, "vt:vector");
228
+
229
+ LXW_FREE_ATTRIBUTES();
230
+ }
231
+
232
+ /*
233
+ * Write the <HeadingPairs> element.
234
+ */
235
+ STATIC void
236
+ _write_heading_pairs(lxw_app *self)
237
+ {
238
+ lxw_xml_start_tag(self->file, "HeadingPairs", NULL);
239
+
240
+ /* Write the vt:vector element. */
241
+ _write_vt_vector_heading_pairs(self);
242
+
243
+ lxw_xml_end_tag(self->file, "HeadingPairs");
244
+ }
245
+
246
+ /*
247
+ * Write the <TitlesOfParts> element.
248
+ */
249
+ STATIC void
250
+ _write_titles_of_parts(lxw_app *self)
251
+ {
252
+ lxw_xml_start_tag(self->file, "TitlesOfParts", NULL);
253
+
254
+ /* Write the vt:vector element. */
255
+ _write_vt_vector_lpstr_named_parts(self);
256
+
257
+ lxw_xml_end_tag(self->file, "TitlesOfParts");
258
+ }
259
+
260
+ /*
261
+ * Write the <Manager> element.
262
+ */
263
+ STATIC void
264
+ _write_manager(lxw_app *self)
265
+ {
266
+ lxw_doc_properties *properties = self->properties;
267
+
268
+ if (!properties)
269
+ return;
270
+
271
+ if (properties->manager)
272
+ lxw_xml_data_element(self->file, "Manager", properties->manager,
273
+ NULL);
274
+ }
275
+
276
+ /*
277
+ * Write the <Company> element.
278
+ */
279
+ STATIC void
280
+ _write_company(lxw_app *self)
281
+ {
282
+ lxw_doc_properties *properties = self->properties;
283
+
284
+ if (properties && properties->company)
285
+ lxw_xml_data_element(self->file, "Company", properties->company,
286
+ NULL);
287
+ else
288
+ lxw_xml_data_element(self->file, "Company", "", NULL);
289
+ }
290
+
291
+ /*
292
+ * Write the <LinksUpToDate> element.
293
+ */
294
+ STATIC void
295
+ _write_links_up_to_date(lxw_app *self)
296
+ {
297
+ lxw_xml_data_element(self->file, "LinksUpToDate", "false", NULL);
298
+ }
299
+
300
+ /*
301
+ * Write the <SharedDoc> element.
302
+ */
303
+ STATIC void
304
+ _write_shared_doc(lxw_app *self)
305
+ {
306
+ lxw_xml_data_element(self->file, "SharedDoc", "false", NULL);
307
+ }
308
+
309
+ /*
310
+ * Write the <HyperlinkBase> element.
311
+ */
312
+ STATIC void
313
+ _write_hyperlink_base(lxw_app *self)
314
+ {
315
+ lxw_doc_properties *properties = self->properties;
316
+
317
+ if (!properties)
318
+ return;
319
+
320
+ if (properties->hyperlink_base)
321
+ lxw_xml_data_element(self->file, "HyperlinkBase",
322
+ properties->hyperlink_base, NULL);
323
+ }
324
+
325
+ /*
326
+ * Write the <HyperlinksChanged> element.
327
+ */
328
+ STATIC void
329
+ _write_hyperlinks_changed(lxw_app *self)
330
+ {
331
+ lxw_xml_data_element(self->file, "HyperlinksChanged", "false", NULL);
332
+ }
333
+
334
+ /*
335
+ * Write the <AppVersion> element.
336
+ */
337
+ STATIC void
338
+ _write_app_version(lxw_app *self)
339
+ {
340
+ lxw_xml_data_element(self->file, "AppVersion", "12.0000", NULL);
341
+ }
342
+
343
+ /*****************************************************************************
344
+ *
345
+ * XML file assembly functions.
346
+ *
347
+ ****************************************************************************/
348
+
349
+ /*
350
+ * Assemble and write the XML file.
351
+ */
352
+ void
353
+ lxw_app_assemble_xml_file(lxw_app *self)
354
+ {
355
+
356
+ /* Write the XML declaration. */
357
+ _app_xml_declaration(self);
358
+
359
+ _write_properties(self);
360
+ _write_application(self);
361
+ _write_doc_security(self);
362
+ _write_scale_crop(self);
363
+ _write_heading_pairs(self);
364
+ _write_titles_of_parts(self);
365
+ _write_manager(self);
366
+ _write_company(self);
367
+ _write_links_up_to_date(self);
368
+ _write_shared_doc(self);
369
+ _write_hyperlink_base(self);
370
+ _write_hyperlinks_changed(self);
371
+ _write_app_version(self);
372
+
373
+ lxw_xml_end_tag(self->file, "Properties");
374
+ }
375
+
376
+ /*****************************************************************************
377
+ *
378
+ * Public functions.
379
+ *
380
+ ****************************************************************************/
381
+
382
+ /*
383
+ * Add the name of a workbook Part such as 'Sheet1' or 'Print_Titles'.
384
+ */
385
+ void
386
+ lxw_app_add_part_name(lxw_app *self, const char *name)
387
+ {
388
+ lxw_part_name *part_name;
389
+
390
+ if (!name)
391
+ return;
392
+
393
+ part_name = calloc(1, sizeof(lxw_part_name));
394
+ GOTO_LABEL_ON_MEM_ERROR(part_name, mem_error);
395
+
396
+ part_name->name = lxw_strdup(name);
397
+ GOTO_LABEL_ON_MEM_ERROR(part_name->name, mem_error);
398
+
399
+ STAILQ_INSERT_TAIL(self->part_names, part_name, list_pointers);
400
+ self->num_part_names++;
401
+
402
+ return;
403
+
404
+ mem_error:
405
+ if (part_name) {
406
+ free(part_name->name);
407
+ free(part_name);
408
+ }
409
+ }
410
+
411
+ /*
412
+ * Add the name of a workbook Heading Pair such as 'Worksheets', 'Charts' or
413
+ * 'Named Ranges'.
414
+ */
415
+ void
416
+ lxw_app_add_heading_pair(lxw_app *self, const char *key, const char *value)
417
+ {
418
+ lxw_heading_pair *heading_pair;
419
+
420
+ if (!key || !value)
421
+ return;
422
+
423
+ heading_pair = calloc(1, sizeof(lxw_heading_pair));
424
+ GOTO_LABEL_ON_MEM_ERROR(heading_pair, mem_error);
425
+
426
+ heading_pair->key = lxw_strdup(key);
427
+ GOTO_LABEL_ON_MEM_ERROR(heading_pair->key, mem_error);
428
+
429
+ heading_pair->value = lxw_strdup(value);
430
+ GOTO_LABEL_ON_MEM_ERROR(heading_pair->value, mem_error);
431
+
432
+ STAILQ_INSERT_TAIL(self->heading_pairs, heading_pair, list_pointers);
433
+ self->num_heading_pairs++;
434
+
435
+ return;
436
+
437
+ mem_error:
438
+ if (heading_pair) {
439
+ free(heading_pair->key);
440
+ free(heading_pair->value);
441
+ free(heading_pair);
442
+ }
443
+ }