@@ -34,7 +34,8 @@ namespace
3434 Signed value{0 };
3535 if (!cbor_nondet_read_int64 (cbor, &value))
3636 {
37- throw CBORDecodeError (" Failed to decode signed value" );
37+ throw CBORDecodeError (
38+ Error::DECODE_FAILED, " Failed to decode signed value" );
3839 }
3940 return std::make_unique<ValueImpl>(value);
4041 }
@@ -45,7 +46,8 @@ namespace
4546 uint64_t length = 0 ;
4647 if (!cbor_nondet_get_byte_string (cbor, &data, &length))
4748 {
48- throw CBORDecodeError (" Failed to decode byte string" );
49+ throw CBORDecodeError (
50+ Error::DECODE_FAILED, " Failed to decode byte string" );
4951 }
5052 Bytes value{data, static_cast <size_t >(length)};
5153 return std::make_unique<ValueImpl>(value);
@@ -57,7 +59,8 @@ namespace
5759 uint64_t length = 0 ;
5860 if (!cbor_nondet_get_text_string (cbor, &data, &length))
5961 {
60- throw CBORDecodeError (" Failed to decode text string" );
62+ throw CBORDecodeError (
63+ Error::DECODE_FAILED, " Failed to decode text string" );
6164 }
6265 String value{
6366 reinterpret_cast <const char *>(data), static_cast <size_t >(length)};
@@ -69,7 +72,8 @@ namespace
6972 cbor_nondet_array_iterator_t iter;
7073 if (!cbor_nondet_array_iterator_start (cbor, &iter))
7174 {
72- throw CBORDecodeError (" Failed to start array iterator" );
75+ throw CBORDecodeError (
76+ Error::DECODE_FAILED, " Failed to start array iterator" );
7377 }
7478
7579 Array array;
@@ -78,7 +82,8 @@ namespace
7882 cbor_nondet_t item;
7983 if (!cbor_nondet_array_iterator_next (&iter, &item))
8084 {
81- throw CBORDecodeError (" Failed to get next array item" );
85+ throw CBORDecodeError (
86+ Error::DECODE_FAILED, " Failed to get next array item" );
8287 }
8388 array.items .push_back (consume (item));
8489 }
@@ -90,7 +95,8 @@ namespace
9095 cbor_map_iterator iter;
9196 if (!cbor_nondet_map_iterator_start (cbor, &iter))
9297 {
93- throw CBORDecodeError (" Failed to start map iterator" );
98+ throw CBORDecodeError (
99+ Error::DECODE_FAILED, " Failed to start map iterator" );
94100 }
95101
96102 Map map;
@@ -100,7 +106,8 @@ namespace
100106 cbor_raw value_raw;
101107 if (!cbor_nondet_map_iterator_next (&iter, &key_raw, &value_raw))
102108 {
103- throw CBORDecodeError (" Failed to get next map entry" );
109+ throw CBORDecodeError (
110+ Error::DECODE_FAILED, " Failed to get next map entry" );
104111 }
105112 map.items .emplace_back (consume (key_raw), consume (value_raw));
106113 }
@@ -113,7 +120,8 @@ namespace
113120 cbor_nondet_t payload;
114121 if (!cbor_nondet_get_tagged (cbor, &payload, &tag))
115122 {
116- throw CBORDecodeError (" Failed to decode tagged value" );
123+ throw CBORDecodeError (
124+ Error::DECODE_FAILED, " Failed to decode tagged value" );
117125 }
118126
119127 Tagged tagged;
@@ -130,7 +138,8 @@ namespace
130138 Simple value{0 };
131139 if (!cbor_nondet_read_simple_value (cbor, &value))
132140 {
133- throw CBORDecodeError (" Failed to decode simple value" );
141+ throw CBORDecodeError (
142+ Error::DECODE_FAILED, " Failed to decode simple value" );
134143 }
135144 return std::make_unique<ValueImpl>(value);
136145 }
@@ -156,7 +165,7 @@ namespace
156165 case CBOR_MAJOR_TYPE_SIMPLE_VALUE:
157166 return consume_simple (cbor);
158167 default :
159- throw CBORDecodeError (" Unknown CBOR major type" );
168+ throw CBORDecodeError (Error::DECODE_FAILED, " Unknown CBOR major type" );
160169 }
161170 }
162171
@@ -256,6 +265,16 @@ namespace
256265
257266namespace ccf ::cbor
258267{
268+ CBORDecodeError::CBORDecodeError (Error err, const std::string& what) :
269+ std::runtime_error (what),
270+ error (err)
271+ {}
272+
273+ Error CBORDecodeError::error_code () const
274+ {
275+ return error;
276+ }
277+
259278 Value make_signed (int64_t value)
260279 {
261280 return std::make_unique<ValueImpl>(value);
@@ -285,7 +304,8 @@ namespace ccf::cbor
285304 &cbor_parse_size,
286305 &cbor))
287306 {
288- throw CBORDecodeError (" Failed to parse top-level cbor" );
307+ throw CBORDecodeError (
308+ Error::DECODE_FAILED, " Failed to parse top-level cbor" );
289309 }
290310
291311 return consume (cbor);
@@ -313,21 +333,22 @@ namespace ccf::cbor
313333 case SimpleValue::True:
314334 return true ;
315335 default :
316- throw CBORDecodeError (" Simple value cannot be matched to boolean" );
336+ throw CBORDecodeError (
337+ Error::TYPE_MISMATCH, " Simple value cannot be matched to boolean" );
317338 }
318339 }
319340
320341 const Value& ValueImpl::array_at (size_t index) const
321342 {
322343 if (!std::holds_alternative<Array>(value))
323344 {
324- throw CBORDecodeError (" Not an array" );
345+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not an array" );
325346 }
326347
327348 const auto & arr = std::get<Array>(value);
328349 if (index >= arr.items .size ())
329350 {
330- throw CBORDecodeError (" Array index out of bounds" );
351+ throw CBORDecodeError (Error::OUT_OF_BOUND, " Array index out of bounds" );
331352 }
332353
333354 return arr.items [index];
@@ -337,7 +358,7 @@ namespace ccf::cbor
337358 {
338359 if (!std::holds_alternative<Map>(value))
339360 {
340- throw CBORDecodeError (" Not a map" );
361+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not a map" );
341362 }
342363
343364 // Fail fast: Array, Map, Tagged are not supported as map keys in this
@@ -350,6 +371,7 @@ namespace ccf::cbor
350371 std::is_same_v<T, Tagged>)
351372 {
352373 throw CBORDecodeError (
374+ Error::TYPE_MISMATCH,
353375 " Array, Map, and Tagged values cannot be used as map keys" );
354376 }
355377 },
@@ -390,7 +412,7 @@ namespace ccf::cbor
390412 }
391413 }
392414
393- throw CBORDecodeError (" Key not found in map" );
415+ throw CBORDecodeError (Error::KEY_NOT_FOUND, " Key not found in map" );
394416 }
395417
396418 size_t ValueImpl::size () const
@@ -405,20 +427,20 @@ namespace ccf::cbor
405427 const auto & map = std::get<Map>(value);
406428 return map.items .size ();
407429 }
408- throw CBORDecodeError (" Not a collection" );
430+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not a collection" );
409431 }
410432
411433 const Value& ValueImpl::tag_at (uint64_t tag) const
412434 {
413435 if (!std::holds_alternative<Tagged>(value))
414436 {
415- throw CBORDecodeError (" Not a tagged value" );
437+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not a tagged value" );
416438 }
417439
418440 const auto & tagged = std::get<Tagged>(value);
419441 if (tagged.tag != tag)
420442 {
421- throw CBORDecodeError (" Tag does not match" );
443+ throw CBORDecodeError (Error::KEY_NOT_FOUND, " Tag does not match" );
422444 }
423445
424446 return tagged.item ;
@@ -428,7 +450,7 @@ namespace ccf::cbor
428450 {
429451 if (!std::holds_alternative<Signed>(value))
430452 {
431- throw CBORDecodeError (" Not a signed value" );
453+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not a signed value" );
432454 }
433455 return std::get<Signed>(value);
434456 }
@@ -437,7 +459,7 @@ namespace ccf::cbor
437459 {
438460 if (!std::holds_alternative<Bytes>(value))
439461 {
440- throw CBORDecodeError (" Not a bytes value" );
462+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not a bytes value" );
441463 }
442464 return std::get<Bytes>(value);
443465 }
@@ -446,7 +468,7 @@ namespace ccf::cbor
446468 {
447469 if (!std::holds_alternative<String>(value))
448470 {
449- throw CBORDecodeError (" Not a string value" );
471+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not a string value" );
450472 }
451473 return std::get<String>(value);
452474 }
@@ -455,7 +477,7 @@ namespace ccf::cbor
455477 {
456478 if (!std::holds_alternative<Simple>(value))
457479 {
458- throw CBORDecodeError (" Not a simple value" );
480+ throw CBORDecodeError (Error::TYPE_MISMATCH, " Not a simple value" );
459481 }
460482 return std::get<Simple>(value);
461483 }
0 commit comments