#pragma once
#if ENABLE(WEB_AUTHN)
#include <stdint.h>
#include <wtf/Noncopyable.h>
#include <wtf/StdMap.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace cbor {
class WEBCORE_EXPORT CBORValue {
WTF_MAKE_NONCOPYABLE(CBORValue);
public:
struct CTAPLess {
bool operator()(const CBORValue& a, const CBORValue& b) const
{
ASSERT((a.isInteger() || a.isString()) && (b.isInteger() || b.isString()));
if (a.type() != b.type())
return a.type() < b.type();
switch (a.type()) {
case Type::Unsigned:
return a.getInteger() < b.getInteger();
case Type::Negative:
return a.getInteger() > b.getInteger();
case Type::String: {
const auto& aStr = a.getString();
const size_t aLength = aStr.length();
const auto& bStr = b.getString();
const size_t bLength = bStr.length();
if (aLength != bLength)
return aLength < bLength;
return WTF::codePointCompareLessThan(aStr, bStr);
}
default:
break;
}
ASSERT_NOT_REACHED();
return false;
}
};
using BinaryValue = Vector<uint8_t>;
using ArrayValue = Vector<CBORValue>;
using MapValue = StdMap<CBORValue, CBORValue, CTAPLess>;
enum class Type {
Unsigned = 0,
Negative = 1,
ByteString = 2,
String = 3,
Array = 4,
Map = 5,
SimpleValue = 7,
None = -1,
};
enum class SimpleValue {
FalseValue = 20,
TrueValue = 21,
NullValue = 22,
Undefined = 23,
};
CBORValue(CBORValue&& that);
CBORValue();
explicit CBORValue(Type);
explicit CBORValue(int);
explicit CBORValue(int64_t);
explicit CBORValue(uint64_t) = delete;
explicit CBORValue(const BinaryValue&);
explicit CBORValue(BinaryValue&&);
explicit CBORValue(const char*);
explicit CBORValue(String&&);
explicit CBORValue(const String&);
explicit CBORValue(const ArrayValue&);
explicit CBORValue(ArrayValue&&);
explicit CBORValue(const MapValue&);
explicit CBORValue(MapValue&&);
explicit CBORValue(SimpleValue);
explicit CBORValue(bool);
CBORValue& operator=(CBORValue&&);
~CBORValue();
CBORValue clone() const;
Type type() const { return m_type; }
bool isType(Type type) const { return type == m_type; }
bool isNone() const { return type() == Type::None; }
bool isUnsigned() const { return type() == Type::Unsigned; }
bool isNegative() const { return type() == Type::Negative; }
bool isInteger() const { return isUnsigned() || isNegative(); }
bool isByteString() const { return type() == Type::ByteString; }
bool isString() const { return type() == Type::String; }
bool isArray() const { return type() == Type::Array; }
bool isMap() const { return type() == Type::Map; }
bool isSimple() const { return type() == Type::SimpleValue; }
bool isBool() const { return isSimple() && (m_simpleValue == SimpleValue::TrueValue || m_simpleValue == SimpleValue::FalseValue); }
SimpleValue getSimpleValue() const;
bool getBool() const;
const int64_t& getInteger() const;
const int64_t& getUnsigned() const;
const int64_t& getNegative() const;
const BinaryValue& getByteString() const;
const String& getString() const;
const ArrayValue& getArray() const;
const MapValue& getMap() const;
private:
Type m_type;
union {
SimpleValue m_simpleValue;
int64_t m_integerValue;
BinaryValue m_byteStringValue;
String m_stringValue;
ArrayValue m_arrayValue;
MapValue m_mapValue;
};
void internalMoveConstructFrom(CBORValue&&);
void internalCleanup();
};
}
#endif // ENABLE(WEB_AUTHN)