ensure only exceptions derived from xlnt::exception are thrown by library code plus some minor code cleanup, closes #163

pull/243/head
Thomas Fussell 2017-09-13 08:48:22 -04:00
parent bc1e3656c7
commit 9d71dda531
13 changed files with 169 additions and 121 deletions

View File

@ -310,7 +310,7 @@ class python_streambuf : public std::basic_streambuf<char>
upper_bound = reinterpret_cast<std::streamsize>(farthest_pptr) + 1;
}
else {
throw std::runtime_error("unreachable");
throw xlnt::exception("unreachable");
}
// Sought position in "buffer coordinate"
@ -325,7 +325,7 @@ class python_streambuf : public std::basic_streambuf<char>
return failure;
}
else {
throw std::runtime_error("unreachable");
throw xlnt::exception("unreachable");
}
// if the sought position is not in the buffer, give up

View File

@ -38,7 +38,7 @@ void import_pyarrow()
{
if (arrow::py::import_pyarrow() != 0)
{
throw std::runtime_error("Import of pyarrow failed.");
throw xlnt::exception("Import of pyarrow failed.");
}
imported = true;
@ -156,7 +156,7 @@ arrow::ArrayBuilder *make_array_builder(arrow::Type::type type)
break;
*/
default:
throw std::runtime_error("not implemented");
throw xlnt::exception("not implemented");
}
return builder;
@ -322,7 +322,7 @@ void append_cell_value(arrow::ArrayBuilder *builder, arrow::Type::type type, xln
break;
*/
default:
throw std::runtime_error("not implemented");
throw xlnt::exception("not implemented");
}
}

View File

@ -59,7 +59,7 @@ pixmap load_image(const std::string &filename)
if (image_data == nullptr)
{
throw std::runtime_error("bad image or file not found: " + filename);
throw xlnt::exception("bad image or file not found: " + filename);
}
pixmap result;
@ -99,8 +99,8 @@ xlnt::workbook build_workbook_cf(const pixmap &image)
// The reference to the cell which is being operated upon
auto current_cell = xlnt::cell_reference("A1");
// The range of cells which will be modified. This is required for conditional formats
auto range = ws.range(xlnt::range_reference(1, 1,
static_cast<xlnt::column_t::index_t>(image[0].size()),
auto range = ws.range(xlnt::range_reference(1, 1,
static_cast<xlnt::column_t::index_t>(image[0].size()),
static_cast<xlnt::row_t>(image.size())));
// Track the previously created conditonal formats so they are only created once
@ -119,7 +119,7 @@ xlnt::workbook build_workbook_cf(const pixmap &image)
if (defined_colors.count(color.hex_string()) == 0)
{
// The condition under which the conditional format applies to a cell
// In this case, the condition is satisfied when the text of the cell
// In this case, the condition is satisfied when the text of the cell
// contains the hex string representing the pixel color.
const auto condition = xlnt::condition::text_contains(color.hex_string());
// Create a new conditional format with the above condition on the image pixel range
@ -144,7 +144,7 @@ xlnt::workbook build_workbook_cf(const pixmap &image)
// Show some progress, it can take a while...
std::cout << current_cell.row() << " " << defined_colors.size() << std::endl;
}
// Return the resulting workbook
return wb;
}

View File

@ -323,7 +323,9 @@ bool cell::is_merged() const
bool cell::is_date() const
{
return data_type() == type::number && has_format() && number_format().is_date_format();
return data_type() == type::number
&& has_format()
&& number_format().is_date_format();
}
cell_reference cell::reference() const
@ -364,7 +366,8 @@ std::string cell::hyperlink() const
void cell::hyperlink(const std::string &hyperlink)
{
if (hyperlink.length() == 0 || std::find(hyperlink.begin(), hyperlink.end(), ':') == hyperlink.end())
if (hyperlink.length() == 0
|| std::find(hyperlink.begin(), hyperlink.end(), ':') == hyperlink.end())
{
throw invalid_parameter();
}
@ -400,7 +403,7 @@ void cell::formula(const std::string &formula)
}
data_type(type::number);
worksheet().register_calc_chain_in_manifest();
}

View File

@ -66,7 +66,10 @@ cell_reference::cell_reference(const char *reference_string)
cell_reference::cell_reference(column_t column_index, row_t row)
: column_(column_index), row_(row), absolute_row_(false), absolute_column_(false)
{
if (row_ == 0 || column_ == 0 || !(row_ <= constants::max_row()) || !(column_ <= constants::max_column()))
if (row_ == 0
|| column_ == 0
|| !(row_ <= constants::max_row())
|| !(column_ <= constants::max_column()))
{
throw invalid_cell_reference(column_, row_);
}
@ -264,12 +267,15 @@ cell_reference cell_reference::make_offset(int column_offset, int row_offset) co
// TODO: check for overflow/underflow
auto relative_column = static_cast<column_t::index_t>(static_cast<int>(column_.index) + column_offset);
auto relative_row = static_cast<row_t>(static_cast<int>(row_) + row_offset);
return cell_reference(relative_column, relative_row);
}
bool cell_reference::operator==(const cell_reference &comparand) const
{
return comparand.column_ == column_ && comparand.row_ == row_ && absolute_column_ == comparand.absolute_column_
return comparand.column_ == column_
&& comparand.row_ == row_
&& absolute_column_ == comparand.absolute_column_
&& absolute_row_ == comparand.absolute_row_;
}

View File

@ -54,22 +54,27 @@ const path constants::package_properties()
{
return path("docProps");
}
const path constants::package_xl()
{
return path("/xl");
}
const path constants::package_root_rels()
{
return path(std::string("_rels"));
}
const path constants::package_theme()
{
return package_xl().append("theme");
}
const path constants::package_worksheets()
{
return package_xl().append("worksheets");
}
const path constants::package_drawings()
{
return package_xl().append("drawings");
@ -79,30 +84,37 @@ const path constants::part_content_types()
{
return path("[Content_Types].xml");
}
const path constants::part_root_relationships()
{
return package_root_rels().append(".rels");
}
const path constants::part_core()
{
return package_properties().append("core.xml");
}
const path constants::part_app()
{
return package_properties().append("app.xml");
}
const path constants::part_workbook()
{
return package_xl().append("workbook.xml");
}
const path constants::part_styles()
{
return package_xl().append("styles.xml");
}
const path constants::part_theme()
{
return package_theme().append("theme1.xml");
}
const path constants::part_shared_strings()
{
return package_xl().append("sharedStrings.xml");
@ -140,7 +152,8 @@ const std::unordered_map<std::string, std::string> &constants::namespaces()
{"xml", "http://www.w3.org/XML/1998/namespace"},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
{"loext", "http://schemas.libreoffice.org/"}};
{"loext", "http://schemas.libreoffice.org/"}
};
return *namespaces;
}
@ -156,4 +169,5 @@ const std::string &constants::ns(const std::string &id)
return match->second;
}
}
} // namespace xlnt

View File

@ -31,7 +31,8 @@
#include <stdlib.h>
#include <stdio.h>
#include "aes.hpp"
#include <detail/cryptography/aes.hpp>
#include <xlnt/utils/exceptions.hpp>
namespace {
@ -959,7 +960,9 @@ rijndael_key rijndael_setup(const std::vector<std::uint8_t> &key_data)
if (key_data.size() != 16 && key_data.size() != 24 && key_data.size() != 32)
{
throw std::runtime_error("");
throw xlnt::exception("Invalid AES key length ("
+ std::to_string(key_data.size())
+ " bytes). Must be 16, 24 or 32 bytes.");
}
skey.Nr = 10 + ((static_cast<int>(key_data.size())/8)-2)*2;
@ -1029,8 +1032,6 @@ rijndael_key rijndael_setup(const std::vector<std::uint8_t> &key_data)
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
} else {
throw std::runtime_error("");
}
/* setup the inverse key now */
@ -1347,7 +1348,9 @@ std::vector<std::uint8_t> aes_ecb_encrypt(
if (len % 16 != 0)
{
throw std::runtime_error("");
throw xlnt::exception("Invalid ECB plaintext length ("
+ std::to_string(len)
+ " bytes). Must be a multiple of 16 bytes.");
}
auto ciphertext = std::vector<std::uint8_t>(len);
@ -1378,7 +1381,9 @@ std::vector<std::uint8_t> aes_ecb_decrypt(
if (len % 16 != 0)
{
throw std::runtime_error("");
throw xlnt::exception("Invalid ECB ciphertext length ("
+ std::to_string(len)
+ " bytes). Must be a multiple of 16 bytes.");
}
auto plaintext = std::vector<std::uint8_t>(len);
@ -1410,7 +1415,9 @@ std::vector<std::uint8_t> aes_cbc_encrypt(
if (len % 16 != 0)
{
throw std::runtime_error("");
throw xlnt::exception("Invalid CBC plaintext length ("
+ std::to_string(len)
+ " bytes). Must be a multiple of 16 bytes.");
}
auto ciphertext = std::vector<std::uint8_t>(len);
@ -1454,7 +1461,9 @@ std::vector<std::uint8_t> aes_cbc_decrypt(
if (ciphertext.size() % 16 != 0)
{
throw std::runtime_error("");
throw xlnt::exception("Invalid ECB ciphertext length ("
+ std::to_string(len)
+ " bytes). Must be a multiple of 16 bytes.");
}
std::array<std::uint8_t, 16> temporary{{0}};

View File

@ -20,6 +20,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <array>
#include <detail/cryptography/base64.hpp>
namespace xlnt {
@ -31,15 +32,15 @@ std::string encode_base64(const std::vector<std::uint8_t> &input)
auto output = std::string(encoded_length, '\0');
auto input_iterator = input.begin();
auto output_iterator = output.begin();
int i = 0, j = 0;
unsigned char a3[3];
unsigned char a4[4];
const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
auto i = std::size_t(0);
auto j = std::size_t(0);
std::array<std::uint8_t, 3> a3{{0}};
std::array<std::uint8_t, 4> a4{{0}};
const std::string alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/");
while (input_iterator != input.end())
{
a3[i++] = *input_iterator++;
@ -47,60 +48,68 @@ std::string encode_base64(const std::vector<std::uint8_t> &input)
if (i == 3)
{
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = static_cast<std::uint8_t>(((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4));
a4[2] = static_cast<std::uint8_t>(((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6));
a4[1] = static_cast<std::uint8_t>(((a3[0] & 0x03) << 4)
+ ((a3[1] & 0xf0) >> 4));
a4[2] = static_cast<std::uint8_t>(((a3[1] & 0x0f) << 2)
+ ((a3[2] & 0xc0) >> 6));
a4[3] = (a3[2] & 0x3f);
for (i = 0; i < 4; i++)
{
*output_iterator++ = kBase64Alphabet[a4[i]];
*output_iterator++ = alphabet[a4[i]];
}
i = 0;
}
}
if (i)
if (i != 0)
{
for (j = i; j < 3; j++)
{
a3[j] = '\0';
a3[j] = 0;
}
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = static_cast<std::uint8_t>(((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4));
a4[2] = static_cast<std::uint8_t>(((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6));
a4[1] = static_cast<std::uint8_t>(((a3[0] & 0x03) << 4)
+ ((a3[1] & 0xf0) >> 4));
a4[2] = static_cast<std::uint8_t>(((a3[1] & 0x0f) << 2)
+ ((a3[2] & 0xc0) >> 6));
a4[3] = (a3[2] & 0x3f);
for (j = 0; j < i + 1; j++)
{
*output_iterator++ = kBase64Alphabet[a4[j]];
*output_iterator++ = alphabet[a4[j]];
}
while ((i++ < 3))
while (i++ < 3)
{
*output_iterator++ = '=';
}
}
return output;
}
std::vector<std::uint8_t> decode_base64(const std::string &input)
{
std::size_t numEq = 0;
std::size_t padding_count = 0;
auto in_end = input.data() + input.size();
while (*--in_end == '=') ++numEq;
auto decoded_length = ((6 * input.size()) / 8) - numEq;
while (*--in_end == '=')
{
++padding_count;
}
auto decoded_length = ((6 * input.size()) / 8) - padding_count;
auto output = std::vector<std::uint8_t>(decoded_length);
auto input_iterator = input.begin();
auto output_iterator = output.begin();
int i = 0, j = 0;
std::uint8_t a3[3];
std::uint8_t a4[4];
auto i = std::size_t(0);
auto j = std::size_t(0);
std::array<std::uint8_t, 3> a3{{0}};
std::array<std::uint8_t, 4> a4{{0}};
auto b64_lookup = [](std::uint8_t c) -> std::uint8_t
{
if(c >='A' && c <='Z') return c - 'A';
@ -110,58 +119,64 @@ std::vector<std::uint8_t> decode_base64(const std::string &input)
if(c == '/') return 63;
return 255;
};
while (input_iterator != input.end())
{
if (*input_iterator == '=')
{
break;
}
a4[i++] = static_cast<std::uint8_t>(*(input_iterator++));
if (i == 4)
{
for (i = 0; i <4; i++)
for (i = 0; i < 4; i++)
{
a4[i] = b64_lookup(a4[i]);
}
a3[0] = static_cast<std::uint8_t>(a4[0] << 2) + static_cast<std::uint8_t>((a4[1] & 0x30) >> 4);
a3[1] = static_cast<std::uint8_t>((a4[1] & 0xf) << 4) + static_cast<std::uint8_t>((a4[2] & 0x3c) >> 2);
a3[2] = static_cast<std::uint8_t>((a4[2] & 0x3) << 6) + static_cast<std::uint8_t>(a4[3]);
a3[0] = static_cast<std::uint8_t>(a4[0] << 2)
+ static_cast<std::uint8_t>((a4[1] & 0x30) >> 4);
a3[1] = static_cast<std::uint8_t>((a4[1] & 0xf) << 4)
+ static_cast<std::uint8_t>((a4[2] & 0x3c) >> 2);
a3[2] = static_cast<std::uint8_t>((a4[2] & 0x3) << 6)
+ static_cast<std::uint8_t>(a4[3]);
for (i = 0; i < 3; i++)
{
*output_iterator++ = a3[i];
}
i = 0;
}
}
if (i)
if (i != 0)
{
for (j = i; j < 4; j++)
{
a4[j] = '\0';
a4[j] = 0;
}
for (j = 0; j < 4; j++)
{
a4[j] = b64_lookup(a4[j]);
}
a3[0] = static_cast<std::uint8_t>(a4[0] << 2) + static_cast<std::uint8_t>((a4[1] & 0x30) >> 4);
a3[1] = static_cast<std::uint8_t>((a4[1] & 0xf) << 4) + static_cast<std::uint8_t>((a4[2] & 0x3c) >> 2);
a3[2] = static_cast<std::uint8_t>((a4[2] & 0x3) << 6) + static_cast<std::uint8_t>(a4[3]);
a3[0] = static_cast<std::uint8_t>(a4[0] << 2)
+ static_cast<std::uint8_t>((a4[1] & 0x30) >> 4);
a3[1] = static_cast<std::uint8_t>((a4[1] & 0xf) << 4)
+ static_cast<std::uint8_t>((a4[2] & 0x3c) >> 2);
a3[2] = static_cast<std::uint8_t>((a4[2] & 0x3) << 6)
+ static_cast<std::uint8_t>(a4[3]);
for (j = 0; j < i - 1; j++)
{
*output_iterator++ = a3[j];
}
}
return output;
}

View File

@ -21,7 +21,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <array>
#include <algorithm>
#include <cstring>
@ -45,6 +45,7 @@ int compare_keys(const std::string &left, const std::string &right)
{
static const auto *locale = new std::locale();
std::use_facet<std::ctype<char>>(*locale).tolower(&s[0], &s[0] + s.size());
return s;
};
@ -112,7 +113,7 @@ public:
compound_document_istreambuf(const compound_document_istreambuf &) = delete;
compound_document_istreambuf &operator=(const compound_document_istreambuf &) = delete;
~compound_document_istreambuf() override;
private:
@ -135,7 +136,7 @@ private:
document_.read_short_sector(current_sector, sector_writer_);
}
const auto available = std::min(entry_.size - position_,
const auto available = std::min(entry_.size - position_,
document_.short_sector_size() - position_ % document_.short_sector_size());
const auto to_read = std::min(available, std::size_t(remaining));
@ -402,14 +403,14 @@ private:
chain_.push_back(next_sector);
document_.write_sat();
}
auto value = static_cast<std::uint8_t>(c);
if (c != traits_type::eof())
{
current_sector_[position_ % current_sector_.size()] = value;
}
pbump(1);
return traits_type::to_int_type(static_cast<char>(value));
@ -641,7 +642,7 @@ void compound_document::read_short_sector(sector_id id, binary_writer<T> &writer
const auto container_chain = follow_chain(entries_[0].start, sat_);
auto container = std::vector<byte>();
auto container_writer = binary_writer<byte>(container);
for (auto sector : container_chain)
{
read_sector(sector, container_writer);
@ -677,7 +678,7 @@ sector_id compound_document::allocate_sector()
{
const auto sectors_per_sector = sector_size() / sizeof(sector_id);
auto next_free_iter = std::find(sat_.begin(), sat_.end(), FreeSector);
if (next_free_iter == sat_.end())
{
auto next_msat_index = header_.num_msat_sectors;
@ -699,16 +700,16 @@ sector_id compound_document::allocate_sector()
next_free_iter = std::find(sat_.begin(), sat_.end(), FreeSector);
}
auto next_free = sector_id(next_free_iter - sat_.begin());
sat_[static_cast<std::size_t>(next_free)] = EndOfChain;
write_sat();
auto empty_sector = std::vector<byte>(sector_size());
auto empty_sector_reader = binary_reader<byte>(empty_sector);
write_sector(empty_sector_reader, next_free);
return next_free;
}
@ -726,7 +727,7 @@ sector_chain compound_document::allocate_sectors(std::size_t count)
sat_[static_cast<std::size_t>(current)] = next;
current = next;
}
chain.push_back(current);
write_sat();
@ -761,7 +762,7 @@ sector_chain compound_document::allocate_short_sectors(std::size_t count)
ssat_[static_cast<std::size_t>(current)] = next;
current = next;
}
chain.push_back(current);
write_ssat();
@ -772,11 +773,11 @@ sector_id compound_document::allocate_short_sector()
{
const auto sectors_per_sector = sector_size() / sizeof(sector_id);
auto next_free_iter = std::find(ssat_.begin(), ssat_.end(), FreeSector);
if (next_free_iter == ssat_.end())
{
auto new_ssat_sector_id = allocate_sector();
if (header_.ssat_start < 0)
{
header_.ssat_start = new_ssat_sector_id;
@ -787,9 +788,9 @@ sector_id compound_document::allocate_short_sector()
sat_[static_cast<std::size_t>(ssat_chain.back())] = new_ssat_sector_id;
write_sat();
}
write_header();
auto old_size = ssat_.size();
ssat_.resize(old_size + sectors_per_sector, FreeSector);
@ -807,10 +808,10 @@ sector_id compound_document::allocate_short_sector()
ssat_[static_cast<std::size_t>(next_free)] = EndOfChain;
write_ssat();
const auto short_sectors_per_sector = sector_size() / short_sector_size();
const auto required_container_sectors = static_cast<std::size_t>(next_free) / short_sectors_per_sector + std::size_t(1);
if (required_container_sectors > 0)
{
if (entries_[0].start < 0)
@ -818,16 +819,16 @@ sector_id compound_document::allocate_short_sector()
entries_[0].start = allocate_sector();
write_entry(0);
}
auto container_chain = follow_chain(entries_[0].start, sat_);
if (required_container_sectors > container_chain.size())
{
sat_[static_cast<std::size_t>(container_chain.back())] = allocate_sector();
write_sat();
}
}
return next_free;
}
@ -858,7 +859,7 @@ directory_id compound_document::next_empty_entry()
write_sat();
}
const auto entries_per_sector = sector_size()
const auto entries_per_sector = sector_size()
/ sizeof(compound_document_entry);
for (auto i = std::size_t(0); i < entries_per_sector; ++i)

View File

@ -143,7 +143,7 @@ void number_format_parser::parse()
{
if (section.has_color || section.has_condition || section.has_locale || !section.parts.empty())
{
throw std::runtime_error("color should be the first part of a format");
throw xlnt::exception("color should be the first part of a format");
}
section.has_color = true;
@ -156,7 +156,7 @@ void number_format_parser::parse()
{
if (section.has_locale)
{
throw std::runtime_error("multiple locales");
throw xlnt::exception("multiple locales");
}
section.has_locale = true;
@ -178,7 +178,7 @@ void number_format_parser::parse()
{
if (section.has_condition)
{
throw std::runtime_error("multiple conditions");
throw xlnt::exception("multiple conditions");
}
section.has_condition = true;
@ -623,12 +623,12 @@ number_format_token number_format_parser::parse_next_token()
case '[':
if (position_ == format_string_.size())
{
throw std::runtime_error("missing ]");
throw xlnt::exception("missing ]");
}
if (format_string_[position_] == ']')
{
throw std::runtime_error("empty []");
throw xlnt::exception("empty []");
}
do
@ -670,7 +670,7 @@ number_format_token number_format_parser::parse_next_token()
case 'G':
if (format_string_.substr(position_ - 1, 7) != "General")
{
throw std::runtime_error("expected General");
throw xlnt::exception("expected General");
}
token.type = number_format_token::token_type::number;
@ -744,7 +744,7 @@ number_format_token number_format_parser::parse_next_token()
}
else
{
throw std::runtime_error("expected AM/PM or A/P");
throw xlnt::exception("expected AM/PM or A/P");
}
break;
@ -839,7 +839,7 @@ number_format_token number_format_parser::parse_next_token()
break;
default:
throw std::runtime_error("unexpected character");
throw xlnt::exception("unexpected character");
}
return token;
@ -849,14 +849,14 @@ void number_format_parser::validate()
{
if (codes_.size() > 4)
{
throw std::runtime_error("too many format codes");
throw xlnt::exception("too many format codes");
}
if (codes_.size() > 2)
{
if (codes_[0].has_condition && codes_[1].has_condition && codes_[2].has_condition)
{
throw std::runtime_error("format should have a maximum of two codes with conditions");
throw xlnt::exception("format should have a maximum of two codes with conditions");
}
}
}
@ -1029,7 +1029,7 @@ std::pair<format_locale, std::string> number_format_parser::locale_from_string(c
if (locale_string.empty() || locale_string.front() != '$' || hyphen_index == std::string::npos)
{
throw std::runtime_error("bad locale: " + locale_string);
throw xlnt::exception("bad locale: " + locale_string);
}
std::pair<format_locale, std::string> result;
@ -1043,14 +1043,14 @@ std::pair<format_locale, std::string> number_format_parser::locale_from_string(c
if (country_code_string.empty())
{
throw std::runtime_error("bad locale: " + locale_string);
throw xlnt::exception("bad locale: " + locale_string);
}
for (auto c : country_code_string)
{
if (!((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9')))
{
throw std::runtime_error("bad locale: " + locale_string);
throw xlnt::exception("bad locale: " + locale_string);
}
}
@ -1065,7 +1065,7 @@ std::pair<format_locale, std::string> number_format_parser::locale_from_string(c
}
}
throw std::runtime_error("unknown country code: " + country_code_string);
throw xlnt::exception("unknown country code: " + country_code_string);
}
number_formatter::number_formatter(const std::string &format_string, xlnt::calendar calendar)

View File

@ -57,17 +57,17 @@ public:
{
return sample_data_directory().append(xlnt::path(filename));
}
static void copy_file(const xlnt::path &source, const xlnt::path &destination, bool overwrite)
{
if(!overwrite && destination.exists())
{
throw std::runtime_error("destination file already exists and overwrite==false");
throw xlnt::exception("destination file already exists and overwrite==false");
}
std::ifstream src(source.string(), std::ios::binary);
std::ofstream dst(destination.string(), std::ios::binary);
dst << src.rdbuf();
}

View File

@ -18,11 +18,11 @@ public:
DWORD result = GetTempPath(static_cast<DWORD>(buffer.size()), buffer.data());
if(result > MAX_PATH)
{
throw std::runtime_error("buffer is too small");
throw xlnt::exception("buffer is too small");
}
if(result == 0)
{
throw std::runtime_error("GetTempPath failed");
throw xlnt::exception("GetTempPath failed");
}
std::string directory(buffer.begin(), buffer.begin() + result);
return path_helper::windows_to_universal_path(directory + "xlnt");

View File

@ -46,7 +46,7 @@ public:
{
auto function_that_throws = []()
{
throw std::runtime_error("test");
throw xlnt::exception("test");
};
auto function_that_doesnt_throw = []()