Skip to content

Commit 00f4a30

Browse files
authored
adding the Cbor Deserializer (#3877)
* adding the Cbor Deserializer * Add error handling, validation on timestamp for negative value and adding size_t on beginStruct for definite length maps * Optional returns to ShapeDeserializer
1 parent 519f224 commit 00f4a30

4 files changed

Lines changed: 938 additions & 0 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#pragma once
2+
3+
#include <aws/core/utils/memory/AWSMemory.h>
4+
#include <smithy/Smithy_EXPORTS.h>
5+
#include <smithy/client/schema/ShapeDeserializer.h>
6+
7+
namespace smithy {
8+
namespace schema {
9+
10+
class SMITHY_API CborShapeDeserializer final : public ShapeDeserializer {
11+
public:
12+
CborShapeDeserializer(const unsigned char* data, size_t length);
13+
~CborShapeDeserializer();
14+
15+
Aws::Crt::Optional<bool> ReadBoolean() override;
16+
Aws::Crt::Optional<int> ReadInteger() override;
17+
Aws::Crt::Optional<int64_t> ReadLong() override;
18+
Aws::Crt::Optional<float> ReadFloat() override;
19+
Aws::Crt::Optional<double> ReadDouble() override;
20+
Aws::Crt::Optional<Aws::String> ReadString() override;
21+
Aws::Crt::Optional<Aws::Utils::DateTime> ReadTimestamp() override;
22+
Aws::Crt::Optional<Aws::Utils::ByteBuffer> ReadBlob() override;
23+
Aws::Crt::Optional<int> ReadEnum() override;
24+
25+
size_t BeginStruct() override;
26+
void EndStruct() override;
27+
28+
size_t BeginList() override;
29+
void EndList() override;
30+
31+
size_t BeginMap() override;
32+
void EndMap() override;
33+
34+
Aws::Crt::Optional<Aws::String> ReadKey() override;
35+
bool IsBreak() override;
36+
bool IsNull() override;
37+
void ReadNull() override;
38+
void SkipValue() override;
39+
40+
private:
41+
class Impl;
42+
Aws::UniquePtr<Impl> m_impl;
43+
};
44+
45+
} // namespace schema
46+
} // namespace smithy
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#pragma once
2+
3+
#include <aws/core/utils/Array.h>
4+
#include <aws/core/utils/DateTime.h>
5+
#include <aws/core/utils/memory/stl/AWSString.h>
6+
#include <aws/crt/Optional.h>
7+
#include <smithy/Smithy_EXPORTS.h>
8+
9+
#include <cstdint>
10+
11+
namespace smithy {
12+
namespace schema {
13+
14+
class SMITHY_API ShapeDeserializer {
15+
public:
16+
virtual ~ShapeDeserializer() = default;
17+
18+
virtual Aws::Crt::Optional<bool> ReadBoolean() = 0;
19+
virtual Aws::Crt::Optional<int> ReadInteger() = 0;
20+
virtual Aws::Crt::Optional<int64_t> ReadLong() = 0;
21+
virtual Aws::Crt::Optional<float> ReadFloat() = 0;
22+
virtual Aws::Crt::Optional<double> ReadDouble() = 0;
23+
virtual Aws::Crt::Optional<Aws::String> ReadString() = 0;
24+
virtual Aws::Crt::Optional<Aws::Utils::DateTime> ReadTimestamp() = 0;
25+
virtual Aws::Crt::Optional<Aws::Utils::ByteBuffer> ReadBlob() = 0;
26+
virtual Aws::Crt::Optional<int> ReadEnum() = 0;
27+
28+
virtual size_t BeginStruct() = 0;
29+
virtual void EndStruct() = 0;
30+
31+
virtual size_t BeginList() = 0;
32+
virtual void EndList() = 0;
33+
34+
virtual size_t BeginMap() = 0;
35+
virtual void EndMap() = 0;
36+
37+
virtual Aws::Crt::Optional<Aws::String> ReadKey() = 0;
38+
virtual bool IsBreak() = 0;
39+
virtual bool IsNull() = 0;
40+
virtual void ReadNull() = 0;
41+
virtual void SkipValue() = 0;
42+
};
43+
44+
} // namespace schema
45+
} // namespace smithy
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
#include <aws/crt/cbor/Cbor.h>
6+
#include <smithy/client/schema/CborShapeDeserializer.h>
7+
8+
using namespace smithy::schema;
9+
using namespace Aws::Utils;
10+
using namespace Aws::Crt::Cbor;
11+
12+
class CborShapeDeserializer::Impl {
13+
public:
14+
Impl(const unsigned char* data, size_t length) : m_decoder(Aws::Crt::ByteCursorFromArray(data, length)) {}
15+
16+
Aws::Crt::Optional<bool> ReadBoolean() {
17+
auto val = m_decoder.PopNextBooleanVal();
18+
if (!val.has_value()) {
19+
return {};
20+
}
21+
return val.value();
22+
}
23+
24+
Aws::Crt::Optional<int> ReadInteger() {
25+
auto val = ReadLong();
26+
if (!val.has_value()) {
27+
return {};
28+
}
29+
return static_cast<int>(val.value());
30+
}
31+
32+
Aws::Crt::Optional<int64_t> ReadLong() {
33+
auto type = m_decoder.PeekType();
34+
if (!type.has_value()) {
35+
return {};
36+
}
37+
if (*type == CborType::UInt) {
38+
auto val = m_decoder.PopNextUnsignedIntVal();
39+
if (!val.has_value()) {
40+
return {};
41+
}
42+
return static_cast<int64_t>(val.value());
43+
}
44+
if (*type == CborType::NegInt) {
45+
auto val = m_decoder.PopNextNegativeIntVal();
46+
if (!val.has_value()) {
47+
return {};
48+
}
49+
return static_cast<int64_t>(-(static_cast<int64_t>(val.value()) + 1));
50+
}
51+
return {};
52+
}
53+
54+
Aws::Crt::Optional<float> ReadFloat() {
55+
auto val = ReadDouble();
56+
if (!val.has_value()) {
57+
return {};
58+
}
59+
return static_cast<float>(val.value());
60+
}
61+
62+
Aws::Crt::Optional<double> ReadDouble() {
63+
auto type = m_decoder.PeekType();
64+
if (!type.has_value()) {
65+
return {};
66+
}
67+
if (*type == CborType::Float) {
68+
auto val = m_decoder.PopNextFloatVal();
69+
if (!val.has_value()) {
70+
return {};
71+
}
72+
return val.value();
73+
}
74+
auto longVal = ReadLong();
75+
if (!longVal.has_value()) {
76+
return {};
77+
}
78+
return static_cast<double>(longVal.value());
79+
}
80+
81+
Aws::Crt::Optional<Aws::String> ReadString() {
82+
auto val = m_decoder.PopNextTextVal();
83+
if (!val.has_value()) {
84+
return {};
85+
}
86+
return Aws::String(reinterpret_cast<const char*>(val->ptr), val->len);
87+
}
88+
89+
Aws::Crt::Optional<DateTime> ReadTimestamp() {
90+
auto tag = m_decoder.PopNextTagVal();
91+
if (!tag.has_value() || tag.value() != 1) {
92+
return {};
93+
}
94+
auto type = m_decoder.PeekType();
95+
if (!type.has_value()) {
96+
return {};
97+
}
98+
if (*type == CborType::Float) {
99+
auto val = m_decoder.PopNextFloatVal();
100+
if (!val.has_value() || val.value() < 0.0) {
101+
return {};
102+
}
103+
return DateTime(val.value());
104+
}
105+
if (*type == CborType::NegInt) {
106+
return {};
107+
}
108+
auto val = ReadLong();
109+
if (!val.has_value()) {
110+
return {};
111+
}
112+
return DateTime(static_cast<double>(val.value()));
113+
}
114+
115+
Aws::Crt::Optional<ByteBuffer> ReadBlob() {
116+
auto val = m_decoder.PopNextBytesVal();
117+
if (!val.has_value()) {
118+
return {};
119+
}
120+
return ByteBuffer(val->ptr, val->len);
121+
}
122+
123+
Aws::Crt::Optional<int> ReadEnum() { return ReadInteger(); }
124+
125+
size_t BeginStruct() {
126+
auto type = m_decoder.PeekType();
127+
if (type.has_value() && *type == CborType::IndefMapStart) {
128+
m_decoder.ConsumeNextSingleElement();
129+
return 0;
130+
}
131+
auto size = m_decoder.PopNextMapStart();
132+
if (!size.has_value()) {
133+
return 0;
134+
}
135+
return static_cast<size_t>(size.value());
136+
}
137+
138+
void EndStruct() {}
139+
140+
size_t BeginList() {
141+
auto type = m_decoder.PeekType();
142+
if (type.has_value() && *type == CborType::IndefArrayStart) {
143+
m_decoder.ConsumeNextSingleElement();
144+
return 0;
145+
}
146+
auto size = m_decoder.PopNextArrayStart();
147+
if (!size.has_value()) {
148+
return 0;
149+
}
150+
return static_cast<size_t>(size.value());
151+
}
152+
153+
void EndList() {}
154+
155+
size_t BeginMap() {
156+
auto type = m_decoder.PeekType();
157+
if (type.has_value() && *type == CborType::IndefMapStart) {
158+
m_decoder.ConsumeNextSingleElement();
159+
return 0;
160+
}
161+
auto size = m_decoder.PopNextMapStart();
162+
if (!size.has_value()) {
163+
return 0;
164+
}
165+
return static_cast<size_t>(size.value());
166+
}
167+
168+
void EndMap() {}
169+
170+
Aws::Crt::Optional<Aws::String> ReadKey() { return ReadString(); }
171+
172+
bool IsBreak() {
173+
auto type = m_decoder.PeekType();
174+
return type.has_value() && *type == CborType::Break;
175+
}
176+
177+
bool IsNull() {
178+
auto type = m_decoder.PeekType();
179+
return type.has_value() && *type == CborType::Null;
180+
}
181+
182+
void ReadNull() { m_decoder.ConsumeNextSingleElement(); }
183+
184+
void SkipValue() { m_decoder.ConsumeNextWholeDataItem(); }
185+
186+
private:
187+
CborDecoder m_decoder;
188+
};
189+
190+
CborShapeDeserializer::CborShapeDeserializer(const unsigned char* data, size_t length)
191+
: m_impl(Aws::MakeUnique<Impl>("CborShapeDeserializer", data, length)) {}
192+
CborShapeDeserializer::~CborShapeDeserializer() = default;
193+
194+
Aws::Crt::Optional<bool> CborShapeDeserializer::ReadBoolean() { return m_impl->ReadBoolean(); }
195+
Aws::Crt::Optional<int> CborShapeDeserializer::ReadInteger() { return m_impl->ReadInteger(); }
196+
Aws::Crt::Optional<int64_t> CborShapeDeserializer::ReadLong() { return m_impl->ReadLong(); }
197+
Aws::Crt::Optional<float> CborShapeDeserializer::ReadFloat() { return m_impl->ReadFloat(); }
198+
Aws::Crt::Optional<double> CborShapeDeserializer::ReadDouble() { return m_impl->ReadDouble(); }
199+
Aws::Crt::Optional<Aws::String> CborShapeDeserializer::ReadString() { return m_impl->ReadString(); }
200+
Aws::Crt::Optional<DateTime> CborShapeDeserializer::ReadTimestamp() { return m_impl->ReadTimestamp(); }
201+
Aws::Crt::Optional<ByteBuffer> CborShapeDeserializer::ReadBlob() { return m_impl->ReadBlob(); }
202+
Aws::Crt::Optional<int> CborShapeDeserializer::ReadEnum() { return m_impl->ReadEnum(); }
203+
size_t CborShapeDeserializer::BeginStruct() { return m_impl->BeginStruct(); }
204+
void CborShapeDeserializer::EndStruct() { m_impl->EndStruct(); }
205+
size_t CborShapeDeserializer::BeginList() { return m_impl->BeginList(); }
206+
void CborShapeDeserializer::EndList() { m_impl->EndList(); }
207+
size_t CborShapeDeserializer::BeginMap() { return m_impl->BeginMap(); }
208+
void CborShapeDeserializer::EndMap() { m_impl->EndMap(); }
209+
Aws::Crt::Optional<Aws::String> CborShapeDeserializer::ReadKey() { return m_impl->ReadKey(); }
210+
bool CborShapeDeserializer::IsBreak() { return m_impl->IsBreak(); }
211+
bool CborShapeDeserializer::IsNull() { return m_impl->IsNull(); }
212+
void CborShapeDeserializer::ReadNull() { m_impl->ReadNull(); }
213+
void CborShapeDeserializer::SkipValue() { m_impl->SkipValue(); }

0 commit comments

Comments
 (0)