Compare commits

..

No commits in common. "acf4d93fded24b558946cf226aedc32ce6709fde" and "257be2e57a383851fa2335dfed4a6f959d607de3" have entirely different histories.

3 changed files with 125 additions and 98 deletions

View file

@ -40,10 +40,8 @@ namespace CBOR
float Float ();
double Double ();
std::span<std::uint8_t> Binary();
std::string_view String();
class Binary IndefiniteBinary();
class String IndefiniteString();
class Binary Binary ();
class String String ();
class Array Array ();
class Map Map ();
@ -82,13 +80,16 @@ namespace CBOR
Binary(Decoder &decoder);
public:
std::span<std::uint8_t> Get();
void AllowIndefinite();
bool Done();
std::span<std::uint8_t> Next();
private:
friend class Decoder;
bool mHeaderParsed;
bool mIndefiniteAllowed;
bool mDone;
bool mCheckedDone;
Decoder *mDecoder;
@ -100,13 +101,16 @@ namespace CBOR
String(Decoder &decoder);
public:
std::string_view Get();
void AllowIndefinite();
bool Done();
std::string_view Next();
private:
friend class Decoder;
bool mHeaderParsed;
bool mIndefiniteAllowed;
bool mDone;
bool mCheckedDone;
Decoder *mDecoder;
@ -174,12 +178,10 @@ namespace CBOR
float Float ();
double Double ();
std::span<std::uint8_t> Binary();
std::string_view String();
class Binary IndefiniteBinary();
class String IndefiniteString();
class Array Array();
class Map Map();
Binary Binary ();
String String ();
Array Array ();
Map Map ();
private:
friend class Binary;

View file

@ -139,11 +139,11 @@ namespace CBOR
std::uint64_t ArgumentValue(std::uint8_t header, std::span<std::uint8_t> buffer, std::size_t &current)
{
ArgumentPosition position = GetArgumentPosition(header);
if (std::to_underlying(position) <= 23) {
return std::to_underlying(position);
ArgumentPosition pos = GetArgumentPosition(header);
if (std::to_underlying(pos) <= 23) {
return std::to_underlying(pos);
}
switch (position) {
switch (pos) {
case ArgumentPosition::Next1B:
return Consume1B(buffer, current);
case ArgumentPosition::Next2B:
@ -416,26 +416,16 @@ namespace CBOR
return mDecoder->Double();
}
std::span<std::uint8_t> Item::Binary()
Binary Item::Binary()
{
return mDecoder->Binary();
}
std::string_view Item::String()
String Item::String()
{
return mDecoder->String();
}
Binary Item::IndefiniteBinary()
{
return mDecoder->IndefiniteBinary();
}
String Item::IndefiniteString()
{
return mDecoder->IndefiniteString();
}
Array Item::Array()
{
return mDecoder->Array();
@ -472,11 +462,44 @@ namespace CBOR
Binary::Binary(Decoder &decoder)
: mHeaderParsed(false)
, mIndefiniteAllowed(false)
, mDone(false)
, mCheckedDone(false)
, mDecoder(&decoder)
{}
std::span<std::uint8_t> Binary::Get()
{
if (mDone) {
throw InvalidUsageError("this item has already been fully parsed");
}
if (mIndefiniteAllowed) {
throw InvalidUsageError("indefinite-length items have been explicitly enabled, "
"use the funcions for those instead");
}
std::uint8_t header = Consume1B(mDecoder->mBuffer, mDecoder->mCurrent);
MajorType major = GetMajorType(header);
mHeaderParsed = true;
if (major != MajorType::Binary) {
throw TypeMismatchError("binary", ToString(major));
}
if (GetArgumentPosition(header) == ArgumentPosition::Indefinite) {
throw IndefiniteLengthError();
}
mDone = true;
std::uint64_t arg = ArgumentValue(header, mDecoder->mBuffer, mDecoder->mCurrent);
return ExtractBinary(arg, mDecoder->mBuffer, mDecoder->mCurrent);
}
void Binary::AllowIndefinite()
{
mIndefiniteAllowed = true;
}
bool Binary::Done()
{
if (!mHeaderParsed) {
@ -527,8 +550,8 @@ namespace CBOR
std::uint8_t header = Consume1B(mDecoder->mBuffer, mDecoder->mCurrent);
MajorType major = GetMajorType(header);
ArgumentPosition position = GetArgumentPosition(header);
if (major != MajorType::Binary || position == ArgumentPosition::Indefinite){
ArgumentPosition pos = GetArgumentPosition(header);
if (major != MajorType::Binary || pos == ArgumentPosition::Indefinite){
throw MalformedDataError("an indefinite length string may only contain "
"definite length strings");
}
@ -539,11 +562,44 @@ namespace CBOR
String::String(Decoder &decoder)
: mHeaderParsed(false)
, mIndefiniteAllowed(false)
, mDone(false)
, mCheckedDone(false)
, mDecoder(&decoder)
{}
std::string_view String::Get()
{
if (mDone) {
throw InvalidUsageError("this item has already been fully parsed");
}
if (mIndefiniteAllowed) {
throw InvalidUsageError("indefinite-length items have been explicitly enabled, "
"use the funcions for those instead");
}
std::uint8_t header = Consume1B(mDecoder->mBuffer, mDecoder->mCurrent);
mHeaderParsed = true;
MajorType major = GetMajorType(header);
if (major != MajorType::String) {
throw TypeMismatchError("string", ToString(major));
}
if (GetArgumentPosition(header) == ArgumentPosition::Indefinite) {
throw IndefiniteLengthError();
}
mDone = true;
std::uint64_t arg = ArgumentValue(header, mDecoder->mBuffer, mDecoder->mCurrent);
return ExtractString(arg, mDecoder->mBuffer, mDecoder->mCurrent);
}
void String::AllowIndefinite()
{
mIndefiniteAllowed = true;
}
bool String::Done()
{
if (!mHeaderParsed) {
@ -594,8 +650,8 @@ namespace CBOR
std::uint8_t header = Consume1B(mDecoder->mBuffer, mDecoder->mCurrent);
MajorType major = GetMajorType(header);
ArgumentPosition position = GetArgumentPosition(header);
if (major != MajorType::String || position == ArgumentPosition::Indefinite){
ArgumentPosition pos = GetArgumentPosition(header);
if (major != MajorType::String || pos == ArgumentPosition::Indefinite){
throw MalformedDataError("an indefinite length string may only contain "
"definite length strings");
}
@ -846,44 +902,12 @@ namespace CBOR
throw TypeMismatchError("double", ToString(major));
}
std::span<std::uint8_t> Decoder::Binary()
{
std::uint8_t header = Consume1B(mBuffer, mCurrent);
MajorType major = GetMajorType(header);
if (major != MajorType::Binary) {
throw TypeMismatchError("binary", ToString(major));
}
if (GetArgumentPosition(header) == ArgumentPosition::Indefinite) {
throw IndefiniteLengthError();
}
std::uint64_t arg = ArgumentValue(header, mBuffer, mCurrent);
return ExtractBinary(arg, mBuffer, mCurrent);
}
std::string_view Decoder::String()
{
std::uint8_t header = Consume1B(mBuffer, mCurrent);
MajorType major = GetMajorType(header);
if (major != MajorType::String) {
throw TypeMismatchError("string", ToString(major));
}
if (GetArgumentPosition(header) == ArgumentPosition::Indefinite) {
throw IndefiniteLengthError();
}
std::uint64_t arg = ArgumentValue(header, mBuffer, mCurrent);
return ExtractString(arg, mBuffer, mCurrent);
}
Binary Decoder::IndefiniteBinary()
Binary Decoder::Binary()
{
return { *this };
}
String Decoder::IndefiniteString()
String Decoder::String()
{
return { *this };
}

View file

@ -59,10 +59,10 @@ SomeStruct Decode1(std::span<std::uint8_t> buffer)
CBOR::Map object = dec.Map();
while (!object.Done()) {
CBOR::KeyValue kv = object.Next();
std::string_view key = kv.Key().String();
std::string_view key = kv.Key().String().Get();
CBOR::Item value = kv.Value();
if (key == "name") {
result.name = value.String();
result.name = value.String().Get();
}
else if (key == "speed") {
result.speed = value.Double();
@ -82,7 +82,7 @@ SomeStruct Decode1(std::span<std::uint8_t> buffer)
else if (key == "tools") {
CBOR::Array tools = value.Array();
while(!tools.Done()) {
result.tools.push_back(std::string(tools.Next().String()));
result.tools.push_back(std::string(tools.Next().String().Get()));
}
}
}
@ -98,10 +98,10 @@ SomeStruct Decode2(std::span<std::uint8_t> buffer)
CBOR::Map object = dec.Map();
while (!object.Done()) {
CBOR::KeyValue kv = object.Next();
std::string_view key = kv.Key().String();
std::string_view key = kv.Key().String().Get();
CBOR::Item value = kv.Value();
if (key == "name") {
result.name = value.String();
result.name = value.String().Get();
}
else if (key == "speed") {
result.speed = value.Double();
@ -122,7 +122,8 @@ SomeStruct Decode2(std::span<std::uint8_t> buffer)
CBOR::Array tools = value.Array();
while(!tools.Done()) {
result.tools.push_back("");
CBOR::String tool = tools.Next().IndefiniteString();
CBOR::String tool = tools.Next().String();
tool.AllowIndefinite();
while (!tool.Done()) {
result.tools.back().append(tool.Next());
}