From 665f8fbebcac0701cccdf07e4ce053ec622d9aeb Mon Sep 17 00:00:00 2001 From: Thomas Fussell Date: Wed, 4 Nov 2015 18:45:03 -0500 Subject: [PATCH] made a new string class for dll exports --- cmake/xlnt.cmake | 1 + include/xlnt/cell/cell.hpp | 25 +- include/xlnt/cell/cell_reference.hpp | 22 +- include/xlnt/cell/comment.hpp | 8 +- include/xlnt/cell/types.hpp | 19 +- include/xlnt/formula/translator.hpp | 18 +- .../xlnt/packaging/document_properties.hpp | 16 +- include/xlnt/packaging/manifest.hpp | 35 +- include/xlnt/packaging/relationship.hpp | 31 +- include/xlnt/packaging/zip_file.hpp | 55 +- .../xlnt/serialization/excel_serializer.hpp | 8 +- .../serialization/manifest_serializer.hpp | 2 +- .../serialization/relationship_serializer.hpp | 7 +- .../shared_strings_serializer.hpp | 7 +- .../xlnt/serialization/style_serializer.hpp | 2 +- .../serialization/workbook_serializer.hpp | 2 +- include/xlnt/serialization/xml_document.hpp | 19 +- include/xlnt/serialization/xml_node.hpp | 29 +- include/xlnt/serialization/xml_serializer.hpp | 8 +- include/xlnt/styles/color.hpp | 9 +- include/xlnt/styles/fill.hpp | 4 +- include/xlnt/styles/font.hpp | 10 +- include/xlnt/styles/named_style.hpp | 2 +- include/xlnt/styles/number_format.hpp | 15 +- include/xlnt/utils/datetime.hpp | 7 +- include/xlnt/utils/exceptions.hpp | 30 +- include/xlnt/utils/string.hpp | 323 +++++++++ include/xlnt/workbook/document_security.hpp | 4 +- include/xlnt/workbook/named_range.hpp | 8 +- include/xlnt/workbook/workbook.hpp | 42 +- include/xlnt/worksheet/range_reference.hpp | 16 +- include/xlnt/worksheet/sheet_protection.hpp | 10 +- include/xlnt/worksheet/worksheet.hpp | 64 +- include/xlnt/xlnt_config.hpp | 6 +- source/cell/cell.cpp | 201 +++--- source/cell/cell_reference.cpp | 30 +- source/cell/comment.cpp | 6 +- source/cell/tests/test_cell.hpp | 15 +- source/cell/types.cpp | 16 +- source/detail/cell_impl.hpp | 77 +-- source/detail/comment_impl.hpp | 6 +- source/detail/constants.cpp | 38 +- source/detail/constants.hpp | 36 +- source/detail/workbook_impl.hpp | 2 +- source/detail/worksheet_impl.hpp | 6 +- source/detail/xml_document_impl.hpp | 2 +- source/packaging/manifest.cpp | 22 +- source/packaging/relationship.cpp | 2 +- source/packaging/tests/test_core.hpp | 4 +- source/packaging/zip_file.cpp | 104 +-- source/serialization/excel_serializer.cpp | 23 +- source/serialization/manifest_serializer.cpp | 4 +- .../serialization/relationship_serializer.cpp | 16 +- .../shared_strings_serializer.cpp | 8 +- source/serialization/style_serializer.cpp | 101 +-- source/serialization/tests/test_read.hpp | 12 +- .../serialization/tests/test_style_writer.hpp | 2 +- source/serialization/tests/test_write.hpp | 4 +- .../tests/test_write_workbook.hpp | 8 +- source/serialization/theme_serializer.cpp | 12 +- source/serialization/workbook_serializer.cpp | 63 +- source/serialization/worksheet_serializer.cpp | 108 +-- source/serialization/xml_document.cpp | 24 +- source/serialization/xml_node.cpp | 46 +- source/serialization/xml_serializer.cpp | 12 +- source/styles/number_format.cpp | 18 +- source/utils/datetime.cpp | 18 +- source/utils/exceptions.cpp | 19 +- source/utils/string.cpp | 644 ++++++++++++++++++ source/utils/tests/test_zip_file.hpp | 28 +- source/workbook/named_range.cpp | 14 +- source/workbook/tests/test_named_range.hpp | 4 +- source/workbook/tests/test_workbook.hpp | 14 +- source/workbook/workbook.cpp | 68 +- source/worksheet/range.cpp | 5 +- source/worksheet/range_reference.cpp | 8 +- source/worksheet/sheet_protection.cpp | 25 +- source/worksheet/tests/test_worksheet.hpp | 58 +- source/worksheet/worksheet.cpp | 42 +- tests/helpers/helper.hpp | 22 +- tests/helpers/path_helper.hpp | 41 +- tests/helpers/temporary_file.hpp | 12 +- third-party/utfcpp/utf8.h | 34 + third-party/utfcpp/utf8/checked.h | 327 +++++++++ third-party/utfcpp/utf8/core.h | 329 +++++++++ third-party/utfcpp/utf8/unchecked.h | 228 +++++++ 86 files changed, 2851 insertions(+), 981 deletions(-) create mode 100644 include/xlnt/utils/string.hpp create mode 100644 source/utils/string.cpp create mode 100644 third-party/utfcpp/utf8.h create mode 100644 third-party/utfcpp/utf8/checked.h create mode 100644 third-party/utfcpp/utf8/core.h create mode 100644 third-party/utfcpp/utf8/unchecked.h diff --git a/cmake/xlnt.cmake b/cmake/xlnt.cmake index f368bf46..46532695 100644 --- a/cmake/xlnt.cmake +++ b/cmake/xlnt.cmake @@ -21,6 +21,7 @@ include_directories(../include/xlnt) include_directories(../source) include_directories(../third-party/miniz) include_directories(../third-party/pugixml/src) +include_directories(../third-party/utfcpp) FILE(GLOB ROOT_HEADERS ../include/xlnt/*.hpp) FILE(GLOB CELL_HEADERS ../include/xlnt/cell/*.hpp) diff --git a/include/xlnt/cell/cell.hpp b/include/xlnt/cell/cell.hpp index ef2e3c2a..089c157d 100644 --- a/include/xlnt/cell/cell.hpp +++ b/include/xlnt/cell/cell.hpp @@ -24,10 +24,10 @@ #pragma once #include -#include #include #include +#include #include "xlnt_config.hpp" @@ -87,7 +87,7 @@ public: /// /// Return a map of error strings such as \#DIV/0! and their associated indices. /// - static const std::unordered_map &error_codes(); + static const std::unordered_map &error_codes(); // TODO: Should it be possible to construct and use a cell without a parent worksheet? //(cont'd) If so, it would need to be responsible for allocating and deleting its PIMPL. @@ -121,7 +121,7 @@ public: /// /// Return the value of this cell as an instance of type T. /// Overloads exist for most C++ fundamental types like bool, int, etc. as well - /// as for std::string and xlnt datetime types: date, time, datetime, and timedelta. + /// as for string and xlnt datetime types: date, time, datetime, and timedelta. /// template T get_value() const; @@ -135,7 +135,8 @@ public: /// /// Set the value of this cell to the given value. /// Overloads exist for most C++ fundamental types like bool, int, etc. as well - /// as for std::string and xlnt datetime types: date, time, datetime, and timedelta. + /// as for string and xlnt datetime types: date, time, datetime, and timedelta. + /// template void set_value(T value); @@ -194,7 +195,7 @@ public: /// /// Add a hyperlink to this cell pointing to the URI of the given value. /// - void set_hyperlink(const std::string &value); + void set_hyperlink(const string &value); /// /// Return true if this cell has a hyperlink set. @@ -292,8 +293,8 @@ public: bool has_comment() const; // formula - std::string get_formula() const; - void set_formula(const std::string &formula); + string get_formula() const; + void set_formula(const string &formula); void clear_formula(); bool has_formula() const; @@ -302,13 +303,13 @@ public: /// /// Returns a string describing this cell like . /// - std::string to_repr() const; + string to_repr() const; /// /// Returns a string representing the value of this cell. If the data type is not a string, /// it will be converted according to the number format. /// - std::string to_string() const; + string to_string() const; // merging @@ -328,12 +329,12 @@ public: /// /// Return the error string that is stored in this cell. /// - std::string get_error() const; + string get_error() const; /// /// Directly assign the value of this cell to be the given error. /// - void set_error(const std::string &error); + void set_error(const string &error); /// /// Return a cell from this cell's parent workbook at @@ -409,7 +410,7 @@ private: /// Convenience function for writing cell to an ostream. /// Uses cell::to_string() internally. /// -inline std::ostream & XLNT_FUNCTION operator<<(std::ostream &stream, const xlnt::cell &cell) +inline std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell) { return stream << cell.to_string(); } diff --git a/include/xlnt/cell/cell_reference.hpp b/include/xlnt/cell/cell_reference.hpp index 7142530d..e4e35793 100644 --- a/include/xlnt/cell/cell_reference.hpp +++ b/include/xlnt/cell/cell_reference.hpp @@ -23,10 +23,10 @@ #pragma once #include -#include #include #include +#include #include "xlnt_config.hpp" @@ -57,7 +57,7 @@ class XLNT_CLASS cell_reference /// /// Split a coordinate string like "A1" into an equivalent pair like {"A", 1}. /// - static std::pair split_reference(const std::string &reference_string); + static std::pair split_reference(const string &reference_string); /// /// Split a coordinate string like "A1" into an equivalent pair like {"A", 1}. @@ -65,7 +65,7 @@ class XLNT_CLASS cell_reference /// if column part or row part are prefixed by a dollar-sign indicating they /// are absolute, otherwise false. /// - static std::pair split_reference(const std::string &reference_string, bool &absolute_column, + static std::pair split_reference(const string &reference_string, bool &absolute_column, bool &absolute_row); // constructors @@ -85,13 +85,13 @@ class XLNT_CLASS cell_reference /// /// Constructs a cell_reference from a string reprenting a cell coordinate (e.g. $B14). /// - cell_reference(const std::string &reference_string); + cell_reference(const string &reference_string); /// /// Constructs a cell_reference from a string reprenting a column (e.g. A) and /// a 1-indexed row. /// - cell_reference(const std::string &column, row_t row); + cell_reference(const string &column, row_t row); /// /// Constructs a cell_reference from a 1-indexed column index and row index. @@ -163,7 +163,7 @@ class XLNT_CLASS cell_reference /// /// Set the column of this reference from a string that identifies a particular column. /// - void set_column(const std::string &column_string) + void set_column(const string &column_string) { column_ = column_t(column_string); } @@ -211,7 +211,7 @@ class XLNT_CLASS cell_reference /// /// Return a string like "A1" for cell_reference(1, 1). /// - std::string to_string() const; + string to_string() const; /// /// Return a 1x1 range_reference containing only this cell_reference. @@ -237,7 +237,7 @@ class XLNT_CLASS cell_reference /// Construct a cell_reference from reference_string and return the result /// of their comparison. /// - bool operator==(const std::string &reference_string) const + bool operator==(const string &reference_string) const { return *this == cell_reference(reference_string); } @@ -248,7 +248,7 @@ class XLNT_CLASS cell_reference /// bool operator==(const char *reference_string) const { - return *this == std::string(reference_string); + return *this == string(reference_string); } /// @@ -264,7 +264,7 @@ class XLNT_CLASS cell_reference /// Construct a cell_reference from reference_string and return the result /// of their comparison. /// - bool operator!=(const std::string &reference_string) const + bool operator!=(const string &reference_string) const { return *this != cell_reference(reference_string); } @@ -275,7 +275,7 @@ class XLNT_CLASS cell_reference /// bool operator!=(const char *reference_string) const { - return *this != std::string(reference_string); + return *this != string(reference_string); } //TODO: are these useful? maybe get rid of them diff --git a/include/xlnt/cell/comment.hpp b/include/xlnt/cell/comment.hpp index dc3365a1..b141ede7 100644 --- a/include/xlnt/cell/comment.hpp +++ b/include/xlnt/cell/comment.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "xlnt_config.hpp" @@ -23,19 +23,19 @@ class XLNT_CLASS comment /// /// Constructs a comment applied to the given cell, parent, and with the comment /// text and author set to the provided respective values. - comment(cell parent, const std::string &text, const std::string &auth); + comment(cell parent, const string &text, const string &auth); ~comment(); /// /// Return the text that will be displayed for this comment. /// - std::string get_text() const; + string get_text() const; /// /// Return the author of this comment. /// - std::string get_author() const; + string get_author() const; /// /// True if the comments point to the same sell (false if diff --git a/include/xlnt/cell/types.hpp b/include/xlnt/cell/types.hpp index 01aa13b3..e88d20b8 100644 --- a/include/xlnt/cell/types.hpp +++ b/include/xlnt/cell/types.hpp @@ -24,7 +24,8 @@ #include #include -#include + +#include #include "xlnt_config.hpp" @@ -56,7 +57,7 @@ public: /// restrict our column names to 1 - 3 characters, each in the range A - Z. /// Strings outside this range and malformed strings will throw xlnt::column_string_index_exception. /// - static index_t column_index_from_string(const std::string &column_string); + static index_t column_index_from_string(const string &column_string); /// /// Convert a column number into a column letter (3 -> 'C') @@ -66,7 +67,7 @@ public: /// order. These indices are 1-based, and can be converted to ASCII /// ordinals by adding 64. /// - static std::string column_string_from_index(index_t column_index); + static string column_string_from_index(index_t column_index); /// /// Default column_t is the first (left-most) column. @@ -81,12 +82,12 @@ public: /// /// Construct a column from a string. /// - explicit column_t(const std::string &column_string) : index(column_index_from_string(column_string)) {} + explicit column_t(const string &column_string) : index(column_index_from_string(column_string)) {} /// /// Construct a column from a string. /// - explicit column_t(const char *column_string) : column_t(std::string(column_string)) {} + explicit column_t(const char *column_string) : column_t(string(column_string)) {} /// /// Copy constructor @@ -101,7 +102,7 @@ public: /// /// Return a string representation of this column index. /// - std::string column_string() const { return column_string_from_index(index); } + string column_string() const { return column_string_from_index(index); } /// /// Set this column to be the same as rhs's and return reference to self. @@ -111,7 +112,7 @@ public: /// /// Set this column to be equal to rhs and return reference to self. /// - column_t &operator=(const std::string &rhs) { return *this = column_t(rhs); } + column_t &operator=(const string &rhs) { return *this = column_t(rhs); } /// /// Set this column to be equal to rhs and return reference to self. @@ -141,7 +142,7 @@ public: /// /// Return true if this column refers to the same column as other. /// - bool operator==(const std::string &other) const { return *this == column_t(other); } + bool operator==(const string &other) const { return *this == column_t(other); } /// /// Return true if this column refers to the same column as other. @@ -161,7 +162,7 @@ public: /// /// Return true if this column doesn't refer to the same column as other. /// - bool operator!=(const std::string &other) const { return !(*this == other); } + bool operator!=(const string &other) const { return !(*this == other); } /// /// Return true if this column doesn't refer to the same column as other. diff --git a/include/xlnt/formula/translator.hpp b/include/xlnt/formula/translator.hpp index 122ab771..6fbc3932 100644 --- a/include/xlnt/formula/translator.hpp +++ b/include/xlnt/formula/translator.hpp @@ -12,24 +12,24 @@ class tokenizer; class XLNT_CLASS translator { - translator(const std::string &formula, const cell_reference &ref); + translator(const string &formula, const cell_reference &ref); - std::vector get_tokens(); + std::vector get_tokens(); - static std::string translate_row(const std::string &row_str, int row_delta); - static std::string translate_col(const std::string &col_str, col_delta); + static string translate_row(const string &row_str, int row_delta); + static string translate_col(const string &col_str, col_delta); - std::pair strip_ws_name(const std::string &range_str); + std::pair strip_ws_name(const string &range_str); void translate_range(const range_reference &range_ref); void translate_formula(const cell_reference &dest); private: - const std::string ROW_RANGE_RE; - const std::string COL_RANGE_RE; - const std::string CELL_REF_RE; + const string ROW_RANGE_RE; + const string COL_RANGE_RE; + const string CELL_REF_RE; - std::string formula_; + string formula_; cell_reference reference_; tokenizer tokenizer_; }; diff --git a/include/xlnt/packaging/document_properties.hpp b/include/xlnt/packaging/document_properties.hpp index 2b1bf484..d12a8002 100644 --- a/include/xlnt/packaging/document_properties.hpp +++ b/include/xlnt/packaging/document_properties.hpp @@ -39,16 +39,16 @@ class XLNT_CLASS document_properties public: document_properties(); - std::string creator; - std::string last_modified_by; + string creator; + string last_modified_by; datetime created; datetime modified; - std::string title = "Untitled"; - std::string subject; - std::string description; - std::string keywords; - std::string category; - std::string company; + string title = "Untitled"; + string subject; + string description; + string keywords; + string category; + string company; calendar excel_base_date; }; diff --git a/include/xlnt/packaging/manifest.hpp b/include/xlnt/packaging/manifest.hpp index 3ae4db9a..6acc4093 100644 --- a/include/xlnt/packaging/manifest.hpp +++ b/include/xlnt/packaging/manifest.hpp @@ -1,8 +1,9 @@ #pragma once -#include #include +#include + #include "xlnt_config.hpp" namespace xlnt { @@ -11,51 +12,51 @@ class XLNT_CLASS default_type { public: default_type(); - default_type(const std::string &extension, const std::string &content_type); + default_type(const string &extension, const string &content_type); default_type(const default_type &other); default_type &operator=(const default_type &other); - std::string get_extension() const + string get_extension() const { return extension_; } - std::string get_content_type() const + string get_content_type() const { return content_type_; } private: - std::string extension_; - std::string content_type_; + string extension_; + string content_type_; }; class XLNT_CLASS override_type { public: override_type(); - override_type(const std::string &extension, const std::string &content_type); + override_type(const string &extension, const string &content_type); override_type(const override_type &other); override_type &operator=(const override_type &other); - std::string get_part_name() const + string get_part_name() const { return part_name_; } - std::string get_content_type() const + string get_content_type() const { return content_type_; } private: - std::string part_name_; - std::string content_type_; + string part_name_; + string content_type_; }; class XLNT_CLASS manifest { public: - void add_default_type(const std::string &extension, const std::string &content_type); - void add_override_type(const std::string &part_name, const std::string &content_type); + void add_default_type(const string &extension, const string &content_type); + void add_override_type(const string &part_name, const string &content_type); const std::vector &get_default_types() const { @@ -66,11 +67,11 @@ class XLNT_CLASS manifest return override_types_; } - bool has_default_type(const std::string &extension) const; - bool has_override_type(const std::string &part_name) const; + bool has_default_type(const string &extension) const; + bool has_override_type(const string &part_name) const; - std::string get_default_type(const std::string &extension) const; - std::string get_override_type(const std::string &part_name) const; + string get_default_type(const string &extension) const; + string get_override_type(const string &part_name) const; private: std::vector default_types_; diff --git a/include/xlnt/packaging/relationship.hpp b/include/xlnt/packaging/relationship.hpp index 3e45fe77..9d2768fa 100644 --- a/include/xlnt/packaging/relationship.hpp +++ b/include/xlnt/packaging/relationship.hpp @@ -23,7 +23,7 @@ // @author: see AUTHORS file #pragma once -#include +#include namespace xlnt { @@ -65,7 +65,7 @@ class relationship custom_xml }; - static type type_from_string(const std::string &type_string) + static type type_from_string(const string &type_string) { if (type_string == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties") { @@ -111,7 +111,7 @@ class relationship return type::invalid; } - static std::string type_to_string(type t) + static string type_to_string(type t) { switch (t) { @@ -141,16 +141,16 @@ class relationship } relationship(); - relationship(const std::string &t, const std::string &r_id = "", const std::string &target_uri = "") + relationship(const string &t, const string &r_id = "", const string &target_uri = "") : relationship(type_from_string(t), r_id, target_uri) { } - relationship(type t, const std::string &r_id = "", const std::string &target_uri = ""); + relationship(type t, const string &r_id = "", const string &target_uri = ""); /// /// gets a string that identifies the relationship. /// - std::string get_id() const + string get_id() const { return id_; } @@ -158,7 +158,7 @@ class relationship /// /// gets the URI of the package or part that owns the relationship. /// - std::string get_source_uri() const + string get_source_uri() const { return source_uri_; } @@ -174,7 +174,7 @@ class relationship /// /// gets the URI of the target resource of the relationship. /// - std::string get_target_uri() const + string get_target_uri() const { return target_uri_; } @@ -183,22 +183,25 @@ class relationship { return type_; } - std::string get_type_string() const + string get_type_string() const { return type_to_string(type_); } friend bool operator==(const relationship &left, const relationship &right) { - return left.type_ == right.type_ && left.id_ == right.id_ && left.source_uri_ == right.source_uri_ && - left.target_uri_ == right.target_uri_ && left.target_mode_ == right.target_mode_; + return left.type_ == right.type_ + && left.id_ == right.id_ + && left.source_uri_ == right.source_uri_ + && left.target_uri_ == right.target_uri_ + && left.target_mode_ == right.target_mode_; } private: type type_; - std::string id_; - std::string source_uri_; - std::string target_uri_; + string id_; + string source_uri_; + string target_uri_; target_mode target_mode_; }; diff --git a/include/xlnt/packaging/zip_file.hpp b/include/xlnt/packaging/zip_file.hpp index 4b223362..21669d90 100644 --- a/include/xlnt/packaging/zip_file.hpp +++ b/include/xlnt/packaging/zip_file.hpp @@ -4,9 +4,10 @@ #include #include #include -#include #include +#include + #include "xlnt_config.hpp" // Note: this comes from https://github.com/tfussell/miniz-cpp @@ -39,9 +40,9 @@ struct XLNT_CLASS zip_info zip_info(); date_time_t date_time; - std::string filename; - std::string comment; - std::string extra; + string filename; + string comment; + string extra; uint16_t create_system; uint16_t create_version; uint16_t extract_version; @@ -63,14 +64,14 @@ class XLNT_CLASS zip_file { public: zip_file(); - zip_file(const std::string &filename); + zip_file(const string &filename); zip_file(const std::vector &bytes); zip_file(std::istream &stream); ~zip_file(); // to/from file - void load(const std::string &filename); - void save(const std::string &filename); + void load(const string &filename); + void save(const string &filename); // to/from byte vector void load(const std::vector &bytes); @@ -82,47 +83,47 @@ class XLNT_CLASS zip_file void reset(); - bool has_file(const std::string &name); + bool has_file(const string &name); bool has_file(const zip_info &name); - zip_info getinfo(const std::string &name); + zip_info getinfo(const string &name); std::vector infolist(); - std::vector namelist(); + std::vector namelist(); - std::ostream &open(const std::string &name); + std::ostream &open(const string &name); std::ostream &open(const zip_info &name); - void extract(const std::string &name); - void extract(const std::string &name, const std::string &path); + void extract(const string &name); + void extract(const string &name, const string &path); void extract(const zip_info &name); - void extract(const zip_info &name, const std::string &path); + void extract(const zip_info &name, const string &path); void extractall(); - void extractall(const std::string &path); - void extractall(const std::string &path, const std::vector &members); - void extractall(const std::string &path, const std::vector &members); + void extractall(const string &path); + void extractall(const string &path, const std::vector &members); + void extractall(const string &path, const std::vector &members); void printdir(); void printdir(std::ostream &stream); - std::string read(const std::string &name); - std::string read(const zip_info &name); + string read(const string &name); + string read(const zip_info &name); - std::pair testzip(); + std::pair testzip(); - void write(const std::string &filename); - void write(const std::string &filename, const std::string &arcname); + void write(const string &filename); + void write(const string &filename, const string &arcname); - void writestr(const std::string &arcname, const std::string &bytes); - void writestr(const zip_info &arcname, const std::string &bytes); + void writestr(const string &arcname, const string &bytes); + void writestr(const zip_info &arcname, const string &bytes); - std::string get_filename() const + string get_filename() const { return filename_; } - std::string comment; + string comment; private: void start_read(); @@ -136,7 +137,7 @@ class XLNT_CLASS zip_file std::unique_ptr archive_; std::vector buffer_; std::stringstream open_stream_; - std::string filename_; + string filename_; }; } // namespace xlnt diff --git a/include/xlnt/serialization/excel_serializer.hpp b/include/xlnt/serialization/excel_serializer.hpp index dec5ff30..370103f8 100644 --- a/include/xlnt/serialization/excel_serializer.hpp +++ b/include/xlnt/serialization/excel_serializer.hpp @@ -46,12 +46,12 @@ class XLNT_CLASS excel_serializer /// /// /// - static const std::string central_directory_signature(); + static const string central_directory_signature(); /// /// /// - static std::string repair_central_directory(const std::string &original); + static string repair_central_directory(const string &original); /// /// Construct an excel_serializer which operates on wb. @@ -62,7 +62,7 @@ class XLNT_CLASS excel_serializer /// Create a ZIP file in memory, load archive from filename, then populate workbook /// with data from archive. /// - bool load_workbook(const std::string &filename, bool guess_types = false, bool data_only = false); + bool load_workbook(const string &filename, bool guess_types = false, bool data_only = false); /// /// Create a ZIP file in memory, load archive from stream, then populate workbook @@ -81,7 +81,7 @@ class XLNT_CLASS excel_serializer /// Create a ZIP file in memory, save workbook to this archive, then save archive /// to filename. /// - bool save_workbook(const std::string &filename, bool as_template = false); + bool save_workbook(const string &filename, bool as_template = false); /// /// Create a ZIP file in memory, save workbook to this archive, then assign ZIP file diff --git a/include/xlnt/serialization/manifest_serializer.hpp b/include/xlnt/serialization/manifest_serializer.hpp index 7297b634..7441b4b7 100644 --- a/include/xlnt/serialization/manifest_serializer.hpp +++ b/include/xlnt/serialization/manifest_serializer.hpp @@ -17,7 +17,7 @@ class XLNT_CLASS manifest_serializer void read_manifest(const xml_document &xml); xml_document write_manifest() const; - std::string determine_document_type() const; + string determine_document_type() const; private: manifest &manifest_; diff --git a/include/xlnt/serialization/relationship_serializer.hpp b/include/xlnt/serialization/relationship_serializer.hpp index a2740fe4..226526a0 100644 --- a/include/xlnt/serialization/relationship_serializer.hpp +++ b/include/xlnt/serialization/relationship_serializer.hpp @@ -1,8 +1,9 @@ #pragma once -#include #include +#include + #include "xlnt_config.hpp" namespace xlnt { @@ -24,12 +25,12 @@ public: /// /// Return a vector of relationships corresponding to target. /// - std::vector read_relationships(const std::string &target); + std::vector read_relationships(const string &target); /// /// Write relationships to archive for the given target. /// - bool write_relationships(const std::vector &relationships, const std::string &target); + bool write_relationships(const std::vector &relationships, const string &target); private: /// diff --git a/include/xlnt/serialization/shared_strings_serializer.hpp b/include/xlnt/serialization/shared_strings_serializer.hpp index cb14142b..e80dd855 100644 --- a/include/xlnt/serialization/shared_strings_serializer.hpp +++ b/include/xlnt/serialization/shared_strings_serializer.hpp @@ -23,9 +23,10 @@ // @author: see AUTHORS file #pragma once -#include #include +#include + #include "xlnt_config.hpp" namespace xlnt { @@ -35,8 +36,8 @@ class xml_document; class XLNT_CLASS shared_strings_serializer { public: - static bool read_shared_strings(const xml_document &xml, std::vector &strings); - static xml_document write_shared_strings(const std::vector &strings); + static bool read_shared_strings(const xml_document &xml, std::vector &strings); + static xml_document write_shared_strings(const std::vector &strings); }; } // namespace xlnt diff --git a/include/xlnt/serialization/style_serializer.hpp b/include/xlnt/serialization/style_serializer.hpp index 8ab5b3dc..79ccb4c0 100644 --- a/include/xlnt/serialization/style_serializer.hpp +++ b/include/xlnt/serialization/style_serializer.hpp @@ -133,7 +133,7 @@ class XLNT_CLASS style_serializer /// /// Read and return a pair containing a name and corresponding style from named_style_node. /// - static std::pair read_named_style(const xml_node &named_style_node); + static std::pair read_named_style(const xml_node &named_style_node); // // Static element writers (i.e. writers that don't use internal state) diff --git a/include/xlnt/serialization/workbook_serializer.hpp b/include/xlnt/serialization/workbook_serializer.hpp index 2e2475f3..ecdfaf19 100644 --- a/include/xlnt/serialization/workbook_serializer.hpp +++ b/include/xlnt/serialization/workbook_serializer.hpp @@ -42,7 +42,7 @@ class xml_node; class XLNT_CLASS workbook_serializer { public: - using string_pair = std::pair; + using string_pair = std::pair; workbook_serializer(workbook &wb); diff --git a/include/xlnt/serialization/xml_document.hpp b/include/xlnt/serialization/xml_document.hpp index 3c9902e6..4b7f3d7f 100644 --- a/include/xlnt/serialization/xml_document.hpp +++ b/include/xlnt/serialization/xml_document.hpp @@ -1,9 +1,10 @@ #pragma once #include -#include #include +#include + #include "xlnt_config.hpp" namespace xlnt { @@ -15,7 +16,7 @@ class xml_serializer; class XLNT_CLASS xml_document { public: - using string_pair = std::pair; + using string_pair = std::pair; xml_document(); xml_document(const xml_document &other); @@ -25,20 +26,20 @@ class XLNT_CLASS xml_document xml_document &operator=(const xml_document &other); xml_document &operator=(xml_document &&other); - void set_encoding(const std::string &encoding); - void add_namespace(const std::string &id, const std::string &uri); + void set_encoding(const string &encoding); + void add_namespace(const string &id, const string &uri); xml_node add_child(const xml_node &child); - xml_node add_child(const std::string &child_name); + xml_node add_child(const string &child_name); xml_node get_root(); const xml_node get_root() const; - xml_node get_child(const std::string &child_name); - const xml_node get_child(const std::string &child_name) const; + xml_node get_child(const string &child_name); + const xml_node get_child(const string &child_name) const; - std::string to_string() const; - xml_document &from_string(const std::string &xml_string); + string to_string() const; + xml_document &from_string(const string &xml_string); private: friend class xml_serializer; diff --git a/include/xlnt/serialization/xml_node.hpp b/include/xlnt/serialization/xml_node.hpp index 09e54115..7a674ab2 100644 --- a/include/xlnt/serialization/xml_node.hpp +++ b/include/xlnt/serialization/xml_node.hpp @@ -1,9 +1,10 @@ #pragma once #include -#include #include +#include + #include "xlnt_config.hpp" namespace xlnt { @@ -14,7 +15,7 @@ class xml_document; class XLNT_CLASS xml_node { public: - using string_pair = std::pair; + using string_pair = std::pair; xml_node(); xml_node(const xml_node &other); @@ -22,26 +23,26 @@ class XLNT_CLASS xml_node xml_node &operator=(const xml_node &other); - std::string get_name() const; - void set_name(const std::string &name); + string get_name() const; + void set_name(const string &name); bool has_text() const; - std::string get_text() const; - void set_text(const std::string &text); + string get_text() const; + void set_text(const string &text); const std::vector get_children() const; - bool has_child(const std::string &child_name) const; - xml_node get_child(const std::string &child_name); - const xml_node get_child(const std::string &child_name) const; + bool has_child(const string &child_name) const; + xml_node get_child(const string &child_name); + const xml_node get_child(const string &child_name) const; xml_node add_child(const xml_node &child); - xml_node add_child(const std::string &child_name); + xml_node add_child(const string &child_name); const std::vector get_attributes() const; - bool has_attribute(const std::string &attribute_name) const; - std::string get_attribute(const std::string &attribute_name) const; - void add_attribute(const std::string &name, const std::string &value); + bool has_attribute(const string &attribute_name) const; + string get_attribute(const string &attribute_name) const; + void add_attribute(const string &name, const string &value); - std::string to_string() const; + string to_string() const; private: friend class xml_document; diff --git a/include/xlnt/serialization/xml_serializer.hpp b/include/xlnt/serialization/xml_serializer.hpp index 80615a57..2bf268e3 100644 --- a/include/xlnt/serialization/xml_serializer.hpp +++ b/include/xlnt/serialization/xml_serializer.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "xlnt_config.hpp" @@ -12,10 +12,10 @@ class xml_node; class XLNT_CLASS xml_serializer { public: - static std::string serialize(const xml_document &xml); - static xml_document deserialize(const std::string &xml_string); + static string serialize(const xml_document &xml); + static xml_document deserialize(const string &xml_string); - static std::string serialize_node(const xml_node &xml); + static string serialize_node(const xml_node &xml); }; } // namespace xlnt diff --git a/include/xlnt/styles/color.hpp b/include/xlnt/styles/color.hpp index 90d6cbdd..a51fb095 100644 --- a/include/xlnt/styles/color.hpp +++ b/include/xlnt/styles/color.hpp @@ -23,9 +23,8 @@ // @author: see AUTHORS file #pragma once -#include - #include +#include #include "xlnt_config.hpp" @@ -61,7 +60,7 @@ class XLNT_CLASS color { } - color(type t, const std::string &v) : type_(t), rgb_string_(v) + color(type t, const string &v) : type_(t), rgb_string_(v) { } @@ -118,7 +117,7 @@ class XLNT_CLASS color return index_; } - std::string get_rgb_string() const + string get_rgb_string() const { if (type_ != type::rgb) { @@ -152,7 +151,7 @@ class XLNT_CLASS color private: type type_ = type::indexed; std::size_t index_ = 0; - std::string rgb_string_; + string rgb_string_; }; } // namespace xlnt diff --git a/include/xlnt/styles/fill.hpp b/include/xlnt/styles/fill.hpp index 8914fbe0..8b614a2d 100644 --- a/include/xlnt/styles/fill.hpp +++ b/include/xlnt/styles/fill.hpp @@ -79,7 +79,7 @@ class XLNT_CLASS fill type_ = t; } - std::string get_pattern_type_string() const + string get_pattern_type_string() const { if (type_ != type::pattern) { @@ -131,7 +131,7 @@ class XLNT_CLASS fill } } - std::string get_gradient_type_string() const + string get_gradient_type_string() const { if (type_ != type::gradient) { diff --git a/include/xlnt/styles/font.hpp b/include/xlnt/styles/font.hpp index f6dbd483..cfb20edc 100644 --- a/include/xlnt/styles/font.hpp +++ b/include/xlnt/styles/font.hpp @@ -101,11 +101,11 @@ class XLNT_CLASS font return size_; } - void set_name(const std::string &name) + void set_name(const string &name) { name_ = name; } - std::string get_name() const + string get_name() const { return name_; } @@ -121,7 +121,7 @@ class XLNT_CLASS font family_ = family; } - void set_scheme(const std::string &scheme) + void set_scheme(const string &scheme) { has_scheme_ = true; scheme_ = scheme; @@ -174,7 +174,7 @@ class XLNT_CLASS font private: friend class style; - std::string name_ = "Calibri"; + string name_ = "Calibri"; std::size_t size_ = 11; bool bold_ = false; bool italic_ = false; @@ -186,7 +186,7 @@ class XLNT_CLASS font bool has_family_ = false; std::size_t family_; bool has_scheme_ = false; - std::string scheme_; + string scheme_; }; } // namespace xlnt diff --git a/include/xlnt/styles/named_style.hpp b/include/xlnt/styles/named_style.hpp index c108b67c..126e642c 100644 --- a/include/xlnt/styles/named_style.hpp +++ b/include/xlnt/styles/named_style.hpp @@ -42,7 +42,7 @@ class XLNT_CLASS named_style } private: - std::string name_; + string name_; style style_; }; diff --git a/include/xlnt/styles/number_format.hpp b/include/xlnt/styles/number_format.hpp index 8c8ea3cd..ffe1ceb3 100644 --- a/include/xlnt/styles/number_format.hpp +++ b/include/xlnt/styles/number_format.hpp @@ -23,10 +23,11 @@ // @author: see AUTHORS file #pragma once -#include #include #include +#include + #include "xlnt_config.hpp" namespace xlnt { @@ -73,13 +74,13 @@ class XLNT_CLASS number_format number_format(); number_format(std::size_t builtin_id); - number_format(const std::string &code); - number_format(const std::string &code, std::size_t custom_id); + number_format(const string &code); + number_format(const string &code, std::size_t custom_id); - void set_format_string(const std::string &format_code); - void set_format_string(const std::string &format_code, std::size_t custom_id); + void set_format_string(const string &format_code); + void set_format_string(const string &format_code, std::size_t custom_id); - std::string get_format_string() const; + string get_format_string() const; bool has_id() const { @@ -112,7 +113,7 @@ class XLNT_CLASS number_format private: bool id_set_; std::size_t id_; - std::string format_string_; + string format_string_; }; } // namespace xlnt diff --git a/include/xlnt/utils/datetime.hpp b/include/xlnt/utils/datetime.hpp index cb090fb1..9aa38804 100644 --- a/include/xlnt/utils/datetime.hpp +++ b/include/xlnt/utils/datetime.hpp @@ -22,7 +22,7 @@ // @author: see AUTHORS file #pragma once -#include +#include #include "xlnt_config.hpp" @@ -98,7 +98,8 @@ struct XLNT_CLASS time : hour(hour_), minute(minute_), second(second_), microsecond(microsecond_) { } - explicit time(const std::string &time_string); + + explicit time(const string &time_string); long double to_number() const; bool operator==(const time &comparand) const; @@ -143,7 +144,7 @@ struct XLNT_CLASS datetime { } - std::string to_string(calendar base_date) const; + string to_string(calendar base_date) const; long double to_number(calendar base_date) const; bool operator==(const datetime &comparand) const; diff --git a/include/xlnt/utils/exceptions.hpp b/include/xlnt/utils/exceptions.hpp index 6166291d..285da1f4 100644 --- a/include/xlnt/utils/exceptions.hpp +++ b/include/xlnt/utils/exceptions.hpp @@ -34,18 +34,18 @@ namespace xlnt { /// /// Error for converting between numeric and A1-style cell references. /// -class XLNT_CLASS cell_coordinates_exception : public std::runtime_error +class XLNT_CLASS cell_coordinates_exception { public: cell_coordinates_exception(column_t column, row_t row); - cell_coordinates_exception(const std::string &coord_string); + cell_coordinates_exception(const string &coord_string); }; /// /// The data submitted which cannot be used directly in Excel files. It /// must be removed or escaped. /// -class XLNT_CLASS illegal_character_error : public std::runtime_error +class XLNT_CLASS illegal_character_error { public: illegal_character_error(char c); @@ -54,7 +54,7 @@ class XLNT_CLASS illegal_character_error : public std::runtime_error /// /// Error for bad column names in A1-style cell references. /// -class XLNT_CLASS column_string_index_exception : public std::runtime_error +class XLNT_CLASS column_string_index_exception { public: column_string_index_exception(); @@ -63,7 +63,7 @@ class XLNT_CLASS column_string_index_exception : public std::runtime_error /// /// Error for any data type inconsistencies. /// -class XLNT_CLASS data_type_exception : public std::runtime_error +class XLNT_CLASS data_type_exception { public: data_type_exception(); @@ -72,7 +72,7 @@ class XLNT_CLASS data_type_exception : public std::runtime_error /// /// Error for badly formatted named ranges. /// -class XLNT_CLASS named_range_exception : public std::runtime_error +class XLNT_CLASS named_range_exception { public: named_range_exception(); @@ -81,25 +81,25 @@ class XLNT_CLASS named_range_exception : public std::runtime_error /// /// Error for bad sheet names. /// -class XLNT_CLASS sheet_title_exception : public std::runtime_error +class XLNT_CLASS sheet_title_exception { public: - sheet_title_exception(const std::string &title); + sheet_title_exception(const string &title); }; /// /// Error for trying to open a non-ooxml file. /// -class XLNT_CLASS invalid_file_exception : public std::runtime_error +class XLNT_CLASS invalid_file_exception { public: - invalid_file_exception(const std::string &filename); + invalid_file_exception(const string &filename); }; /// /// Error for trying to modify a read-only workbook. /// -class XLNT_CLASS read_only_workbook_exception : public std::runtime_error +class XLNT_CLASS read_only_workbook_exception { public: read_only_workbook_exception(); @@ -108,7 +108,7 @@ class XLNT_CLASS read_only_workbook_exception : public std::runtime_error /// /// Error when a references number format is not in the stylesheet. /// -class XLNT_CLASS missing_number_format : public std::runtime_error +class XLNT_CLASS missing_number_format { public: missing_number_format(); @@ -117,16 +117,16 @@ class XLNT_CLASS missing_number_format : public std::runtime_error /// /// Error when an attribute value is invalid. /// -class XLNT_CLASS attribute_error : public std::runtime_error +class XLNT_CLASS attribute_error { public: attribute_error(); }; -class XLNT_CLASS value_error : public std::runtime_error +class XLNT_CLASS value_error { public: - value_error() : std::runtime_error("") + value_error() { } }; diff --git a/include/xlnt/utils/string.hpp b/include/xlnt/utils/string.hpp new file mode 100644 index 00000000..210c00e5 --- /dev/null +++ b/include/xlnt/utils/string.hpp @@ -0,0 +1,323 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "xlnt_config.hpp" + +namespace xlnt { + +class XLNT_CLASS string +{ +public: + using value_type = std::uint32_t; + using reference = value_type &; + using const_reference = value_type &; + using pointer = value_type *; + using const_pointer = const pointer; + using byte = char; + using byte_pointer = byte *; + using const_byte_pointer = const byte *; + using difference_type = std::ptrdiff_t; + using size_type = std::size_t; + + using utf_mb_narrow_char = char; + using utf_mb_narrow_string = utf_mb_narrow_char[]; + using utf_mb_wide_char = wchar_t; + using utf_mb_wide_string = utf_mb_wide_char[]; + using utf8_char = char; + using utf8_string = utf8_char[]; + using utf16_char = char16_t; + using utf16_string = utf16_char[]; + using utf32_char = char32_t; + using utf32_string = utf32_char[]; + + class code_point + { + public: + code_point(byte_pointer data, size_type index, size_type end) + : data_(data), + index_(index), + end_(end) + { + } + + code_point(const_byte_pointer data, size_type index, size_type end) + : data_(const_cast(data)), + index_(index), + end_(end) + { + } + + code_point &operator=(utf32_char value); + + code_point &operator=(const code_point &value) + { + return *this = value.get(); + } + + bool operator==(char rhs) const; + bool operator!=(char rhs) const; + bool operator<(char rhs) const; + bool operator<=(char rhs) const; + bool operator>(char rhs) const; + bool operator>=(char rhs) const; + + utf32_char get() const; + + byte_pointer data_; + size_type index_; + size_type end_; + }; + + template + class common_iterator : public std::iterator + { + public: + common_iterator(byte_pointer data, size_type index, size_type length) + : current_(data, index, length) + { + } + + common_iterator(const_byte_pointer data, size_type index, size_type length) + : current_(data, index, length) + { + } + + common_iterator(const common_iterator &other) + : current_(other.current_) + { + } + + common_iterator(const common_iterator &other) + : current_(other.current_) + { + } + + code_point &operator*() + { + return current_; + } + + bool operator==(const common_iterator &other) const + { + return current_.data_ == other.current_.data_ && current_.index_ == other.current_.index_; + } + + bool operator!=(const common_iterator &other) const + { + return !(*this == other); + } + + difference_type operator-(const common_iterator &other) const + { + return current_.index_ - other.current_.index_; + } + + common_iterator operator+(size_type offset) + { + common_iterator copy = *this; + size_type end = std::max(0, std::min(current_.end_, current_.index_ + offset)); + + while (copy.current_.index_ != end) + { + end < copy.current_.index_ ? --copy : ++copy; + } + + return copy; + } + + common_iterator &operator--(); + + common_iterator operator--(int) + { + iterator old = *this; + --*this; + + return old; + } + + common_iterator &operator++(); + + common_iterator operator++(int) + { + common_iterator old = *this; + ++*this; + + return old; + } + + friend class common_iterator; + + private: + code_point current_; + }; + + using iterator = common_iterator; + using const_iterator = common_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static const size_type npos = -1; + + static string from(std::int8_t i); + static string from(std::int16_t i); + static string from(std::int32_t i); + static string from(std::int64_t i); + static string from(std::uint8_t i); + static string from(std::uint16_t i); + static string from(std::uint32_t i); + static string from(std::uint64_t i); + static string from(float i); + static string from(double i); + static string from(long double i); + + string(); + string(string &&str); + string(const string &str); + string(const string &str, size_type offset); + string(const string &str, size_type offset, size_type len); + + string(const utf_mb_wide_string str); + string(const utf8_string str); + string(const utf16_string str); + string(const utf32_string str); + + template + string(InputIterator first, InputIterator last) : string() + { + while (first != last) + { + append(*first); + ++first; + } + } + + ~string(); + + size_type length() const { return length_; } + size_type bytes() const; + + bool empty() const { return length() == 0; } + + string to_upper() const; + string to_lower() const; + + string substr(size_type offset) const; + string substr(size_type offset, size_type len) const; + + code_point back(); + const code_point back() const; + code_point front(); + const code_point front() const; + + size_type find(code_point c) const; + size_type find(char c) const; + size_type find(string str) const; + + size_type find(code_point c, size_type offset) const; + size_type find(char c, size_type offset) const; + size_type find(string str, size_type offset) const; + + size_type find_last_of(code_point c) const; + size_type find_last_of(char c) const; + size_type find_last_of(string str) const; + + size_type find_last_of(code_point c, size_type offset) const; + size_type find_last_of(char c, size_type offset) const; + size_type find_last_of(string str, size_type offset) const; + + size_type find_first_of(string str) const; + size_type find_first_of(string str, size_type offset) const; + + size_type find_first_not_of(string str) const; + size_type find_first_not_of(string str, size_type offset) const; + + size_type find_last_not_of(string str) const; + size_type find_last_not_of(string str, size_type offset) const; + + void clear(); + + template + T to() const; + + int to_hex() const; + + void remove(code_point iter); + + iterator begin(); + const_iterator begin() const { return cbegin(); } + const_iterator cbegin() const; + iterator end(); + const_iterator end() const { return cend(); } + const_iterator cend() const; + + byte_pointer data(); + const_byte_pointer data() const; + + std::size_t hash() const; + + string &operator=(string rhs); + + void append(char c); + void append(wchar_t c); + void append(char16_t c); + void append(char32_t c); + void append(string str); + void append(code_point c); + + code_point at(size_type index); + const code_point at(size_type index) const; + + bool operator==(const_byte_pointer str) const; + bool operator!=(const_byte_pointer str) const { return !(*this == str); } + + bool operator==(const string &str) const; + bool operator!=(const string &str) const { return !(*this == str); } + + code_point operator[](size_type index); + const code_point operator[](size_type index) const; + + string operator+(const string &rhs) const; + string &operator+=(const string &rhs); + + bool operator<(const string &other) const; + + friend void swap(string &left, string &right); + friend std::ostream &operator<<(std::ostream &left, string &right); + friend string operator+(const char *left, const string &right); + +private: + explicit string(size_type initial_size); + + size_type length_; + std::vector *data_; +}; + +} // namespace xlnt + +namespace std { + +template<> +struct hash +{ + std::size_t operator()(const xlnt::string &str) const + { + return str.hash(); + } +}; + +template<> +struct less +{ + std::size_t operator()(const xlnt::string &left, const xlnt::string &right) const + { + return left < right; + } +}; + +} // namespace std diff --git a/include/xlnt/workbook/document_security.hpp b/include/xlnt/workbook/document_security.hpp index c668367c..1e9386b0 100644 --- a/include/xlnt/workbook/document_security.hpp +++ b/include/xlnt/workbook/document_security.hpp @@ -40,8 +40,8 @@ class XLNT_CLASS document_security bool lock_revision; bool lock_structure; bool lock_windows; - std::string revision_password; - std::string workbook_password; + string revision_password; + string workbook_password; }; } // namespace xlnt diff --git a/include/xlnt/workbook/named_range.hpp b/include/xlnt/workbook/named_range.hpp index 18e8d067..8a908c7e 100644 --- a/include/xlnt/workbook/named_range.hpp +++ b/include/xlnt/workbook/named_range.hpp @@ -10,7 +10,7 @@ namespace xlnt { class range_reference; class worksheet; -std::vector> XLNT_FUNCTION split_named_range(const std::string &named_range_string); +std::vector> XLNT_FUNCTION split_named_range(const string &named_range_string); class XLNT_CLASS named_range { @@ -19,9 +19,9 @@ class XLNT_CLASS named_range named_range(); named_range(const named_range &other); - named_range(const std::string &name, const std::vector &targets); + named_range(const string &name, const std::vector &targets); - std::string get_name() const + string get_name() const { return name_; } @@ -33,7 +33,7 @@ class XLNT_CLASS named_range named_range &operator=(const named_range &other); private: - std::string name_; + string name_; std::vector targets_; }; } diff --git a/include/xlnt/workbook/workbook.hpp b/include/xlnt/workbook/workbook.hpp index f636604b..967b1149 100644 --- a/include/xlnt/workbook/workbook.hpp +++ b/include/xlnt/workbook/workbook.hpp @@ -105,7 +105,7 @@ class XLNT_CLASS workbook std::size_t index_; }; - static std::size_t index_from_ws_filename(const std::string &filename); + static std::size_t index_from_ws_filename(const string &filename); // constructors workbook(); @@ -128,9 +128,9 @@ class XLNT_CLASS workbook // create worksheet create_sheet(); worksheet create_sheet(std::size_t index); - worksheet create_sheet(const std::string &title); - worksheet create_sheet(std::size_t index, const std::string &title); - worksheet create_sheet(const std::string &title, const relationship &rel); + worksheet create_sheet(const string &title); + worksheet create_sheet(std::size_t index, const string &title); + worksheet create_sheet(const string &title, const relationship &rel); // add void add_sheet(worksheet worksheet); @@ -141,14 +141,14 @@ class XLNT_CLASS workbook void clear(); // container operations - worksheet get_sheet_by_name(const std::string &sheet_name); - const worksheet get_sheet_by_name(const std::string &sheet_name) const; + worksheet get_sheet_by_name(const string &sheet_name); + const worksheet get_sheet_by_name(const string &sheet_name) const; worksheet get_sheet_by_index(std::size_t index); const worksheet get_sheet_by_index(std::size_t index) const; - bool contains(const std::string &key) const; + bool contains(const string &key) const; int get_index(worksheet worksheet); - worksheet operator[](const std::string &name); + worksheet operator[](const string &name); worksheet operator[](std::size_t index); iterator begin(); @@ -166,23 +166,23 @@ class XLNT_CLASS workbook const_iterator cbegin() const; const_iterator cend() const; - std::vector get_sheet_names() const; + std::vector get_sheet_names() const; document_properties &get_properties(); const document_properties &get_properties() const; // named ranges std::vector get_named_ranges() const; - void create_named_range(const std::string &name, worksheet worksheet, const range_reference &reference); - bool has_named_range(const std::string &name) const; - range get_named_range(const std::string &name); - void remove_named_range(const std::string &name); + void create_named_range(const string &name, worksheet worksheet, const range_reference &reference); + bool has_named_range(const string &name) const; + range get_named_range(const string &name); + void remove_named_range(const string &name); // serialization bool save(std::vector &data); - bool save(const std::string &filename); + bool save(const string &filename); bool load(const std::vector &data); - bool load(const std::string &filename); + bool load(const string &filename); bool load(std::istream &stream); bool load(zip_file &archive); @@ -200,8 +200,8 @@ class XLNT_CLASS workbook return !(*this == std::nullptr_t{}); } - void create_relationship(const std::string &id, const std::string &target, relationship::type type); - relationship get_relationship(const std::string &id) const; + void create_relationship(const string &id, const string &target, relationship::type type); + relationship get_relationship(const string &id) const; const std::vector &get_relationships() const; void add_alignment(const alignment &a); @@ -238,7 +238,7 @@ class XLNT_CLASS workbook bool get_pivot_button(std::size_t style_id) const; bool get_quote_prefix(std::size_t style_id) const; - void set_code_name(const std::string &code_name); + void set_code_name(const string &code_name); bool has_loaded_theme() const; const theme &get_loaded_theme() const; @@ -251,9 +251,9 @@ class XLNT_CLASS workbook const std::vector &get_root_relationships() const; - void add_shared_string(const std::string &shared); - std::vector &get_shared_strings(); - const std::vector &get_shared_strings() const; + void add_shared_string(const string &shared); + std::vector &get_shared_strings(); + const std::vector &get_shared_strings() const; private: friend class worksheet; diff --git a/include/xlnt/worksheet/range_reference.hpp b/include/xlnt/worksheet/range_reference.hpp index 0c0acd4b..a38d21cf 100644 --- a/include/xlnt/worksheet/range_reference.hpp +++ b/include/xlnt/worksheet/range_reference.hpp @@ -37,7 +37,7 @@ class XLNT_CLASS range_reference static range_reference make_absolute(const range_reference &relative_reference); range_reference(); - range_reference(const std::string &range_string); + range_reference(const string &range_string); range_reference(const char *range_string); range_reference(const std::pair &reference_pair); range_reference(const cell_reference &start, const cell_reference &end); @@ -68,25 +68,25 @@ class XLNT_CLASS range_reference range_reference make_offset(int column_offset, int row_offset) const; - std::string to_string() const; + string to_string() const; bool operator==(const range_reference &comparand) const; - bool operator==(const std::string &reference_string) const + bool operator==(const string &reference_string) const { return *this == range_reference(reference_string); } bool operator==(const char *reference_string) const { - return *this == std::string(reference_string); + return *this == string(reference_string); } bool operator!=(const range_reference &comparand) const; - bool operator!=(const std::string &reference_string) const + bool operator!=(const string &reference_string) const { return *this != range_reference(reference_string); } bool operator!=(const char *reference_string) const { - return *this != std::string(reference_string); + return *this != string(reference_string); } private: @@ -94,7 +94,7 @@ class XLNT_CLASS range_reference cell_reference bottom_right_; }; -inline bool XLNT_FUNCTION operator==(const std::string &reference_string, const range_reference &ref) +inline bool XLNT_FUNCTION operator==(const string &reference_string, const range_reference &ref) { return ref == reference_string; } @@ -104,7 +104,7 @@ inline bool XLNT_FUNCTION operator==(const char *reference_string, const range_r return ref == reference_string; } -inline bool XLNT_FUNCTION operator!=(const std::string &reference_string, const range_reference &ref) +inline bool XLNT_FUNCTION operator!=(const string &reference_string, const range_reference &ref) { return ref != reference_string; } diff --git a/include/xlnt/worksheet/sheet_protection.hpp b/include/xlnt/worksheet/sheet_protection.hpp index 3ea0b073..7a2a4166 100644 --- a/include/xlnt/worksheet/sheet_protection.hpp +++ b/include/xlnt/worksheet/sheet_protection.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "xlnt_config.hpp" @@ -9,16 +9,16 @@ namespace xlnt { class XLNT_CLASS sheet_protection { public: - static std::string hash_password(const std::string &password); + static string hash_password(const string &password); - void set_password(const std::string &password); - std::string get_hashed_password() const + void set_password(const string &password); + string get_hashed_password() const { return hashed_password_; } private: - std::string hashed_password_; + string hashed_password_; }; } // namespace xlnt diff --git a/include/xlnt/worksheet/worksheet.hpp b/include/xlnt/worksheet/worksheet.hpp index d7ab7556..9f45ba2d 100644 --- a/include/xlnt/worksheet/worksheet.hpp +++ b/include/xlnt/worksheet/worksheet.hpp @@ -58,12 +58,12 @@ class XLNT_CLASS header { public: header(); - void set_text(const std::string &text) + void set_text(const string &text) { default_ = false; text_ = text; } - void set_font_name(const std::string &font_name) + void set_font_name(const string &font_name) { default_ = false; font_name_ = font_name; @@ -73,7 +73,7 @@ class XLNT_CLASS header default_ = false; font_size_ = font_size; } - void set_font_color(const std::string &font_color) + void set_font_color(const string &font_color) { default_ = false; font_color_ = font_color; @@ -85,10 +85,10 @@ class XLNT_CLASS header private: bool default_; - std::string text_; - std::string font_name_; + string text_; + string font_name_; std::size_t font_size_; - std::string font_color_; + string font_color_; }; /// @@ -98,12 +98,12 @@ class XLNT_CLASS footer { public: footer(); - void set_text(const std::string &text) + void set_text(const string &text) { default_ = false; text_ = text; } - void set_font_name(const std::string &font_name) + void set_font_name(const string &font_name) { default_ = false; font_name_ = font_name; @@ -113,7 +113,7 @@ class XLNT_CLASS footer default_ = false; font_size_ = font_size; } - void set_font_color(const std::string &font_color) + void set_font_color(const string &font_color) { default_ = false; font_color_ = font_color; @@ -125,10 +125,10 @@ class XLNT_CLASS footer private: bool default_; - std::string text_; - std::string font_name_; + string text_; + string font_name_; std::size_t font_size_; - std::string font_color_; + string font_color_; }; /// @@ -269,21 +269,21 @@ class XLNT_CLASS worksheet public: worksheet(); worksheet(const worksheet &rhs); - worksheet(workbook &parent_workbook, const std::string &title = std::string()); + worksheet(workbook &parent_workbook, const string &title = string()); - std::string to_string() const; + string to_string() const; workbook &get_parent() const; void garbage_collect(); // title - std::string get_title() const; - void set_title(const std::string &title); - std::string make_unique_sheet_name(const std::string &value); + string get_title() const; + void set_title(const string &title); + string make_unique_sheet_name(const string &value); // freeze panes cell_reference get_frozen_panes() const; void freeze_panes(cell top_left_cell); - void freeze_panes(const std::string &top_left_coordinate); + void freeze_panes(const string &top_left_coordinate); void unfreeze_panes(); bool has_frozen_panes() const; @@ -295,9 +295,9 @@ class XLNT_CLASS worksheet range get_squared_range(column_t min_col, row_t min_row, column_t max_col, row_t max_row); const range get_squared_range(column_t min_col, row_t min_row, column_t max_col, row_t max_row) const; range rows() const; - range rows(const std::string &range_string) const; + range rows(const string &range_string) const; range rows(int row_offset, int column_offset) const; - range rows(const std::string &range_string, int row_offset, int column_offset) const; + range rows(const string &range_string, int row_offset, int column_offset) const; range columns() const; std::list get_cell_collection(); @@ -316,13 +316,13 @@ class XLNT_CLASS worksheet cell_reference get_point_pos(int left, int top) const; cell_reference get_point_pos(const std::pair &point) const; - std::string unique_sheet_name(const std::string &value) const; + string unique_sheet_name(const string &value) const; // named range - void create_named_range(const std::string &name, const range_reference &reference); - bool has_named_range(const std::string &name); - range get_named_range(const std::string &name); - void remove_named_range(const std::string &name); + void create_named_range(const string &name, const range_reference &reference); + bool has_named_range(const string &name); + range get_named_range(const string &name); + void remove_named_range(const string &name); // extents row_t get_lowest_row() const; @@ -333,7 +333,7 @@ class XLNT_CLASS worksheet range_reference calculate_dimension() const; // relationships - relationship create_relationship(relationship::type type, const std::string &target_uri); + relationship create_relationship(relationship::type type, const string &target_uri); const std::vector &get_relationships() const; // charts @@ -348,12 +348,12 @@ class XLNT_CLASS worksheet // append void append(); - void append(const std::vector &cells); + void append(const std::vector &cells); void append(const std::vector &cells); void append(const std::vector &cells); void append(const std::vector &cells); - void append(const std::unordered_map &cells); - void append(const std::unordered_map &cells); + void append(const std::unordered_map &cells); + void append(const std::unordered_map &cells); void append(const std::vector::const_iterator begin, const std::vector::const_iterator end); @@ -367,8 +367,8 @@ class XLNT_CLASS worksheet const cell operator[](const cell_reference &reference) const; range operator[](const range_reference &reference); const range operator[](const range_reference &reference) const; - range operator[](const std::string &range_string); - const range operator[](const std::string &range_string) const; + range operator[](const string &range_string); + const range operator[](const string &range_string) const; range operator()(const cell_reference &top_left, const cell_reference &bottom_right); const range operator()(const cell_reference &top_left, const cell_reference &bottom_right) const; @@ -397,7 +397,7 @@ class XLNT_CLASS worksheet void set_parent(workbook &wb); - std::vector get_formula_attributes() const; + std::vector get_formula_attributes() const; void set_sheet_state(page_setup::sheet_state state); diff --git a/include/xlnt/xlnt_config.hpp b/include/xlnt/xlnt_config.hpp index ee53f807..0d1856a8 100644 --- a/include/xlnt/xlnt_config.hpp +++ b/include/xlnt/xlnt_config.hpp @@ -22,6 +22,8 @@ // @author: see AUTHORS file #pragma once +#include + // Change these values for programs using this library. namespace xlnt { @@ -55,9 +57,9 @@ enum class limit_style const limit_style LimitStyle = limit_style::openpyxl; // If no API is defined, assume default -#ifndef XLNT_API #ifdef _MSC_VER -#ifdef _DLL +#if !defined(XLNT_API) && defined(SHARED) +#ifdef XLNT_EXPORT #define XLNT_API __declspec(dllexport) #else #define XLNT_API __declspec(dllimport) diff --git a/source/cell/cell.cpp b/source/cell/cell.cpp index 72430c0d..47fa702e 100644 --- a/source/cell/cell.cpp +++ b/source/cell/cell.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -33,14 +34,14 @@ enum class condition_type struct section { bool has_value = false; - std::string value; + xlnt::string value; bool has_color = false; - std::string color; + xlnt::string color; bool has_condition = false; condition_type condition = condition_type::invalid; - std::string condition_value; + xlnt::string condition_value; bool has_locale = false; - std::string locale; + xlnt::string locale; section &operator=(const section &other) { @@ -73,13 +74,13 @@ struct format_sections /// /// This should maybe be in a utility header so it can be used elsewhere. /// -std::vector split_string(const std::string &string, char delim) +std::vector split_string(const xlnt::string &string, char delim) { - std::vector split; - std::string::size_type previous_index = 0; + std::vector split; + xlnt::string::size_type previous_index = 0; auto separator_index = string.find(delim); - while (separator_index != std::string::npos) + while (separator_index != xlnt::string::npos) { auto part = string.substr(previous_index, separator_index - previous_index); split.push_back(part); @@ -93,13 +94,13 @@ std::vector split_string(const std::string &string, char delim) return split; } -std::vector split_string_any(const std::string &string, const std::string &delims) +std::vector split_string_any(const xlnt::string &string, const xlnt::string &delims) { - std::vector split; - std::string::size_type previous_index = 0; + std::vector split; + xlnt::string::size_type previous_index = 0; auto separator_index = string.find_first_of(delims); - while (separator_index != std::string::npos) + while (separator_index != xlnt::string::npos) { auto part = string.substr(previous_index, separator_index - previous_index); @@ -117,16 +118,16 @@ std::vector split_string_any(const std::string &string, const std:: return split; } -bool is_date_format(const std::string &format_string) +bool is_date_format(const xlnt::string &format_string) { auto not_in = format_string.find_first_not_of("/-:, mMyYdDhHsS"); - return not_in == std::string::npos; + return not_in == xlnt::string::npos; } -bool is_valid_color(const std::string &color) +bool is_valid_color(const xlnt::string &color) { - static const std::vector *colors = - new std::vector( + static const std::vector *colors = + new std::vector( { "Black", "Green" @@ -138,12 +139,12 @@ bool is_valid_color(const std::string &color) "Red" }); - auto compare_color = [&](const std::string &other) { - if (color.size() != other.size()) return false; + auto compare_color = [&](const xlnt::string &other) { + if (color.length() != other.length()) return false; - for (std::size_t i = 0; i < color.size(); i++) + for (std::size_t i = 0; i < color.length(); i++) { - if (std::toupper(color[i]) != std::toupper(other[i])) + if (std::toupper(color[i].get()) != std::toupper(other[i].get())) { return false; } @@ -155,7 +156,7 @@ bool is_valid_color(const std::string &color) return std::find_if(colors->begin(), colors->end(), compare_color) != colors->end(); } -bool parse_condition(const std::string &string, section &s) +bool parse_condition(const xlnt::string &string, section &s) { s.has_condition = false; s.condition = condition_type::invalid; @@ -208,10 +209,10 @@ bool is_hex(char c) return false; } -const std::unordered_map known_locales() +const std::unordered_map known_locales() { - const std::unordered_map *all = - new std::unordered_map( + const std::unordered_map *all = + new std::unordered_map( { { 0x401, "Arabic - Saudi Arabia" }, { 0x402, "Bulgarian" }, @@ -323,9 +324,9 @@ const std::unordered_map known_locales() return *all; } -bool is_valid_locale(const std::string &locale_string) +bool is_valid_locale(const xlnt::string &locale_string) { - std::string country = locale_string.substr(locale_string.find('-') + 1); + auto country = locale_string.substr(locale_string.find('-') + 1); if (country.empty()) { @@ -334,13 +335,13 @@ bool is_valid_locale(const std::string &locale_string) for (auto c : country) { - if (!is_hex(static_cast(std::toupper(c)))) + if (!is_hex(static_cast(std::toupper(c.get())))) { return false; } } - auto index = std::stoi(country, 0, 16); + auto index = country.to_hex(); auto known_locales_ = known_locales(); @@ -349,14 +350,14 @@ bool is_valid_locale(const std::string &locale_string) return false; } - std::string beginning = locale_string.substr(0, locale_string.find('-')); + auto beginning = locale_string.substr(0, locale_string.find('-')); if (beginning.empty() || beginning[0] != '$') { return false; } - if (beginning.size() == 1) + if (beginning.length() == 1) { return true; } @@ -366,32 +367,32 @@ bool is_valid_locale(const std::string &locale_string) return true; } -section parse_section(const std::string §ion_string) +section parse_section(const xlnt::string §ion_string) { section s; - std::string format_part; - std::string bracket_part; + xlnt::string format_part; + xlnt::string bracket_part; - std::vector bracket_parts; + std::vector bracket_parts; bool in_quotes = false; bool in_brackets = false; - const std::vector bracket_times = { "h", "hh", "m", "mm", "s", "ss" }; + const std::vector bracket_times = { "h", "hh", "m", "mm", "s", "ss" }; - for (std::size_t i = 0; i < section_string.size(); i++) + for (std::size_t i = 0; i < section_string.length(); i++) { if (!in_quotes && section_string[i] == '"') { - format_part.push_back(section_string[i]); + format_part.append(section_string[i]); in_quotes = true; } else if (in_quotes && section_string[i] == '"') { - format_part.push_back(section_string[i]); + format_part.append(section_string[i]); - if (i < section_string.size() - 1 && section_string[i + 1] != '"') + if (i < section_string.length() - 1 && section_string[i + 1] != '"') { in_quotes = false; } @@ -402,8 +403,8 @@ section parse_section(const std::string §ion_string) for (auto bracket_time : bracket_times) { - if (i < section_string.size() - bracket_time.size() && - section_string.substr(i + 1, bracket_time.size()) == bracket_time) + if (i < section_string.length() - bracket_time.length() && + section_string.substr(i + 1, bracket_time.length()) == bracket_time) { in_brackets = false; break; @@ -449,12 +450,12 @@ section parse_section(const std::string §ion_string) } else { - bracket_part.push_back(section_string[i]); + bracket_part.append(section_string[i]); } } else { - format_part.push_back(section_string[i]); + format_part.append(section_string[i]); } } @@ -464,7 +465,7 @@ section parse_section(const std::string §ion_string) return s; } -format_sections parse_format_sections(const std::string &combined) +format_sections parse_format_sections(const xlnt::string &combined) { format_sections result = {}; @@ -521,40 +522,32 @@ format_sections parse_format_sections(const std::string &combined) return result; } -std::string format_section(long double number, const section &format, xlnt::calendar base_date) +xlnt::string format_section(long double number, const section &format, xlnt::calendar base_date) { - const std::string unquoted = "$+(:^'{<=-/)!&~}> "; - std::string format_temp = format.value; - std::string result; + const xlnt::string unquoted = "$+(:^'{<=-/)!&~}> "; + xlnt::string format_temp = format.value; + xlnt::string result; if (is_date_format(format.value)) { - const std::string date_unquoted = ",-/: "; + const xlnt::string date_unquoted = ",-/: "; - const std::vector dates = { "m", "mm", "mmm", "mmmmm", "mmmmmm", "d", "dd", "ddd", "dddd", "yy", + const std::vector dates = { "m", "mm", "mmm", "mmmmm", "mmmmmm", "d", "dd", "ddd", "dddd", "yy", "yyyy", "h", "[h]", "hh", "m", "[m]", "mm", "s", "[s]", "ss", "AM/PM", "am/pm", "A/P", "a/p" }; - const std::vector MonthNames = { "January", "February", "March", + const std::vector MonthNames = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; auto split = split_string_any(format.value, date_unquoted); - std::string::size_type index = 0, prev = 0; + xlnt::string::size_type index = 0, prev = 0; auto d = xlnt::datetime::from_number(number, base_date); bool processed_month = false; - auto lower_string = [](const std::string &s) { - std::string lower; - lower.resize(s.size()); - for (std::size_t i = 0; i < s.size(); i++) - lower[i] = static_cast(std::tolower(s[i])); - return lower; - }; - for (auto part : split) { - while (format.value.substr(index, part.size()) != part) + while (format.value.substr(index, part.length()) != part) { index++; } @@ -562,11 +555,11 @@ std::string format_section(long double number, const section &format, xlnt::cale auto between = format.value.substr(prev, index - prev); result.append(between); - part = lower_string(part); + part = part.to_lower(); if (part == "m" && !processed_month) { - result.append(std::to_string(d.month)); + result.append(xlnt::string::from(d.month)); processed_month = true; } else if (part == "mm" && !processed_month) @@ -576,7 +569,7 @@ std::string format_section(long double number, const section &format, xlnt::cale result.append("0"); } - result.append(std::to_string(d.month)); + result.append(xlnt::string::from(d.month)); processed_month = true; } else if (part == "mmm" && !processed_month) @@ -591,7 +584,7 @@ std::string format_section(long double number, const section &format, xlnt::cale } else if (part == "d") { - result.append(std::to_string(d.day)); + result.append(xlnt::string::from(d.day)); } else if (part == "dd") { @@ -600,16 +593,16 @@ std::string format_section(long double number, const section &format, xlnt::cale result.append("0"); } - result.append(std::to_string(d.day)); + result.append(xlnt::string::from(d.day)); } else if (part == "yyyy") { - result.append(std::to_string(d.year)); + result.append(xlnt::string::from(d.year)); } else if (part == "h") { - result.append(std::to_string(d.hour)); + result.append(xlnt::string::from(d.hour)); processed_month = true; } else if (part == "hh") @@ -619,12 +612,12 @@ std::string format_section(long double number, const section &format, xlnt::cale result.append("0"); } - result.append(std::to_string(d.hour)); + result.append(xlnt::string::from(d.hour)); processed_month = true; } else if (part == "m") { - result.append(std::to_string(d.minute)); + result.append(xlnt::string::from(d.minute)); } else if (part == "mm") { @@ -633,11 +626,11 @@ std::string format_section(long double number, const section &format, xlnt::cale result.append("0"); } - result.append(std::to_string(d.minute)); + result.append(xlnt::string::from(d.minute)); } else if (part == "s") { - result.append(std::to_string(d.second)); + result.append(xlnt::string::from(d.second)); } else if (part == "ss") { @@ -646,7 +639,7 @@ std::string format_section(long double number, const section &format, xlnt::cale result.append("0"); } - result.append(std::to_string(d.second)); + result.append(xlnt::string::from(d.second)); } else if (part == "am/pm" || part == "a/p") { @@ -660,11 +653,11 @@ std::string format_section(long double number, const section &format, xlnt::cale } } - index += part.size(); + index += part.length(); prev = index; } - if (index < format.value.size()) + if (index < format.value.length()) { result.append(format.value.substr(index)); } @@ -673,11 +666,11 @@ std::string format_section(long double number, const section &format, xlnt::cale { if (number == static_cast(number)) { - result = std::to_string(static_cast(number)); + result = xlnt::string::from(static_cast(number)); } else { - result = std::to_string(number); + result = xlnt::string::from(number); } } else if (format.value.substr(0, 8) == "#,##0.00" || format.value.substr(0, 9) == "-#,##0.00") @@ -700,18 +693,18 @@ std::string format_section(long double number, const section &format, xlnt::cale result += "$"; } - result += std::to_string(number < 0 ? -number : number); + result += xlnt::string::from(number < 0 ? -number : number); auto decimal_pos = result.find('.'); - if (decimal_pos != std::string::npos) + if (decimal_pos != xlnt::string::npos) { result[decimal_pos] = ','; decimal_pos += 3; - while (decimal_pos < result.size()) + while (decimal_pos < result.length()) { - result.pop_back(); + result.remove(result.back()); } } } @@ -719,13 +712,13 @@ std::string format_section(long double number, const section &format, xlnt::cale return result; } -std::string format_section(const std::string &text, const section &format) +xlnt::string format_section(const xlnt::string &text, const section &format) { auto arobase_index = format.value.find('@'); - std::string first_part, middle_part, last_part; + xlnt::string first_part, middle_part, last_part; - if (arobase_index != std::string::npos) + if (arobase_index != xlnt::string::npos) { first_part = format.value.substr(0, arobase_index); middle_part = text; @@ -736,11 +729,11 @@ std::string format_section(const std::string &text, const section &format) first_part = format.value; } - auto unquote = [](std::string &s) { + auto unquote = [](xlnt::string &s) { if (!s.empty()) { if (s.front() != '"' || s.back() != '"') return false; - s = s.substr(0, s.size() - 2); + s = s.substr(0, s.length() - 2); } return true; @@ -748,13 +741,13 @@ std::string format_section(const std::string &text, const section &format) if (!unquote(first_part) || !unquote(last_part)) { - throw std::runtime_error(std::string("additional text must be enclosed in quotes: ") + format.value); + throw std::runtime_error("additional text must be enclosed in quotes"); } return first_part + middle_part + last_part; } -std::string format_number(long double number, const std::string &format, xlnt::calendar base_date) +xlnt::string format_number(long double number, const xlnt::string &format, xlnt::calendar base_date) { auto sections = parse_format_sections(format); @@ -771,7 +764,7 @@ std::string format_number(long double number, const std::string &format, xlnt::c return format_section(number, sections.third, base_date); } -std::string format_text(const std::string &text, const std::string &format) +xlnt::string format_text(const xlnt::string &text, const xlnt::string &format) { if (format == "General") return text; auto sections = parse_format_sections(format); @@ -781,10 +774,10 @@ std::string format_text(const std::string &text, const std::string &format) namespace xlnt { -const std::unordered_map &cell::error_codes() +const std::unordered_map &cell::error_codes() { - static const std::unordered_map *codes = - new std::unordered_map({ { "#NULL!", 0 }, { "#DIV/0!", 1 }, { "#VALUE!", 2 }, + static const std::unordered_map *codes = + new std::unordered_map({ { "#NULL!", 0 }, { "#DIV/0!", 1 }, { "#VALUE!", 2 }, { "#REF!", 3 }, { "#NAME?", 4 }, { "#NUM!", 5 }, { "#N/A!", 6 } }); @@ -926,7 +919,7 @@ void cell::set_value(long double d) } template <> -void cell::set_value(std::string s) +void XLNT_FUNCTION cell::set_value(string s) { d_->set_string(s, get_parent().get_parent().get_guess_types()); @@ -937,9 +930,9 @@ void cell::set_value(std::string s) } template <> -void cell::set_value(char const *c) +void XLNT_FUNCTION cell::set_value(char const *c) { - set_value(std::string(c)); + set_value(string(c)); } template <> @@ -1056,7 +1049,7 @@ bool operator<(cell left, cell right) return left.get_reference() < right.get_reference(); } -std::string cell::to_repr() const +string cell::to_repr() const { return "parent_).get_title() + "." + get_reference().to_string() + ">"; } @@ -1076,7 +1069,7 @@ bool cell::has_hyperlink() const return d_->has_hyperlink_; } -void cell::set_hyperlink(const std::string &hyperlink) +void cell::set_hyperlink(const string &hyperlink) { if (hyperlink.length() == 0 || std::find(hyperlink.begin(), hyperlink.end(), ':') == hyperlink.end()) { @@ -1092,7 +1085,7 @@ void cell::set_hyperlink(const std::string &hyperlink) } } -void cell::set_formula(const std::string &formula) +void cell::set_formula(const string &formula) { if (formula.length() == 0) { @@ -1114,7 +1107,7 @@ bool cell::has_formula() const return !d_->formula_.empty(); } -std::string cell::get_formula() const +string cell::get_formula() const { if (d_->formula_.empty()) { @@ -1159,7 +1152,7 @@ bool cell::has_comment() const return d_->comment_ != nullptr; } -void cell::set_error(const std::string &error) +void cell::set_error(const string &error) { if (error.length() == 0 || error[0] != '#') { @@ -1426,7 +1419,7 @@ void cell::set_number_format(const number_format &number_format_) } template <> -std::string cell::get_value() const +string cell::get_value() const { return d_->value_string_; } @@ -1436,7 +1429,7 @@ bool cell::has_value() const return d_->type_ != cell::type::null; } -std::string cell::to_string() const +string cell::to_string() const { auto nf = get_number_format(); @@ -1449,7 +1442,7 @@ std::string cell::to_string() const case cell::type::string: case cell::type::formula: case cell::type::error: - return format_text(get_value(), nf.get_format_string()); + return format_text(get_value(), nf.get_format_string()); case cell::type::boolean: return get_value() == 0 ? "FALSE" : "TRUE"; default: diff --git a/source/cell/cell_reference.cpp b/source/cell/cell_reference.cpp index b59a91ad..5f64809a 100644 --- a/source/cell/cell_reference.cpp +++ b/source/cell/cell_reference.cpp @@ -25,7 +25,7 @@ cell_reference::cell_reference() : cell_reference(1, 1) { } -cell_reference::cell_reference(const std::string &string) +cell_reference::cell_reference(const string &string) { auto split = split_reference(string, absolute_column_, absolute_row_); @@ -34,11 +34,11 @@ cell_reference::cell_reference(const std::string &string) } cell_reference::cell_reference(const char *reference_string) - : cell_reference(std::string(reference_string)) + : cell_reference(string(reference_string)) { } -cell_reference::cell_reference(const std::string &column, row_t row) +cell_reference::cell_reference(const string &column, row_t row) : cell_reference(column_t(column), row) { } @@ -57,9 +57,9 @@ range_reference cell_reference::operator, (const xlnt::cell_reference &other) co return range_reference(*this, other); } -std::string cell_reference::to_string() const +string cell_reference::to_string() const { - std::string string_representation; + string string_representation; if (absolute_column_) { @@ -73,7 +73,7 @@ std::string cell_reference::to_string() const string_representation.append("$"); } - string_representation.append(std::to_string(row_)); + string_representation.append(string::from(row_)); return string_representation; } @@ -83,7 +83,7 @@ range_reference cell_reference::to_range() const return range_reference(column_, row_, column_, row_); } -std::pair cell_reference::split_reference(const std::string &reference_string, +std::pair cell_reference::split_reference(const string &reference_string, bool &absolute_column, bool &absolute_row) { absolute_column = false; @@ -92,17 +92,17 @@ std::pair cell_reference::split_reference(const std::string // Convert a coordinate string like 'B12' to a tuple ('B', 12) bool column_part = true; - std::string column_string; + string column_string; for (auto character : reference_string) { - char upper = std::toupper(character, std::locale::classic()); + auto upper = std::toupper(character.get(), std::locale::classic()); - if (std::isalpha(character, std::locale::classic())) + if (std::isalpha(character.get(), std::locale::classic())) { if (column_part) { - column_string.append(1, upper); + column_string.append(upper); } else { @@ -115,7 +115,7 @@ std::pair cell_reference::split_reference(const std::string { if (column_string.empty()) { - column_string.append(1, upper); + column_string.append(upper); } else { @@ -129,14 +129,14 @@ std::pair cell_reference::split_reference(const std::string { column_part = false; } - else if (!std::isdigit(character, std::locale::classic())) + else if (!std::isdigit(character.get(), std::locale::classic())) { throw cell_coordinates_exception(reference_string); } } } - std::string row_string = reference_string.substr(column_string.length()); + string row_string = reference_string.substr(column_string.length()); if (row_string.length() == 0) { @@ -155,7 +155,7 @@ std::pair cell_reference::split_reference(const std::string row_string = row_string.substr(1); } - return { column_string, std::stoi(row_string) }; + return { column_string, row_string.to() }; } cell_reference cell_reference::make_offset(int column_offset, int row_offset) const diff --git a/source/cell/comment.cpp b/source/cell/comment.cpp index 2801e2ff..12430b16 100644 --- a/source/cell/comment.cpp +++ b/source/cell/comment.cpp @@ -9,7 +9,7 @@ comment::comment(detail::comment_impl *d) : d_(d) { } -comment::comment(cell parent, const std::string &text, const std::string &author) : d_(nullptr) +comment::comment(cell parent, const string &text, const string &author) : d_(nullptr) { d_ = parent.get_comment().d_; d_->text_ = text; @@ -24,12 +24,12 @@ comment::~comment() { } -std::string comment::get_author() const +string comment::get_author() const { return d_->author_; } -std::string comment::get_text() const +string comment::get_text() const { return d_->text_; } diff --git a/source/cell/tests/test_cell.hpp b/source/cell/tests/test_cell.hpp index 46f46ba0..60cad656 100644 --- a/source/cell/tests/test_cell.hpp +++ b/source/cell/tests/test_cell.hpp @@ -145,7 +145,7 @@ public: cell.set_value("="); TS_ASSERT(cell.get_data_type() == xlnt::cell::type::string); - TS_ASSERT(cell.get_value() == "="); + TS_ASSERT(cell.get_value() == "="); TS_ASSERT(!cell.has_formula()); } @@ -228,7 +228,7 @@ public: cell.set_value(xlnt::datetime::today()); cell.set_value("testme"); TS_ASSERT(!cell.is_date()); - TS_ASSERT(cell.get_value() == "testme"); + TS_ASSERT(cell.get_value() == "testme"); } void test_cell_formatted_as_date3() @@ -252,14 +252,15 @@ public: for(auto i : illegal_chrs) { - std::string str(1, i); + xlnt::string str; + str.append(char(i)); TS_ASSERT_THROWS(cell.set_value(str), xlnt::illegal_character_error); } - cell.set_value(std::string(1, 33)); - cell.set_value(std::string(1, 9)); // Tab - cell.set_value(std::string(1, 10)); // Newline - cell.set_value(std::string(1, 13)); // Carriage return + cell.set_value(xlnt::string("\33")); + cell.set_value(xlnt::string("\t")); // Tab + cell.set_value(xlnt::string("\n")); // Newline + cell.set_value(xlnt::string("\r")); // Carriage return cell.set_value(" Leading and trailing spaces are legal "); } /* diff --git a/source/cell/types.cpp b/source/cell/types.cpp index 4e211839..561ac233 100644 --- a/source/cell/types.cpp +++ b/source/cell/types.cpp @@ -7,7 +7,7 @@ namespace xlnt { -column_t::index_t column_t::column_index_from_string(const std::string &column_string) +column_t::index_t column_t::column_index_from_string(const string &column_string) { if (column_string.length() > 3 || column_string.empty()) { @@ -19,12 +19,12 @@ column_t::index_t column_t::column_index_from_string(const std::string &column_s for (int i = static_cast(column_string.length()) - 1; i >= 0; i--) { - if (!std::isalpha(column_string[static_cast(i)], std::locale::classic())) + if (!std::isalpha(column_string[static_cast(i)].get(), std::locale::classic())) { throw column_string_index_exception(); } - auto char_index = std::toupper(column_string[static_cast(i)], std::locale::classic()) - 'A'; + auto char_index = std::toupper(column_string[static_cast(i)].get(), std::locale::classic()) - U'A'; column_index += static_cast((char_index + 1) * place); place *= 26; @@ -37,18 +37,18 @@ column_t::index_t column_t::column_index_from_string(const std::string &column_s // Right shift the column col_idx by 26 to find column letters in reverse // order.These numbers are 1 - based, and can be converted to ASCII // ordinals by adding 64. -std::string column_t::column_string_from_index(column_t::index_t column_index) +string column_t::column_string_from_index(column_t::index_t column_index) { // these indicies corrospond to A->ZZZ and include all allowed // columns if (column_index < constants::MinColumn() || column_index > constants::MaxColumn()) { - // auto msg = "Column index out of bounds: " + std::to_string(column_index); + // auto msg = "Column index out of bounds: " + string::from(column_index); throw column_string_index_exception(); } int temp = static_cast(column_index); - std::string column_letter = ""; + string column_letter = ""; while (temp > 0) { @@ -61,7 +61,9 @@ std::string column_t::column_string_from_index(column_t::index_t column_index) remainder = 26; } - column_letter = std::string(1, char(remainder + 64)) + column_letter; + string char_string; + char_string.append(char(remainder + 64)); + column_letter = char_string + column_letter; temp = quotient; } diff --git a/source/detail/cell_impl.hpp b/source/detail/cell_impl.hpp index 846bf3e5..e641750e 100644 --- a/source/detail/cell_impl.hpp +++ b/source/detail/cell_impl.hpp @@ -5,55 +5,56 @@ #include #include #include -#include -#include #include #include +#include +#include +#include -#include "comment_impl.hpp" +#include namespace { // return s after checking encoding, size, and illegal characters -std::string check_string(std::string s) +xlnt::string check_string(xlnt::string s) { - if (s.size() == 0) + if (s.length() == 0) { return s; } // check encoding? - if (s.size() > 32767) + if (s.length() > 32767) { s = s.substr(0, 32767); // max string length in Excel } - for (char c : s) + for (xlnt::string::code_point c : s) { if (c >= 0 && (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31))) { - throw xlnt::illegal_character_error(c); + throw xlnt::illegal_character_error(0); } } return s; } -std::pair cast_numeric(const std::string &s) +std::pair cast_numeric(const xlnt::string &s) { - const char *str = s.c_str(); + const char *str = s.data(); char *str_end = nullptr; auto result = std::strtold(str, &str_end); - if (str_end != str + s.size()) return { false, 0 }; + if (str_end != str + s.length()) return { false, 0 }; return { true, result }; } -std::pair cast_percentage(const std::string &s) +std::pair cast_percentage(const xlnt::string &s) { if (s.back() == '%') { - auto number = cast_numeric(s.substr(0, s.size() - 1)); + auto number = cast_numeric(s.substr(0, s.length() - 1)); if (number.first) { @@ -64,46 +65,10 @@ std::pair cast_percentage(const std::string &s) return { false, 0 }; } -std::pair cast_time(const std::string &s) +std::pair cast_time(const xlnt::string &s) { xlnt::time result; - - try - { - auto last_colon = s.find_last_of(':'); - if (last_colon == std::string::npos) return { false, result }; - double seconds = std::stod(s.substr(last_colon + 1)); - result.second = static_cast(seconds); - result.microsecond = static_cast((seconds - static_cast(result.second)) * 1e6); - - auto first_colon = s.find_first_of(':'); - - if (first_colon == last_colon) - { - auto decimal_pos = s.find('.'); - if (decimal_pos != std::string::npos) - { - result.minute = std::stoi(s.substr(0, first_colon)); - } - else - { - result.hour = std::stoi(s.substr(0, first_colon)); - result.minute = result.second; - result.second = 0; - } - } - else - { - result.hour = std::stoi(s.substr(0, first_colon)); - result.minute = std::stoi(s.substr(first_colon + 1, last_colon - first_colon - 1)); - } - } - catch (std::invalid_argument) - { - return { false, result }; - } - - return { true, result }; + return { false, result }; } } // namespace @@ -129,16 +94,16 @@ struct cell_impl return xlnt::cell(this); } - void set_string(const std::string &s, bool guess_types) + void set_string(const string &s, bool guess_types) { value_string_ = check_string(s); type_ = cell::type::string; - if (value_string_.size() > 1 && value_string_.front() == '=') + if (value_string_.length() > 1 && value_string_.front() == '=') { formula_ = value_string_; type_ = cell::type::formula; - value_string_.clear(); + value_string_.length(); } else if (cell::error_codes().find(s) != cell::error_codes().end()) { @@ -185,10 +150,10 @@ struct cell_impl column_t column_; row_t row_; - std::string value_string_; + string value_string_; long double value_numeric_; - std::string formula_; + string formula_; bool has_hyperlink_; relationship hyperlink_; diff --git a/source/detail/comment_impl.hpp b/source/detail/comment_impl.hpp index 1c762502..f3229e46 100644 --- a/source/detail/comment_impl.hpp +++ b/source/detail/comment_impl.hpp @@ -10,12 +10,12 @@ struct cell_impl; struct comment_impl { comment_impl(); - comment_impl(cell_impl *parent, const std::string &text, const std::string &author); + comment_impl(cell_impl *parent, const string &text, const string &author); comment_impl(const comment_impl &rhs); comment_impl &operator=(const comment_impl &rhs); - std::string text_; - std::string author_; + string text_; + string author_; }; } // namespace detail diff --git a/source/detail/constants.cpp b/source/detail/constants.cpp index 016ec52f..0dac013c 100644 --- a/source/detail/constants.cpp +++ b/source/detail/constants.cpp @@ -42,27 +42,27 @@ const column_t constants::MaxColumn() } // constants -const std::string constants::PackageProps() { return "docProps"; } -const std::string constants::PackageXl() { return "xl"; } -const std::string constants::PackageRels() { return "_rels"; } -const std::string constants::PackageTheme() { return PackageXl() + "/" + "theme"; } -const std::string constants::PackageWorksheets() { return PackageXl() + "/" + "worksheets"; } -const std::string constants::PackageDrawings() { return PackageXl() + "/" + "drawings"; } -const std::string constants::PackageCharts() { return PackageXl() + "/" + "charts"; } +const string constants::PackageProps() { return "docProps"; } +const string constants::PackageXl() { return "xl"; } +const string constants::PackageRels() { return "_rels"; } +const string constants::PackageTheme() { return PackageXl() + "/" + "theme"; } +const string constants::PackageWorksheets() { return PackageXl() + "/" + "worksheets"; } +const string constants::PackageDrawings() { return PackageXl() + "/" + "drawings"; } +const string constants::PackageCharts() { return PackageXl() + "/" + "charts"; } -const std::string constants::ArcContentTypes() { return "[Content_Types].xml"; } -const std::string constants::ArcRootRels() { return PackageRels() + "/.rels"; } -const std::string constants::ArcWorkbookRels() { return PackageXl() + "/" + PackageRels() + "/workbook.xml.rels"; } -const std::string constants::ArcCore() { return PackageProps() + "/core.xml"; } -const std::string constants::ArcApp() { return PackageProps() + "/app.xml"; } -const std::string constants::ArcWorkbook() { return PackageXl() + "/workbook.xml"; } -const std::string constants::ArcStyles() { return PackageXl() + "/styles.xml"; } -const std::string constants::ArcTheme() { return PackageTheme() + "/theme1.xml"; } -const std::string constants::ArcSharedString() { return PackageXl() + "/sharedStrings.xml"; } +const string constants::ArcContentTypes() { return "[Content_Types].xml"; } +const string constants::ArcRootRels() { return PackageRels() + "/.rels"; } +const string constants::ArcWorkbookRels() { return PackageXl() + "/" + PackageRels() + "/workbook.xml.rels"; } +const string constants::ArcCore() { return PackageProps() + "/core.xml"; } +const string constants::ArcApp() { return PackageProps() + "/app.xml"; } +const string constants::ArcWorkbook() { return PackageXl() + "/workbook.xml"; } +const string constants::ArcStyles() { return PackageXl() + "/styles.xml"; } +const string constants::ArcTheme() { return PackageTheme() + "/theme1.xml"; } +const string constants::ArcSharedString() { return PackageXl() + "/sharedStrings.xml"; } -const std::unordered_map constants::Namespaces() +const std::unordered_map constants::Namespaces() { - const std::unordered_map namespaces = + const std::unordered_map namespaces = { { "spreadsheetml", "http://schemas.openxmlformats.org/spreadsheetml/2006/main" }, { "content-types", "http://schemas.openxmlformats.org/package/2006/content-types" }, @@ -81,7 +81,7 @@ const std::unordered_map constants::Namespaces() return namespaces; } -const std::string constants::Namespace(const std::string &id) +const string constants::Namespace(const string &id) { return Namespaces().find(id)->second; } diff --git a/source/detail/constants.hpp b/source/detail/constants.hpp index 9c1676c6..bd2ea522 100644 --- a/source/detail/constants.hpp +++ b/source/detail/constants.hpp @@ -15,27 +15,27 @@ struct constants static const column_t MaxColumn(); // constants - static const std::string PackageProps(); - static const std::string PackageXl(); - static const std::string PackageRels(); - static const std::string PackageTheme(); - static const std::string PackageWorksheets(); - static const std::string PackageDrawings(); - static const std::string PackageCharts(); + static const string PackageProps(); + static const string PackageXl(); + static const string PackageRels(); + static const string PackageTheme(); + static const string PackageWorksheets(); + static const string PackageDrawings(); + static const string PackageCharts(); - static const std::string ArcContentTypes(); - static const std::string ArcRootRels(); - static const std::string ArcWorkbookRels(); - static const std::string ArcCore(); - static const std::string ArcApp(); - static const std::string ArcWorkbook(); - static const std::string ArcStyles(); - static const std::string ArcTheme(); - static const std::string ArcSharedString(); + static const string ArcContentTypes(); + static const string ArcRootRels(); + static const string ArcWorkbookRels(); + static const string ArcCore(); + static const string ArcApp(); + static const string ArcWorkbook(); + static const string ArcStyles(); + static const string ArcTheme(); + static const string ArcSharedString(); - static const std::unordered_map Namespaces(); + static const std::unordered_map Namespaces(); - static const std::string Namespace(const std::string &id); + static const string Namespace(const string &id); }; } // namespace xlnt diff --git a/source/detail/workbook_impl.hpp b/source/detail/workbook_impl.hpp index 81e015f7..262e6af7 100644 --- a/source/detail/workbook_impl.hpp +++ b/source/detail/workbook_impl.hpp @@ -63,7 +63,7 @@ struct workbook_impl std::vector relationships_; std::vector root_relationships_; std::vector drawings_; - std::vector shared_strings_; + std::vector shared_strings_; document_properties properties_; diff --git a/source/detail/worksheet_impl.hpp b/source/detail/worksheet_impl.hpp index 0e6d84b0..8289b357 100644 --- a/source/detail/worksheet_impl.hpp +++ b/source/detail/worksheet_impl.hpp @@ -15,7 +15,7 @@ namespace detail { struct worksheet_impl { - worksheet_impl(workbook *parent_workbook, const std::string &title) + worksheet_impl(workbook *parent_workbook, const string &title) : parent_(parent_workbook), title_(title), freeze_panes_("A1"), comment_count_(0) { page_margins_.set_left(0.75); @@ -59,7 +59,7 @@ struct worksheet_impl workbook *parent_; std::unordered_map column_properties_; std::unordered_map row_properties_; - std::string title_; + string title_; cell_reference freeze_panes_; std::unordered_map> cell_map_; std::vector relationships_; @@ -67,7 +67,7 @@ struct worksheet_impl range_reference auto_filter_; margins page_margins_; std::vector merged_cells_; - std::unordered_map named_ranges_; + std::unordered_map named_ranges_; std::size_t comment_count_; header_footer header_footer_; }; diff --git a/source/detail/xml_document_impl.hpp b/source/detail/xml_document_impl.hpp index b1f84085..0d14c353 100644 --- a/source/detail/xml_document_impl.hpp +++ b/source/detail/xml_document_impl.hpp @@ -9,7 +9,7 @@ namespace detail { struct xml_document_impl { - std::string encoding; + string encoding; pugi::xml_document doc; }; diff --git a/source/packaging/manifest.cpp b/source/packaging/manifest.cpp index e8c0f0b0..83cd20f8 100644 --- a/source/packaging/manifest.cpp +++ b/source/packaging/manifest.cpp @@ -5,7 +5,7 @@ namespace { -bool match_path(const std::string &path, const std::string &comparand) +bool match_path(const xlnt::string &path, const xlnt::string &comparand) { if (path == comparand) { @@ -32,7 +32,7 @@ default_type::default_type() { } -default_type::default_type(const std::string &extension, const std::string &content_type) +default_type::default_type(const string &extension, const string &content_type) : extension_(extension), content_type_(content_type) { } @@ -53,7 +53,7 @@ override_type::override_type() { } -override_type::override_type(const std::string &part_name, const std::string &content_type) +override_type::override_type(const string &part_name, const string &content_type) : part_name_(part_name), content_type_(content_type) { } @@ -71,52 +71,52 @@ override_type &override_type::operator=(const override_type &other) return *this; } -bool manifest::has_default_type(const std::string &extension) const +bool manifest::has_default_type(const string &extension) const { return std::find_if(default_types_.begin(), default_types_.end(), [&](const default_type &d) { return d.get_extension() == extension; }) != default_types_.end(); } -bool manifest::has_override_type(const std::string &part_name) const +bool manifest::has_override_type(const string &part_name) const { return std::find_if(override_types_.begin(), override_types_.end(), [&](const override_type &d) { return match_path(d.get_part_name(), part_name); }) != override_types_.end(); } -void manifest::add_default_type(const std::string &extension, const std::string &content_type) +void manifest::add_default_type(const string &extension, const string &content_type) { if(has_default_type(extension)) return; default_types_.push_back(default_type(extension, content_type)); } -void manifest::add_override_type(const std::string &part_name, const std::string &content_type) +void manifest::add_override_type(const string &part_name, const string &content_type) { if(has_override_type(part_name)) return; override_types_.push_back(override_type(part_name, content_type)); } -std::string manifest::get_default_type(const std::string &extension) const +string manifest::get_default_type(const string &extension) const { auto match = std::find_if(default_types_.begin(), default_types_.end(), [&](const default_type &d) { return d.get_extension() == extension; }); if (match == default_types_.end()) { - throw std::runtime_error("no default type found for extension: " + extension); + throw std::runtime_error("no default type found for extension"); } return match->get_content_type(); } -std::string manifest::get_override_type(const std::string &part_name) const +string manifest::get_override_type(const string &part_name) const { auto match = std::find_if(override_types_.begin(), override_types_.end(), [&](const override_type &d) { return match_path(d.get_part_name(), part_name); }); if (match == override_types_.end()) { - throw std::runtime_error("no default type found for part name: " + part_name); + throw std::runtime_error("no default type found for part name"); } return match->get_content_type(); diff --git a/source/packaging/relationship.cpp b/source/packaging/relationship.cpp index 8a030d6d..6bd07a5a 100644 --- a/source/packaging/relationship.cpp +++ b/source/packaging/relationship.cpp @@ -2,7 +2,7 @@ namespace xlnt { -relationship::relationship(type t, const std::string &r_id, const std::string &target_uri) +relationship::relationship(type t, const string &r_id, const string &target_uri) : type_(t), id_(r_id), source_uri_(""), target_uri_(target_uri), target_mode_(target_mode::internal) { if (t == type::hyperlink) diff --git a/source/packaging/tests/test_core.hpp b/source/packaging/tests/test_core.hpp index 13963824..6ab3cbc8 100644 --- a/source/packaging/tests/test_core.hpp +++ b/source/packaging/tests/test_core.hpp @@ -28,7 +28,7 @@ public: { auto path = PathHelper::GetDataDirectory() + "/genuine/empty.xlsx"; - const std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; + const std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; std::size_t i = 0; @@ -57,7 +57,7 @@ public: { auto path = PathHelper::GetDataDirectory() + "/genuine/empty_libre.xlsx"; - const std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; + const std::vector expected_titles = {"Sheet1 - Text", "Sheet2 - Numbers", "Sheet3 - Formulas", "Sheet4 - Dates"}; std::size_t i = 0; diff --git a/source/packaging/zip_file.cpp b/source/packaging/zip_file.cpp index 850558e0..dc832e0c 100644 --- a/source/packaging/zip_file.cpp +++ b/source/packaging/zip_file.cpp @@ -11,13 +11,13 @@ namespace { -std::string get_working_directory() +xlnt::string get_working_directory() { #ifdef _WIN32 TCHAR buffer[MAX_PATH]; GetCurrentDirectory(MAX_PATH, buffer); std::basic_string working_directory(buffer); - return std::string(working_directory.begin(), working_directory.end()); + return xlnt::string(working_directory.begin(), working_directory.end()); #else return ""; #endif @@ -31,9 +31,9 @@ char directory_separator = '/'; char alt_directory_separator = '\\'; #endif -std::string join_path(const std::vector &parts) +xlnt::string join_path(const std::vector &parts) { - std::string joined; + xlnt::string joined; std::size_t i = 0; for (auto part : parts) { @@ -41,19 +41,19 @@ std::string join_path(const std::vector &parts) if (i++ != parts.size() - 1) { - joined.append(1, '/'); + joined.append('/'); } } return joined; } -std::vector split_path(const std::string &path, char delim = directory_separator) +std::vector split_path(const xlnt::string &path, char delim = directory_separator) { - std::vector split; - std::string::size_type previous_index = 0; + std::vector split; + xlnt::string::size_type previous_index = 0; auto separator_index = path.find(delim); - while (separator_index != std::string::npos) + while (separator_index != xlnt::string::npos) { auto part = path.substr(previous_index, separator_index - previous_index); if (part != "..") @@ -190,7 +190,7 @@ zip_file::zip_file() : archive_(new mz_zip_archive()) reset(); } -zip_file::zip_file(const std::string &filename) : zip_file() +zip_file::zip_file(const string &filename) : zip_file() { load(filename); } @@ -218,10 +218,10 @@ void zip_file::load(std::istream &stream) start_read(); } -void zip_file::load(const std::string &filename) +void zip_file::load(const string &filename) { filename_ = filename; - std::ifstream stream(filename, std::ios::binary); + std::ifstream stream(filename.data(), std::ios::binary); load(stream); } @@ -233,10 +233,10 @@ void zip_file::load(const std::vector &bytes) start_read(); } -void zip_file::save(const std::string &filename) +void zip_file::save(const string &filename) { filename_ = filename; - std::ofstream stream(filename, std::ios::binary); + std::ofstream stream(filename.data(), std::ios::binary); save(stream); } @@ -289,7 +289,7 @@ void zip_file::append_comment() auto comment_length = std::min(static_cast(comment.length()), std::numeric_limits::max()); buffer_[buffer_.size() - 2] = static_cast(comment_length); buffer_[buffer_.size() - 1] = static_cast(comment_length >> 8); - std::copy(comment.begin(), comment.end(), std::back_inserter(buffer_)); + std::copy(comment.data(), comment.data() + comment.bytes(), std::back_inserter(buffer_)); } } @@ -320,7 +320,7 @@ void zip_file::remove_comment() if (length != 0) { - comment = std::string(buffer_.data() + position, buffer_.data() + position + length); + comment = string(buffer_.data() + position, buffer_.data() + position + length); buffer_.resize(buffer_.size() - length); buffer_[buffer_.size() - 1] = 0; buffer_[buffer_.size() - 2] = 0; @@ -358,14 +358,14 @@ void zip_file::reset() mz_zip_writer_end(archive_.get()); } -zip_info zip_file::getinfo(const std::string &name) +zip_info zip_file::getinfo(const string &name) { if (archive_->m_zip_mode != MZ_ZIP_MODE_READING) { start_read(); } - int index = mz_zip_reader_locate_file(archive_.get(), name.c_str(), nullptr, 0); + int index = mz_zip_reader_locate_file(archive_.get(), name.data(), nullptr, 0); if (index == -1) { @@ -387,8 +387,8 @@ zip_info zip_file::getinfo(int index) zip_info result; - result.filename = std::string(stat.m_filename, stat.m_filename + std::strlen(stat.m_filename)); - result.comment = std::string(stat.m_comment, stat.m_comment + stat.m_comment_size); + result.filename = string(stat.m_filename, stat.m_filename + std::strlen(stat.m_filename)); + result.comment = string(stat.m_comment, stat.m_comment + stat.m_comment_size); result.compress_size = static_cast(stat.m_comp_size); result.file_size = static_cast(stat.m_uncomp_size); result.header_offset = static_cast(stat.m_local_header_ofs); @@ -487,7 +487,7 @@ void zip_file::start_write() } } -void zip_file::write(const std::string &filename) +void zip_file::write(const string &filename) { auto split = split_path(filename); if (split.size() > 1) @@ -498,30 +498,30 @@ void zip_file::write(const std::string &filename) write(filename, arcname); } -void zip_file::write(const std::string &filename, const std::string &arcname) +void zip_file::write(const string &filename, const string &arcname) { - std::fstream file(filename, std::ios::binary | std::ios::in); + std::fstream file(filename.data(), std::ios::binary | std::ios::in); std::stringstream ss; ss << file.rdbuf(); - std::string bytes = ss.str(); + string bytes = ss.str().data(); writestr(arcname, bytes); } -void zip_file::writestr(const std::string &arcname, const std::string &bytes) +void zip_file::writestr(const string &arcname, const string &bytes) { if (archive_->m_zip_mode != MZ_ZIP_MODE_WRITING) { start_write(); } - if (!mz_zip_writer_add_mem(archive_.get(), arcname.c_str(), bytes.data(), bytes.size(), MZ_BEST_COMPRESSION)) + if (!mz_zip_writer_add_mem(archive_.get(), arcname.data(), bytes.data(), bytes.length(), MZ_BEST_COMPRESSION)) { throw std::runtime_error("write error"); } } -void zip_file::writestr(const zip_info &info, const std::string &bytes) +void zip_file::writestr(const zip_info &info, const string &bytes) { if (info.filename.empty() || info.date_time.year < 1980) { @@ -533,43 +533,43 @@ void zip_file::writestr(const zip_info &info, const std::string &bytes) start_write(); } - auto crc = crc32buf(bytes.c_str(), bytes.size()); + auto crc = crc32buf(bytes.data(), bytes.length()); - if (!mz_zip_writer_add_mem_ex(archive_.get(), info.filename.c_str(), bytes.data(), bytes.size(), - info.comment.c_str(), static_cast(info.comment.size()), + if (!mz_zip_writer_add_mem_ex(archive_.get(), info.filename.data(), bytes.data(), bytes.length(), + info.comment.data(), static_cast(info.comment.length()), MZ_BEST_COMPRESSION, 0, crc)) { throw std::runtime_error("write error"); } } -std::string zip_file::read(const zip_info &info) +string zip_file::read(const zip_info &info) { std::size_t size; char *data = - static_cast(mz_zip_reader_extract_file_to_heap(archive_.get(), info.filename.c_str(), &size, 0)); + static_cast(mz_zip_reader_extract_file_to_heap(archive_.get(), info.filename.data(), &size, 0)); if (data == nullptr) { throw std::runtime_error("file couldn't be read"); } - std::string extracted(data, data + size); + string extracted(data, data + size); mz_free(data); return extracted; } -std::string zip_file::read(const std::string &name) +string zip_file::read(const string &name) { return read(getinfo(name)); } -bool zip_file::has_file(const std::string &name) +bool zip_file::has_file(const string &name) { if (archive_->m_zip_mode != MZ_ZIP_MODE_READING) { start_read(); } - int index = mz_zip_reader_locate_file(archive_.get(), name.c_str(), nullptr, 0); + int index = mz_zip_reader_locate_file(archive_.get(), name.data(), nullptr, 0); return index != -1; } @@ -596,9 +596,9 @@ std::vector zip_file::infolist() return info; } -std::vector zip_file::namelist() +std::vector zip_file::namelist() { - std::vector names; + std::vector names; for (auto &info : infolist()) { @@ -608,7 +608,7 @@ std::vector zip_file::namelist() return names; } -std::ostream &zip_file::open(const std::string &name) +std::ostream &zip_file::open(const string &name) { return open(getinfo(name)); } @@ -616,19 +616,19 @@ std::ostream &zip_file::open(const std::string &name) std::ostream &zip_file::open(const zip_info &name) { auto data = read(name); - std::string data_string(data.begin(), data.end()); + string data_string(data.begin(), data.end()); open_stream_ << data_string; return open_stream_; } -void zip_file::extract(const std::string &member) +void zip_file::extract(const string &member) { extract(member, get_working_directory()); } -void zip_file::extract(const std::string &member, const std::string &path) +void zip_file::extract(const string &member, const string &path) { - std::fstream stream(join_path({ path, member }), std::ios::binary | std::ios::out); + std::fstream stream(join_path({ path, member }).data(), std::ios::binary | std::ios::out); stream << open(member).rdbuf(); } @@ -637,18 +637,18 @@ void zip_file::extract(const zip_info &member) extract(member, get_working_directory()); } -void zip_file::extract(const zip_info &member, const std::string &path) +void zip_file::extract(const zip_info &member, const string &path) { - std::fstream stream(join_path({ path, member.filename }), std::ios::binary | std::ios::out); + std::fstream stream(join_path({ path, member.filename }).data(), std::ios::binary | std::ios::out); stream << open(member).rdbuf(); } -void zip_file::extractall(const std::string &path) +void zip_file::extractall(const string &path) { extractall(path, infolist()); } -void zip_file::extractall(const std::string &path, const std::vector &members) +void zip_file::extractall(const string &path, const std::vector &members) { for (auto &member : members) { @@ -656,7 +656,7 @@ void zip_file::extractall(const std::string &path, const std::vector &members) +void zip_file::extractall(const string &path, const std::vector &members) { for (auto &member : members) { @@ -690,7 +690,7 @@ void zip_file::printdir(std::ostream &stream) sum_length += member.file_size; file_count++; - std::string length_string = std::to_string(member.file_size); + string length_string = string::from(member.file_size); while (length_string.length() < 9) { length_string = " " + length_string; @@ -714,7 +714,7 @@ void zip_file::printdir(std::ostream &stream) stream << "--------- -------" << std::endl; - std::string length_string = std::to_string(sum_length); + string length_string = string::from(sum_length); while (length_string.length() < 9) { length_string = " " + length_string; @@ -723,7 +723,7 @@ void zip_file::printdir(std::ostream &stream) stream << std::endl; } -std::pair zip_file::testzip() +std::pair zip_file::testzip() { if (archive_->m_zip_mode == MZ_ZIP_MODE_INVALID) { @@ -733,7 +733,7 @@ std::pair zip_file::testzip() for (auto &file : infolist()) { auto content = read(file); - auto crc = crc32buf(content.c_str(), content.size()); + auto crc = crc32buf(content.data(), content.length()); if (crc != file.crc) { diff --git a/source/serialization/excel_serializer.cpp b/source/serialization/excel_serializer.cpp index f9efe52b..d9c8af6f 100644 --- a/source/serialization/excel_serializer.cpp +++ b/source/serialization/excel_serializer.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -22,13 +23,13 @@ namespace { -std::string::size_type find_string_in_string(const std::string &string, const std::string &substring) +xlnt::string::size_type find_string_in_string(const xlnt::string &string, const xlnt::string &substring) { - std::string::size_type possible_match_index = string.find(substring.at(0)); + xlnt::string::size_type possible_match_index = string.find(substring.at(0)); - while (possible_match_index != std::string::npos) + while (possible_match_index != xlnt::string::npos) { - if (string.substr(possible_match_index, substring.size()) == substring) + if (string.substr(possible_match_index, substring.length()) == substring) { return possible_match_index; } @@ -90,7 +91,7 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl if(archive.has_file(xlnt::constants::ArcSharedString())) { - std::vector shared_strings; + std::vector shared_strings; xlnt::xml_document shared_strings_xml; shared_strings_xml.from_string(archive.read(xlnt::constants::ArcSharedString())); xlnt::shared_strings_serializer::read_shared_strings(shared_strings_xml, shared_strings); @@ -136,16 +137,16 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl namespace xlnt { -const std::string excel_serializer::central_directory_signature() +const string excel_serializer::central_directory_signature() { return "\x50\x4b\x05\x06"; } -std::string excel_serializer::repair_central_directory(const std::string &original) +string excel_serializer::repair_central_directory(const string &original) { auto pos = find_string_in_string(original, central_directory_signature()); - if (pos != std::string::npos) + if (pos != string::npos) { return original.substr(0, pos + 22); } @@ -166,7 +167,7 @@ bool excel_serializer::load_stream_workbook(std::istream &stream, bool guess_typ return load_virtual_workbook(bytes, guess_types, data_only); } -bool excel_serializer::load_workbook(const std::string &filename, bool guess_types, bool data_only) +bool excel_serializer::load_workbook(const string &filename, bool guess_types, bool data_only) { try { @@ -232,7 +233,7 @@ void excel_serializer::write_worksheets() workbook::index_from_ws_filename(relationship.get_target_uri()) == index) { worksheet_serializer serializer_(ws); - std::string ws_filename = (relationship.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + relationship.get_target_uri(); + string ws_filename = (relationship.get_target_uri().substr(0, 3) != "xl/" ? "xl/" : "") + relationship.get_target_uri(); archive_.writestr(ws_filename, serializer_.write_worksheet().to_string()); break; } @@ -254,7 +255,7 @@ bool excel_serializer::save_stream_workbook(std::ostream &stream, bool as_templa return true; } -bool excel_serializer::save_workbook(const std::string &filename, bool as_template) +bool excel_serializer::save_workbook(const string &filename, bool as_template) { write_data(as_template); archive_.save(filename); diff --git a/source/serialization/manifest_serializer.cpp b/source/serialization/manifest_serializer.cpp index e2cd53bf..00f3d47b 100644 --- a/source/serialization/manifest_serializer.cpp +++ b/source/serialization/manifest_serializer.cpp @@ -52,14 +52,14 @@ xml_document manifest_serializer::write_manifest() const return xml; } -std::string manifest_serializer::determine_document_type() const +string manifest_serializer::determine_document_type() const { if (!manifest_.has_override_type(constants::ArcWorkbook())) { return "unsupported"; } - std::string type = manifest_.get_override_type(constants::ArcWorkbook()); + string type = manifest_.get_override_type(constants::ArcWorkbook()); if (type == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml") { diff --git a/source/serialization/relationship_serializer.cpp b/source/serialization/relationship_serializer.cpp index b548d9f6..59051fa5 100644 --- a/source/serialization/relationship_serializer.cpp +++ b/source/serialization/relationship_serializer.cpp @@ -1,15 +1,15 @@ #include - #include #include #include #include +#include -#include "detail/constants.hpp" +#include namespace { -std::string make_rels_name(const std::string &target) +xlnt::string make_rels_name(const xlnt::string &target) { const char sep = '/'; @@ -32,7 +32,7 @@ relationship_serializer::relationship_serializer(zip_file &archive) : archive_(a { } -std::vector relationship_serializer::read_relationships(const std::string &target) +std::vector relationship_serializer::read_relationships(const string &target) { xml_document xml; xml.from_string(archive_.read(make_rels_name(target))); @@ -48,9 +48,9 @@ std::vector relationship_serializer::read_relationships(const std: continue; } - std::string id = relationship_node.get_attribute("Id"); - std::string type = relationship_node.get_attribute("Type"); - std::string rel_target = relationship_node.get_attribute("Target"); + string id = relationship_node.get_attribute("Id"); + string type = relationship_node.get_attribute("Type"); + string rel_target = relationship_node.get_attribute("Target"); relationships.push_back(xlnt::relationship(type, id, rel_target)); } @@ -59,7 +59,7 @@ std::vector relationship_serializer::read_relationships(const std: } bool relationship_serializer::write_relationships(const std::vector &relationships, - const std::string &target) + const string &target) { xml_document xml; diff --git a/source/serialization/shared_strings_serializer.cpp b/source/serialization/shared_strings_serializer.cpp index 8a3c10bd..d8a7122e 100644 --- a/source/serialization/shared_strings_serializer.cpp +++ b/source/serialization/shared_strings_serializer.cpp @@ -4,7 +4,7 @@ namespace xlnt { -xml_document shared_strings_serializer::write_shared_strings(const std::vector &strings) +xml_document shared_strings_serializer::write_shared_strings(const std::vector &strings) { xml_document xml; @@ -12,7 +12,7 @@ xml_document shared_strings_serializer::write_shared_strings(const std::vector &strings) +bool shared_strings_serializer::read_shared_strings(const xml_document &xml, std::vector &strings) { strings.clear(); auto root_node = xml.get_child("sst"); - auto unique_count = std::stoull(root_node.get_attribute("uniqueCount")); + auto unique_count = root_node.get_attribute("uniqueCount").to(); for (const auto &si_node : root_node.get_children()) { diff --git a/source/serialization/style_serializer.cpp b/source/serialization/style_serializer.cpp index e8ccabb5..8081dd83 100644 --- a/source/serialization/style_serializer.cpp +++ b/source/serialization/style_serializer.cpp @@ -8,15 +8,16 @@ #include #include #include +#include namespace { -bool is_true(const std::string &bool_string) +bool is_true(const xlnt::string &bool_string) { return bool_string == "1"; } -xlnt::protection::type protection_type_from_string(const std::string &type_string) +xlnt::protection::type protection_type_from_string(const xlnt::string &type_string) { if (type_string == "true") { @@ -30,7 +31,7 @@ xlnt::protection::type protection_type_from_string(const std::string &type_strin return xlnt::protection::type::unprotected; }; -xlnt::font::underline_style underline_style_from_string(const std::string &underline_string) +xlnt::font::underline_style underline_style_from_string(const xlnt::string &underline_string) { if (underline_string == "none") { @@ -56,7 +57,7 @@ xlnt::font::underline_style underline_style_from_string(const std::string &under return xlnt::font::underline_style::none; } -xlnt::fill::pattern_type pattern_fill_type_from_string(const std::string &fill_type) +xlnt::fill::pattern_type pattern_fill_type_from_string(const xlnt::string &fill_type) { if (fill_type == "none") return xlnt::fill::pattern_type::none; if (fill_type == "solid") return xlnt::fill::pattern_type::solid; @@ -64,7 +65,7 @@ xlnt::fill::pattern_type pattern_fill_type_from_string(const std::string &fill_t return xlnt::fill::pattern_type::none; }; -xlnt::border_style border_style_from_string(const std::string &border_style_string) +xlnt::border_style border_style_from_string(const xlnt::string &border_style_string) { if (border_style_string == "none") { @@ -156,7 +157,7 @@ alignment style_serializer::read_alignment(const xml_node &alignment_node) if (has_vertical) { - std::string vertical = alignment_node.get_attribute("vertical"); + string vertical = alignment_node.get_attribute("vertical"); if (vertical == "bottom") { @@ -184,7 +185,7 @@ alignment style_serializer::read_alignment(const xml_node &alignment_node) if (has_horizontal) { - std::string horizontal = alignment_node.get_attribute("horizontal"); + string horizontal = alignment_node.get_attribute("horizontal"); if (horizontal == "left") { @@ -224,7 +225,7 @@ style style_serializer::read_style(const xml_node &style_node) style s; s.apply_number_format(is_true(style_node.get_attribute("applyNumberFormat"))); - s.number_format_id_ = std::stoull(style_node.get_attribute("numFmtId")); + s.number_format_id_ = style_node.get_attribute("numFmtId").to(); bool builtin_format = true; @@ -244,15 +245,15 @@ style style_serializer::read_style(const xml_node &style_node) } s.apply_font(is_true(style_node.get_attribute("applyFont"))); - s.font_id_ = style_node.has_attribute("fontId") ? std::stoull(style_node.get_attribute("fontId")) : 0; + s.font_id_ = style_node.has_attribute("fontId") ? style_node.get_attribute("fontId").to() : 0; s.font_ = workbook_.get_font(s.font_id_); s.apply_fill(is_true(style_node.get_attribute("applyFill"))); - s.fill_id_ = style_node.has_attribute("fillId") ? std::stoull(style_node.get_attribute("fillId")) : 0; + s.fill_id_ = style_node.has_attribute("fillId") ? style_node.get_attribute("fillId").to() : 0; s.fill_ = workbook_.get_fill(s.fill_id_); s.apply_border(is_true(style_node.get_attribute("applyBorder"))); - s.border_id_ = style_node.has_attribute("borderId") ? std::stoull(style_node.get_attribute("borderId")) : 0; + s.border_id_ = style_node.has_attribute("borderId") ? style_node.get_attribute("borderId").to() : 0; s.border_ = workbook_.get_border(s.border_id_); s.apply_protection(style_node.has_attribute("protection")); @@ -318,7 +319,7 @@ bool style_serializer::read_number_formats(const xml_node &number_formats_node) number_format nf; nf.set_format_string(format_string); - nf.set_id(std::stoull(num_fmt_node.get_attribute("numFmtId"))); + nf.set_id(num_fmt_node.get_attribute("numFmtId").to()); workbook_.add_number_format(nf); } @@ -340,7 +341,7 @@ font style_serializer::read_font(const xlnt::xml_node &font_node) { font new_font; - new_font.set_size(std::stoull(font_node.get_child("sz").get_attribute("val"))); + new_font.set_size(font_node.get_child("sz").get_attribute("val").to()); new_font.set_name(font_node.get_child("name").get_attribute("val")); if (font_node.has_child("color")) @@ -350,7 +351,7 @@ font style_serializer::read_font(const xlnt::xml_node &font_node) if (font_node.has_child("family")) { - new_font.set_family(std::stoull(font_node.get_child("family").get_attribute("val"))); + new_font.set_family(font_node.get_child("family").get_attribute("val").to()); } if (font_node.has_child("scheme")) @@ -375,7 +376,7 @@ font style_serializer::read_font(const xlnt::xml_node &font_node) if (font_node.has_child("u")) { - std::string underline_string = font_node.get_child("u").get_attribute("val"); + string underline_string = font_node.get_child("u").get_attribute("val"); new_font.set_underline(underline_style_from_string(underline_string)); } @@ -540,15 +541,15 @@ color style_serializer::read_color(const xml_node &color_node) } else if (color_node.has_attribute("theme")) { - return color(color::type::theme, std::stoull(color_node.get_attribute("theme"))); + return color(color::type::theme, color_node.get_attribute("theme").to()); } else if (color_node.has_attribute("indexed")) { - return color(color::type::indexed, std::stoull(color_node.get_attribute("indexed"))); + return color(color::type::indexed, color_node.get_attribute("indexed").to()); } else if (color_node.has_attribute("auto")) { - return color(color::type::auto_, std::stoull(color_node.get_attribute("auto"))); + return color(color::type::auto_, color_node.get_attribute("auto").to()); } throw std::runtime_error("bad color"); @@ -566,12 +567,12 @@ xml_document style_serializer::write_stylesheet() const auto num_fmts_node = style_sheet_node.add_child("numFmts"); auto num_fmts = workbook_.get_number_formats(); - num_fmts_node.add_attribute("count", std::to_string(num_fmts.size())); + num_fmts_node.add_attribute("count", string::from(num_fmts.size())); for (const auto &num_fmt : num_fmts) { auto num_fmt_node = num_fmts_node.add_child("numFmt"); - num_fmt_node.add_attribute("numFmtId", std::to_string(num_fmt.get_id())); + num_fmt_node.add_attribute("numFmtId", string::from(num_fmt.get_id())); num_fmt_node.add_attribute("formatCode", num_fmt.get_format_string()); } @@ -583,7 +584,7 @@ xml_document style_serializer::write_stylesheet() const fonts.push_back(font()); } - fonts_node.add_attribute("count", std::to_string(fonts.size())); + fonts_node.add_attribute("count", string::from(fonts.size())); // TODO: what does this do? // fonts_node.add_attribute("x14ac:knownFonts", "1"); @@ -624,17 +625,17 @@ xml_document style_serializer::write_stylesheet() const } auto size_node = font_node.add_child("sz"); - size_node.add_attribute("val", std::to_string(f.get_size())); + size_node.add_attribute("val", string::from(f.get_size())); auto color_node = font_node.add_child("color"); if (f.get_color().get_type() == color::type::indexed) { - color_node.add_attribute("indexed", std::to_string(f.get_color().get_index())); + color_node.add_attribute("indexed", string::from(f.get_color().get_index())); } else if (f.get_color().get_type() == color::type::theme) { - color_node.add_attribute("theme", std::to_string(f.get_color().get_theme())); + color_node.add_attribute("theme", string::from(f.get_color().get_theme())); } auto name_node = font_node.add_child("name"); @@ -643,7 +644,7 @@ xml_document style_serializer::write_stylesheet() const if (f.has_family()) { auto family_node = font_node.add_child("family"); - family_node.add_attribute("val", std::to_string(f.get_family())); + family_node.add_attribute("val", string::from(f.get_family())); } if (f.has_scheme()) @@ -655,7 +656,7 @@ xml_document style_serializer::write_stylesheet() const auto fills_node = style_sheet_node.add_child("fills"); const auto &fills = workbook_.get_fills(); - fills_node.add_attribute("count", std::to_string(fills.size())); + fills_node.add_attribute("count", string::from(fills.size())); for (auto &fill_ : fills) { @@ -674,13 +675,13 @@ xml_document style_serializer::write_stylesheet() const switch (fill_.get_foreground_color().get_type()) { case color::type::auto_: - fg_color_node.add_attribute("auto", std::to_string(fill_.get_foreground_color().get_auto())); + fg_color_node.add_attribute("auto", string::from(fill_.get_foreground_color().get_auto())); break; case color::type::theme: - fg_color_node.add_attribute("theme", std::to_string(fill_.get_foreground_color().get_theme())); + fg_color_node.add_attribute("theme", string::from(fill_.get_foreground_color().get_theme())); break; case color::type::indexed: - fg_color_node.add_attribute("indexed", std::to_string(fill_.get_foreground_color().get_index())); + fg_color_node.add_attribute("indexed", string::from(fill_.get_foreground_color().get_index())); break; default: throw std::runtime_error("bad type"); @@ -694,13 +695,13 @@ xml_document style_serializer::write_stylesheet() const switch (fill_.get_background_color().get_type()) { case color::type::auto_: - bg_color_node.add_attribute("auto", std::to_string(fill_.get_background_color().get_auto())); + bg_color_node.add_attribute("auto", string::from(fill_.get_background_color().get_auto())); break; case color::type::theme: - bg_color_node.add_attribute("theme", std::to_string(fill_.get_background_color().get_theme())); + bg_color_node.add_attribute("theme", string::from(fill_.get_background_color().get_theme())); break; case color::type::indexed: - bg_color_node.add_attribute("indexed", std::to_string(fill_.get_background_color().get_index())); + bg_color_node.add_attribute("indexed", string::from(fill_.get_background_color().get_index())); break; default: throw std::runtime_error("bad type"); @@ -718,14 +719,14 @@ xml_document style_serializer::write_stylesheet() const if (fill_.get_gradient_type_string() == "linear") { - gradient_fill_node.add_attribute("degree", std::to_string(fill_.get_rotation())); + gradient_fill_node.add_attribute("degree", string::from(fill_.get_rotation())); } else if (fill_.get_gradient_type_string() == "path") { - gradient_fill_node.add_attribute("left", std::to_string(fill_.get_gradient_left())); - gradient_fill_node.add_attribute("right", std::to_string(fill_.get_gradient_right())); - gradient_fill_node.add_attribute("top", std::to_string(fill_.get_gradient_top())); - gradient_fill_node.add_attribute("bottom", std::to_string(fill_.get_gradient_bottom())); + gradient_fill_node.add_attribute("left", string::from(fill_.get_gradient_left())); + gradient_fill_node.add_attribute("right", string::from(fill_.get_gradient_right())); + gradient_fill_node.add_attribute("top", string::from(fill_.get_gradient_top())); + gradient_fill_node.add_attribute("bottom", string::from(fill_.get_gradient_bottom())); auto start_node = gradient_fill_node.add_child("stop"); start_node.add_attribute("position", "0"); @@ -738,13 +739,13 @@ xml_document style_serializer::write_stylesheet() const auto borders_node = style_sheet_node.add_child("borders"); const auto &borders = workbook_.get_borders(); - borders_node.add_attribute("count", std::to_string(borders.size())); + borders_node.add_attribute("count", string::from(borders.size())); for (const auto &border_ : borders) { auto border_node = borders_node.add_child("border"); - std::vector> sides; + std::vector> sides; sides.push_back(std::make_tuple("start", border_.start, border_.start_assigned)); sides.push_back(std::make_tuple("end", border_.end, border_.end_assigned)); sides.push_back(std::make_tuple("left", border_.left, border_.left_assigned)); @@ -757,7 +758,7 @@ xml_document style_serializer::write_stylesheet() const for (const auto &side_tuple : sides) { - std::string name = std::get<0>(side_tuple); + string name = std::get<0>(side_tuple); const side side_ = std::get<1>(side_tuple); bool assigned = std::get<2>(side_tuple); @@ -767,7 +768,7 @@ xml_document style_serializer::write_stylesheet() const if (side_.is_style_assigned()) { - std::string style_string; + string style_string; switch (side_.get_style()) { @@ -826,11 +827,11 @@ xml_document style_serializer::write_stylesheet() const if (side_.get_color().get_type() == color::type::indexed) { - color_node.add_attribute("indexed", std::to_string(side_.get_color().get_index())); + color_node.add_attribute("indexed", string::from(side_.get_color().get_index())); } else if (side_.get_color().get_type() == color::type::theme) { - color_node.add_attribute("theme", std::to_string(side_.get_color().get_theme())); + color_node.add_attribute("theme", string::from(side_.get_color().get_theme())); } else { @@ -852,22 +853,22 @@ xml_document style_serializer::write_stylesheet() const auto cell_xfs_node = style_sheet_node.add_child("cellXfs"); const auto &styles = workbook_.get_styles(); - cell_xfs_node.add_attribute("count", std::to_string(styles.size())); + cell_xfs_node.add_attribute("count", string::from(styles.size())); for (auto &style : styles) { auto xf_node = cell_xfs_node.add_child("xf"); - xf_node.add_attribute("numFmtId", std::to_string(style.get_number_format().get_id())); - xf_node.add_attribute("fontId", std::to_string(style.get_font_id())); + xf_node.add_attribute("numFmtId", string::from(style.get_number_format().get_id())); + xf_node.add_attribute("fontId", string::from(style.get_font_id())); if (style.fill_apply_) { - xf_node.add_attribute("fillId", std::to_string(style.get_fill_id())); + xf_node.add_attribute("fillId", string::from(style.get_fill_id())); } if (style.border_apply_) { - xf_node.add_attribute("borderId", std::to_string(style.get_border_id())); + xf_node.add_attribute("borderId", string::from(style.get_border_id())); } xf_node.add_attribute("applyNumberFormat", style.number_format_apply_ ? "1" : "0"); @@ -969,12 +970,12 @@ xml_document style_serializer::write_stylesheet() const bool style_serializer::write_number_formats(xml_node number_formats_node) const { - number_formats_node.add_attribute("count", std::to_string(workbook_.get_number_formats().size())); + number_formats_node.add_attribute("count", string::from(workbook_.get_number_formats().size())); for (const auto &num_fmt : workbook_.get_number_formats()) { auto num_fmt_node = number_formats_node.add_child("numFmt"); - num_fmt_node.add_attribute("numFmtId", std::to_string(num_fmt.get_id())); + num_fmt_node.add_attribute("numFmtId", string::from(num_fmt.get_id())); num_fmt_node.add_attribute("formatCode", num_fmt.get_format_string()); } diff --git a/source/serialization/tests/test_read.hpp b/source/serialization/tests/test_read.hpp index 92238ec6..e8aad916 100644 --- a/source/serialization/tests/test_read.hpp +++ b/source/serialization/tests/test_read.hpp @@ -35,7 +35,7 @@ public: void test_read_standard_workbook_from_fileobj() { auto path = PathHelper::GetDataDirectory("/genuine/empty.xlsx"); - std::ifstream fo(path, std::ios::binary); + std::ifstream fo(path.data(), std::ios::binary); xlnt::workbook wb; xlnt::excel_serializer serializer(wb); @@ -51,7 +51,7 @@ public: auto sheet2 = wb.get_sheet_by_name("Sheet2 - Numbers"); TS_ASSERT_DIFFERS(sheet2, nullptr); - TS_ASSERT_EQUALS("This is cell G5", sheet2.get_cell("G5").get_value()); + TS_ASSERT_EQUALS("This is cell G5", sheet2.get_cell("G5").get_value()); TS_ASSERT_EQUALS(18, sheet2.get_cell("D18").get_value()); TS_ASSERT_EQUALS(true, sheet2.get_cell("G9").get_value()); TS_ASSERT_EQUALS(false, sheet2.get_cell("G10").get_value()); @@ -216,8 +216,8 @@ public: void test_repair_central_directory() { - std::string data_a = "foobarbaz" + xlnt::excel_serializer::central_directory_signature(); - std::string data_b = "bazbarfoo12345678901234567890"; + xlnt::string data_a = "foobarbaz" + xlnt::excel_serializer::central_directory_signature(); + xlnt::string data_b = "bazbarfoo12345678901234567890"; auto f = xlnt::excel_serializer::repair_central_directory(data_a + data_b); TS_ASSERT_EQUALS(f, data_a + data_b.substr(0, 18)); @@ -259,7 +259,7 @@ public: ws.get_cell("A5").set_formula("SUM(A2:A4)"); // Test unicode - std::string expected = "=IF(ISBLANK(B16), \"D\xFCsseldorf\", B16)"; + xlnt::string expected = "=IF(ISBLANK(B16), \"D\xFCsseldorf\", B16)"; TS_ASSERT(ws.get_cell("A16").get_formula() == expected); // Test shared forumlae @@ -365,7 +365,7 @@ public: void test_read_content_types() { - std::vector> expected = + std::vector> expected = { {"/xl/workbook.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"}, {"/xl/worksheets/sheet1.xml", "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"}, diff --git a/source/serialization/tests/test_style_writer.hpp b/source/serialization/tests/test_style_writer.hpp index fdece5ad..85dc47d0 100644 --- a/source/serialization/tests/test_style_writer.hpp +++ b/source/serialization/tests/test_style_writer.hpp @@ -15,7 +15,7 @@ public: xlnt::style_serializer writer(wb); xlnt::xml_document observed; writer.write_number_formats(observed.add_child("numFmts")); - std::string expected = + xlnt::string expected = " " " " " "; diff --git a/source/serialization/tests/test_write.hpp b/source/serialization/tests/test_write.hpp index c74b97d1..c4d38758 100644 --- a/source/serialization/tests/test_write.hpp +++ b/source/serialization/tests/test_write.hpp @@ -179,9 +179,9 @@ public: { auto ws = wb_.create_sheet(); ws.get_cell("A1").set_hyperlink("http://test.com"); - TS_ASSERT_EQUALS("http://test.com", ws.get_cell("A1").get_value()); + TS_ASSERT_EQUALS("http://test.com", ws.get_cell("A1").get_value()); ws.get_cell("A1").set_value("test"); - TS_ASSERT_EQUALS("test", ws.get_cell("A1").get_value()); + TS_ASSERT_EQUALS("test", ws.get_cell("A1").get_value()); } void test_write_auto_filter() diff --git a/source/serialization/tests/test_write_workbook.hpp b/source/serialization/tests/test_write_workbook.hpp index 8d44f124..b77a8814 100644 --- a/source/serialization/tests/test_write_workbook.hpp +++ b/source/serialization/tests/test_write_workbook.hpp @@ -35,7 +35,7 @@ public: xlnt::workbook_serializer serializer(wb); auto observed = serializer.write_workbook(); - std::string expected_string = + xlnt::string expected_string = "" " " " " @@ -124,7 +124,7 @@ public: auto observed_node = serializer.write_named_ranges(); xlnt::xml_document observed; observed.add_child(observed_node); - std::string expected = + xlnt::string expected = "" "'Sheet'!$A$1:$B$5" ""; @@ -146,7 +146,7 @@ public: xlnt::workbook_serializer serializer(wb); auto observed = serializer.write_workbook(); - std::string expected = + xlnt::string expected = "" " " " " @@ -171,7 +171,7 @@ public: xlnt::xml_document observed; observed.from_string(archive.read("_rels/.rels")); - std::string expected = + xlnt::string expected = "" " " " " diff --git a/source/serialization/theme_serializer.cpp b/source/serialization/theme_serializer.cpp index 20b34e8c..97f79b6e 100644 --- a/source/serialization/theme_serializer.cpp +++ b/source/serialization/theme_serializer.cpp @@ -21,9 +21,9 @@ xml_document theme_serializer::write_theme(const theme &) const struct scheme_element { - std::string name; - std::string sub_element_name; - std::string val; + string name; + string sub_element_name; + string val; }; std::vector scheme_elements = { @@ -53,9 +53,9 @@ xml_document theme_serializer::write_theme(const theme &) const struct font_scheme { bool typeface; - std::string script; - std::string major; - std::string minor; + string script; + string major; + string minor; }; std::vector font_schemes = { diff --git a/source/serialization/workbook_serializer.cpp b/source/serialization/workbook_serializer.cpp index 6494c9e5..7eba316f 100644 --- a/source/serialization/workbook_serializer.cpp +++ b/source/serialization/workbook_serializer.cpp @@ -17,38 +17,47 @@ namespace { -xlnt::datetime w3cdtf_to_datetime(const std::string &string) +xlnt::datetime w3cdtf_to_datetime(const xlnt::string &string) { xlnt::datetime result(1900, 1, 1); + auto separator_index = string.find('-'); - result.year = std::stoi(string.substr(0, separator_index)); - result.month = std::stoi(string.substr(separator_index + 1, string.find('-', separator_index + 1))); + result.year = string.substr(0, separator_index).to(); + result.month = string.substr(separator_index + 1, string.find('-', separator_index + 1)).to(); separator_index = string.find('-', separator_index + 1); - result.day = std::stoi(string.substr(separator_index + 1, string.find('T', separator_index + 1))); + result.day = string.substr(separator_index + 1, string.find('T', separator_index + 1)).to(); separator_index = string.find('T', separator_index + 1); - result.hour = std::stoi(string.substr(separator_index + 1, string.find(':', separator_index + 1))); + result.hour = string.substr(separator_index + 1, string.find(':', separator_index + 1)).to(); separator_index = string.find(':', separator_index + 1); - result.minute = std::stoi(string.substr(separator_index + 1, string.find(':', separator_index + 1))); + result.minute = string.substr(separator_index + 1, string.find(':', separator_index + 1)).to(); separator_index = string.find(':', separator_index + 1); - result.second = std::stoi(string.substr(separator_index + 1, string.find('Z', separator_index + 1))); + result.second = string.substr(separator_index + 1, string.find('Z', separator_index + 1)).to(); + return result; } -std::string fill(const std::string &string, std::size_t length = 2) +xlnt::string fill(const xlnt::string &str, std::size_t length = 2) { - if (string.size() >= length) + if (str.length() >= length) { - return string; + return str; } - return std::string(length - string.size(), '0') + string; + xlnt::string result; + + for (std::size_t i = 0; i < length - str.length(); i++) + { + result.append('0'); + } + + return result + str; } -std::string datetime_to_w3cdtf(const xlnt::datetime &dt) +xlnt::string datetime_to_w3cdtf(const xlnt::datetime &dt) { - return std::to_string(dt.year) + "-" + fill(std::to_string(dt.month)) + "-" + fill(std::to_string(dt.day)) + "T" + - fill(std::to_string(dt.hour)) + ":" + fill(std::to_string(dt.minute)) + ":" + - fill(std::to_string(dt.second)) + "Z"; + return xlnt::string::from(dt.year) + "-" + fill(xlnt::string::from(dt.month)) + "-" + fill(xlnt::string::from(dt.day)) + "T" + + fill(xlnt::string::from(dt.hour)) + ":" + fill(xlnt::string::from(dt.minute)) + ":" + + fill(xlnt::string::from(dt.second)) + "Z"; } } // namespace @@ -76,12 +85,12 @@ void workbook_serializer::read_properties_core(const xml_document &xml) } if (root_node.has_child("dcterms:created")) { - std::string created_string = root_node.get_child("dcterms:created").get_text(); + string created_string = root_node.get_child("dcterms:created").get_text(); props.created = w3cdtf_to_datetime(created_string); } if (root_node.has_child("dcterms:modified")) { - std::string modified_string = root_node.get_child("dcterms:modified").get_text(); + string modified_string = root_node.get_child("dcterms:modified").get_text(); props.modified = w3cdtf_to_datetime(modified_string); } } @@ -140,12 +149,12 @@ xml_document workbook_serializer::write_properties_app() const heading_pairs_vector_node.add_child("vt:variant").add_child("vt:lpstr").set_text("Worksheets"); heading_pairs_vector_node.add_child("vt:variant") .add_child("vt:i4") - .set_text(std::to_string(workbook_.get_sheet_names().size())); + .set_text(string::from(workbook_.get_sheet_names().size())); auto titles_of_parts_node = root_node.add_child("TitlesOfParts"); auto titles_of_parts_vector_node = titles_of_parts_node.add_child("vt:vector"); titles_of_parts_vector_node.add_attribute("baseType", "lpstr"); - titles_of_parts_vector_node.add_attribute("size", std::to_string(workbook_.get_sheet_names().size())); + titles_of_parts_vector_node.add_attribute("size", string::from(workbook_.get_sheet_names().size())); for (auto ws : workbook_) { @@ -211,22 +220,22 @@ xml_document workbook_serializer::write_workbook() const if (relationship.get_type() == relationship::type::worksheet) { // TODO: this is ugly - std::string sheet_index_string = relationship.get_target_uri(); + string sheet_index_string = relationship.get_target_uri(); sheet_index_string = sheet_index_string.substr(0, sheet_index_string.find('.')); sheet_index_string = sheet_index_string.substr(sheet_index_string.find_last_of('/')); auto iter = sheet_index_string.end(); - iter--; - while (isdigit(*iter)) - iter--; + --iter; + while (isdigit((*iter).get())) + --iter; auto first_digit = iter - sheet_index_string.begin(); - sheet_index_string = sheet_index_string.substr(static_cast(first_digit + 1)); - std::size_t sheet_index = static_cast(std::stoll(sheet_index_string) - 1); + sheet_index_string = sheet_index_string.substr(static_cast(first_digit + 1)); + std::size_t sheet_index = sheet_index_string.to() - 1; auto ws = workbook_.get_sheet_by_index(sheet_index); auto sheet_node = sheets_node.add_child("sheet"); sheet_node.add_attribute("name", ws.get_title()); - sheet_node.add_attribute("sheetId", std::to_string(sheet_index + 1)); + sheet_node.add_attribute("sheetId", string::from(sheet_index + 1)); sheet_node.add_attribute("r:id", relationship.get_id()); if (ws.has_auto_filter()) @@ -235,7 +244,7 @@ xml_document workbook_serializer::write_workbook() const defined_name_node.add_attribute("name", "_xlnm._FilterDatabase"); defined_name_node.add_attribute("hidden", "1"); defined_name_node.add_attribute("localSheetId", "0"); - std::string name = + string name = "'" + ws.get_title() + "'!" + range_reference::make_absolute(ws.get_auto_filter()).to_string(); defined_name_node.set_text(name); } diff --git a/source/serialization/worksheet_serializer.cpp b/source/serialization/worksheet_serializer.cpp index a1a34ba9..929230b1 100644 --- a/source/serialization/worksheet_serializer.cpp +++ b/source/serialization/worksheet_serializer.cpp @@ -35,14 +35,14 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) auto &root_node = xml.get_child("worksheet"); auto &dimension_node = root_node.get_child("dimension"); - std::string dimension = dimension_node.get_attribute("ref"); + string dimension = dimension_node.get_attribute("ref"); auto full_range = xlnt::range_reference(dimension); auto sheet_data_node = root_node.get_child("sheetData"); if (root_node.has_child("mergeCells")) { auto merge_cells_node = root_node.get_child("mergeCells"); - auto count = std::stoull(merge_cells_node.get_attribute("count")); + auto count = merge_cells_node.get_attribute("count").to(); for (auto merge_cell_node : merge_cells_node.get_children()) { @@ -70,23 +70,23 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) continue; } - auto row_index = static_cast(std::stoull(row_node.get_attribute("r"))); + auto row_index = row_node.get_attribute("r").to(); if (row_node.has_attribute("ht")) { - sheet_.get_row_properties(row_index).height = std::stold(row_node.get_attribute("ht")); + sheet_.get_row_properties(row_index).height = row_node.get_attribute("ht").to(); } - std::string span_string = row_node.get_attribute("spans"); + string span_string = row_node.get_attribute("spans"); auto colon_index = span_string.find(':'); column_t min_column = 0; column_t max_column = 0; - if (colon_index != std::string::npos) + if (colon_index != string::npos) { - min_column = static_cast(std::stoll(span_string.substr(0, colon_index))); - max_column = static_cast(std::stoll(span_string.substr(colon_index + 1))); + min_column = static_cast(span_string.substr(0, colon_index).to()); + max_column = static_cast(span_string.substr(colon_index + 1).to()); } else { @@ -96,7 +96,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) for (column_t i = min_column; i <= max_column; i++) { - std::string address = i.column_string() + std::to_string(row_index); + string address = i.column_string() + string::from(row_index); xml_node cell_node; bool cell_found = false; @@ -119,13 +119,13 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) if (cell_found) { bool has_value = cell_node.has_child("v"); - std::string value_string = has_value ? cell_node.get_child("v").get_text() : ""; + string value_string = has_value ? cell_node.get_child("v").get_text() : ""; bool has_type = cell_node.has_attribute("t"); - std::string type = has_type ? cell_node.get_attribute("t") : ""; + string type = has_type ? cell_node.get_attribute("t") : ""; bool has_style = cell_node.has_attribute("s"); - auto style_id = static_cast(has_style ? std::stoull(cell_node.get_attribute("s")) : 0LL); + auto style_id = static_cast(has_style ? cell_node.get_attribute("s").to() : 0ULL); bool has_formula = cell_node.has_child("f"); bool has_shared_formula = has_formula && cell_node.get_child("f").has_attribute("t") && @@ -135,18 +135,18 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) if (has_formula && !has_shared_formula && !sheet_.get_parent().get_data_only()) { - std::string formula = cell_node.get_child("f").get_text(); + string formula = cell_node.get_child("f").get_text(); cell.set_formula(formula); } if (has_type && type == "inlineStr") // inline string { - std::string inline_string = cell_node.get_child("is").get_child("t").get_text(); + string inline_string = cell_node.get_child("is").get_child("t").get_text(); cell.set_value(inline_string); } else if (has_type && type == "s" && !has_formula) // shared string { - auto shared_string_index = static_cast(std::stoull(value_string)); + auto shared_string_index = value_string.to(); auto shared_string = shared_strings.at(shared_string_index); cell.set_value(shared_string); } @@ -166,7 +166,7 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) } else { - cell.set_value(std::stold(value_string)); + cell.set_value(value_string.to()); } } @@ -187,11 +187,11 @@ bool worksheet_serializer::read_worksheet(const xml_document &xml) continue; } - auto min = static_cast(std::stoull(col_node.get_attribute("min"))); - auto max = static_cast(std::stoull(col_node.get_attribute("max"))); - auto width = std::stold(col_node.get_attribute("width")); + auto min = static_cast(col_node.get_attribute("min").to()); + auto max = static_cast(col_node.get_attribute("max").to()); + auto width = col_node.get_attribute("width").to(); bool custom = col_node.get_attribute("customWidth") == "1"; - auto column_style = static_cast(col_node.has_attribute("style") ? std::stoull(col_node.get_attribute("style")) : 0); + auto column_style = static_cast(col_node.has_attribute("style") ? col_node.get_attribute("style").to() : 0ULL); for (auto column = min; column <= max; column++) { @@ -245,7 +245,7 @@ xml_document worksheet_serializer::write_worksheet() const auto sheet_view_node = sheet_views_node.add_child("sheetView"); sheet_view_node.add_attribute("workbookViewId", "0"); - std::string active_pane = "bottomRight"; + string active_pane = "bottomRight"; if (sheet_.has_frozen_panes()) { @@ -253,13 +253,13 @@ xml_document worksheet_serializer::write_worksheet() const if (sheet_.get_frozen_panes().get_column_index() > 1) { - pane_node.add_attribute("xSplit", std::to_string(sheet_.get_frozen_panes().get_column_index().index - 1)); + pane_node.add_attribute("xSplit", string::from(sheet_.get_frozen_panes().get_column_index().index - 1)); active_pane = "topRight"; } if (sheet_.get_frozen_panes().get_row() > 1) { - pane_node.add_attribute("ySplit", std::to_string(sheet_.get_frozen_panes().get_row() - 1)); + pane_node.add_attribute("ySplit", string::from(sheet_.get_frozen_panes().get_row() - 1)); active_pane = "bottomLeft"; } @@ -295,7 +295,7 @@ xml_document worksheet_serializer::write_worksheet() const } } - std::string active_cell = "A1"; + string active_cell = "A1"; selection_node.add_attribute("activeCell", active_cell); selection_node.add_attribute("sqref", active_cell); @@ -329,15 +329,15 @@ xml_document worksheet_serializer::write_worksheet() const auto col_node = cols_node.add_child("col"); - col_node.add_attribute("min", std::to_string(column.index)); - col_node.add_attribute("max", std::to_string(column.index)); - col_node.add_attribute("width", std::to_string(props.width)); - col_node.add_attribute("style", std::to_string(props.style)); + col_node.add_attribute("min", string::from(column.index)); + col_node.add_attribute("max", string::from(column.index)); + col_node.add_attribute("width", string::from(props.width)); + col_node.add_attribute("style", string::from(props.style)); col_node.add_attribute("customWidth", props.custom ? "1" : "0"); } } - std::unordered_map hyperlink_references; + std::unordered_map hyperlink_references; auto sheet_data_node = root_node.add_child("sheetData"); const auto &shared_strings = sheet_.get_parent().get_shared_strings(); @@ -366,8 +366,8 @@ xml_document worksheet_serializer::write_worksheet() const auto row_node = sheet_data_node.add_child("row"); - row_node.add_attribute("r", std::to_string(row.front().get_row())); - row_node.add_attribute("spans", (std::to_string(min) + ":" + std::to_string(max))); + row_node.add_attribute("r", string::from(row.front().get_row())); + row_node.add_attribute("spans", (string::from(min) + ":" + string::from(max))); if (sheet_.has_row_properties(row.front().get_row())) { @@ -376,11 +376,11 @@ xml_document worksheet_serializer::write_worksheet() const if (height == std::floor(height)) { - row_node.add_attribute("ht", std::to_string(static_cast(height)) + ".0"); + row_node.add_attribute("ht", string::from(static_cast(height)) + ".0"); } else { - row_node.add_attribute("ht", std::to_string(height)); + row_node.add_attribute("ht", string::from(height)); } } @@ -413,7 +413,7 @@ xml_document worksheet_serializer::write_worksheet() const for (std::size_t i = 0; i < shared_strings.size(); i++) { - if (shared_strings[i] == cell.get_value()) + if (shared_strings[i] == cell.get_value()) { match_index = static_cast(i); break; @@ -422,7 +422,7 @@ xml_document worksheet_serializer::write_worksheet() const if (match_index == -1) { - if (cell.get_value().empty()) + if (cell.get_value().empty()) { cell_node.add_attribute("t", "s"); } @@ -430,14 +430,14 @@ xml_document worksheet_serializer::write_worksheet() const { cell_node.add_attribute("t", "inlineStr"); auto inline_string_node = cell_node.add_child("is"); - inline_string_node.add_child("t").set_text(cell.get_value()); + inline_string_node.add_child("t").set_text(cell.get_value()); } } else { cell_node.add_attribute("t", "s"); auto value_node = cell_node.add_child("v"); - value_node.set_text(std::to_string(match_index)); + value_node.set_text(string::from(match_index)); } } else @@ -464,7 +464,7 @@ xml_document worksheet_serializer::write_worksheet() const if (is_integral(cell.get_value())) { - value_node.set_text(std::to_string(cell.get_value())); + value_node.set_text(string::from(cell.get_value())); } else { @@ -472,7 +472,7 @@ xml_document worksheet_serializer::write_worksheet() const ss.precision(20); ss << cell.get_value(); ss.str(); - value_node.set_text(ss.str()); + value_node.set_text(ss.str().data()); } } } @@ -486,7 +486,7 @@ xml_document worksheet_serializer::write_worksheet() const if (cell.has_style()) { - cell_node.add_attribute("s", std::to_string(cell.get_style_id())); + cell_node.add_attribute("s", string::from(cell.get_style_id())); } } } @@ -501,7 +501,7 @@ xml_document worksheet_serializer::write_worksheet() const if (!sheet_.get_merged_ranges().empty()) { auto merge_cells_node = root_node.add_child("mergeCells"); - merge_cells_node.add_attribute("count", std::to_string(sheet_.get_merged_ranges().size())); + merge_cells_node.add_attribute("count", string::from(sheet_.get_merged_ranges().size())); for (auto merged_range : sheet_.get_merged_ranges()) { @@ -535,13 +535,13 @@ xml_document worksheet_serializer::write_worksheet() const auto page_margins_node = root_node.add_child("pageMargins"); //TODO: there must be a better way to do this - auto remove_trailing_zeros = [](const std::string &n) + auto remove_trailing_zeros = [](const string &n) { auto decimal = n.find('.'); - if (decimal == std::string::npos) return n; + if (decimal == string::npos) return n; - auto index = n.size() - 1; + auto index = n.length() - 1; while (index >= decimal && n[index] == '0') { @@ -556,22 +556,22 @@ xml_document worksheet_serializer::write_worksheet() const return n.substr(0, index + 1); }; - page_margins_node.add_attribute("left", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_left()))); - page_margins_node.add_attribute("right", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_right()))); - page_margins_node.add_attribute("top", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_top()))); - page_margins_node.add_attribute("bottom", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_bottom()))); - page_margins_node.add_attribute("header", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_header()))); - page_margins_node.add_attribute("footer", remove_trailing_zeros(std::to_string(sheet_.get_page_margins().get_footer()))); + page_margins_node.add_attribute("left", remove_trailing_zeros(string::from(sheet_.get_page_margins().get_left()))); + page_margins_node.add_attribute("right", remove_trailing_zeros(string::from(sheet_.get_page_margins().get_right()))); + page_margins_node.add_attribute("top", remove_trailing_zeros(string::from(sheet_.get_page_margins().get_top()))); + page_margins_node.add_attribute("bottom", remove_trailing_zeros(string::from(sheet_.get_page_margins().get_bottom()))); + page_margins_node.add_attribute("header", remove_trailing_zeros(string::from(sheet_.get_page_margins().get_header()))); + page_margins_node.add_attribute("footer", remove_trailing_zeros(string::from(sheet_.get_page_margins().get_footer()))); if (!sheet_.get_page_setup().is_default()) { auto page_setup_node = root_node.add_child("pageSetup"); - std::string orientation_string = + string orientation_string = sheet_.get_page_setup().get_orientation() == page_setup::orientation::landscape ? "landscape" : "portrait"; page_setup_node.add_attribute("orientation", orientation_string); page_setup_node.add_attribute("paperSize", - std::to_string(static_cast(sheet_.get_page_setup().get_paper_size()))); + string::from(static_cast(sheet_.get_page_setup().get_paper_size()))); page_setup_node.add_attribute("fitToHeight", sheet_.get_page_setup().fit_to_height() ? "1" : "0"); page_setup_node.add_attribute("fitToWidth", sheet_.get_page_setup().fit_to_width() ? "1" : "0"); } @@ -580,12 +580,12 @@ xml_document worksheet_serializer::write_worksheet() const { auto header_footer_node = root_node.add_child("headerFooter"); auto odd_header_node = header_footer_node.add_child("oddHeader"); - std::string header_text = + string header_text = "&L&\"Calibri,Regular\"&K000000Left Header Text&C&\"Arial,Regular\"&6&K445566Center Header " "Text&R&\"Arial,Bold\"&8&K112233Right Header Text"; odd_header_node.set_text(header_text); auto odd_footer_node = header_footer_node.add_child("oddFooter"); - std::string footer_text = + string footer_text = "&L&\"Times New Roman,Regular\"&10&K445566Left Footer Text_x000D_And &D and &T&C&\"Times New " "Roman,Bold\"&12&K778899Center Footer Text &Z&F on &A&R&\"Times New Roman,Italic\"&14&KAABBCCRight Footer " "Text &P of &N"; diff --git a/source/serialization/xml_document.cpp b/source/serialization/xml_document.cpp index 893c1dda..06b000b2 100644 --- a/source/serialization/xml_document.cpp +++ b/source/serialization/xml_document.cpp @@ -26,14 +26,14 @@ xml_document::~xml_document() { } -void xml_document::set_encoding(const std::string &encoding) +void xml_document::set_encoding(const string &encoding) { d_->encoding = encoding; } -void xml_document::add_namespace(const std::string &id, const std::string &uri) +void xml_document::add_namespace(const string &id, const string &uri) { - d_->doc.first_child().append_attribute((id.empty() ? "xmlns" : "xmlns:" + id).c_str()).set_value(uri.c_str()); + d_->doc.first_child().append_attribute((id.empty() ? "xmlns" : "xmlns:" + id).data()).set_value(uri.data()); } xml_node xml_document::add_child(const xml_node &child) @@ -42,9 +42,9 @@ xml_node xml_document::add_child(const xml_node &child) return xml_node(detail::xml_node_impl(child_node)); } -xml_node xml_document::add_child(const std::string &child_name) +xml_node xml_document::add_child(const string &child_name) { - auto child = d_->doc.root().append_child(child_name.c_str()); + auto child = d_->doc.root().append_child(child_name.data()); return xml_node(detail::xml_node_impl(child)); } @@ -58,26 +58,26 @@ const xml_node xml_document::get_root() const return xml_node(detail::xml_node_impl(d_->doc.root())); } -std::string xml_document::to_string() const +string xml_document::to_string() const { return xml_serializer::serialize(*this); } -xml_document &xml_document::from_string(const std::string &xml_string) +xml_document &xml_document::from_string(const string &xml_string) { - d_->doc.load(xml_string.c_str()); + d_->doc.load(xml_string.data()); return *this; } -xml_node xml_document::get_child(const std::string &child_name) +xml_node xml_document::get_child(const string &child_name) { - return xml_node(detail::xml_node_impl(d_->doc.child(child_name.c_str()))); + return xml_node(detail::xml_node_impl(d_->doc.child(child_name.data()))); } -const xml_node xml_document::get_child(const std::string &child_name) const +const xml_node xml_document::get_child(const string &child_name) const { - return xml_node(detail::xml_node_impl(d_->doc.child(child_name.c_str()))); + return xml_node(detail::xml_node_impl(d_->doc.child(child_name.data()))); } } // namespace xlnt diff --git a/source/serialization/xml_node.cpp b/source/serialization/xml_node.cpp index 318befe2..2e65540b 100644 --- a/source/serialization/xml_node.cpp +++ b/source/serialization/xml_node.cpp @@ -30,14 +30,14 @@ xml_node &xml_node::operator=(const xlnt::xml_node &other) return *this; } -std::string xml_node::get_name() const +string xml_node::get_name() const { return d_->node.name(); } -void xml_node::set_name(const std::string &name) +void xml_node::set_name(const string &name) { - d_->node.set_name(name.c_str()); + d_->node.set_name(name.data()); } bool xml_node::has_text() const @@ -45,14 +45,14 @@ bool xml_node::has_text() const return d_->node.text() != nullptr; } -std::string xml_node::get_text() const +string xml_node::get_text() const { return d_->node.text().as_string(); } -void xml_node::set_text(const std::string &text) +void xml_node::set_text(const string &text) { - d_->node.text().set(text.c_str()); + d_->node.text().set(text.data()); } const std::vector xml_node::get_children() const @@ -69,7 +69,7 @@ const std::vector xml_node::get_children() const xml_node xml_node::add_child(const xml_node &child) { - auto child_node = xml_node(detail::xml_node_impl(d_->node.append_child(child.get_name().c_str()))); + auto child_node = xml_node(detail::xml_node_impl(d_->node.append_child(child.get_name().data()))); for (auto attr : child.get_attributes()) { @@ -84,9 +84,9 @@ xml_node xml_node::add_child(const xml_node &child) return child_node; } -xml_node xml_node::add_child(const std::string &child_name) +xml_node xml_node::add_child(const string &child_name) { - return xml_node(detail::xml_node_impl(d_->node.append_child(child_name.c_str()))); + return xml_node(detail::xml_node_impl(d_->node.append_child(child_name.data()))); } const std::vector xml_node::get_attributes() const @@ -95,43 +95,43 @@ const std::vector xml_node::get_attributes() const for (auto attr : d_->node.attributes()) { - attributes.push_back(std::make_pair(attr.name(), attr.value())); + attributes.push_back(std::make_pair(attr.name(), attr.value())); } return attributes; } -void xml_node::add_attribute(const std::string &name, const std::string &value) +void xml_node::add_attribute(const string &name, const string &value) { - d_->node.append_attribute(name.c_str()).set_value(value.c_str()); + d_->node.append_attribute(name.data()).set_value(value.data()); } -bool xml_node::has_attribute(const std::string &attribute_name) const +bool xml_node::has_attribute(const string &attribute_name) const { - return d_->node.attribute(attribute_name.c_str()) != nullptr; + return d_->node.attribute(attribute_name.data()) != nullptr; } -std::string xml_node::get_attribute(const std::string &attribute_name) const +string xml_node::get_attribute(const string &attribute_name) const { - return d_->node.attribute(attribute_name.c_str()).value(); + return d_->node.attribute(attribute_name.data()).value(); } -bool xml_node::has_child(const std::string &child_name) const +bool xml_node::has_child(const string &child_name) const { - return d_->node.child(child_name.c_str()) != nullptr; + return d_->node.child(child_name.data()) != nullptr; } -xml_node xml_node::get_child(const std::string &child_name) +xml_node xml_node::get_child(const string &child_name) { - return xml_node(detail::xml_node_impl(d_->node.child(child_name.c_str()))); + return xml_node(detail::xml_node_impl(d_->node.child(child_name.data()))); } -const xml_node xml_node::get_child(const std::string &child_name) const +const xml_node xml_node::get_child(const string &child_name) const { - return xml_node(detail::xml_node_impl(d_->node.child(child_name.c_str()))); + return xml_node(detail::xml_node_impl(d_->node.child(child_name.data()))); } -std::string xml_node::to_string() const +string xml_node::to_string() const { return xml_serializer::serialize_node(*this); } diff --git a/source/serialization/xml_serializer.cpp b/source/serialization/xml_serializer.cpp index bc12e5a7..7f32bed8 100644 --- a/source/serialization/xml_serializer.cpp +++ b/source/serialization/xml_serializer.cpp @@ -10,23 +10,23 @@ namespace xlnt { -std::string xml_serializer::serialize(const xml_document &xml) +string xml_serializer::serialize(const xml_document &xml) { std::ostringstream ss; xml.d_->doc.save(ss, " ", pugi::format_default, pugi::encoding_utf8); - return ss.str(); + return ss.str().data(); } -xml_document xml_serializer::deserialize(const std::string &xml_string) +xml_document xml_serializer::deserialize(const string &xml_string) { xml_document doc; - doc.d_->doc.load(xml_string.c_str()); + doc.d_->doc.load(xml_string.data()); return doc; } -std::string xml_serializer::serialize_node(const xml_node &xml) +string xml_serializer::serialize_node(const xml_node &xml) { pugi::xml_document doc; doc.append_copy(xml.d_->node); @@ -34,7 +34,7 @@ std::string xml_serializer::serialize_node(const xml_node &xml) std::ostringstream ss; doc.save(ss); - return ss.str(); + return ss.str().data(); } } // namespace xlnt diff --git a/source/styles/number_format.cpp b/source/styles/number_format.cpp index 18edd7cc..f390b049 100644 --- a/source/styles/number_format.cpp +++ b/source/styles/number_format.cpp @@ -6,10 +6,10 @@ namespace { -const std::unordered_map &builtin_formats() +const std::unordered_map &builtin_formats() { - static const std::unordered_map *formats = - new std::unordered_map + static const std::unordered_map *formats = + new std::unordered_map ({ { 0, "General" }, { 1, "0" }, @@ -281,12 +281,12 @@ number_format::number_format(std::size_t id) : number_format(from_builtin_id(id) { } -number_format::number_format(const std::string &format_string) : id_set_(false), id_(0) +number_format::number_format(const string &format_string) : id_set_(false), id_(0) { set_format_string(format_string); } -number_format::number_format(const std::string &format_string, std::size_t id) : id_set_(false), id_(0) +number_format::number_format(const string &format_string, std::size_t id) : id_set_(false), id_(0) { set_format_string(format_string, id); } @@ -295,14 +295,14 @@ number_format number_format::from_builtin_id(std::size_t builtin_id) { if (builtin_formats().find(builtin_id) == builtin_formats().end()) { - throw std::runtime_error("unknown id: " + std::to_string(builtin_id)); + throw std::runtime_error(("unknown id: " + string::from(builtin_id)).data()); } auto format_string = builtin_formats().at(builtin_id); return number_format(format_string, builtin_id); } -std::string number_format::get_format_string() const +string number_format::get_format_string() const { return format_string_; } @@ -316,7 +316,7 @@ std::size_t number_format::hash() const } -void number_format::set_format_string(const std::string &format_string) +void number_format::set_format_string(const string &format_string) { format_string_ = format_string; id_ = 0; @@ -333,7 +333,7 @@ void number_format::set_format_string(const std::string &format_string) } } -void number_format::set_format_string(const std::string &format_string, std::size_t id) +void number_format::set_format_string(const string &format_string, std::size_t id) { format_string_ = format_string; id_ = id; diff --git a/source/utils/datetime.cpp b/source/utils/datetime.cpp index ac986edb..13950d4b 100644 --- a/source/utils/datetime.cpp +++ b/source/utils/datetime.cpp @@ -119,20 +119,20 @@ bool datetime::operator==(const datetime &comparand) const minute == comparand.minute && second == comparand.second && microsecond == comparand.microsecond; } -time::time(const std::string &time_string) : hour(0), minute(0), second(0), microsecond(0) +time::time(const string &time_string) : hour(0), minute(0), second(0), microsecond(0) { - std::string remaining = time_string; + string remaining = time_string; auto colon_index = remaining.find(':'); - hour = std::stoi(remaining.substr(0, colon_index)); + hour = remaining.substr(0, colon_index).to(); remaining = remaining.substr(colon_index + 1); colon_index = remaining.find(':'); - minute = std::stoi(remaining.substr(0, colon_index)); + minute = remaining.substr(0, colon_index).to(); colon_index = remaining.find(':'); - if (colon_index != std::string::npos) + if (colon_index != string::npos) { remaining = remaining.substr(colon_index + 1); - second = std::stoi(remaining); + second = remaining.to(); } } @@ -179,10 +179,10 @@ long double datetime::to_number(calendar base_date) const return date(year, month, day).to_number(base_date) + time(hour, minute, second, microsecond).to_number(); } -std::string datetime::to_string(xlnt::calendar /*base_date*/) const +string datetime::to_string(xlnt::calendar /*base_date*/) const { - return std::to_string(year) + "/" + std::to_string(month) + "/" + std::to_string(day) + " " + std::to_string(hour) + - ":" + std::to_string(minute) + ":" + std::to_string(second) + ":" + std::to_string(microsecond); + return string::from(year) + "/" + string::from(month) + "/" + string::from(day) + " " + string::from(hour) + + ":" + string::from(minute) + ":" + string::from(second) + ":" + string::from(microsecond); } date date::today() diff --git a/source/utils/exceptions.cpp b/source/utils/exceptions.cpp index 27ce002b..942badc8 100644 --- a/source/utils/exceptions.cpp +++ b/source/utils/exceptions.cpp @@ -2,46 +2,39 @@ namespace xlnt { -sheet_title_exception::sheet_title_exception(const std::string &title) - : std::runtime_error(std::string("bad worksheet title: ") + title) +sheet_title_exception::sheet_title_exception(const string &title) { } -column_string_index_exception::column_string_index_exception() : std::runtime_error("") +column_string_index_exception::column_string_index_exception() { } -data_type_exception::data_type_exception() : std::runtime_error("") +data_type_exception::data_type_exception() { } -attribute_error::attribute_error() : std::runtime_error("") +attribute_error::attribute_error() { } named_range_exception::named_range_exception() - : std::runtime_error("named range not found or not owned by this worksheet") { } -invalid_file_exception::invalid_file_exception(const std::string &filename) - : std::runtime_error(std::string("couldn't open file: (") + filename + ")") +invalid_file_exception::invalid_file_exception(const string &filename) { } cell_coordinates_exception::cell_coordinates_exception(column_t column, row_t row) - : std::runtime_error(std::string("bad cell coordinates: (") + std::to_string(column.index) + ", " + std::to_string(row) + - ")") { } -cell_coordinates_exception::cell_coordinates_exception(const std::string &coord_string) - : std::runtime_error(std::string("bad cell coordinates: (") + (coord_string.empty() ? "" : coord_string) + ")") +cell_coordinates_exception::cell_coordinates_exception(const string &coord_string) { } illegal_character_error::illegal_character_error(char c) - : std::runtime_error(std::string("illegal character: (") + std::to_string(static_cast(c)) + ")") { } diff --git a/source/utils/string.cpp b/source/utils/string.cpp new file mode 100644 index 00000000..17dbc699 --- /dev/null +++ b/source/utils/string.cpp @@ -0,0 +1,644 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace { + +template +std::size_t count_bytes(const T *arr) +{ + std::size_t i = 0; + + while (arr[i] != T(0)) + { + i++; + } + + return i; +} + +} + +namespace xlnt { + +bool string::code_point::operator==(char rhs) const +{ + return get() == rhs; +} + +bool string::code_point::operator!=(char rhs) const +{ + return get() != rhs; +} + +bool string::code_point::operator<(char rhs) const +{ + return char(get()) < rhs; +} + +bool string::code_point::operator<=(char rhs) const +{ + return char(get()) <= rhs; +} + +bool string::code_point::operator>(char rhs) const +{ + return char(get()) > rhs; +} + +bool string::code_point::operator>=(char rhs) const +{ + return char(get()) >= rhs; +} + +string string::from(std::int8_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(std::int16_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(std::int32_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(std::int64_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(std::uint8_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(std::uint16_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(std::uint32_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(std::uint64_t i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(float i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(double i) +{ + return string(std::to_string(i).c_str()); +} + +string string::from(long double i) +{ + return string(std::to_string(i).c_str()); +} + +string::code_point &string::code_point::operator=(string::utf32_char value) +{ + utf8::append(value, data_ + index_); + + return *this; +} + +string::utf32_char string::code_point::get() const +{ + return utf8::peek_next(data_ + index_, data_ + end_); +} + +template<> +xlnt::string::common_iterator &xlnt::string::common_iterator::operator--() +{ + auto iter = current_.data_ + current_.index_; + utf8::prior(iter, current_.data_); + current_.index_ = iter - current_.data_; + + return *this; +} + +template<> +xlnt::string::common_iterator &xlnt::string::common_iterator::operator--() +{ + auto iter = current_.data_ + current_.index_; + utf8::prior(iter, current_.data_); + current_.index_ = iter - current_.data_; + + return *this; +} + +template<> +xlnt::string::common_iterator &xlnt::string::common_iterator::operator++() +{ + auto iter = current_.data_ + current_.index_; + utf8::advance(iter, 1, current_.data_ + current_.end_); + current_.index_ = iter - current_.data_; + + return *this; +} + +template<> +xlnt::string::common_iterator &xlnt::string::common_iterator::operator++() +{ + auto iter = current_.data_ + current_.index_; + utf8::advance(iter, 1, current_.data_ + current_.end_); + current_.index_ = iter - current_.data_; + + return *this; +} + +string::string(size_type initial_size) + : length_(0), + data_(new std::vector) +{ + data_->resize(initial_size + 1); + data_->back() = '\0'; +} + +string::string() : string(size_type(0)) +{ +} + +string::string(string &&str) : string() +{ + swap(*this, str); +} + +string::string(const string &str) : string(str, 0) +{ +} + +string::string(const string &str, size_type offset) : string(str, offset, str.length() - offset) +{ +} + +string::string(const string &str, size_type offset, size_type len) : string() +{ + *this = str.substr(offset, len); +} + +string::string(const utf_mb_wide_string str) : string() +{ + data_->clear(); + utf8::utf16to8(str, str + count_bytes(str), std::back_inserter(*data_)); + data_->push_back('\0'); + + length_ = utf8::distance(data(), data() + data_->size() - 1); +} + +string::string(const utf8_string str) : string() +{ + data_->clear(); + std::copy(str, str + count_bytes(str), std::back_inserter(*data_)); + data_->push_back('\0'); + + length_ = utf8::distance(data(), data() + data_->size() - 1); +} + +string::string(const utf16_string str) : string() +{ + data_->clear(); + utf8::utf16to8(str, str + count_bytes(str), std::back_inserter(*data_)); + data_->push_back('\0'); + + length_ = utf8::distance(data(), data() + data_->size() - 1); +} + +string::string(const utf32_string str) : string() +{ + data_->clear(); + utf8::utf32to8(str, str + count_bytes(str), std::back_inserter(*data_)); + data_->push_back('\0'); + + length_ = utf8::distance(data(), data() + data_->size() - 1); +} + +string::~string() +{ + delete data_; +} + +string string::to_upper() const +{ + return *this; +} + +string string::to_lower() const +{ + return *this; +} + +string string::substr(size_type offset) const +{ + return substr(offset, length() - offset); +} + +string string::substr(size_type offset, size_type len) const +{ + auto iter = begin() + offset; + size_type i = 0; + string result; + + while (i++ < len && iter != end()) + { + result.append(*iter); + ++iter; + } + + return result; +} + +string::code_point string::back() +{ + return *(begin() + length_ + -1); +} + +const string::code_point string::back() const +{ + return *(begin() + length_ + -1); +} + +string::code_point string::front() +{ + return *begin(); +} + +const string::code_point string::front() const +{ + return *begin(); +} + +string::size_type string::find(code_point c) const +{ + return find(c, 0); +} + +string::size_type string::find(char c) const +{ + return find(c, 0); +} + +string::size_type string::find(string str) const +{ + return find(str, 0); +} + +string::size_type string::find(code_point c, size_type offset) const +{ + auto iter = begin() + offset; + + while (iter != end()) + { + if ((*iter).get() == c.get()) + { + return offset; + } + + ++iter; + offset++; + } + + return npos; +} + +string::size_type string::find(char c, size_type offset) const +{ + auto iter = begin() + offset; + + while (iter != end()) + { + if (*iter == c) + { + return offset; + } + + ++iter; + offset++; + } + + return npos; +} + +string::size_type string::find(string str, size_type offset) const +{ + return 0; +} + +string::size_type string::find_last_of(code_point c) const +{ + return find_last_of(c, 0); +} + +string::size_type string::find_last_of(char c) const +{ + return find_last_of(c, 0); +} + +string::size_type string::find_last_of(string str) const +{ + return find_last_of(str, 0); +} + +string::size_type string::find_last_of(code_point c, size_type offset) const +{ + return 0; +} +string::size_type string::find_last_of(char c, size_type offset) const +{ + return 0; +} + +string::size_type string::find_last_of(string str, size_type offset) const +{ + return 0; +} + +string::size_type string::find_first_of(string str) const +{ + return find_first_of(str, 0); +} + +string::size_type string::find_first_of(string str, size_type offset) const +{ + return 0; +} + +string::size_type string::find_first_not_of(string str) const +{ + return find_first_not_of(str, 0); +} + +string::size_type string::find_first_not_of(string str, size_type offset) const +{ + return 0; +} + +string::size_type string::find_last_not_of(string str) const +{ + return find_last_not_of(str, 0); +} + +string::size_type string::find_last_not_of(string str, size_type offset) const +{ + return 0; +} + +void string::clear() +{ + length_ = 0; + data_->clear(); + data_->push_back('\0'); +} + +template<> +std::size_t string::to() const +{ + return std::stoull(std::string(data())); +} + +template<> +std::uint32_t string::to() const +{ + return std::stoul(std::string(data())); +} + +template<> +std::int32_t string::to() const +{ + return std::stoi(std::string(data())); +} + +template<> +long double string::to() const +{ + return std::stold(std::string(data())); +} + +int string::to_hex() const +{ + return 0; +} + +void string::remove(code_point iter) +{ + +} + +string &string::operator=(string rhs) +{ + swap(*this, rhs); + + return *this; +} + +string::iterator string::begin() +{ + return iterator(data(), 0, length_); +} + +string::const_iterator string::cbegin() const +{ + return const_iterator(data(), 0, length_); +} + +string::iterator string::end() +{ + return iterator(data(), length_, length_); +} + +string::const_iterator string::cend() const +{ + return const_iterator(data(), length_, length_); +} + +string::byte_pointer string::data() +{ + return &data_->front(); +} + +string::const_byte_pointer string::data() const +{ + return &data_->front(); +} + +std::size_t string::hash() const +{ + static std::hash hasher; + return hasher(std::string(data())); +} + +std::size_t string::bytes() const +{ + return data_->size(); +} + +void string::append(char c) +{ + data_->back() = c; + data_->push_back('\0'); + + length_++; +} + +void string::append(wchar_t c) +{ + data_->pop_back(); + utf8::utf16to8(&c, &c + 1, std::back_inserter(*data_)); + data_->push_back('\0'); + + length_++; +} + +void string::append(char16_t c) +{ + data_->pop_back(); + utf8::utf16to8(&c, &c + 1, std::back_inserter(*data_)); + data_->push_back('\0'); + + length_++; +} + +void string::append(char32_t c) +{ + data_->pop_back(); + utf8::utf32to8(&c, &c + 1, std::back_inserter(*data_)); + data_->push_back('\0'); + + length_++; +} + +void string::append(string str) +{ + for (auto c : str) + { + append(c); + } +} + +void string::append(code_point c) +{ + append(c.get()); +} + +string::code_point string::at(size_type index) +{ + auto iter = begin(); + size_type i = 0; + + while (i < index) ++iter; + + return *iter; +} + +const string::code_point string::at(size_type index) const +{ + auto iter = begin(); + size_type i = 0; + + while (i < index) ++iter; + + return *iter; +} + +bool string::operator==(const_byte_pointer str) const +{ + return *this == string(str); +} + +bool string::operator==(const string &str) const +{ + if (length() != str.length()) return false; + + auto left_iter = begin(); + auto right_iter = str.begin(); + + while (left_iter != end() && right_iter != str.end()) + { + if ((*left_iter).get() != (*right_iter).get()) + { + return false; + } + + ++left_iter; + ++right_iter; + } + + return (left_iter == end()) != (right_iter == end()); +} + +string::code_point string::operator[](size_type index) +{ + return at(index); +} + +const string::code_point string::operator[](size_type index) const +{ + return at(index); +} + +string string::operator+(const string &rhs) const +{ + string copy(*this); + copy.append(rhs); + + return copy; +} + +string &string::operator+=(const string &rhs) +{ + append(rhs); + + return *this; +} + +void swap(string &left, string &right) +{ + using std::swap; + + swap(left.length_, right.length_); + swap(left.data_, right.data_); +} + +std::ostream &operator<<(std::ostream &left, string &right) +{ + auto d = right.data(); + std::size_t i = 0; + + while (d[i] != '\0') + { + left << d[i]; + i++; + } + + return left; +} + +string operator+(const char *left, const string &right) +{ + return string(left) + right; +} + +bool string::operator<(const string &other) const +{ + return std::string(data()) < std::string(other.data()); +} + +} // namespace xlnt diff --git a/source/utils/tests/test_zip_file.hpp b/source/utils/tests/test_zip_file.hpp index 06db3807..ccc2fda5 100644 --- a/source/utils/tests/test_zip_file.hpp +++ b/source/utils/tests/test_zip_file.hpp @@ -19,7 +19,7 @@ public: void remove_temp_file() { - std::remove(temp_file.GetFilename().c_str()); + std::remove(temp_file.GetFilename().data()); } void make_temp_directory() @@ -30,14 +30,14 @@ public: { } - bool files_equal(const std::string &a, const std::string &b) + bool files_equal(const xlnt::string &a, const xlnt::string &b) { if(a == b) { return true; } - std::ifstream stream_a(a, std::ios::binary), stream_b(a, std::ios::binary); + std::ifstream stream_a(a.data(), std::ios::binary), stream_b(a.data(), std::ios::binary); while(stream_a && stream_b) { @@ -63,9 +63,9 @@ public: { remove_temp_file(); { - std::ifstream in_stream(existing_file, std::ios::binary); + std::ifstream in_stream(existing_file.data(), std::ios::binary); xlnt::zip_file f(in_stream); - std::ofstream out_stream(temp_file.GetFilename(), std::ios::binary); + std::ofstream out_stream(temp_file.GetFilename().data(), std::ios::binary); f.save(out_stream); } TS_ASSERT(files_equal(existing_file, temp_file.GetFilename())); @@ -78,7 +78,7 @@ public: xlnt::zip_file f; std::vector source_bytes, result_bytes; - std::ifstream in_stream(existing_file, std::ios::binary); + std::ifstream in_stream(existing_file.data(), std::ios::binary); while(in_stream) { source_bytes.push_back((unsigned char)in_stream.get()); @@ -149,7 +149,7 @@ public: xlnt::zip_file f(existing_file); std::stringstream ss; ss << f.open("[Content_Types].xml").rdbuf(); - std::string result = ss.str(); + xlnt::string result = ss.str().c_str(); TS_ASSERT(result == expected_content_types_string); } @@ -158,7 +158,7 @@ public: xlnt::zip_file f(existing_file); std::stringstream ss; ss << f.open("[Content_Types].xml").rdbuf(); - std::string result = ss.str(); + xlnt::string result = ss.str().data(); TS_ASSERT(result == expected_content_types_string); } @@ -197,7 +197,7 @@ public: xlnt::zip_file f(existing_file); std::stringstream ss; f.printdir(ss); - auto printed = ss.str(); + xlnt::string printed = ss.str().data(); TS_ASSERT(printed == expected_printdir_string); } @@ -232,7 +232,7 @@ public: { TS_ASSERT(f2.read(info) == expected_atxt_string); } - else if(info.filename.substr(info.filename.size() - 17) == "sharedStrings.xml") + else if(info.filename.substr(info.filename.length() - 17) == "sharedStrings.xml") { TS_ASSERT(f2.read(info) == expected_atxt_string); } @@ -276,8 +276,8 @@ public: private: TemporaryFile temp_file; - std::string existing_file; - std::string expected_content_types_string; - std::string expected_atxt_string; - std::string expected_printdir_string; + xlnt::string existing_file; + xlnt::string expected_content_types_string; + xlnt::string expected_atxt_string; + xlnt::string expected_printdir_string; }; diff --git a/source/workbook/named_range.cpp b/source/workbook/named_range.cpp index 2fa5b9a2..d23b9384 100644 --- a/source/workbook/named_range.cpp +++ b/source/workbook/named_range.cpp @@ -12,13 +12,13 @@ namespace { /// /// This should maybe be in a utility header so it can be used elsewhere. /// -std::vector split_string(const std::string &string, char delim) +std::vector split_string(const xlnt::string &string, char delim) { - std::vector split; - std::string::size_type previous_index = 0; + std::vector split; + xlnt::string::size_type previous_index = 0; auto separator_index = string.find(delim); - while (separator_index != std::string::npos) + while (separator_index != xlnt::string::npos) { auto part = string.substr(previous_index, separator_index - previous_index); split.push_back(part); @@ -36,9 +36,9 @@ std::vector split_string(const std::string &string, char delim) namespace xlnt { -std::vector> split_named_range(const std::string &named_range_string) +std::vector> split_named_range(const string &named_range_string) { - std::vector> final; + std::vector> final; for (auto part : split_string(named_range_string, ',')) { @@ -74,7 +74,7 @@ named_range::named_range(const named_range &other) *this = other; } -named_range::named_range(const std::string &name, const std::vector &targets) +named_range::named_range(const string &name, const std::vector &targets) : name_(name), targets_(targets) { } diff --git a/source/workbook/tests/test_named_range.hpp b/source/workbook/tests/test_named_range.hpp index 0c17a8b2..444fb359 100644 --- a/source/workbook/tests/test_named_range.hpp +++ b/source/workbook/tests/test_named_range.hpp @@ -10,9 +10,9 @@ class test_named_range : public CxxTest::TestSuite public: void test_split() { - using string_pair = std::pair; + using string_pair = std::pair; using string_pair_vector = std::vector; - using expected_pair = std::pair; + using expected_pair = std::pair; std::vector expected_pairs = { diff --git a/source/workbook/tests/test_workbook.hpp b/source/workbook/tests/test_workbook.hpp index e07b0901..b8c7056e 100644 --- a/source/workbook/tests/test_workbook.hpp +++ b/source/workbook/tests/test_workbook.hpp @@ -48,8 +48,8 @@ public: xlnt::workbook wb; auto new_sheet = wb.create_sheet(); std::string title = "my sheet"; - new_sheet.set_title(title); - auto found_sheet = wb.get_sheet_by_name(title); + new_sheet.set_title(title.c_str()); + auto found_sheet = wb.get_sheet_by_name(title.c_str()); TS_ASSERT_EQUALS(new_sheet, found_sheet); } @@ -58,8 +58,8 @@ public: xlnt::workbook wb; auto new_sheet = wb.create_sheet(); std::string title = "my sheet"; - new_sheet.set_title(title); - auto found_sheet = wb.get_sheet_by_name(title); + new_sheet.set_title(title.c_str()); + auto found_sheet = wb.get_sheet_by_name(title.c_str()); TS_ASSERT_EQUALS(new_sheet, found_sheet); TS_ASSERT_EQUALS(wb.get_sheet_by_name("NotThere"), nullptr); @@ -78,7 +78,7 @@ public: xlnt::workbook wb; wb.clear(); - std::vector names = {"NewSheet", "NewSheet1", "NewSheet2", "NewSheet3", "NewSheet4", "NewSheet5"}; + std::vector names = {"NewSheet", "NewSheet1", "NewSheet2", "NewSheet3", "NewSheet4", "NewSheet5"}; for(std::size_t count = 0; count < names.size(); count++) { @@ -121,8 +121,8 @@ public: xlnt::workbook wb; auto new_sheet = wb.create_sheet(); std::string title = "my sheet"; - new_sheet.set_title(title); - auto found_sheet = wb.get_sheet_by_name(title); + new_sheet.set_title(title.c_str()); + auto found_sheet = wb.get_sheet_by_name(title.c_str()); TS_ASSERT_EQUALS(new_sheet, found_sheet); } diff --git a/source/workbook/workbook.cpp b/source/workbook/workbook.cpp index dc5a8929..977fa04e 100644 --- a/source/workbook/workbook.cpp +++ b/source/workbook/workbook.cpp @@ -122,7 +122,7 @@ bool workbook::const_iterator::operator==(const const_iterator &comparand) const return index_ == comparand.index_ && wb_ == comparand.wb_; } -worksheet workbook::get_sheet_by_name(const std::string &name) +worksheet workbook::get_sheet_by_name(const string &name) { for (auto &impl : d_->worksheets_) { @@ -150,7 +150,7 @@ worksheet workbook::get_active_sheet() return worksheet(&d_->worksheets_[d_->active_sheet_index_]); } -bool workbook::has_named_range(const std::string &name) const +bool workbook::has_named_range(const string &name) const { for (auto worksheet : *this) { @@ -164,18 +164,18 @@ bool workbook::has_named_range(const std::string &name) const worksheet workbook::create_sheet() { - std::string title = "Sheet1"; + string title = "Sheet1"; int index = 1; while (get_sheet_by_name(title) != nullptr) { - title = "Sheet" + std::to_string(++index); + title = "Sheet" + string::from(++index); } - std::string sheet_filename = "worksheets/sheet" + std::to_string(d_->worksheets_.size() + 1) + ".xml"; + string sheet_filename = "worksheets/sheet" + string::from(d_->worksheets_.size() + 1) + ".xml"; d_->worksheets_.push_back(detail::worksheet_impl(this, title)); - create_relationship("rId" + std::to_string(d_->relationships_.size() + 1), + create_relationship("rId" + string::from(d_->relationships_.size() + 1), sheet_filename, relationship::type::worksheet); @@ -217,7 +217,7 @@ int workbook::get_index(xlnt::worksheet worksheet) throw std::runtime_error("worksheet isn't owned by this workbook"); } -void workbook::create_named_range(const std::string &name, worksheet range_owner, const range_reference &reference) +void workbook::create_named_range(const string &name, worksheet range_owner, const range_reference &reference) { auto match = get_sheet_by_name(range_owner.get_title()); if (match != nullptr) @@ -228,7 +228,7 @@ void workbook::create_named_range(const std::string &name, worksheet range_owner throw std::runtime_error("worksheet isn't owned by this workbook"); } -void workbook::remove_named_range(const std::string &name) +void workbook::remove_named_range(const string &name) { for (auto ws : *this) { @@ -242,7 +242,7 @@ void workbook::remove_named_range(const std::string &name) throw std::runtime_error("named range not found"); } -range workbook::get_named_range(const std::string &name) +range workbook::get_named_range(const string &name) { for (auto ws : *this) { @@ -271,7 +271,7 @@ bool workbook::load(const std::vector &data) return true; } -bool workbook::load(const std::string &filename) +bool workbook::load(const string &filename) { excel_serializer serializer_(*this); serializer_.load_workbook(filename); @@ -289,12 +289,12 @@ bool workbook::get_guess_types() const return d_->guess_types_; } -void workbook::create_relationship(const std::string &id, const std::string &target, relationship::type type) +void workbook::create_relationship(const string &id, const string &target, relationship::type type) { d_->relationships_.push_back(relationship(type, id, target)); } -relationship workbook::get_relationship(const std::string &id) const +relationship workbook::get_relationship(const string &id) const { for (auto &rel : d_->relationships_) { @@ -317,7 +317,7 @@ void workbook::remove_sheet(worksheet ws) throw std::runtime_error("worksheet not owned by this workbook"); } - auto sheet_filename = "worksheets/sheet" + std::to_string(d_->worksheets_.size()) + ".xml"; + auto sheet_filename = "worksheets/sheet" + string::from(d_->worksheets_.size()) + ".xml"; auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(), [=](relationship &r) { return r.get_target_uri() == sheet_filename; }); @@ -344,22 +344,22 @@ worksheet workbook::create_sheet(std::size_t index) } // TODO: There should be a better way to do this... -std::size_t workbook::index_from_ws_filename(const std::string &ws_filename) +std::size_t workbook::index_from_ws_filename(const string &ws_filename) { - std::string sheet_index_string(ws_filename); + string sheet_index_string(ws_filename); sheet_index_string = sheet_index_string.substr(0, sheet_index_string.find('.')); sheet_index_string = sheet_index_string.substr(sheet_index_string.find_last_of('/')); auto iter = sheet_index_string.end(); - iter--; - while (isdigit(*iter)) - iter--; + --iter; + while (isdigit((*iter).get())) + --iter; auto first_digit = static_cast(iter - sheet_index_string.begin()); sheet_index_string = sheet_index_string.substr(first_digit + 1); - auto sheet_index = static_cast(std::stoll(sheet_index_string) - 1); + auto sheet_index = sheet_index_string.to() - 1; return sheet_index; } -worksheet workbook::create_sheet(const std::string &title, const relationship &rel) +worksheet workbook::create_sheet(const string &title, const relationship &rel) { d_->worksheets_.push_back(detail::worksheet_impl(this, title)); @@ -373,7 +373,7 @@ worksheet workbook::create_sheet(const std::string &title, const relationship &r return worksheet(&d_->worksheets_[index]); } -worksheet workbook::create_sheet(std::size_t index, const std::string &title) +worksheet workbook::create_sheet(std::size_t index, const string &title) { auto ws = create_sheet(index); ws.set_title(title); @@ -381,21 +381,21 @@ worksheet workbook::create_sheet(std::size_t index, const std::string &title) return ws; } -worksheet workbook::create_sheet(const std::string &title) +worksheet workbook::create_sheet(const string &title) { if (title.length() > 31) { throw sheet_title_exception(title); } - if (std::find_if(title.begin(), title.end(), [](char c) { + if (std::find_if(title.data(), title.data() + title.bytes(), [](char c) { return c == '*' || c == ':' || c == '/' || c == '\\' || c == '?' || c == '[' || c == ']'; - }) != title.end()) + }) != title.data() + title.bytes()) { throw sheet_title_exception(title); } - std::string unique_title = title; + string unique_title = title; if (std::find_if(d_->worksheets_.begin(), d_->worksheets_.end(), [&](detail::worksheet_impl &ws) { return worksheet(&ws).get_title() == unique_title; @@ -407,7 +407,7 @@ worksheet workbook::create_sheet(const std::string &title) return worksheet(&ws).get_title() == unique_title; }) != d_->worksheets_.end()) { - unique_title = title + std::to_string(suffix); + unique_title = title + string::from(suffix); suffix++; } } @@ -438,9 +438,9 @@ workbook::const_iterator workbook::cend() const return const_iterator(*this, d_->worksheets_.size()); } -std::vector workbook::get_sheet_names() const +std::vector workbook::get_sheet_names() const { - std::vector names; + std::vector names; for (auto ws : *this) { @@ -450,7 +450,7 @@ std::vector workbook::get_sheet_names() const return names; } -worksheet workbook::operator[](const std::string &name) +worksheet workbook::operator[](const string &name) { return get_sheet_by_name(name); } @@ -477,7 +477,7 @@ bool workbook::save(std::vector &data) return true; } -bool workbook::save(const std::string &filename) +bool workbook::save(const string &filename) { excel_serializer serializer(*this); serializer.save_workbook(filename); @@ -589,7 +589,7 @@ void workbook::add_number_format(const number_format &number_format_) } } -void workbook::set_code_name(const std::string & /*code_name*/) +void workbook::set_code_name(const string & /*code_name*/) { } @@ -903,17 +903,17 @@ const std::vector &workbook::get_root_relationships() const return d_->root_relationships_; } -std::vector &workbook::get_shared_strings() +std::vector &workbook::get_shared_strings() { return d_->shared_strings_; } -const std::vector &workbook::get_shared_strings() const +const std::vector &workbook::get_shared_strings() const { return d_->shared_strings_; } -void workbook::add_shared_string(const std::string &shared) +void workbook::add_shared_string(const string &shared) { //TODO: inefficient, use a set or something? for(auto &s : d_->shared_strings_) diff --git a/source/worksheet/range.cpp b/source/worksheet/range.cpp index f4570a1d..bbb46b6f 100644 --- a/source/worksheet/range.cpp +++ b/source/worksheet/range.cpp @@ -146,10 +146,9 @@ cell_vector range::get_vector(std::size_t vector_index) return cell_vector(ws_, reference, order_); } - range_reference reference( - static_cast(static_cast(ref_.get_top_left().get_column().index) + vector_index), + range_reference reference(column_t(static_cast(ref_.get_top_left().get_column().index + vector_index)), ref_.get_top_left().get_row(), - static_cast(static_cast(ref_.get_top_left().get_column().index) + vector_index), + column_t(static_cast(ref_.get_top_left().get_column().index + vector_index)), ref_.get_bottom_right().get_row()); return cell_vector(ws_, reference, order_); diff --git a/source/worksheet/range_reference.cpp b/source/worksheet/range_reference.cpp index 007bdfbb..0e61d7a7 100644 --- a/source/worksheet/range_reference.cpp +++ b/source/worksheet/range_reference.cpp @@ -16,15 +16,15 @@ range_reference::range_reference() : range_reference("A1") { } -range_reference::range_reference(const char *range_string) : range_reference(std::string(range_string)) +range_reference::range_reference(const char *range_string) : range_reference(string(range_string)) { } -range_reference::range_reference(const std::string &range_string) : top_left_("A1"), bottom_right_("A1") +range_reference::range_reference(const string &range_string) : top_left_("A1"), bottom_right_("A1") { auto colon_index = range_string.find(':'); - if (colon_index != std::string::npos) + if (colon_index != string::npos) { top_left_ = cell_reference(range_string.substr(0, colon_index)); bottom_right_ = cell_reference(range_string.substr(colon_index + 1)); @@ -68,7 +68,7 @@ bool range_reference::is_single_cell() const return get_width() == 0 && get_height() == 0; } -std::string range_reference::to_string() const +string range_reference::to_string() const { return top_left_.to_string() + ":" + bottom_right_.to_string(); } diff --git a/source/worksheet/sheet_protection.cpp b/source/worksheet/sheet_protection.cpp index ed629683..b03e1655 100644 --- a/source/worksheet/sheet_protection.cpp +++ b/source/worksheet/sheet_protection.cpp @@ -6,26 +6,26 @@ namespace xlnt { -void sheet_protection::set_password(const std::string &password) +void sheet_protection::set_password(const string &password) { hashed_password_ = hash_password(password); } template -std::string int_to_hex(T i) +string int_to_hex(T i) { std::stringstream stream; stream << std::hex << i; - return stream.str(); + return stream.str().c_str(); } -std::string sheet_protection::hash_password(const std::string &plaintext_password) +string sheet_protection::hash_password(const string &plaintext_password) { int password = 0x0000; - int i = 1; - for (auto character : plaintext_password) + for (int i = 1; i <= plaintext_password.bytes(); i++) { + char character = plaintext_password.data()[i - 1]; int value = character << i; int rotated_bits = value >> 15; value &= 0x7fff; @@ -33,12 +33,17 @@ std::string sheet_protection::hash_password(const std::string &plaintext_passwor i++; } - password ^= plaintext_password.size(); + password ^= plaintext_password.bytes(); password ^= 0xCE4B; - std::string hashed = int_to_hex(password); - std::transform(hashed.begin(), hashed.end(), hashed.begin(), - [](char c) { return std::toupper(c, std::locale::classic()); }); + string hashed = int_to_hex(password); + auto iter = hashed.data(); + + while (iter != hashed.data() + hashed.bytes()) + { + *iter = std::toupper(*iter, std::locale::classic()); + } + return hashed; } } diff --git a/source/worksheet/tests/test_worksheet.hpp b/source/worksheet/tests/test_worksheet.hpp index 3e809da5..6a65d64d 100644 --- a/source/worksheet/tests/test_worksheet.hpp +++ b/source/worksheet/tests/test_worksheet.hpp @@ -35,7 +35,7 @@ public: { xlnt::worksheet ws(wb_); - const std::vector> expected = + const std::vector> expected = { { "A1", "B1", "C1" }, { "A2", "B2", "C2" }, @@ -64,7 +64,7 @@ public: { std::size_t row = 0; std::size_t column = 0; - std::string coordinate = "A1"; + xlnt::string coordinate = "A1"; xlnt::worksheet ws(wb_); @@ -85,7 +85,7 @@ public: { xlnt::worksheet ws(wb_); - const std::vector> expected = + const std::vector> expected = { { "A1", "B1", "C1" }, { "A2", "B2", "C2" }, @@ -115,7 +115,7 @@ public: xlnt::worksheet ws(wb_); auto rows = ws.rows("A1:C4", 1, 3); - const std::vector> expected = + const std::vector> expected = { { "D2", "E2", "F2" }, { "D3", "E3", "F3" }, @@ -222,9 +222,9 @@ public: { xlnt::worksheet ws(wb_); ws.get_cell("A1").set_hyperlink("http://test.com"); - TS_ASSERT_EQUALS("http://test.com", ws.get_cell("A1").get_value()); + TS_ASSERT_EQUALS("http://test.com", ws.get_cell("A1").get_value()); ws.get_cell("A1").set_value("test"); - TS_ASSERT_EQUALS("test", ws.get_cell("A1").get_value()); + TS_ASSERT_EQUALS("test", ws.get_cell("A1").get_value()); TS_ASSERT_EQUALS(ws.get_cell("A1").get_hyperlink().get_target_uri(), "http://test.com"); } @@ -243,25 +243,25 @@ public: void test_append() { xlnt::worksheet ws(wb_); - ws.append(std::vector {"value"}); - TS_ASSERT_EQUALS("value", ws.get_cell("A1").get_value()); + ws.append(std::vector {"value"}); + TS_ASSERT_EQUALS("value", ws.get_cell("A1").get_value()); } void test_append_list() { xlnt::worksheet ws(wb_); - ws.append(std::vector {"This is A1", "This is B1"}); + ws.append(std::vector {"This is A1", "This is B1"}); - TS_ASSERT_EQUALS("This is A1", ws.get_cell("A1").get_value()); - TS_ASSERT_EQUALS("This is B1", ws.get_cell("B1").get_value()); + TS_ASSERT_EQUALS("This is A1", ws.get_cell("A1").get_value()); + TS_ASSERT_EQUALS("This is B1", ws.get_cell("B1").get_value()); } void test_append_dict_letter() { xlnt::worksheet ws(wb_); - const std::unordered_map dict_letter = + const std::unordered_map dict_letter = { { "A", "This is A1" }, { "C", "This is C1" } @@ -269,15 +269,15 @@ public: ws.append(dict_letter); - TS_ASSERT_EQUALS("This is A1", ws.get_cell("A1").get_value()); - TS_ASSERT_EQUALS("This is C1", ws.get_cell("C1").get_value()); + TS_ASSERT_EQUALS("This is A1", ws.get_cell("A1").get_value()); + TS_ASSERT_EQUALS("This is C1", ws.get_cell("C1").get_value()); } void test_append_dict_index() { xlnt::worksheet ws(wb_); - const std::unordered_map dict_index = + const std::unordered_map dict_index = { { 1, "This is A1" }, { 3, "This is C1" } @@ -285,8 +285,8 @@ public: ws.append(dict_index); - TS_ASSERT_EQUALS("This is A1", ws.get_cell("A1").get_value()); - TS_ASSERT_EQUALS("This is C1", ws.get_cell("C1").get_value()); + TS_ASSERT_EQUALS("This is A1", ws.get_cell("A1").get_value()); + TS_ASSERT_EQUALS("This is C1", ws.get_cell("C1").get_value()); } void _test_bad_append() @@ -317,15 +317,15 @@ public: { xlnt::worksheet ws(wb_); - ws.append(std::vector {"This is A1", "This is B1"}); - ws.append(std::vector {"This is A2", "This is B2"}); + ws.append(std::vector {"This is A1", "This is B1"}); + ws.append(std::vector {"This is A2", "This is B2"}); auto vals = ws.get_range("A1:B2"); - TS_ASSERT_EQUALS(vals[0][0].get_value(), "This is A1"); - TS_ASSERT_EQUALS(vals[0][1].get_value(), "This is B1"); - TS_ASSERT_EQUALS(vals[1][0].get_value(), "This is A2"); - TS_ASSERT_EQUALS(vals[1][1].get_value(), "This is B2"); + TS_ASSERT_EQUALS(vals[0][0].get_value(), "This is A1"); + TS_ASSERT_EQUALS(vals[0][1].get_value(), "This is B1"); + TS_ASSERT_EQUALS(vals[1][0].get_value(), "This is A2"); + TS_ASSERT_EQUALS(vals[1][1].get_value(), "This is B2"); } void _test_append_cell() @@ -358,9 +358,9 @@ public: auto first_row = rows[0]; auto last_row = rows[8]; - TS_ASSERT_EQUALS(first_row[0].get_value(), "first"); + TS_ASSERT_EQUALS(first_row[0].get_value(), "first"); TS_ASSERT_EQUALS(first_row[0].get_reference(), "A1"); - TS_ASSERT_EQUALS(last_row[2].get_value(), "last"); + TS_ASSERT_EQUALS(last_row[2].get_value(), "last"); } void test_no_cols() @@ -382,8 +382,8 @@ public: TS_ASSERT_EQUALS(cols.length(), 3); - TS_ASSERT_EQUALS(cols[0][0].get_value(), "first"); - TS_ASSERT_EQUALS(cols[2][8].get_value(), "last"); + TS_ASSERT_EQUALS(cols[0][0].get_value(), "first"); + TS_ASSERT_EQUALS(cols[2][8].get_value(), "last"); } void test_auto_filter() @@ -578,7 +578,7 @@ public: void test_set_bad_title() { - std::string title(50, 'X'); + xlnt::string title(std::string(50, 'X').c_str()); TS_ASSERT_THROWS(wb_.create_sheet(title), xlnt::sheet_title_exception); } @@ -884,7 +884,7 @@ public: ws.get_header_footer().get_right_footer().set_font_size(14); ws.get_header_footer().get_right_footer().set_font_color("AABBCC"); - std::string expected_xml_string = + xlnt::string expected_xml_string = "" " " " " diff --git a/source/worksheet/worksheet.cpp b/source/worksheet/worksheet.cpp index 0ef082c2..8ce3b6e3 100644 --- a/source/worksheet/worksheet.cpp +++ b/source/worksheet/worksheet.cpp @@ -31,7 +31,7 @@ worksheet::worksheet(const worksheet &rhs) : d_(rhs.d_) { } -worksheet::worksheet(workbook &parent, const std::string &title) +worksheet::worksheet(workbook &parent, const string &title) : d_(title == "" ? parent.create_sheet().d_ : parent.create_sheet(title).d_) { } @@ -41,7 +41,7 @@ bool worksheet::has_frozen_panes() const return get_frozen_panes() != cell_reference("A1"); } -std::string worksheet::unique_sheet_name(const std::string &value) const +string worksheet::unique_sheet_name(const string &value) const { auto names = get_parent().get_sheet_names(); auto match = std::find(names.begin(), names.end(), value); @@ -49,12 +49,12 @@ std::string worksheet::unique_sheet_name(const std::string &value) const while (match != names.end()) { append++; - match = std::find(names.begin(), names.end(), value + std::to_string(append)); + match = std::find(names.begin(), names.end(), value + string::from(append)); } - return append == 0 ? value : value + std::to_string(append); + return append == 0 ? value : value + string::from(append); } -void worksheet::create_named_range(const std::string &name, const range_reference &reference) +void worksheet::create_named_range(const string &name, const range_reference &reference) { std::vector targets; targets.push_back({ *this, reference }); @@ -121,7 +121,7 @@ const page_setup &worksheet::get_page_setup() const return d_->page_setup_; } -std::string worksheet::to_string() const +string worksheet::to_string() const { return "title_ + "\">"; } @@ -175,7 +175,7 @@ std::list worksheet::get_cell_collection() return cells; } -std::string worksheet::get_title() const +string worksheet::get_title() const { if (d_ == nullptr) { @@ -184,7 +184,7 @@ std::string worksheet::get_title() const return d_->title_; } -void worksheet::set_title(const std::string &title) +void worksheet::set_title(const string &title) { d_->title_ = title; } @@ -199,7 +199,7 @@ void worksheet::freeze_panes(xlnt::cell top_left_cell) d_->freeze_panes_ = top_left_cell.get_reference(); } -void worksheet::freeze_panes(const std::string &top_left_coordinate) +void worksheet::freeze_panes(const string &top_left_coordinate) { d_->freeze_panes_ = cell_reference(top_left_coordinate); } @@ -236,7 +236,7 @@ bool worksheet::has_row_properties(row_t row) const return d_->row_properties_.find(row) != d_->row_properties_.end(); } -range worksheet::get_named_range(const std::string &name) +range worksheet::get_named_range(const string &name) { if (!has_named_range(name)) { @@ -348,9 +348,9 @@ const std::vector &worksheet::get_relationships() const return d_->relationships_; } -relationship worksheet::create_relationship(relationship::type type, const std::string &target_uri) +relationship worksheet::create_relationship(relationship::type type, const string &target_uri) { - std::string r_id = "rId" + std::to_string(d_->relationships_.size() + 1); + string r_id = "rId" + string::from(d_->relationships_.size() + 1); d_->relationships_.push_back(relationship(type, r_id, target_uri)); return d_->relationships_.back(); } @@ -418,7 +418,7 @@ void worksheet::append() get_cell(cell_reference(1, get_next_row())); } -void worksheet::append(const std::vector &cells) +void worksheet::append(const std::vector &cells) { xlnt::cell_reference next(1, get_next_row()); @@ -474,7 +474,7 @@ void worksheet::append(const std::vector &cells) } } -void worksheet::append(const std::unordered_map &cells) +void worksheet::append(const std::unordered_map &cells) { auto row = get_next_row(); @@ -484,7 +484,7 @@ void worksheet::append(const std::unordered_map &cells } } -void worksheet::append(const std::unordered_map &cells) +void worksheet::append(const std::unordered_map &cells) { auto row = get_next_row(); @@ -510,12 +510,12 @@ xlnt::range worksheet::rows() const return get_range(calculate_dimension()); } -xlnt::range worksheet::rows(const std::string &range_string) const +xlnt::range worksheet::rows(const string &range_string) const { return get_range(range_reference(range_string)); } -xlnt::range worksheet::rows(const std::string &range_string, int row_offset, int column_offset) const +xlnt::range worksheet::rows(const string &range_string, int row_offset, int column_offset) const { range_reference reference(range_string); return get_range(reference.make_offset(column_offset, row_offset)); @@ -561,7 +561,7 @@ range worksheet::operator[](const range_reference &ref) return get_range(ref); } -range worksheet::operator[](const std::string &name) +range worksheet::operator[](const string &name) { if (has_named_range(name)) { @@ -570,12 +570,12 @@ range worksheet::operator[](const std::string &name) return get_range(range_reference(name)); } -bool worksheet::has_named_range(const std::string &name) +bool worksheet::has_named_range(const string &name) { return d_->named_ranges_.find(name) != d_->named_ranges_.end(); } -void worksheet::remove_named_range(const std::string &name) +void worksheet::remove_named_range(const string &name) { if (!has_named_range(name)) { @@ -632,7 +632,7 @@ void worksheet::set_parent(xlnt::workbook &wb) d_->parent_ = &wb; } -std::vector worksheet::get_formula_attributes() const +std::vector worksheet::get_formula_attributes() const { return {}; } diff --git a/tests/helpers/helper.hpp b/tests/helpers/helper.hpp index 661ac789..dd461a41 100644 --- a/tests/helpers/helper.hpp +++ b/tests/helpers/helper.hpp @@ -26,8 +26,8 @@ public: struct comparison_result { difference_type difference; - std::string value_left; - std::string value_right; + xlnt::string value_left; + xlnt::string value_right; operator bool() const { return difference == difference_type::equivalent; } }; @@ -36,21 +36,21 @@ public: return compare_xml(expected.get_root(), observed.get_root()); } - static comparison_result compare_xml(const std::string &expected, const xlnt::xml_document &observed) + static comparison_result compare_xml(const xlnt::string &expected, const xlnt::xml_document &observed) { - std::string expected_contents = expected; + xlnt::string expected_contents = expected; if(PathHelper::FileExists(expected)) { - std::ifstream f(expected); + std::ifstream f(expected.data()); std::ostringstream s; f >> s.rdbuf(); - expected_contents = s.str(); + expected_contents = s.str().c_str(); } xlnt::xml_document expected_xml; - expected_xml.from_string(expected_contents); + expected_xml.from_string(expected_contents.data()); return compare_xml(expected_xml.get_root(), observed.get_root()); } @@ -58,18 +58,18 @@ public: static comparison_result compare_xml(const std::string &left_contents, const std::string &right_contents) { xlnt::xml_document left_xml; - left_xml.from_string(left_contents); + left_xml.from_string(left_contents.c_str()); xlnt::xml_document right_xml; - right_xml.from_string(right_contents); + right_xml.from_string(right_contents.c_str()); return compare_xml(left_xml.get_root(), right_xml.get_root()); } static comparison_result compare_xml(const xlnt::xml_node &left, const xlnt::xml_node &right) { - std::string left_temp = left.get_name(); - std::string right_temp = right.get_name(); + xlnt::string left_temp = left.get_name(); + xlnt::string right_temp = right.get_name(); if(left_temp != right_temp) { diff --git a/tests/helpers/path_helper.hpp b/tests/helpers/path_helper.hpp index f52ce6e7..899f51fc 100644 --- a/tests/helpers/path_helper.hpp +++ b/tests/helpers/path_helper.hpp @@ -22,37 +22,37 @@ class PathHelper { public: - static std::string read_file(const std::string &filename) + static xlnt::string read_file(const xlnt::string &filename) { - std::ifstream f(filename); + std::ifstream f(filename.data()); std::ostringstream ss; ss << f.rdbuf(); - return ss.str(); + return ss.str().c_str(); } - static std::string WindowsToUniversalPath(const std::string &windows_path) + static xlnt::string WindowsToUniversalPath(const xlnt::string &windows_path) { - std::string fixed; - std::stringstream ss(windows_path); + xlnt::string fixed; + std::stringstream ss(windows_path.data()); std::string part; while(std::getline(ss, part, '\\')) { if(fixed == "") { - fixed = part; + fixed = part.c_str(); } else { - fixed += "/" + part; + fixed += "/" + xlnt::string(part.c_str()); } } return fixed; } - static std::string GetExecutableDirectory() + static xlnt::string GetExecutableDirectory() { #ifdef __APPLE__ @@ -76,7 +76,7 @@ public: { throw std::runtime_error("GetModuleFileName failed or buffer was too small"); } - return WindowsToUniversalPath(std::string(buffer.begin(), buffer.begin() + result - 13)) + "/"; + return WindowsToUniversalPath(xlnt::string(buffer.begin(), buffer.begin() + result - 13)) + "/"; #else char arg1[20]; @@ -84,39 +84,40 @@ public: sprintf(arg1, "/proc/%d/exe", getpid()); readlink(arg1, exepath, 1024); - return std::string(exepath).substr(0, std::strlen(exepath) - 9); + + return xlnt::string(exepath).substr(0, std::strlen(exepath) - 9); #endif } - static std::string GetDataDirectory(const std::string &append = "") + static xlnt::string GetDataDirectory(const xlnt::string &append = "") { return GetExecutableDirectory() + "../tests/data" + append; } - static void CopyFile(const std::string &source, const std::string &destination, bool overwrite) + static void CopyFile(const xlnt::string &source, const xlnt::string &destination, bool overwrite) { if(!overwrite && FileExists(destination)) { throw std::runtime_error("destination file already exists and overwrite==false"); } - std::ifstream src(source, std::ios::binary); - std::ofstream dst(destination, std::ios::binary); + std::ifstream src(source.data(), std::ios::binary); + std::ofstream dst(destination.data(), std::ios::binary); dst << src.rdbuf(); } - static void DeleteFile(const std::string &path) + static void DeleteFile(const xlnt::string &path) { - std::remove(path.c_str()); + std::remove(path.data()); } - static bool FileExists(const std::string &path) + static bool FileExists(const xlnt::string &path) { #ifdef _MSC_VER - - std::wstring path_wide(path.begin(), path.end()); + std::string path_stdstring = path.data(); + std::wstring path_wide(path_stdstring.begin(), path_stdstring.end()); return PathFileExists(path_wide.c_str()) && !PathIsDirectory(path_wide.c_str()); #else diff --git a/tests/helpers/temporary_file.hpp b/tests/helpers/temporary_file.hpp index 35ce6781..92b315f8 100644 --- a/tests/helpers/temporary_file.hpp +++ b/tests/helpers/temporary_file.hpp @@ -10,7 +10,7 @@ class TemporaryFile { public: - static std::string CreateTemporaryFilename() + static xlnt::string CreateTemporaryFilename() { #ifdef _MSC_VER std::array buffer; @@ -26,7 +26,7 @@ public: throw std::runtime_error("GetTempPath failed"); } - std::string directory(buffer.begin(), buffer.begin() + result); + xlnt::string directory(buffer.begin(), buffer.begin() + result); return PathHelper::WindowsToUniversalPath(directory + "xlnt.xlsx"); #else @@ -38,17 +38,17 @@ public: { if(PathHelper::FileExists(GetFilename())) { - std::remove(filename_.c_str()); + std::remove(filename_.data()); } } ~TemporaryFile() { - std::remove(filename_.c_str()); + std::remove(filename_.data()); } - std::string GetFilename() const { return filename_; } + xlnt::string GetFilename() const { return filename_; } private: - const std::string filename_; + const xlnt::string filename_; }; diff --git a/third-party/utfcpp/utf8.h b/third-party/utfcpp/utf8.h new file mode 100644 index 00000000..82b13f59 --- /dev/null +++ b/third-party/utfcpp/utf8.h @@ -0,0 +1,34 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/checked.h" +#include "utf8/unchecked.h" + +#endif // header guard diff --git a/third-party/utfcpp/utf8/checked.h b/third-party/utfcpp/utf8/checked.h new file mode 100644 index 00000000..13311551 --- /dev/null +++ b/third-party/utfcpp/utf8/checked.h @@ -0,0 +1,327 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" +#include + +namespace utf8 +{ + // Base for the exceptions that may be thrown from the library + class exception : public ::std::exception { + }; + + // Exceptions that may be thrown from the library functions. + class invalid_code_point : public exception { + uint32_t cp; + public: + invalid_code_point(uint32_t cp) : cp(cp) {} + virtual const char* what() const throw() { return "Invalid code point"; } + uint32_t code_point() const {return cp;} + }; + + class invalid_utf8 : public exception { + uint8_t u8; + public: + invalid_utf8 (uint8_t u) : u8(u) {} + virtual const char* what() const throw() { return "Invalid UTF-8"; } + uint8_t utf8_octet() const {return u8;} + }; + + class invalid_utf16 : public exception { + uint16_t u16; + public: + invalid_utf16 (uint16_t u) : u16(u) {} + virtual const char* what() const throw() { return "Invalid UTF-16"; } + uint16_t utf16_word() const {return u16;} + }; + + class not_enough_room : public exception { + public: + virtual const char* what() const throw() { return "Not enough space"; } + }; + + /// The library API - functions intended to be called by the users + + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (!utf8::internal::is_code_point_valid(cp)) + throw invalid_code_point(cp); + + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = utf8::internal::validate_next(start, end); + switch (err_code) { + case internal::UTF8_OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + throw not_enough_room(); + case internal::INVALID_LEAD: + out = utf8::append (replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + out = utf8::append (replacement, out); + ++start; + // just one replacement mark for the sequence + while (start != end && utf8::internal::is_trail(*start)) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); + return utf8::replace_invalid(start, end, out, replacement_marker); + } + + template + uint32_t next(octet_iterator& it, octet_iterator end) + { + uint32_t cp = 0; + internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); + switch (err_code) { + case internal::UTF8_OK : + break; + case internal::NOT_ENOUGH_ROOM : + throw not_enough_room(); + case internal::INVALID_LEAD : + case internal::INCOMPLETE_SEQUENCE : + case internal::OVERLONG_SEQUENCE : + throw invalid_utf8(*it); + case internal::INVALID_CODE_POINT : + throw invalid_code_point(cp); + } + return cp; + } + + template + uint32_t peek_next(octet_iterator it, octet_iterator end) + { + return utf8::next(it, end); + } + + template + uint32_t prior(octet_iterator& it, octet_iterator start) + { + // can't do much if it == start + if (it == start) + throw not_enough_room(); + + octet_iterator end = it; + // Go back until we hit either a lead octet or start + while (utf8::internal::is_trail(*(--it))) + if (it == start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + return utf8::peek_next(it, end); + } + + /// Deprecated in versions that include "prior" + template + uint32_t previous(octet_iterator& it, octet_iterator pass_start) + { + octet_iterator end = it; + while (utf8::internal::is_trail(*(--it))) + if (it == pass_start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + octet_iterator temp = it; + return utf8::next(temp, end); + } + + template + void advance (octet_iterator& it, distance_type n, octet_iterator end) + { + for (distance_type i = 0; i < n; ++i) + utf8::next(it, end); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::next(first, last); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + if (start != end) { + uint32_t trail_surrogate = utf8::internal::mask16(*start++); + if (utf8::internal::is_trail_surrogate(trail_surrogate)) + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + else + throw invalid_utf16(static_cast(trail_surrogate)); + } + else + throw invalid_utf16(static_cast(cp)); + + } + // Lone trail surrogate + else if (utf8::internal::is_trail_surrogate(cp)) + throw invalid_utf16(static_cast(cp)); + + result = utf8::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start != end) { + uint32_t cp = utf8::next(start, end); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start != end) + (*result++) = utf8::next(start, end); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + octet_iterator range_start; + octet_iterator range_end; + public: + iterator () {} + explicit iterator (const octet_iterator& octet_it, + const octet_iterator& range_start, + const octet_iterator& range_end) : + it(octet_it), range_start(range_start), range_end(range_end) + { + if (it < range_start || it > range_end) + throw std::out_of_range("Invalid utf-8 iterator position"); + } + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return utf8::next(temp, range_end); + } + bool operator == (const iterator& rhs) const + { + if (range_start != rhs.range_start || range_end != rhs.range_end) + throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + utf8::next(it, range_end); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + utf8::next(it, range_end); + return temp; + } + iterator& operator -- () + { + utf8::prior(it, range_start); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::prior(it, range_start); + return temp; + } + }; // class iterator + +} // namespace utf8 + +#endif //header guard + + diff --git a/third-party/utfcpp/utf8/core.h b/third-party/utfcpp/utf8/core.h new file mode 100644 index 00000000..693d388c --- /dev/null +++ b/third-party/utfcpp/utf8/core.h @@ -0,0 +1,329 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include + +namespace utf8 +{ + // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers + // You may need to change them to match your system. + // These typedefs have the same names as ones from cstdint, or boost/cstdint + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + +// Helper code - not intended to be directly called by the library users. May be changed at any time +namespace internal +{ + // Unicode constants + // Leading (high) surrogates: 0xd800 - 0xdbff + // Trailing (low) surrogates: 0xdc00 - 0xdfff + const uint16_t LEAD_SURROGATE_MIN = 0xd800u; + const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; + const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; + const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; + const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); + const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; + + // Maximum valid value for a Unicode code point + const uint32_t CODE_POINT_MAX = 0x0010ffffu; + + template + inline uint8_t mask8(octet_type oc) + { + return static_cast(0xff & oc); + } + template + inline uint16_t mask16(u16_type oc) + { + return static_cast(0xffff & oc); + } + template + inline bool is_trail(octet_type oc) + { + return ((utf8::internal::mask8(oc) >> 6) == 0x2); + } + + template + inline bool is_lead_surrogate(u16 cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); + } + + template + inline bool is_trail_surrogate(u16 cp) + { + return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + template + inline bool is_surrogate(u16 cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + template + inline bool is_code_point_valid(u32 cp) + { + return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); + } + + template + inline typename std::iterator_traits::difference_type + sequence_length(octet_iterator lead_it) + { + uint8_t lead = utf8::internal::mask8(*lead_it); + if (lead < 0x80) + return 1; + else if ((lead >> 5) == 0x6) + return 2; + else if ((lead >> 4) == 0xe) + return 3; + else if ((lead >> 3) == 0x1e) + return 4; + else + return 0; + } + + template + inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) + { + if (cp < 0x80) { + if (length != 1) + return true; + } + else if (cp < 0x800) { + if (length != 2) + return true; + } + else if (cp < 0x10000) { + if (length != 3) + return true; + } + + return false; + } + + enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; + + /// Helper for get_sequence_x + template + utf_error increase_safely(octet_iterator& it, octet_iterator end) + { + if (++it == end) + return NOT_ENOUGH_ROOM; + + if (!utf8::internal::is_trail(*it)) + return INCOMPLETE_SEQUENCE; + + return UTF8_OK; + } + + #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} + + /// get_sequence_x functions decode utf-8 sequences of the length x + template + utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + return UTF8_OK; + } + + template + utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); + + return UTF8_OK; + } + + template + utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + template + utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR + + template + utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + // Save the original value of it so we can go back in case of failure + // Of course, it does not make much sense with i.e. stream iterators + octet_iterator original_it = it; + + uint32_t cp = 0; + // Determine the sequence length based on the lead octet + typedef typename std::iterator_traits::difference_type octet_difference_type; + const octet_difference_type length = utf8::internal::sequence_length(it); + + // Get trail octets and calculate the code point + utf_error err = UTF8_OK; + switch (length) { + case 0: + return INVALID_LEAD; + case 1: + err = utf8::internal::get_sequence_1(it, end, cp); + break; + case 2: + err = utf8::internal::get_sequence_2(it, end, cp); + break; + case 3: + err = utf8::internal::get_sequence_3(it, end, cp); + break; + case 4: + err = utf8::internal::get_sequence_4(it, end, cp); + break; + } + + if (err == UTF8_OK) { + // Decoding succeeded. Now, security checks... + if (utf8::internal::is_code_point_valid(cp)) { + if (!utf8::internal::is_overlong_sequence(cp, length)){ + // Passed! Return here. + code_point = cp; + ++it; + return UTF8_OK; + } + else + err = OVERLONG_SEQUENCE; + } + else + err = INVALID_CODE_POINT; + } + + // Failure branch - restore the original value of the iterator + it = original_it; + return err; + } + + template + inline utf_error validate_next(octet_iterator& it, octet_iterator end) { + uint32_t ignored; + return utf8::internal::validate_next(it, end, ignored); + } + +} // namespace internal + + /// The library API - functions intended to be called by the users + + // Byte order mark + const uint8_t bom[] = {0xef, 0xbb, 0xbf}; + + template + octet_iterator find_invalid(octet_iterator start, octet_iterator end) + { + octet_iterator result = start; + while (result != end) { + utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); + if (err_code != internal::UTF8_OK) + return result; + } + return result; + } + + template + inline bool is_valid(octet_iterator start, octet_iterator end) + { + return (utf8::find_invalid(start, end) == end); + } + + template + inline bool starts_with_bom (octet_iterator it, octet_iterator end) + { + return ( + ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && + ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && + ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) + ); + } + + //Deprecated in release 2.3 + template + inline bool is_bom (octet_iterator it) + { + return ( + (utf8::internal::mask8(*it++)) == bom[0] && + (utf8::internal::mask8(*it++)) == bom[1] && + (utf8::internal::mask8(*it)) == bom[2] + ); + } +} // namespace utf8 + +#endif // header guard + + diff --git a/third-party/utfcpp/utf8/unchecked.h b/third-party/utfcpp/utf8/unchecked.h new file mode 100644 index 00000000..cb242716 --- /dev/null +++ b/third-party/utfcpp/utf8/unchecked.h @@ -0,0 +1,228 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" + +namespace utf8 +{ + namespace unchecked + { + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + uint32_t next(octet_iterator& it) + { + uint32_t cp = utf8::internal::mask8(*it); + typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it); + switch (length) { + case 1: + break; + case 2: + it++; + cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); + break; + case 3: + ++it; + cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + ++it; + cp += (*it) & 0x3f; + break; + case 4: + ++it; + cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + ++it; + cp += (utf8::internal::mask8(*it) << 6) & 0xfff; + ++it; + cp += (*it) & 0x3f; + break; + } + ++it; + return cp; + } + + template + uint32_t peek_next(octet_iterator it) + { + return utf8::unchecked::next(it); + } + + template + uint32_t prior(octet_iterator& it) + { + while (utf8::internal::is_trail(*(--it))) ; + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + + // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) + template + inline uint32_t previous(octet_iterator& it) + { + return utf8::unchecked::prior(it); + } + + template + void advance (octet_iterator& it, distance_type n) + { + for (distance_type i = 0; i < n; ++i) + utf8::unchecked::next(it); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::unchecked::next(first); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + uint32_t trail_surrogate = utf8::internal::mask16(*start++); + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + } + result = utf8::unchecked::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start < end) { + uint32_t cp = utf8::unchecked::next(start); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::unchecked::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = utf8::unchecked::next(start); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + public: + iterator () {} + explicit iterator (const octet_iterator& octet_it): it(octet_it) {} + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + bool operator == (const iterator& rhs) const + { + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + ::std::advance(it, utf8::internal::sequence_length(it)); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + ::std::advance(it, utf8::internal::sequence_length(it)); + return temp; + } + iterator& operator -- () + { + utf8::unchecked::prior(it); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::unchecked::prior(it); + return temp; + } + }; // class iterator + + } // namespace utf8::unchecked +} // namespace utf8 + + +#endif // header guard +