finish up custom string class implementation

This commit is contained in:
Thomas Fussell 2015-11-07 18:37:23 -05:00
parent 4919e7ea00
commit 7b5246f9dd
76 changed files with 807 additions and 502 deletions

View File

@ -29,7 +29,7 @@
#include <xlnt/cell/types.hpp>
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {
@ -412,7 +412,7 @@ private:
/// </summary>
inline std::ostream &operator<<(std::ostream &stream, const xlnt::cell &cell)
{
return stream << cell.to_string();
return stream << std::string(cell.to_string().data());
}
} // namespace xlnt

View File

@ -28,7 +28,7 @@
#include <xlnt/cell/types.hpp>
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -2,7 +2,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -27,7 +27,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
// We might want to change these types for various optimizations in the future
// so use typedefs.

View File

@ -23,7 +23,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -1,6 +1,6 @@
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -3,7 +3,7 @@
#include <string>
#include <vector>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -27,7 +27,7 @@
#include <xlnt/utils/datetime.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -4,7 +4,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -8,7 +8,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
// Note: this comes from https://github.com/tfussell/miniz-cpp

View File

@ -28,7 +28,7 @@
#include <xlnt/cell/comment.hpp>
#include <xlnt/worksheet/worksheet.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -1,6 +1,6 @@
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -30,7 +30,7 @@
#include <xlnt/packaging/zip_file.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -2,7 +2,7 @@
#include <string>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -4,7 +4,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -27,7 +27,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -29,7 +29,7 @@
#include <xlnt/workbook/workbook.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -25,7 +25,7 @@
#include <string>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -26,7 +26,7 @@
#include <string>
#include <vector>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -28,7 +28,7 @@
#include <xlnt/worksheet/worksheet.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -5,7 +5,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {
namespace detail { struct xml_document_impl; }

View File

@ -5,7 +5,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {
namespace detail { struct xml_node_impl; }

View File

@ -2,7 +2,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -25,7 +25,7 @@
#include <xlnt/utils/hash_combine.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -29,7 +29,7 @@
#include <xlnt/utils/hash_combine.hpp>
#include <xlnt/styles/side.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -26,7 +26,7 @@
#include <xlnt/utils/hash_combine.hpp>
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -26,7 +26,7 @@
#include <xlnt/styles/color.hpp>
#include <xlnt/utils/hash_combine.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -28,7 +28,7 @@
#include <xlnt/utils/hash_combine.hpp>
#include <xlnt/styles/color.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -25,7 +25,7 @@
#include <xlnt/styles/style.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -28,7 +28,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -27,7 +27,7 @@
#include <xlnt/utils/hash_combine.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -27,7 +27,7 @@
#include <xlnt/styles/color.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -30,7 +30,7 @@
#include <xlnt/styles/number_format.hpp>
#include <xlnt/styles/protection.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -24,7 +24,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -27,7 +27,7 @@
#include <xlnt/cell/types.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {
@ -48,7 +48,7 @@ class XLNT_CLASS cell_coordinates_exception
class XLNT_CLASS illegal_character_error
{
public:
illegal_character_error(char c);
illegal_character_error(utf32_char c);
};
/// <summary>

View File

@ -2,7 +2,7 @@
#include <functional>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -1,139 +1,87 @@
#pragma once
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <iterator>
#include <unordered_map>
#include <vector>
#include "xlnt_config.hpp"
#ifdef XLNT_STD_STRING
#include <string>
#endif
#include <xlnt/xlnt_config.hpp>
namespace xlnt {
template<typename T>
class iter_range
{
public:
iter_range(T begin_iter, T end_iter) : begin_(begin_iter), end_(end_iter)
{
}
T begin() { return begin_; }
T end() { return end_; }
private:
T begin_;
T end_;
};
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 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 code_point = utf32_char;
using reference = code_point &;
using const_reference = const code_point &;
using pointer = code_point *;
using const_pointer = const code_point *;
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
class const_iterator;
class iterator : public std::iterator<std::bidirectional_iterator_tag, code_point>
{
public:
code_point(byte_pointer data, size_type index, size_type end)
: data_(data),
index_(index),
end_(end)
{
}
iterator(string *parent, size_type index);
iterator(const iterator &other);
code_point operator*();
bool operator==(const iterator &other) const;
bool operator!=(const iterator &other) const { return !(*this == other); }
code_point(const_byte_pointer data, size_type index, size_type end)
: data_(const_cast<byte_pointer>(data)),
index_(index),
end_(end)
{
}
difference_type operator-(const iterator &other) const;
iterator &operator+=(int offset) { return *this = *this + offset; }
iterator &operator-=(int offset) { return *this = *this - offset; }
code_point &operator=(utf32_char value);
iterator operator+(int offset);
iterator operator-(int offset) { return *this + (-1 * offset); }
code_point &operator=(const code_point &value)
{
return *this = value.get();
}
iterator &operator--();
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 <bool is_const = true>
class common_iterator : public std::iterator<std::bidirectional_iterator_tag, value_type>
{
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<false> &other)
: current_(other.current_)
{
}
common_iterator(const common_iterator<true> &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<size_type>(0, std::min<size_type>(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 operator--(int)
{
iterator old = *this;
--*this;
@ -141,46 +89,90 @@ public:
return old;
}
common_iterator &operator++();
iterator &operator++();
common_iterator operator++(int)
iterator operator++(int)
{
common_iterator old = *this;
iterator old = *this;
++*this;
return old;
}
friend class common_iterator<true>;
private:
friend class const_iterator;
string *parent_;
size_type index_;
};
class const_iterator : public std::iterator<std::bidirectional_iterator_tag, code_point>
{
public:
const_iterator(const string *parent, size_type index);
const_iterator(const string::iterator &other);
const_iterator(const const_iterator &other);
const code_point operator*() const;
bool operator==(const const_iterator &other) const;
bool operator!=(const const_iterator &other) const { return !(*this == other); }
difference_type operator-(const const_iterator &other) const;
const_iterator &operator+=(int offset);
const_iterator &operator-=(int offset) { return *this += -offset; }
const_iterator operator+(int offset);
const_iterator operator-(int offset) { return *this + (-1 * offset); }
const_iterator &operator--();
const_iterator operator--(int)
{
const_iterator old = *this;
--*this;
return old;
}
const_iterator &operator++();
const_iterator operator++(int)
{
const_iterator old = *this;
++*this;
return old;
}
private:
code_point current_;
const string *parent_;
size_type index_;
};
using iterator = common_iterator<false>;
using const_iterator = common_iterator<true>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_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);
template<typename T>
static string from(T value);
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);
#ifdef XLNT_STD_STRING
string(const std::string &str);
#endif
string(const utf_mb_wide_string str);
string(const utf8_string str);
@ -199,8 +191,8 @@ public:
~string();
size_type length() const { return length_; }
size_type bytes() const;
size_type length() const;
size_type num_bytes() const;
bool empty() const { return length() == 0; }
@ -210,35 +202,33 @@ public:
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;
code_point back() 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) const;
size_type find(const 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(code_point c, size_type offset) const;
size_type find(const 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) const;
size_type find_last_of(const 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_last_of(code_point c, size_type offset) const;
size_type find_last_of(const 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_of(const string &str) const;
size_type find_first_of(const 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_first_not_of(const string &str) const;
size_type find_first_not_of(const 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;
size_type find_last_not_of(const string &str) const;
size_type find_last_not_of(const string &str, size_type offset) const;
void clear();
@ -247,7 +237,7 @@ public:
int to_hex() const;
void remove(code_point iter);
void erase(size_type index);
iterator begin();
const_iterator begin() const { return cbegin(); }
@ -263,12 +253,13 @@ public:
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(utf_mb_narrow_char c);
void append(utf_mb_wide_char c);
void append(utf16_char c);
void append(code_point c);
void append(const string &str);
void replace(size_type index, utf32_char c);
code_point at(size_type index);
const code_point at(size_type index) const;
@ -297,8 +288,8 @@ public:
private:
explicit string(size_type initial_size);
size_type length_;
std::vector<byte> *data_;
std::unordered_map<size_type, size_type> *code_point_byte_offsets_;
};
} // namespace xlnt

View File

@ -25,7 +25,7 @@
#include <string>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -1,6 +1,6 @@
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -3,7 +3,7 @@
#include <string>
#include <vector>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -1,6 +1,6 @@
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -31,7 +31,7 @@
#include <xlnt/packaging/relationship.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -7,7 +7,7 @@
#include <xlnt/worksheet/major_order.hpp>
#include <xlnt/worksheet/worksheet.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -23,7 +23,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -1,6 +1,6 @@
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -23,7 +23,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -23,7 +23,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -22,7 +22,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -32,7 +32,7 @@
#include <xlnt/worksheet/range_reference.hpp>
#include <xlnt/worksheet/worksheet.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -24,7 +24,7 @@
#include <xlnt/cell/cell_reference.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -23,7 +23,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -22,7 +22,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -2,7 +2,7 @@
#include <xlnt/utils/string.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -22,7 +22,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -33,7 +33,7 @@
#include <xlnt/packaging/relationship.hpp>
#include <xlnt/worksheet/page_setup.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -23,7 +23,7 @@
// @author: see AUTHORS file
#pragma once
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -25,7 +25,7 @@
#include <string>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
#include <xlnt/cell/cell.hpp>
#include <xlnt/cell/cell_reference.hpp>

View File

@ -56,18 +56,25 @@ enum class limit_style
/// </summary>
const limit_style LimitStyle = limit_style::openpyxl;
// If no API is defined, assume default
#ifndef XLNT_API
#ifdef _MSC_VER
#if !defined(XLNT_API) && defined(SHARED)
#ifdef XLNT_SHARED
#ifdef XLNT_EXPORT
#define XLNT_API __declspec(dllexport)
#else
#define XLNT_API __declspec(dllimport)
#endif
#endif // XLNT_EXPORT
#endif // XLNT_SHARED
#else
#define XLNT_API
#endif
#endif
#endif // _MSC_VER
#endif // XLNT_API
#ifndef XLNT_STD_STRING
#ifndef XLNT_SHARED
#define XLNT_STD_STRING
#endif // XLNT_SHARED
#endif // XLNT_STD_STRING
// If no API for classes is defined, assume default
#ifndef XLNT_CLASS

View File

@ -144,7 +144,7 @@ bool is_valid_color(const xlnt::string &color)
for (std::size_t i = 0; i < color.length(); i++)
{
if (std::toupper(color[i].get()) != std::toupper(other[i].get()))
if (std::toupper(color[i]) != std::toupper(other[i]))
{
return false;
}
@ -335,7 +335,7 @@ bool is_valid_locale(const xlnt::string &locale_string)
for (auto c : country)
{
if (!is_hex(static_cast<char>(std::toupper(c.get()))))
if (!is_hex(static_cast<char>(std::toupper(c))))
{
return false;
}
@ -699,12 +699,12 @@ xlnt::string format_section(long double number, const section &format, xlnt::cal
if (decimal_pos != xlnt::string::npos)
{
result[decimal_pos] = ',';
result.replace(decimal_pos, U',');
decimal_pos += 3;
while (decimal_pos < result.length())
{
result.remove(result.back());
result.erase(result.length());
}
}
}
@ -1071,7 +1071,7 @@ bool cell::has_hyperlink() const
void cell::set_hyperlink(const string &hyperlink)
{
if (hyperlink.length() == 0 || hyperlink.find(':') == std::string::npos)
if (hyperlink.length() == 0 || hyperlink.find(':') == xlnt::string::npos)
{
throw data_type_exception();
}

View File

@ -88,71 +88,53 @@ std::pair<string, row_t> cell_reference::split_reference(const string &reference
{
absolute_column = false;
absolute_row = false;
// Convert a coordinate string like 'B12' to a tuple ('B', 12)
bool column_part = true;
string column_string;
for (auto character : reference_string)
auto is_alpha = [](string::code_point c)
{
auto upper = std::toupper(character.get(), std::locale::classic());
if (std::isalpha(character.get(), std::locale::classic()))
{
if (column_part)
{
column_string.append(upper);
}
else
{
throw cell_coordinates_exception(reference_string);
}
}
else if (character == '$')
{
if (column_part)
{
if (column_string.empty())
{
column_string.append(upper);
}
else
{
column_part = false;
}
}
}
else
{
if (column_part)
{
column_part = false;
}
else if (!std::isdigit(character.get(), std::locale::classic()))
{
throw cell_coordinates_exception(reference_string);
}
}
}
string row_string = reference_string.substr(column_string.length());
if (row_string.length() == 0)
return (c >= U'A' && c <= U'Z') || (c >= U'a' && c <= U'z');
};
auto upper_ref_string = reference_string.to_upper();
auto iter = upper_ref_string.begin();
auto end = upper_ref_string.end();
while(iter != end && (is_alpha(*iter) || *iter == U'$'))
{
throw cell_coordinates_exception(reference_string);
++iter;
}
if (column_string[0] == '$')
{
absolute_row = true;
column_string = column_string.substr(1);
}
if (row_string[0] == '$')
string column_string(upper_ref_string.begin(), iter);
if (column_string.length() > 1 && column_string.front() == '$')
{
absolute_column = true;
row_string = row_string.substr(1);
column_string.erase(0);
}
if (column_string.length() > 1 && column_string.back() == '$')
{
absolute_row = true;
column_string.erase(column_string.length() - 1);
}
string row_string(iter, end);
auto is_digit = [](string::code_point c)
{
return (c >= U'0' && c <= U'9');
};
for(auto c : row_string)
{
if(!is_digit(c))
{
throw cell_coordinates_exception(reference_string);
}
}
if (column_string.length() == 0 || row_string.length() == 0)
{
throw cell_coordinates_exception(reference_string);
}
return { column_string, row_string.to<row_t>() };

View File

@ -257,7 +257,7 @@ public:
TS_ASSERT_THROWS(cell.set_value(str), xlnt::illegal_character_error);
}
cell.set_value(xlnt::string("\33"));
cell.set_value(xlnt::string("\41")); // !
cell.set_value(xlnt::string("\t")); // Tab
cell.set_value(xlnt::string("\n")); // Newline
cell.set_value(xlnt::string("\r")); // Carriage return
@ -361,7 +361,7 @@ public:
{
/*
unsigned char pound = 163;
auto test_string = "Compount Value (" + std::string(pound) + ")";
auto test_string = "Compount Value (" + xlnt::string(pound) + ")";
auto ws = wb.create_sheet();
cell = ws[xlnt::cell_reference("A1")];
TS_ASSERT_THROWS(cell.check_string(test_string), xlnt::unicode_decode_error);

View File

@ -16,15 +16,24 @@ column_t::index_t column_t::column_index_from_string(const string &column_string
column_t::index_t column_index = 0;
int place = 1;
auto is_alpha = [](string::code_point c)
{
return (c >= U'A' && c <= U'Z') || (c >= U'a' && c <= U'z');
};
auto column_string_upper = column_string.to_upper();
for (int i = static_cast<int>(column_string.length()) - 1; i >= 0; i--)
{
if (!std::isalpha(column_string[static_cast<std::size_t>(i)].get(), std::locale::classic()))
auto index = static_cast<std::size_t>(i);
if (!is_alpha(column_string[index]))
{
throw column_string_index_exception();
}
auto char_index = std::toupper(column_string[static_cast<std::size_t>(i)].get(), std::locale::classic()) - U'A';
auto char_index = column_string_upper[index] - U'A';
column_index += static_cast<column_t::index_t>((char_index + 1) * place);
place *= 26;

View File

@ -30,11 +30,11 @@ xlnt::string check_string(xlnt::string s)
s = s.substr(0, 32767); // max string length in Excel
}
for (xlnt::string::code_point c : s)
for (auto c : s)
{
if (c >= 0 && (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31)))
if (c <= 8 || c == 11 || c == 12 || (c >= 14 && c <= 31))
{
throw xlnt::illegal_character_error(0);
throw xlnt::illegal_character_error(c);
}
}
@ -68,7 +68,49 @@ std::pair<bool, long double> cast_percentage(const xlnt::string &s)
std::pair<bool, xlnt::time> cast_time(const xlnt::string &s)
{
xlnt::time result;
return { false, result };
try
{
auto last_colon = s.find_last_of(':');
if (last_colon == xlnt::string::npos)
{
return { false, result };
}
double seconds = s.substr(last_colon + 1).to<double>();
result.second = static_cast<int>(seconds);
result.microsecond = static_cast<int>((seconds - static_cast<double>(result.second)) * 1e6);
auto first_colon = s.find(':');
if (first_colon == last_colon)
{
auto decimal_pos = s.find('.');
if (decimal_pos != xlnt::string::npos)
{
result.minute = s.substr(0, first_colon).to<int>();
}
else
{
result.hour = s.substr(0, first_colon).to<int>();
result.minute = result.second;
result.second = 0;
}
}
else
{
result.hour = s.substr(0, first_colon).to<int>();
result.minute = s.substr(first_colon + 1, last_colon - first_colon - 1).to<int>();
}
}
catch (std::invalid_argument)
{
return { false, result };
}
return { true, result };
}
} // namespace

View File

@ -1,6 +1,7 @@
#pragma once
#include <xlnt/cell/comment.hpp>
#include <xlnt/utils/string.hpp>
namespace xlnt {
namespace detail {

View File

@ -2,7 +2,7 @@
#include <detail/constants.hpp>
#include "xlnt_config.hpp"
#include <xlnt/xlnt_config.hpp>
namespace xlnt {

View File

@ -289,7 +289,7 @@ void zip_file::append_comment()
auto comment_length = std::min(static_cast<uint16_t>(comment.length()), std::numeric_limits<uint16_t>::max());
buffer_[buffer_.size() - 2] = static_cast<char>(comment_length);
buffer_[buffer_.size() - 1] = static_cast<char>(comment_length >> 8);
std::copy(comment.data(), comment.data() + comment.bytes(), std::back_inserter(buffer_));
std::copy(comment.data(), comment.data() + comment.num_bytes(), std::back_inserter(buffer_));
}
}

View File

@ -225,7 +225,7 @@ xml_document workbook_serializer::write_workbook() const
sheet_index_string = sheet_index_string.substr(sheet_index_string.find_last_of('/'));
auto iter = sheet_index_string.end();
--iter;
while (isdigit((*iter).get()))
while (isdigit(*iter))
--iter;
auto first_digit = iter - sheet_index_string.begin();
sheet_index_string = sheet_index_string.substr(static_cast<string::size_type>(first_digit + 1));

View File

@ -34,7 +34,7 @@ cell_coordinates_exception::cell_coordinates_exception(const string &coord_strin
{
}
illegal_character_error::illegal_character_error(char c)
illegal_character_error::illegal_character_error(xlnt::utf32_char c)
{
}

View File

@ -1,8 +1,11 @@
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <iterator>
//TODO: make this conditional on XLNT_STD_STRING once std::sto* functions are replaced
#include <string>
#include <vector>
#include <utf8.h>
@ -12,7 +15,7 @@
namespace {
template<typename T>
std::size_t count_bytes(const T *arr)
std::size_t string_length(const T *arr)
{
std::size_t i = 0;
@ -24,153 +27,229 @@ std::size_t count_bytes(const T *arr)
return i;
}
xlnt::string::code_point to_upper(xlnt::string::code_point p)
{
if(p >= U'a' && p <= U'z')
{
return U'A' + p - U'a';
}
return p;
}
xlnt::string::code_point to_lower(xlnt::string::code_point p)
{
if(p >= U'A' && p <= U'Z')
{
return U'a' + p - U'A';
}
return p;
}
}
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;
}
template<>
string string::from(std::int8_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::int16_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::int32_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::int64_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::uint8_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::uint16_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::uint32_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::uint64_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(std::size_t i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(float i)
{
return string(std::to_string(i).c_str());
}
template<>
string string::from(double i)
{
return string(std::to_string(i).c_str());
}
template<>
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_);
}
#ifdef XLNT_STD_STRING
template<>
xlnt::string::common_iterator<false> &xlnt::string::common_iterator<false>::operator--()
string string::from(const std::string &s)
{
auto iter = current_.data_ + current_.index_;
utf8::prior(iter, current_.data_);
current_.index_ = iter - current_.data_;
return string(s.data());
}
#endif
return *this;
xlnt::string::iterator::iterator(xlnt::string *parent, size_type index)
: parent_(parent),
index_(index)
{
}
template<>
xlnt::string::common_iterator<true> &xlnt::string::common_iterator<true>::operator--()
xlnt::string::iterator::iterator(const xlnt::string::iterator &other)
: parent_(other.parent_),
index_(other.index_)
{
auto iter = current_.data_ + current_.index_;
utf8::prior(iter, current_.data_);
current_.index_ = iter - current_.data_;
return *this;
}
template<>
xlnt::string::common_iterator<false> &xlnt::string::common_iterator<false>::operator++()
string::code_point xlnt::string::iterator::operator*()
{
auto iter = current_.data_ + current_.index_;
utf8::advance(iter, 1, current_.data_ + current_.end_);
current_.index_ = iter - current_.data_;
return *this;
return parent_->at(index_);
}
template<>
xlnt::string::common_iterator<true> &xlnt::string::common_iterator<true>::operator++()
bool xlnt::string::iterator::operator==(const iterator &other) const
{
auto iter = current_.data_ + current_.index_;
utf8::advance(iter, 1, current_.data_ + current_.end_);
current_.index_ = iter - current_.data_;
return parent_ == other.parent_ && index_ == other.index_;
}
return *this;
string::difference_type string::iterator::operator-(const iterator &other) const
{
return index_ - other.index_;
}
xlnt::string::const_iterator::const_iterator(const xlnt::string *parent, size_type index)
: parent_(parent),
index_(index)
{
}
xlnt::string::const_iterator::const_iterator(const xlnt::string::iterator &other)
: parent_(other.parent_),
index_(other.index_)
{
}
xlnt::string::const_iterator::const_iterator(const xlnt::string::const_iterator &other)
: parent_(other.parent_),
index_(other.index_)
{
}
string::difference_type string::const_iterator::operator-(const const_iterator &other) const
{
return index_ - other.index_;
}
const string::code_point xlnt::string::const_iterator::operator*() const
{
return parent_->at(index_);
}
bool xlnt::string::const_iterator::operator==(const const_iterator &other) const
{
return parent_ == other.parent_ && index_ == other.index_;
}
xlnt::string::iterator &xlnt::string::iterator::operator--()
{
return *this -= 1;
}
xlnt::string::const_iterator &xlnt::string::const_iterator::operator--()
{
return *this -= 1;
}
xlnt::string::iterator &xlnt::string::iterator::operator++()
{
return *this += 1;
}
xlnt::string::const_iterator &xlnt::string::const_iterator::operator++()
{
return *this += 1;
}
string::const_iterator &string::const_iterator::operator+=(int offset)
{
auto new_index = index_ + offset;
new_index = std::max<int>(0, std::min<int>(parent_->length(), new_index));
index_ = static_cast<std::size_t>(new_index);
return *this;
}
xlnt::string::iterator xlnt::string::iterator::operator+(int offset)
{
iterator copy = *this;
auto new_index = index_ + offset;
new_index = std::max<int>(0, std::min<int>(parent_->length(), new_index));
copy.index_ = static_cast<std::size_t>(new_index);
return copy;
}
xlnt::string::const_iterator xlnt::string::const_iterator::operator+(int offset)
{
const_iterator copy = *this;
auto new_index = index_ + offset;
new_index = std::max<int>(0, std::min<int>(parent_->length(), new_index));
copy.index_ = static_cast<std::size_t>(new_index);
return copy;
}
string::string(size_type initial_size)
: length_(0),
data_(new std::vector<char>)
: data_(new std::vector<char>),
code_point_byte_offsets_(new std::unordered_map<size_type, size_type>)
{
data_->resize(initial_size + 1);
data_->back() = '\0';
code_point_byte_offsets_->insert({0, 0});
}
string::string() : string(size_type(0))
@ -182,7 +261,9 @@ string::string(string &&str) : string()
swap(*this, str);
}
string::string(const string &str) : string(str, 0)
string::string(const string &str)
: data_(new std::vector<char>(*str.data_)),
code_point_byte_offsets_(new std::unordered_map<size_type, size_type>(*str.code_point_byte_offsets_))
{
}
@ -192,58 +273,100 @@ string::string(const string &str, size_type offset) : string(str, offset, str.le
string::string(const string &str, size_type offset, size_type len) : string()
{
*this = str.substr(offset, len);
auto part = str.substr(offset, len);
*data_ = *part.data_;
*code_point_byte_offsets_ = *part.code_point_byte_offsets_;
}
#ifdef XLNT_STD_STRING
string::string(const std::string &str) : string(str.data())
{
}
#endif
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);
auto iter = str;
while(*iter != '\0')
{
append(*iter);
iter++;
}
}
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);
auto start = str;
auto end = str;
while(*end != '\0')
{
++end;
}
auto iter = start;
while(iter != end)
{
append((utf32_char)utf8::next(iter, end));
}
}
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);
auto iter = str;
while(*iter != '\0')
{
append(*iter);
iter++;
}
}
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);
auto iter = str;
while(*iter != '\0')
{
append(*iter);
iter++;
}
}
string::~string()
{
delete data_;
data_ = nullptr;
delete code_point_byte_offsets_;
code_point_byte_offsets_ = nullptr;
}
string string::to_upper() const
{
return *this;
string upper;
for(auto c : *this)
{
upper.append(::to_upper(c));
}
return upper;
}
string string::to_lower() const
{
return *this;
string lower;
for(auto c : *this)
{
lower.append(::to_lower(c));
}
return lower;
}
string string::substr(size_type offset) const
@ -253,37 +376,22 @@ string string::substr(size_type offset) const
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;
if(len != npos && offset + len < length())
{
return string(begin() + offset, begin() + (offset + len));
}
return string(begin() + offset, end());
}
string::code_point string::back()
string::code_point string::back() const
{
return *(begin() + length_ + -1);
return at(length() - 1);
}
const string::code_point string::back() const
string::code_point string::front() const
{
return *(begin() + length_ + -1);
}
string::code_point string::front()
{
return *begin();
}
const string::code_point string::front() const
{
return *begin();
return at(0);
}
string::size_type string::find(code_point c) const
@ -296,7 +404,7 @@ string::size_type string::find(char c) const
return find(c, 0);
}
string::size_type string::find(string str) const
string::size_type string::find(const string &str) const
{
return find(str, 0);
}
@ -305,24 +413,6 @@ 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)
@ -337,9 +427,24 @@ string::size_type string::find(char c, size_type offset) const
return npos;
}
string::size_type string::find(string str, size_type offset) const
string::size_type string::find(char c, size_type offset) const
{
return 0;
return find(static_cast<code_point>(c), offset);
}
string::size_type string::find(const string &str, size_type offset) const
{
while (offset < length() - str.length())
{
if (substr(offset, str.length()) == str)
{
return offset;
}
offset++;
}
return npos;
}
string::size_type string::find_last_of(code_point c) const
@ -352,60 +457,124 @@ 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
string::size_type string::find_last_of(const 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;
auto stop = begin() + offset;
auto iter = end() - 1;
while (iter != stop)
{
if (*iter == c)
{
return iter - begin();
}
--iter;
}
return *stop == c ? offset : npos;
}
string::size_type string::find_last_of(char c, size_type offset) const
{
return 0;
return find_last_of(static_cast<code_point>(c), offset);
}
string::size_type string::find_last_of(string str, size_type offset) const
string::size_type string::find_last_of(const string &str, size_type offset) const
{
return 0;
auto stop = begin() + offset;
auto iter = end() - 1;
while (iter != stop)
{
if(str.find(*iter) != npos)
{
return iter - begin();
}
--iter;
}
return npos;
}
string::size_type string::find_first_of(string str) const
string::size_type string::find_first_of(const string &str) const
{
return find_first_of(str, 0);
}
string::size_type string::find_first_of(string str, size_type offset) const
string::size_type string::find_first_of(const string &str, size_type offset) const
{
return 0;
auto iter = begin() + offset;
while (iter != end())
{
if(str.find(*iter) != npos)
{
return iter - begin();
}
++iter;
}
return npos;
}
string::size_type string::find_first_not_of(string str) const
string::size_type string::find_first_not_of(const string &str) const
{
return find_first_not_of(str, 0);
}
string::size_type string::find_first_not_of(string str, size_type offset) const
string::size_type string::find_first_not_of(const string &str, size_type offset) const
{
return 0;
auto iter = begin() + offset;
while (iter != end())
{
if(str.find(*iter) == npos)
{
return iter - begin();
}
++iter;
}
return npos;
}
string::size_type string::find_last_not_of(string str) const
string::size_type string::find_last_not_of(const string &str) const
{
return find_last_not_of(str, 0);
}
string::size_type string::find_last_not_of(string str, size_type offset) const
string::size_type string::find_last_not_of(const string &str, size_type offset) const
{
return 0;
auto stop = begin() + offset;
auto iter = end() - 1;
while (iter != stop)
{
if(str.find(*iter) == npos)
{
return iter - begin();
}
--iter;
}
return npos;
}
void string::clear()
{
length_ = 0;
data_->clear();
data_->push_back('\0');
code_point_byte_offsets_->clear();
code_point_byte_offsets_->insert({0, 0});
}
template<>
@ -432,14 +601,40 @@ long double string::to() const
return std::stold(std::string(data()));
}
template<>
double string::to() const
{
return std::stod(std::string(data()));
}
#ifdef XLNT_STD_STRING
template<>
std::string string::to() const
{
return std::string(data());
}
#endif
int string::to_hex() const
{
return 0;
}
void string::remove(code_point iter)
void string::erase(size_type index)
{
auto start = code_point_byte_offsets_->at(index);
auto next_start = code_point_byte_offsets_->at(index + 1);
data_->erase(data_->begin() + start, data_->begin() + next_start);
auto code_point_bytes = next_start - start;
for(size_type i = index + 1; i < length(); i++)
{
code_point_byte_offsets_->at(i) = code_point_byte_offsets_->at(i + 1) - code_point_bytes;
}
code_point_byte_offsets_->erase(code_point_byte_offsets_->find(length()));
}
string &string::operator=(string rhs)
@ -451,22 +646,22 @@ string &string::operator=(string rhs)
string::iterator string::begin()
{
return iterator(data(), 0, length_);
return iterator(this, 0);
}
string::const_iterator string::cbegin() const
{
return const_iterator(data(), 0, length_);
return const_iterator(this, 0);
}
string::iterator string::end()
{
return iterator(data(), length_, length_);
return iterator(this, length());
}
string::const_iterator string::cend() const
{
return const_iterator(data(), length_, length_);
return const_iterator(this, length());
}
string::byte_pointer string::data()
@ -485,7 +680,7 @@ std::size_t string::hash() const
return hasher(std::string(data()));
}
std::size_t string::bytes() const
std::size_t string::num_bytes() const
{
return data_->size();
}
@ -494,38 +689,68 @@ void string::append(char c)
{
data_->back() = c;
data_->push_back('\0');
length_++;
code_point_byte_offsets_->insert({length() + 1, num_bytes() - 1});
}
void string::append(wchar_t c)
{
if(c < 128)
{
append(static_cast<char>(c));
return;
}
data_->pop_back();
utf8::utf16to8(&c, &c + 1, std::back_inserter(*data_));
std::array<char, 4> utf8_encoded {{0}};
auto end = utf8::utf16to8(&c, &c + 1, utf8_encoded.begin());
std::copy(utf8_encoded.begin(), end, std::back_inserter(*data_));
data_->push_back('\0');
length_++;
code_point_byte_offsets_->insert({length() + 1, num_bytes() - 1});
}
void string::append(char16_t c)
{
if(c < 128)
{
append(static_cast<char>(c));
return;
}
data_->pop_back();
utf8::utf16to8(&c, &c + 1, std::back_inserter(*data_));
std::array<char, 4> utf8_encoded {{0}};
auto end = utf8::utf16to8(&c, &c + 1, utf8_encoded.begin());
std::copy(utf8_encoded.begin(), end, std::back_inserter(*data_));
data_->push_back('\0');
length_++;
code_point_byte_offsets_->insert({length() + 1, num_bytes() - 1});
}
void string::append(char32_t c)
void string::append(code_point c)
{
if(c < 128)
{
append(static_cast<char>(c));
return;
}
data_->pop_back();
utf8::utf32to8(&c, &c + 1, std::back_inserter(*data_));
data_->push_back('\0');
std::array<char, 4> utf8_encoded {{0}};
auto end = utf8::utf32to8(&c, &c + 1, utf8_encoded.begin());
std::copy(utf8_encoded.begin(), end, std::back_inserter(*data_));
length_++;
data_->push_back('\0');
code_point_byte_offsets_->insert({length() + 1, num_bytes() - 1});
}
void string::append(string str)
void string::append(const string &str)
{
for (auto c : str)
{
@ -533,19 +758,61 @@ void string::append(string str)
}
}
void string::append(code_point c)
void string::replace(size_type index, utf32_char value)
{
append(c.get());
std::array<byte, 4> encoded = {{0}};
auto encoded_end = utf8::utf32to8(&value, &value + 1, encoded.begin());
auto encoded_len = encoded_end - encoded.begin();
auto data_start = code_point_byte_offsets_->at(index);
auto data_end = code_point_byte_offsets_->at(index + 1);
auto previous_len = data_end - data_start;
int difference = encoded_len - previous_len;
if(difference < 0)
{
data_->erase(data_->begin() + data_end + difference, data_->begin() + data_end);
}
else if(difference > 0)
{
data_->insert(data_->begin() + data_start, difference, '\0');
}
for(std::size_t i = index + 1; i < code_point_byte_offsets_->size(); i++)
{
code_point_byte_offsets_->at(i) += difference;
}
auto iter = encoded.begin();
auto data_iter = data_->begin() + data_start;
while(iter != encoded_end)
{
*data_iter = *iter;
++data_iter;
++iter;
}
}
string::code_point string::at(size_type index)
{
return *(begin() + index);
if(index == length())
{
return U'\0';
}
return utf8::peek_next(data_->begin() + code_point_byte_offsets_->at(index), data_->end());
}
const string::code_point string::at(size_type index) const
{
return *(begin() + index);
if(index == length())
{
return U'\0';
}
return utf8::peek_next(data_->begin() + code_point_byte_offsets_->at(index), data_->end());
}
bool string::operator==(const_byte_pointer str) const
@ -562,7 +829,7 @@ bool string::operator==(const string &str) const
while (left_iter != end() && right_iter != str.end())
{
if ((*left_iter).get() != (*right_iter).get())
if (*left_iter != *right_iter)
{
return false;
}
@ -603,8 +870,8 @@ void swap(string &left, string &right)
{
using std::swap;
swap(left.length_, right.length_);
swap(left.data_, right.data_);
swap(left.code_point_byte_offsets_, right.code_point_byte_offsets_);
}
std::ostream &operator<<(std::ostream &left, string &right)
@ -631,4 +898,9 @@ bool string::operator<(const string &other) const
return std::string(data()) < std::string(other.data());
}
string::size_type string::length() const
{
return code_point_byte_offsets_->size() - 1;
}
} // namespace xlnt

View File

@ -27,7 +27,8 @@ std::vector<xlnt::string> split_string(const xlnt::string &string, char delim)
separator_index = string.find(delim, previous_index);
}
split.push_back(string.substr(previous_index));
auto part = string.substr(previous_index);
split.push_back(part);
return split;
}

View File

@ -47,9 +47,9 @@ public:
{
xlnt::workbook wb;
auto new_sheet = wb.create_sheet();
std::string title = "my sheet";
new_sheet.set_title(title.c_str());
auto found_sheet = wb.get_sheet_by_name(title.c_str());
xlnt::string title = "my sheet";
new_sheet.set_title(title);
auto found_sheet = wb.get_sheet_by_name(title);
TS_ASSERT_EQUALS(new_sheet, found_sheet);
}
@ -120,9 +120,9 @@ public:
{
xlnt::workbook wb;
auto new_sheet = wb.create_sheet();
std::string title = "my sheet";
new_sheet.set_title(title.c_str());
auto found_sheet = wb.get_sheet_by_name(title.c_str());
xlnt::string title = "my sheet";
new_sheet.set_title(title);
auto found_sheet = wb.get_sheet_by_name(title);
TS_ASSERT_EQUALS(new_sheet, found_sheet);
}

View File

@ -351,7 +351,7 @@ std::size_t workbook::index_from_ws_filename(const string &ws_filename)
sheet_index_string = sheet_index_string.substr(sheet_index_string.find_last_of('/'));
auto iter = sheet_index_string.end();
--iter;
while (isdigit((*iter).get()))
while (isdigit((*iter)))
--iter;
auto first_digit = static_cast<std::size_t>(iter - sheet_index_string.begin());
sheet_index_string = sheet_index_string.substr(first_digit + 1);
@ -388,9 +388,9 @@ worksheet workbook::create_sheet(const string &title)
throw sheet_title_exception(title);
}
if (std::find_if(title.data(), title.data() + title.bytes(), [](char c) {
if (std::find_if(title.data(), title.data() + title.num_bytes(), [](char c) {
return c == '*' || c == ':' || c == '/' || c == '\\' || c == '?' || c == '[' || c == ']';
}) != title.data() + title.bytes())
}) != title.data() + title.num_bytes())
{
throw sheet_title_exception(title);
}

View File

@ -23,7 +23,7 @@ string sheet_protection::hash_password(const string &plaintext_password)
{
int password = 0x0000;
for (int i = 1; i <= plaintext_password.bytes(); i++)
for (int i = 1; i <= plaintext_password.num_bytes(); i++)
{
char character = plaintext_password.data()[i - 1];
int value = character << i;
@ -33,13 +33,13 @@ string sheet_protection::hash_password(const string &plaintext_password)
i++;
}
password ^= plaintext_password.bytes();
password ^= plaintext_password.num_bytes();
password ^= 0xCE4B;
string hashed = int_to_hex(password);
auto iter = hashed.data();
while (iter != hashed.data() + hashed.bytes())
while (iter != hashed.data() + hashed.num_bytes())
{
*iter = std::toupper(*iter, std::locale::classic());
}

View File

@ -55,13 +55,13 @@ public:
return compare_xml(expected_xml.get_root(), observed.get_root());
}
static comparison_result compare_xml(const std::string &left_contents, const std::string &right_contents)
static comparison_result compare_xml(const xlnt::string &left_contents, const xlnt::string &right_contents)
{
xlnt::xml_document left_xml;
left_xml.from_string(left_contents.c_str());
left_xml.from_string(left_contents.data());
xlnt::xml_document right_xml;
right_xml.from_string(right_contents.c_str());
right_xml.from_string(right_contents.data());
return compare_xml(left_xml.get_root(), right_xml.get_root());
}

View File

@ -62,7 +62,7 @@ public:
if (_NSGetExecutablePath(path.data(), &size) == 0)
{
return std::string(path.begin(), std::find(path.begin(), path.end(), '\0') - 9);
return xlnt::string(path.begin(), std::find(path.begin(), path.end(), '\0') - 9);
}
throw std::runtime_error("buffer too small, " + std::to_string(path.size()) + ", should be: " + std::to_string(size));
@ -126,7 +126,7 @@ public:
{
struct stat fileAtt;
if (stat(path.c_str(), &fileAtt) == 0)
if (stat(path.data(), &fileAtt) == 0)
{
return S_ISREG(fileAtt.st_mode);
}

View File

@ -11,7 +11,7 @@
class TemporaryDirectory
{
public:
static std::string CreateTemporaryFilename()
static xlnt::string CreateTemporaryFilename()
{
#ifdef _WIN32
std::array<TCHAR, MAX_PATH> buffer;
@ -24,7 +24,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");
#else
return "/tmp/xlsx";
@ -41,8 +41,8 @@ public:
remove(filename_.c_str());
}
std::string GetFilename() const { return filename_; }
xlnt::string GetFilename() const { return filename_; }
private:
const std::string filename_;
const xlnt::string filename_;
};