mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
test workbook some
This commit is contained in:
parent
101ba5e49f
commit
026058d111
|
@ -87,7 +87,6 @@ public:
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
workbook();
|
workbook();
|
||||||
workbook(encoding e);
|
|
||||||
|
|
||||||
workbook &operator=(workbook other);
|
workbook &operator=(workbook other);
|
||||||
workbook(workbook &&other);
|
workbook(workbook &&other);
|
||||||
|
@ -97,8 +96,6 @@ public:
|
||||||
|
|
||||||
friend void swap(workbook &left, workbook &right);
|
friend void swap(workbook &left, workbook &right);
|
||||||
|
|
||||||
encoding get_encoding() const;
|
|
||||||
|
|
||||||
worksheet get_active_sheet();
|
worksheet get_active_sheet();
|
||||||
|
|
||||||
bool get_guess_types() const;
|
bool get_guess_types() const;
|
||||||
|
|
|
@ -39,8 +39,6 @@
|
||||||
#include <xlnt/utils/time.hpp>
|
#include <xlnt/utils/time.hpp>
|
||||||
#include <xlnt/utils/timedelta.hpp>
|
#include <xlnt/utils/timedelta.hpp>
|
||||||
#include <xlnt/utils/exceptions.hpp>
|
#include <xlnt/utils/exceptions.hpp>
|
||||||
#include <xlnt/utils/utf8string.hpp>
|
|
||||||
#include <xlnt/workbook/encoding.hpp>
|
|
||||||
#include <xlnt/workbook/workbook.hpp>
|
#include <xlnt/workbook/workbook.hpp>
|
||||||
#include <xlnt/worksheet/column_properties.hpp>
|
#include <xlnt/worksheet/column_properties.hpp>
|
||||||
#include <xlnt/worksheet/row_properties.hpp>
|
#include <xlnt/worksheet/row_properties.hpp>
|
||||||
|
|
|
@ -318,22 +318,6 @@ public:
|
||||||
auto cell = ws.get_cell(xlnt::cell_reference(1, 1));
|
auto cell = ws.get_cell(xlnt::cell_reference(1, 1));
|
||||||
TS_ASSERT(cell.offset(1, 2).get_reference() == "B3");
|
TS_ASSERT(cell.offset(1, 2).get_reference() == "B3");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string make_latin1_string()
|
|
||||||
{
|
|
||||||
unsigned char pound = 163;
|
|
||||||
auto test_string = "Compound Value (" + std::string(1, pound) + ")";
|
|
||||||
return test_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_good_encoding()
|
|
||||||
{
|
|
||||||
xlnt::workbook latin1_wb(xlnt::encoding::latin1);
|
|
||||||
auto ws = latin1_wb.get_active_sheet();
|
|
||||||
auto cell = ws[xlnt::cell_reference("A1")];
|
|
||||||
cell.check_string(make_latin1_string());
|
|
||||||
cell.set_value(make_latin1_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_font()
|
void test_font()
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,7 +66,7 @@ std::string::size_type find_string_in_string(const std::string &string, const st
|
||||||
return possible_match_index;
|
return possible_match_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xlnt::workbook &wb)
|
bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xlnt::workbook &wb, xlnt::detail::stylesheet &stylesheet)
|
||||||
{
|
{
|
||||||
wb.set_guess_types(guess_types);
|
wb.set_guess_types(guess_types);
|
||||||
wb.set_data_only(data_only);
|
wb.set_data_only(data_only);
|
||||||
|
@ -143,7 +143,6 @@ bool load_workbook(xlnt::zip_file &archive, bool guess_types, bool data_only, xl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xlnt::detail::stylesheet stylesheet;
|
|
||||||
xlnt::style_serializer style_serializer(stylesheet);
|
xlnt::style_serializer style_serializer(stylesheet);
|
||||||
pugi::xml_document style_xml;
|
pugi::xml_document style_xml;
|
||||||
style_xml.load(archive.read(xlnt::constants::ArcStyles()).c_str());
|
style_xml.load(archive.read(xlnt::constants::ArcStyles()).c_str());
|
||||||
|
@ -226,14 +225,14 @@ bool excel_serializer::load_workbook(const std::string &filename, bool guess_typ
|
||||||
throw invalid_file_exception(filename);
|
throw invalid_file_exception(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ::load_workbook(archive_, guess_types, data_only, workbook_);
|
return ::load_workbook(archive_, guess_types, data_only, workbook_, get_stylesheet());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool excel_serializer::load_virtual_workbook(const std::vector<std::uint8_t> &bytes, bool guess_types, bool data_only)
|
bool excel_serializer::load_virtual_workbook(const std::vector<std::uint8_t> &bytes, bool guess_types, bool data_only)
|
||||||
{
|
{
|
||||||
archive_.load(bytes);
|
archive_.load(bytes);
|
||||||
|
|
||||||
return ::load_workbook(archive_, guess_types, data_only, workbook_);
|
return ::load_workbook(archive_, guess_types, data_only, workbook_, get_stylesheet());
|
||||||
}
|
}
|
||||||
|
|
||||||
excel_serializer::excel_serializer(workbook &wb) : workbook_(wb)
|
excel_serializer::excel_serializer(workbook &wb) : workbook_(wb)
|
||||||
|
|
|
@ -100,7 +100,6 @@ struct workbook_impl
|
||||||
|
|
||||||
manifest manifest_;
|
manifest manifest_;
|
||||||
theme theme_;
|
theme theme_;
|
||||||
encoding encoding_;
|
|
||||||
std::vector<std::uint8_t> thumbnail_;
|
std::vector<std::uint8_t> thumbnail_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,9 @@ public:
|
||||||
{
|
{
|
||||||
auto path = PathHelper::GetDataDirectory("/genuine/empty.xlsx");
|
auto path = PathHelper::GetDataDirectory("/genuine/empty.xlsx");
|
||||||
std::ifstream fo(path, std::ios::binary);
|
std::ifstream fo(path, std::ios::binary);
|
||||||
|
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb;
|
||||||
xlnt::excel_serializer serializer(wb);
|
TS_ASSERT(wb.load(fo));
|
||||||
|
|
||||||
serializer.load_stream_workbook(fo);
|
|
||||||
|
|
||||||
TS_ASSERT_DIFFERS(wb, nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_read_worksheet()
|
void test_read_worksheet()
|
||||||
|
@ -103,9 +99,7 @@ public:
|
||||||
auto path = PathHelper::GetDataDirectory("/genuine/empty-with-styles.xlsx");
|
auto path = PathHelper::GetDataDirectory("/genuine/empty-with-styles.xlsx");
|
||||||
|
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb;
|
||||||
xlnt::excel_serializer serializer(wb);
|
wb.load(path);
|
||||||
|
|
||||||
serializer.load_workbook(path);
|
|
||||||
|
|
||||||
return wb;
|
return wb;
|
||||||
}
|
}
|
||||||
|
@ -340,7 +334,7 @@ public:
|
||||||
{
|
{
|
||||||
auto path = PathHelper::GetDataDirectory("/reader/formulae.xlsx");
|
auto path = PathHelper::GetDataDirectory("/reader/formulae.xlsx");
|
||||||
|
|
||||||
xlnt::workbook wb(xlnt::encoding::latin1);
|
xlnt::workbook wb;
|
||||||
xlnt::excel_serializer serializer(wb);
|
xlnt::excel_serializer serializer(wb);
|
||||||
|
|
||||||
serializer.load_workbook(path, false, true);
|
serializer.load_workbook(path, false, true);
|
||||||
|
|
|
@ -32,6 +32,18 @@ public:
|
||||||
auto new_sheet = wb.create_sheet("LikeThisName");
|
auto new_sheet = wb.create_sheet("LikeThisName");
|
||||||
auto last = std::distance(wb.begin(), wb.end()) - 1;
|
auto last = std::distance(wb.begin(), wb.end()) - 1;
|
||||||
TS_ASSERT_EQUALS(new_sheet, wb[last]);
|
TS_ASSERT_EQUALS(new_sheet, wb[last]);
|
||||||
|
TS_ASSERT_THROWS(wb.create_sheet(std::string(40, 'a')), std::runtime_error);
|
||||||
|
TS_ASSERT_THROWS(wb.create_sheet("a:a"), std::runtime_error);
|
||||||
|
TS_ASSERT_EQUALS(wb.create_sheet("LikeThisName").get_title(), "LikeThisName1");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_create_sheet_with_name_at_index()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb;
|
||||||
|
TS_ASSERT_EQUALS(wb.get_sheet_by_index(0).get_title(), "Sheet");
|
||||||
|
wb.create_sheet(0, "LikeThisName");
|
||||||
|
TS_ASSERT_EQUALS(wb.get_sheet_by_index(0).get_title(), "LikeThisName");
|
||||||
|
TS_ASSERT_EQUALS(wb.get_sheet_by_index(1).get_title(), "Sheet");
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_add_correct_sheet()
|
void test_add_correct_sheet()
|
||||||
|
@ -44,14 +56,26 @@ public:
|
||||||
wb.create_sheet().get_cell("A6").set_value(1.497);
|
wb.create_sheet().get_cell("A6").set_value(1.497);
|
||||||
TS_ASSERT(!wb[1].compare(wb[3], false));
|
TS_ASSERT(!wb[1].compare(wb[3], false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// void test_add_sheetname() {} unnecessary
|
|
||||||
|
|
||||||
void test_add_sheet_from_other_workbook()
|
void test_add_sheet_from_other_workbook()
|
||||||
{
|
{
|
||||||
xlnt::workbook wb1, wb2;
|
xlnt::workbook wb1, wb2;
|
||||||
auto new_sheet = wb1.get_active_sheet();
|
auto new_sheet = wb1.get_active_sheet();
|
||||||
TS_ASSERT_THROWS(wb2.add_sheet(new_sheet), xlnt::value_error);
|
TS_ASSERT_THROWS(wb2.add_sheet(new_sheet), xlnt::value_error);
|
||||||
|
TS_ASSERT_THROWS(wb2.get_index(new_sheet), std::runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_add_sheet_at_index()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb;
|
||||||
|
auto ws = wb.get_active_sheet();
|
||||||
|
ws.get_cell("B3").set_value(2);
|
||||||
|
ws.set_title("Active");
|
||||||
|
wb.add_sheet(ws, 0);
|
||||||
|
TS_ASSERT_EQUALS(wb.get_sheet_names().at(0), "Sheet");
|
||||||
|
TS_ASSERT_EQUALS(wb.get_sheet_by_index(0).get_cell("B3").get_value<int>(), 2);
|
||||||
|
TS_ASSERT_EQUALS(wb.get_sheet_names().at(1), "Active");
|
||||||
|
TS_ASSERT_EQUALS(wb.get_sheet_by_index(1).get_cell("B3").get_value<int>(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_create_sheet_readonly()
|
void test_create_sheet_readonly()
|
||||||
|
@ -63,10 +87,11 @@ public:
|
||||||
|
|
||||||
void test_remove_sheet()
|
void test_remove_sheet()
|
||||||
{
|
{
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb, wb2;
|
||||||
auto new_sheet = wb.create_sheet(0);
|
auto new_sheet = wb.create_sheet(0);
|
||||||
wb.remove_sheet(new_sheet);
|
wb.remove_sheet(new_sheet);
|
||||||
TS_ASSERT(std::find(wb.begin(), wb.end(), new_sheet) == wb.end());
|
TS_ASSERT(std::find(wb.begin(), wb.end(), new_sheet) == wb.end());
|
||||||
|
TS_ASSERT_THROWS(wb.remove_sheet(wb2.get_active_sheet()), std::runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_get_sheet_by_name()
|
void test_get_sheet_by_name()
|
||||||
|
@ -119,9 +144,14 @@ public:
|
||||||
void test_get_index()
|
void test_get_index()
|
||||||
{
|
{
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb;
|
||||||
auto new_sheet = wb.create_sheet(0);
|
wb.create_sheet().set_title("1");
|
||||||
auto sheet_index = wb.get_index(new_sheet);
|
wb.create_sheet().set_title("2");
|
||||||
TS_ASSERT_EQUALS(sheet_index, 0);
|
|
||||||
|
auto sheet_index = wb.get_index(wb.get_sheet_by_name("1"));
|
||||||
|
TS_ASSERT_EQUALS(sheet_index, 1);
|
||||||
|
|
||||||
|
sheet_index = wb.get_index(wb.get_sheet_by_name("2"));
|
||||||
|
TS_ASSERT_EQUALS(sheet_index, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_get_sheet_names()
|
void test_get_sheet_names()
|
||||||
|
@ -149,11 +179,12 @@ public:
|
||||||
|
|
||||||
void test_add_named_range()
|
void test_add_named_range()
|
||||||
{
|
{
|
||||||
xlnt::workbook wb;
|
xlnt::workbook wb, wb2;
|
||||||
auto new_sheet = wb.create_sheet();
|
auto new_sheet = wb.create_sheet();
|
||||||
wb.create_named_range("test_nr", new_sheet, "A1");
|
wb.create_named_range("test_nr", new_sheet, "A1");
|
||||||
TS_ASSERT(new_sheet.has_named_range("test_nr"));
|
TS_ASSERT(new_sheet.has_named_range("test_nr"));
|
||||||
TS_ASSERT(wb.has_named_range("test_nr"));
|
TS_ASSERT(wb.has_named_range("test_nr"));
|
||||||
|
TS_ASSERT_THROWS(wb2.create_named_range("test_nr", new_sheet, "A1"), std::runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_get_named_range()
|
void test_get_named_range()
|
||||||
|
@ -164,6 +195,7 @@ public:
|
||||||
auto found_range = wb.get_named_range("test_nr");
|
auto found_range = wb.get_named_range("test_nr");
|
||||||
auto expected_range = new_sheet.get_range("A1");
|
auto expected_range = new_sheet.get_range("A1");
|
||||||
TS_ASSERT_EQUALS(expected_range, found_range);
|
TS_ASSERT_EQUALS(expected_range, found_range);
|
||||||
|
TS_ASSERT_THROWS(wb.get_named_range("test_nr2"), std::runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_remove_named_range()
|
void test_remove_named_range()
|
||||||
|
@ -174,6 +206,7 @@ public:
|
||||||
wb.remove_named_range("test_nr");
|
wb.remove_named_range("test_nr");
|
||||||
TS_ASSERT(!new_sheet.has_named_range("test_nr"));
|
TS_ASSERT(!new_sheet.has_named_range("test_nr"));
|
||||||
TS_ASSERT(!wb.has_named_range("test_nr"));
|
TS_ASSERT(!wb.has_named_range("test_nr"));
|
||||||
|
TS_ASSERT_THROWS(wb.remove_named_range("test_nr2"), std::runtime_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_write_regular_date()
|
void test_write_regular_date()
|
||||||
|
@ -270,4 +303,42 @@ public:
|
||||||
TS_ASSERT(o.get_content_type().empty());
|
TS_ASSERT(o.get_content_type().empty());
|
||||||
TS_ASSERT(o.get_part_name().empty());
|
TS_ASSERT(o.get_part_name().empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_get_bad_relationship()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb;
|
||||||
|
TS_ASSERT_THROWS(wb.get_relationship("bad"), std::runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_memory()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb, wb2;
|
||||||
|
wb.get_active_sheet().set_title("swap");
|
||||||
|
std::swap(wb, wb2);
|
||||||
|
TS_ASSERT_EQUALS(wb.get_active_sheet().get_title(), "Sheet");
|
||||||
|
TS_ASSERT_EQUALS(wb2.get_active_sheet().get_title(), "swap");
|
||||||
|
wb = wb2;
|
||||||
|
TS_ASSERT_EQUALS(wb.get_active_sheet().get_title(), "swap");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_clear()
|
||||||
|
{
|
||||||
|
xlnt::workbook wb;
|
||||||
|
xlnt::style s = wb.create_style("s");
|
||||||
|
wb.get_active_sheet().get_cell("B2").set_value("B2");
|
||||||
|
wb.get_active_sheet().get_cell("B2").set_style(s);
|
||||||
|
TS_ASSERT(wb.get_active_sheet().get_cell("B2").has_style());
|
||||||
|
wb.clear_styles();
|
||||||
|
TS_ASSERT(!wb.get_active_sheet().get_cell("B2").has_style());
|
||||||
|
xlnt::format format;
|
||||||
|
xlnt::font font;
|
||||||
|
font.set_size(41);
|
||||||
|
format.set_font(font);
|
||||||
|
wb.get_active_sheet().get_cell("B2").set_format(format);
|
||||||
|
TS_ASSERT(wb.get_active_sheet().get_cell("B2").has_format());
|
||||||
|
wb.clear_formats();
|
||||||
|
TS_ASSERT(!wb.get_active_sheet().get_cell("B2").has_format());
|
||||||
|
wb.clear();
|
||||||
|
TS_ASSERT(wb.get_sheet_names().empty());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include <xlnt/styles/protection.hpp>
|
#include <xlnt/styles/protection.hpp>
|
||||||
#include <xlnt/utils/exceptions.hpp>
|
#include <xlnt/utils/exceptions.hpp>
|
||||||
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
#include <xlnt/workbook/const_worksheet_iterator.hpp>
|
||||||
#include <xlnt/workbook/encoding.hpp>
|
|
||||||
#include <xlnt/workbook/named_range.hpp>
|
#include <xlnt/workbook/named_range.hpp>
|
||||||
#include <xlnt/workbook/theme.hpp>
|
#include <xlnt/workbook/theme.hpp>
|
||||||
#include <xlnt/workbook/workbook.hpp>
|
#include <xlnt/workbook/workbook.hpp>
|
||||||
|
@ -77,8 +76,6 @@ workbook::workbook() : d_(new detail::workbook_impl())
|
||||||
create_relationship("rId2", "styles.xml", relationship::type::styles);
|
create_relationship("rId2", "styles.xml", relationship::type::styles);
|
||||||
create_relationship("rId3", "theme/theme1.xml", relationship::type::theme);
|
create_relationship("rId3", "theme/theme1.xml", relationship::type::theme);
|
||||||
|
|
||||||
d_->encoding_ = encoding::utf8;
|
|
||||||
|
|
||||||
d_->manifest_.add_default_type("rels", "application/vnd.openxmlformats-package.relationships+xml");
|
d_->manifest_.add_default_type("rels", "application/vnd.openxmlformats-package.relationships+xml");
|
||||||
d_->manifest_.add_default_type("xml", "application/xml");
|
d_->manifest_.add_default_type("xml", "application/xml");
|
||||||
|
|
||||||
|
@ -96,11 +93,6 @@ workbook::workbook() : d_(new detail::workbook_impl())
|
||||||
d_->stylesheet_.fills.push_back(gray125);
|
d_->stylesheet_.fills.push_back(gray125);
|
||||||
}
|
}
|
||||||
|
|
||||||
workbook::workbook(encoding e) : workbook()
|
|
||||||
{
|
|
||||||
d_->encoding_ = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
const worksheet workbook::get_sheet_by_name(const std::string &name) const
|
const worksheet workbook::get_sheet_by_name(const std::string &name) const
|
||||||
{
|
{
|
||||||
for (auto &impl : d_->worksheets_)
|
for (auto &impl : d_->worksheets_)
|
||||||
|
@ -175,7 +167,9 @@ void workbook::add_sheet(xlnt::worksheet worksheet)
|
||||||
if(worksheet.d_->parent_ != this) throw xlnt::value_error();
|
if(worksheet.d_->parent_ != this) throw xlnt::value_error();
|
||||||
|
|
||||||
xlnt::detail::worksheet_impl impl(*worksheet.d_);
|
xlnt::detail::worksheet_impl impl(*worksheet.d_);
|
||||||
*create_sheet().d_ = impl;
|
auto new_sheet = create_sheet();
|
||||||
|
impl.title_ = new_sheet.get_title();
|
||||||
|
*new_sheet.d_ = impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void workbook::add_sheet(xlnt::worksheet worksheet, std::size_t index)
|
void workbook::add_sheet(xlnt::worksheet worksheet, std::size_t index)
|
||||||
|
@ -312,11 +306,6 @@ void workbook::remove_sheet(worksheet ws)
|
||||||
auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(),
|
auto rel_iter = std::find_if(d_->relationships_.begin(), d_->relationships_.end(),
|
||||||
[=](relationship &r) { return r.get_target_uri() == sheet_filename; });
|
[=](relationship &r) { return r.get_target_uri() == sheet_filename; });
|
||||||
|
|
||||||
if (rel_iter == d_->relationships_.end())
|
|
||||||
{
|
|
||||||
throw std::runtime_error("no matching rel found");
|
|
||||||
}
|
|
||||||
|
|
||||||
d_->relationships_.erase(rel_iter);
|
d_->relationships_.erase(rel_iter);
|
||||||
d_->worksheets_.erase(match_iter);
|
d_->worksheets_.erase(match_iter);
|
||||||
}
|
}
|
||||||
|
@ -409,11 +398,6 @@ worksheet workbook::create_sheet(const std::string &title)
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
encoding workbook::get_encoding() const
|
|
||||||
{
|
|
||||||
return d_->encoding_;
|
|
||||||
}
|
|
||||||
|
|
||||||
workbook::iterator workbook::begin()
|
workbook::iterator workbook::begin()
|
||||||
{
|
{
|
||||||
return iterator(*this, 0);
|
return iterator(*this, 0);
|
||||||
|
@ -473,6 +457,8 @@ void workbook::clear()
|
||||||
d_->relationships_.clear();
|
d_->relationships_.clear();
|
||||||
d_->active_sheet_index_ = 0;
|
d_->active_sheet_index_ = 0;
|
||||||
d_->properties_ = document_properties();
|
d_->properties_ = document_properties();
|
||||||
|
clear_styles();
|
||||||
|
clear_formats();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool workbook::save(std::vector<unsigned char> &data)
|
bool workbook::save(std::vector<unsigned char> &data)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user