Skip to content
This repository was archived by the owner on Jun 17, 2024. It is now read-only.

Commit 4ba6a01

Browse files
Golfish exceptions to subclass std::exception
1 parent 7eef7e4 commit 4ba6a01

13 files changed

+139
-128
lines changed

inc/goldfish/base64_stream.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace goldfish { namespace stream
77
{
8-
struct ill_formatted_base64_data : ill_formatted {};
8+
struct ill_formatted_base64_data : ill_formatted { using ill_formatted::ill_formatted; };
99

1010
// Reads binary data assuming inner reads base64
1111
template <class inner> class base64_reader
@@ -57,22 +57,22 @@ namespace goldfish { namespace stream
5757
else
5858
c_read = 3;
5959

60-
if (stream::seek(m_stream, 1) != 0) // Padding is only allowed at the end of the stream
61-
throw ill_formatted_base64_data{};
60+
if (stream::seek(m_stream, 1) != 0)
61+
throw ill_formatted_base64_data{ "'=' is only allowed at the end of a base64 stream" };
6262
}
6363

6464
if (c_read == 0)
6565
return 0;
6666
if (c_read == 1)
67-
throw ill_formatted_base64_data{};
67+
throw ill_formatted_base64_data{ "Unexpected number of characters in base64 stream" };
6868

6969
auto a = character_to_6bits(buffer[0]);
7070
auto b = character_to_6bits(buffer[1]);
7171
output[0] = ((a << 2) | (b >> 4));
7272
if (c_read == 2)
7373
{
7474
if (b & 0xF)
75-
throw ill_formatted_base64_data{};
75+
throw ill_formatted_base64_data{ "Invalid character at end of base64 stream" };
7676
return 1;
7777
}
7878

@@ -81,7 +81,7 @@ namespace goldfish { namespace stream
8181
if (c_read == 3)
8282
{
8383
if (c & 0x3)
84-
throw ill_formatted_base64_data{};
84+
throw ill_formatted_base64_data{ "Invalid character at end of base64 stream" };
8585
return 2;
8686
}
8787

@@ -122,7 +122,7 @@ namespace goldfish { namespace stream
122122
static_assert(sizeof(lookup_table) == 256, "");
123123
auto result = lookup_table[c];
124124
if (result >= 64)
125-
throw ill_formatted_base64_data{};
125+
throw ill_formatted_base64_data{ "Invalid character in base64 stream" };
126126
return result;
127127
}
128128
inner m_stream;

inc/goldfish/cbor_reader.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace goldfish { namespace cbor
1313
{
14-
struct ill_formatted_cbor_data : ill_formatted {};
14+
struct ill_formatted_cbor_data : ill_formatted { using ill_formatted::ill_formatted; };
1515

1616
template <class Stream, byte expected_type, class _tag> class string;
1717
template <class Stream> using byte_string = string<Stream, 2, tags::binary>;
@@ -53,7 +53,7 @@ namespace goldfish { namespace cbor
5353
, m_remaining_in_current_block(cb_initial)
5454
{
5555
if (m_remaining_in_current_block >= invalid_remaining)
56-
throw ill_formatted_cbor_data{};
56+
throw ill_formatted_cbor_data{ "CBOR string too large" };
5757
}
5858

5959
size_t read_partial_buffer(buffer_ref buffer)
@@ -74,7 +74,7 @@ namespace goldfish { namespace cbor
7474
{
7575
auto to_skip = std::min(cb, m_remaining_in_current_block);
7676
if (stream::seek(m_stream, to_skip) != to_skip)
77-
throw ill_formatted_cbor_data{};
77+
throw ill_formatted_cbor_data{ "Unexpected end of stream while reading CBOR string" };
7878
cb -= to_skip;
7979
m_remaining_in_current_block -= to_skip;
8080
}
@@ -100,11 +100,11 @@ namespace goldfish { namespace cbor
100100
}
101101

102102
if ((b >> 5) != expected_type)
103-
throw ill_formatted_cbor_data{};
103+
throw ill_formatted_cbor_data{ "Unexpected type in CBOR string block" };
104104

105105
auto cb_next_block = read_integer(b & 31, m_stream);
106106
if (cb_next_block >= invalid_remaining)
107-
throw ill_formatted_cbor_data{};
107+
throw ill_formatted_cbor_data{ "CBOR string too large" };
108108
m_remaining_in_current_block = cb_next_block;
109109
}
110110
return m_remaining_in_current_block != invalid_remaining;
@@ -128,7 +128,7 @@ namespace goldfish { namespace cbor
128128
, m_remaining_length(length)
129129
{
130130
if (m_remaining_length == std::numeric_limits<uint64_t>::max())
131-
throw ill_formatted_cbor_data{};
131+
throw ill_formatted_cbor_data{ "CBOR array too large" };
132132
}
133133
array(Stream&& s)
134134
: m_stream(std::move(s))
@@ -149,7 +149,7 @@ namespace goldfish { namespace cbor
149149
if (m_remaining_length == std::numeric_limits<uint64_t>::max())
150150
m_remaining_length = 0;
151151
else
152-
throw ill_formatted_cbor_data{};
152+
throw ill_formatted_cbor_data{ "CBOR array too large" };
153153
}
154154
return document;
155155
}
@@ -168,7 +168,7 @@ namespace goldfish { namespace cbor
168168
, m_remaining_length(remaining_length)
169169
{
170170
if (m_remaining_length == std::numeric_limits<uint64_t>::max())
171-
throw ill_formatted_cbor_data{};
171+
throw ill_formatted_cbor_data{ "CBOR map too large" };
172172
}
173173
map(Stream&& s)
174174
: m_stream(std::move(s))
@@ -187,7 +187,7 @@ namespace goldfish { namespace cbor
187187
if (m_remaining_length == std::numeric_limits<uint64_t>::max())
188188
m_remaining_length = 0;
189189
else
190-
throw ill_formatted_cbor_data{};
190+
throw ill_formatted_cbor_data{ "Unexpected break code found in finite length map" };
191191
}
192192
if (m_remaining_length != std::numeric_limits<uint64_t>::max())
193193
--m_remaining_length;
@@ -197,7 +197,7 @@ namespace goldfish { namespace cbor
197197
{
198198
auto d = read_no_debug_check(stream::ref(m_stream));
199199
if (!d)
200-
throw ill_formatted_cbor_data{};
200+
throw ill_formatted_cbor_data{ "Unexpected break code found as a map value" };
201201
return std::move(*d);
202202
}
203203
private:
@@ -226,7 +226,7 @@ namespace goldfish { namespace cbor
226226
else if (additional == 27)
227227
return from_big_endian(read<uint64_t>(s));
228228
else
229-
throw ill_formatted_cbor_data{};
229+
throw ill_formatted_cbor_data{ "Bad CBOR integer encoding" };
230230
}
231231
template <class stream> double read_half_point_float(stream& s)
232232
{
@@ -253,7 +253,7 @@ namespace goldfish { namespace cbor
253253
{
254254
auto x = read_integer(static_cast<byte>(first_byte & 31), s);
255255
if (x > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
256-
throw ill_formatted_cbor_data{};
256+
throw ill_formatted_cbor_data{ "CBOR signed integer too large" };
257257

258258
return -1 - static_cast<int64_t>(x);
259259
}
@@ -278,7 +278,7 @@ namespace goldfish { namespace cbor
278278
static optional<document<Stream>> fn_float_16(Stream&& s, byte) { return read_half_point_float(s); }
279279
static optional<document<Stream>> fn_float_32(Stream&& s, byte) { return double{ to_float(from_big_endian(stream::read<uint32_t>(s))) }; }
280280
static optional<document<Stream>> fn_float_64(Stream&& s, byte) { return to_double(from_big_endian(stream::read<uint64_t>(s))); }
281-
static optional<document<Stream>> fn_ill_formatted(Stream&&, byte) { throw ill_formatted_cbor_data{}; };
281+
static optional<document<Stream>> fn_ill_formatted(Stream&&, byte) { throw ill_formatted_cbor_data{ "Unexpected CBOR opcode" }; };
282282

283283
static optional<document<Stream>> fn_small_binary(Stream&& s, byte first_byte) { return byte_string<Stream>{ std::move(s), static_cast<uint8_t>(first_byte & 31) }; };
284284
static optional<document<Stream>> fn_8_binary(Stream&& s, byte) { return byte_string<Stream>{ std::move(s), stream::read<uint8_t>(s) }; };
@@ -392,7 +392,7 @@ namespace goldfish { namespace cbor
392392
{
393393
auto d = read_no_debug_check(std::forward<Stream>(s));
394394
if (!d)
395-
throw ill_formatted_cbor_data{};
395+
throw ill_formatted_cbor_data{ "Unexpected break code in CBOR stream" };
396396
return debug_checks::add_read_checks(std::move(*d), e);
397397
}
398398
template <class Stream> auto read(Stream&& s) { return read(std::forward<Stream>(s), debug_checks::default_error_handler{}); }

inc/goldfish/common.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,26 @@ namespace goldfish
1717
inline uint64_t to_big_endian(uint64_t x) { return from_big_endian(x); }
1818

1919
// All goldfish exceptions subclass this exception
20-
struct exception {};
20+
class exception : public std::exception
21+
{
22+
public:
23+
exception(const char* w)
24+
: m_what(w)
25+
{}
26+
const char* what() const noexcept override { return m_what; }
27+
private:
28+
const char* m_what;
29+
};
2130

2231
// Base class for all formatting errors that happen while parsing a document
23-
struct ill_formatted : exception {};
32+
struct ill_formatted : exception { using exception::exception; };
2433

2534
// Specifically for IO errors, thrown by file_reader/writer and istream_reader/writer
26-
struct io_exception : exception {};
35+
struct io_exception : exception { using exception::exception; };
2736
struct io_exception_with_error_code : io_exception
2837
{
29-
io_exception_with_error_code(int _error_code)
30-
: error_code(_error_code)
38+
io_exception_with_error_code(const char* w, int _error_code)
39+
: io_exception(w), error_code(_error_code)
3140
{}
3241

3342
int error_code;

inc/goldfish/file_stream.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ namespace goldfish { namespace stream
1414
file_handle(const char* path, const char* mode)
1515
{
1616
if (auto error = fopen_s(&m_fp, path, mode))
17-
throw io_exception_with_error_code{ error };
17+
throw io_exception_with_error_code{ "Error during file open", error };
1818
}
1919
file_handle(const wchar_t* path, const wchar_t* wmode)
2020
{
2121
if (auto error = _wfopen_s(&m_fp, path, wmode))
22-
throw io_exception_with_error_code{ error };
22+
throw io_exception_with_error_code{ "Error during file open", error };
2323
}
2424
file_handle(const std::string& path, const char* mode)
2525
: file_handle(path.c_str(), mode)
@@ -68,7 +68,7 @@ namespace goldfish { namespace stream
6868
if (cb != data.size())
6969
{
7070
if (auto error = ferror(m_file.get()))
71-
throw io_exception_with_error_code{ error };
71+
throw io_exception_with_error_code{ "Error during file read", error };
7272
}
7373
return cb;
7474
}
@@ -95,7 +95,7 @@ namespace goldfish { namespace stream
9595
void write_buffer(const_buffer_ref data)
9696
{
9797
if (fwrite(data.data(), 1 /*size*/, data.size() /*count*/, m_file.get()) != data.size())
98-
throw io_exception_with_error_code{ ferror(m_file.get()) };
98+
throw io_exception_with_error_code{ "Error during file write", ferror(m_file.get()) };
9999
}
100100
void flush() { }
101101
private:

inc/goldfish/iostream_adaptor.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ namespace goldfish { namespace stream
1818
return 0;
1919

2020
if (auto cb = m_stream.readsome(reinterpret_cast<char*>(buffer.data()), buffer.size()))
21-
return cb;
21+
return static_cast<size_t>(cb); // static_cast is OK because cb <= buffer.size(), which is a size_t
2222

2323
m_stream.read(reinterpret_cast<char*>(buffer.data()), 1);
2424
if (m_stream.bad() || (m_stream.fail() && !m_stream.eof()))
25-
throw io_exception{};
25+
throw io_exception{ "istream read failed" };
2626

2727
return static_cast<size_t>(m_stream.gcount());
2828
}
@@ -39,13 +39,13 @@ namespace goldfish { namespace stream
3939
{
4040
m_stream.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
4141
if (m_stream.fail())
42-
throw io_exception{};
42+
throw io_exception{ "ostream write failed" };
4343
}
4444
void flush()
4545
{
4646
m_stream.flush();
4747
if (m_stream.fail())
48-
throw io_exception{};
48+
throw io_exception{ "ostream flush failed" };
4949
}
5050
private:
5151
std::ostream& m_stream;

0 commit comments

Comments
 (0)