NOTICK - Add ENUM to the C++ serialiser (#5616)

This commit is contained in:
Katelyn Baker 2019-11-19 16:00:11 +00:00 committed by GitHub
parent ce8ce2ba7c
commit c349ff719d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 668 additions and 210 deletions

View File

@ -0,0 +1,5 @@
# To Build
../../gradlew build
# To Run
java -jar build/libs/blobwriter-4.4-SNAPSHOT.jar

View File

@ -43,19 +43,27 @@ fun initialiseSerialization() {
)
}
data class _i_ (val a: Int)
data class _is_ (val a: Int, val b: String)
data class _i_is__ (val a: Int, val b: _is_)
data class _Li_ (val a: List<Int>)
data class _Mis_ (val a: Map<Int, String>)
data class IntClass (val a: Int)
data class IntStrClass (val a: Int, val b: String)
data class IntIntStrClass (val a: Int, val b: IntStrClass)
data class IntListClass (val a: List<Int>)
data class IntStringMapClass (val a: Map<Int, String>)
enum class E {
A, B, C
}
data class EnumClass (val e: E)
data class EnumListClass (val listy: List<E>)
fun main (args: Array<String>) {
initialiseSerialization()
File("../cpp-serializer/bin/blob-inspector/test/_i_is__").writeBytes(_i_is__(1, _is_ (2, "three")).serialize().bytes)
File("../cpp-serializer/bin/blob-inspector/test/_Li_").writeBytes(_Li_(listOf (1, 2, 3, 4, 5, 6)).serialize().bytes)
File("../cpp-serializer/bin/blob-inspector/test/_Mis_").writeBytes(_Mis_(
File("../cpp-serializer/bin/blob-inspector/test/_i_is__").writeBytes(IntIntStrClass(1, IntStrClass (2, "three")).serialize().bytes)
File("../cpp-serializer/bin/blob-inspector/test/_Li_").writeBytes(IntListClass(listOf (1, 2, 3, 4, 5, 6)).serialize().bytes)
File("../cpp-serializer/bin/blob-inspector/test/_Mis_").writeBytes(IntStringMapClass(
mapOf (1 to "two", 3 to "four", 5 to "six")).serialize().bytes)
File("../cpp-serializer/bin/blob-inspector/test/_e_").writeBytes(EnumClass(E.A).serialize().bytes)
File("../cpp-serializer/bin/blob-inspector/test/_Le_").writeBytes(EnumListClass(listOf (E.A, E.B, E.C)).serialize().bytes)
File("../cpp-serializer/bin/blob-inspector/test/_Le_2").writeBytes(EnumListClass(listOf (E.A, E.B, E.C, E.B, E.A)).serialize().bytes)
}

View File

@ -47,7 +47,7 @@ data_and_stop(std::ifstream & f_, ssize_t sz) {
dynamic_cast<amqp::internal::schema::Envelope *> (
amqp::AMQPDescriptorRegistory[a]->build(d).release()));
DBG (std::cout << std::endl << "Types in schema: " << std::endl
DBG (std::endl << "Types in schema: " << std::endl
<< *envelope << std::endl); // NOLINT
}

View File

@ -11,17 +11,20 @@ set (amqp_sources
descriptors/corda-descriptors/FieldDescriptor.cxx
descriptors/corda-descriptors/SchemaDescriptor.cxx
descriptors/corda-descriptors/ObjectDescriptor.cxx
descriptors/corda-descriptors/ChoiceDescriptor.cxx
descriptors/corda-descriptors/EnvelopeDescriptor.cxx
descriptors/corda-descriptors/CompositeDescriptor.cxx
descriptors/corda-descriptors/RestrictedDescriptor.cxx
schema/Schema.cxx
schema/Field.cxx
schema/Schema.cxx
schema/Choice.cxx
schema/Envelope.cxx
schema/Composite.cxx
schema/Descriptor.cxx
schema/AMQPTypeNotation.cxx
schema/restricted-types/Restricted.cxx
schema/restricted-types/List.cxx
schema/AMQPTypeNotation.cxx
schema/restricted-types/Enum.cxx
reader/Reader.cxx
reader/PropertyReader.cxx
reader/CompositeReader.cxx
@ -32,6 +35,7 @@ set (amqp_sources
reader/property-readers/DoublePropertyReader.cxx
reader/property-readers/StringPropertyReader.cxx
reader/restricted-readers/ListReader.cxx
reader/restricted-readers/EnumReader.cxx
)
ADD_LIBRARY ( amqp ${amqp_sources} )

View File

@ -11,13 +11,16 @@
#include "debug.h"
#include "amqp/reader/IReader.h"
#include "reader/Reader.h"
#include "amqp/reader/PropertyReader.h"
#include "reader/Reader.h"
#include "reader/CompositeReader.h"
#include "reader/RestrictedReader.h"
#include "reader/restricted-readers/ListReader.h"
#include "reader/restricted-readers/EnumReader.h"
#include "schema/restricted-types/List.h"
#include "schema/restricted-types/Enum.h"
/******************************************************************************/
@ -88,7 +91,7 @@ CompositeFactory::process (const SchemaType & schema_) {
std::shared_ptr<amqp::internal::reader::Reader>
amqp::internal::
CompositeFactory::process(
CompositeFactory::process (
const amqp::internal::schema::AMQPTypeNotation & schema_)
{
return computeIfAbsent<reader::Reader> (
@ -97,10 +100,10 @@ CompositeFactory::process(
[& schema_, this] () -> std::shared_ptr<reader::Reader> {
switch (schema_.type()) {
case amqp::internal::schema::AMQPTypeNotation::Composite : {
return processComposite(schema_);
return processComposite (schema_);
}
case amqp::internal::schema::AMQPTypeNotation::Restricted : {
return processRestricted(schema_);
return processRestricted (schema_);
}
}
});
@ -111,8 +114,8 @@ CompositeFactory::process(
std::shared_ptr<amqp::internal::reader::Reader>
amqp::internal::
CompositeFactory::processComposite (
const amqp::internal::schema::AMQPTypeNotation & type_)
{
const amqp::internal::schema::AMQPTypeNotation & type_
) {
std::vector<std::weak_ptr<reader::Reader>> readers;
const auto & fields = dynamic_cast<const amqp::internal::schema::Composite &> (
@ -163,6 +166,47 @@ CompositeFactory::processComposite (
/******************************************************************************/
std::shared_ptr<amqp::internal::reader::Reader>
amqp::internal::
CompositeFactory::processEnum (
const amqp::internal::schema::Enum & enum_
) {
DBG ("Processing Enum - " << enum_.name() << std::endl); // NOLINT
return std::make_shared<reader::EnumReader> (
enum_.name(),
enum_.makeChoices());
}
/******************************************************************************/
std::shared_ptr<amqp::internal::reader::Reader>
amqp::internal::
CompositeFactory::processList (
const amqp::internal::schema::List & list_
) {
DBG ("Processing List - " << list_.listOf() << std::endl); // NOLINT
if (schema::Field::typeIsPrimitive (list_.listOf())) {
DBG (" List of Primitives" << std::endl); // NOLINT
auto reader = computeIfAbsent<reader::Reader>(
m_readersByType,
list_.listOf(),
[& list_]() -> std::shared_ptr<reader::PropertyReader> {
return reader::PropertyReader::make (list_.listOf());
});
return std::make_shared<reader::ListReader>(list_.name(), reader);
} else {
DBG (" List of Composite - " << list_.listOf() << std::endl); // NOLINT
auto reader = m_readersByType[list_.listOf()];
return std::make_shared<reader::ListReader>(list_.name(), reader);
}
}
/******************************************************************************/
std::shared_ptr<amqp::internal::reader::Reader>
amqp::internal::
CompositeFactory::processRestricted (
@ -172,31 +216,21 @@ CompositeFactory::processRestricted (
const auto & restricted = dynamic_cast<const amqp::internal::schema::Restricted &> (
type_);
if (restricted.restrictedType() ==
amqp::internal::schema::Restricted::RestrictedTypes::List)
{
const auto & list = dynamic_cast<const amqp::internal::schema::List &> (restricted);
DBG ("Processing List - " << list.listOf() << std::endl); // NOLINT
if (amqp::internal::schema::Field::typeIsPrimitive(list.listOf())) {
DBG (" List of Primitives" << std::endl); // NOLINT
auto reader = computeIfAbsent<reader::Reader> (
m_readersByType,
list.listOf(),
[& list] () -> std::shared_ptr<reader::PropertyReader> {
return reader::PropertyReader::make (list.listOf());
});
return std::make_shared<reader::ListReader> (type_.name(), reader);
} else {
DBG (" List of Composite - " << list.listOf() << std::endl); // NOLINT
auto reader = m_readersByType[list.listOf()];
return std::make_shared<reader::ListReader> (list.name(), reader);
switch (restricted.restrictedType()) {
case schema::Restricted::RestrictedTypes::List : {
return processList (
dynamic_cast<const amqp::internal::schema::List &> (restricted));
}
case schema::Restricted::RestrictedTypes::Enum : {
return processEnum (
dynamic_cast<const amqp::internal::schema::Enum &> (restricted));
}
case schema::Restricted::RestrictedTypes::Map :{
throw std::runtime_error ("Cannot process maps");
}
}
DBG (" ProcessRestricted: Returning nullptr"); // NOLINT
return nullptr;
}

View File

@ -12,6 +12,8 @@
#include "amqp/schema/Envelope.h"
#include "amqp/schema/Composite.h"
#include "amqp/reader/CompositeReader.h"
#include "amqp/schema/restricted-types/List.h"
#include "amqp/schema/restricted-types/Enum.h"
/******************************************************************************/
@ -47,6 +49,12 @@ namespace amqp::internal {
std::shared_ptr<reader::Reader> processRestricted (
const schema::AMQPTypeNotation &);
std::shared_ptr<reader::Reader> processList (
const schema::List &);
std::shared_ptr<reader::Reader> processEnum (
const schema::Enum &);
};
}

View File

@ -70,7 +70,7 @@ namespace amqp::internal {
void validateAndNext (pn_data_t *) const;
virtual std::unique_ptr<AMQPDescribed> build (pn_data_t * data_) const;
virtual std::unique_ptr<AMQPDescribed> build (pn_data_t *) const;
virtual void read (
pn_data_t *,

View File

@ -4,6 +4,7 @@
#include "corda-descriptors/FieldDescriptor.h"
#include "corda-descriptors/SchemaDescriptor.h"
#include "corda-descriptors/ObjectDescriptor.h"
#include "corda-descriptors/ChoiceDescriptor.h"
#include "corda-descriptors/EnvelopeDescriptor.h"
#include "corda-descriptors/CompositeDescriptor.h"
#include "corda-descriptors/RestrictedDescriptor.h"
@ -48,30 +49,19 @@ namespace amqp {
AMQPDescriptorRegistory = {
{
22UL,
std::make_shared<internal::AMQPDescriptor> (
"DESCRIBED",
-1)
std::make_shared<internal::AMQPDescriptor> ("DESCRIBED", -1)
},
{
1UL | internal::DESCRIPTOR_TOP_32BITS,
std::make_shared<internal::EnvelopeDescriptor> (
internal::EnvelopeDescriptor (
"ENVELOPE",
internal::ENVELOPE))
std::make_shared<internal::EnvelopeDescriptor> ("ENVELOPE", internal::ENVELOPE)
},
{
2UL | internal::DESCRIPTOR_TOP_32BITS,
std::make_shared<internal::SchemaDescriptor> (
internal::SchemaDescriptor (
"SCHEMA",
internal::SCHEMA))
std::make_shared<internal::SchemaDescriptor> ("SCHEMA", internal::SCHEMA)
},
{
3UL | internal::DESCRIPTOR_TOP_32BITS,
std::make_shared<internal::ObjectDescriptor> (
internal::ObjectDescriptor (
"OBJECT_DESCRIPTOR",
internal::OBJECT))
std::make_shared<internal::ObjectDescriptor> ("OBJECT_DESCRIPTOR", internal::OBJECT)
},
{
4UL | internal::DESCRIPTOR_TOP_32BITS,
@ -96,10 +86,7 @@ namespace amqp {
},
{
7UL | internal::DESCRIPTOR_TOP_32BITS,
std::make_shared<internal::ChoiceDescriptor> (
internal::ChoiceDescriptor (
"CHOICE",
internal::CHOICE))
std::make_shared<internal::ChoiceDescriptor> ("CHOICE", internal::CHOICE)
},
{
8UL | internal::DESCRIPTOR_TOP_32BITS,

View File

@ -70,8 +70,8 @@ namespace amqp {
*/
uint32_t stripCorda (uint64_t id);
std::string describedToString(uint64_t);
std::string describedToString(uint32_t);
std::string describedToString (uint64_t);
std::string describedToString (uint32_t);
}
/******************************************************************************/

View File

@ -41,22 +41,6 @@ AMQPDescriptor::validateAndNext (pn_data_t * const data_) const {
pn_data_next (data_);
}
/******************************************************************************
*
* Essentially, an enum.
*
******************************************************************************/
uPtr<amqp::AMQPDescribed>
amqp::internal::
ChoiceDescriptor::build (pn_data_t * data_) const {
validateAndNext(data_);
DBG ("CHOICE " << data_ << std::endl); // NOLINT
return uPtr<amqp::AMQPDescribed> (nullptr);
}
/******************************************************************************/
uPtr<amqp::AMQPDescribed>

View File

@ -39,7 +39,8 @@ namespace amqp::internal::descriptors {
auto id = pn_data_get_ulong(data_);
return uPtr<T>(
static_cast<T *>(amqp::AMQPDescriptorRegistory[id]->build(data_).release()));
static_cast<T *>(
amqp::AMQPDescriptorRegistory[id]->build(data_).release()));
}
}
@ -47,18 +48,6 @@ namespace amqp::internal::descriptors {
namespace amqp::internal {
class ChoiceDescriptor : public AMQPDescriptor {
public :
ChoiceDescriptor() : AMQPDescriptor() { }
ChoiceDescriptor(const std::string & symbol_, int val_)
: AMQPDescriptor(symbol_, val_)
{ }
~ChoiceDescriptor() final = default;
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
};
}

View File

@ -0,0 +1,30 @@
#include "amqp/schema/Choice.h"
#include "ChoiceDescriptor.h"
#include "types.h"
#include "proton/proton_wrapper.h"
/******************************************************************************/
amqp::internal::
ChoiceDescriptor::ChoiceDescriptor (
const std::string & symbol_,
int val_
) : AMQPDescriptor (symbol_, val_) {
}
/******************************************************************************/
std::unique_ptr<amqp::AMQPDescribed>
amqp::internal::
ChoiceDescriptor::build (pn_data_t * data_) const {
validateAndNext (data_);
proton::auto_enter ae (data_);
auto name = proton::get_string (data_);
return std::make_unique<schema::Choice> (name);
}
/******************************************************************************/

View File

@ -0,0 +1,26 @@
#pragma once
#include "amqp/descriptors/AMQPDescriptor.h"
/******************************************************************************
*
* Represents an enumeration
*
******************************************************************************/
namespace amqp::internal {
class ChoiceDescriptor : public AMQPDescriptor {
public :
ChoiceDescriptor() = delete;
ChoiceDescriptor (const std::string &, int);
~ChoiceDescriptor() final = default;
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
};
}
/******************************************************************************/

View File

@ -77,7 +77,12 @@ CompositeDescriptor::build (pn_data_t * data_) const {
}
return std::make_unique<schema::Composite> (
schema::Composite (name, label, provides, descriptor, fields));
schema::Composite (
std::move (name),
std::move (label),
std::move (provides),
std::move (descriptor),
std::move (fields)));
}
/******************************************************************************/

View File

@ -8,7 +8,7 @@ namespace amqp::internal {
class CompositeDescriptor : public AMQPDescriptor {
public :
CompositeDescriptor() : AMQPDescriptor() { }
CompositeDescriptor() = delete;
CompositeDescriptor (const std::string &, int);
~CompositeDescriptor() final = default;

View File

@ -60,11 +60,6 @@ EnvelopeDescriptor::read (
/******************************************************************************/
amqp::internal::
EnvelopeDescriptor::EnvelopeDescriptor() : AMQPDescriptor() { }
/******************************************************************************/
amqp::internal::
EnvelopeDescriptor::EnvelopeDescriptor (
const std::string & symbol_,

View File

@ -23,7 +23,7 @@ namespace amqp::internal {
class EnvelopeDescriptor : public AMQPDescriptor {
public :
EnvelopeDescriptor();
EnvelopeDescriptor() = delete;
EnvelopeDescriptor (const std::string &, int);
~EnvelopeDescriptor() final = default;

View File

@ -15,11 +15,6 @@
*
******************************************************************************/
amqp::internal::
FieldDescriptor::FieldDescriptor() : AMQPDescriptor() { }
/******************************************************************************/
amqp::internal::
FieldDescriptor::FieldDescriptor (
const std::string & symbol_,
@ -35,7 +30,7 @@ amqp::internal::
FieldDescriptor::build(pn_data_t * data_) const {
DBG ("FIELD" << std::endl); // NOLINT
validateAndNext(data_);
validateAndNext (data_);
proton::auto_enter ae (data_);

View File

@ -12,7 +12,7 @@ namespace amqp::internal {
class FieldDescriptor : public AMQPDescriptor {
public :
FieldDescriptor();
FieldDescriptor() = delete;
FieldDescriptor (const std::string &, int);
~FieldDescriptor() final = default;

View File

@ -14,6 +14,15 @@
*
******************************************************************************/
amqp::internal::
ObjectDescriptor::ObjectDescriptor (
const std::string & symbol_,
int val_
) : AMQPDescriptor (symbol_, val_) {
}
/******************************************************************************/
/**
*
*/

View File

@ -14,11 +14,9 @@ namespace amqp::internal {
class ObjectDescriptor : public AMQPDescriptor {
public :
ObjectDescriptor() : AMQPDescriptor() { }
ObjectDescriptor() = delete;
ObjectDescriptor(const std::string & symbol_, int val_)
: AMQPDescriptor(symbol_, val_)
{ }
ObjectDescriptor(const std::string &, int);
~ObjectDescriptor() final = default;

View File

@ -3,6 +3,7 @@
#include "types.h"
#include "debug.h"
#include "amqp/schema/Choice.h"
#include "amqp/schema/restricted-types/Restricted.h"
#include "amqp/descriptors/AMQPDescriptors.h"
@ -36,23 +37,50 @@ RestrictedDescriptor::build (pn_data_t * data_) const {
auto name = proton::readAndNext<std::string>(data_);
auto label = proton::readAndNext<std::string>(data_, true);
DBG (" name: " << name << ", label: \"" << label << "\"" << std::endl);
std::vector<std::string> provides;
{
proton::auto_list_enter ae2 (data_);
while (pn_data_next(data_)) {
provides.push_back (proton::get_string (data_));
DBG (" provides: " << provides.back() << std::endl);
}
}
pn_data_next (data_);
auto source = proton::readAndNext<std::string> (data_);
DBG ("source: " << source << std::endl);
auto descriptor = descriptors::dispatchDescribed<schema::Descriptor> (data_);
// SKIP the choices section **FOR NOW**
pn_data_next (data_);
return schema::Restricted::make (descriptor, name,
label, provides, source);
DBG ("choices: " << data_ << std::endl);
std::vector<std::unique_ptr<schema::Choice>> choices;
{
proton::auto_list_enter ae2 (data_);
while (pn_data_next (data_)) {
choices.push_back (
descriptors::dispatchDescribed<schema::Choice> (data_));
DBG (" choice: " << choices.back()->choice() << std::endl);
}
}
DBG (data_ << std::endl);
return schema::Restricted::make (
std::move (descriptor),
std::move (name),
std::move (label),
std::move (provides),
std::move (source),
std::move (choices));
}
/******************************************************************************/

View File

@ -12,7 +12,7 @@ namespace amqp::internal {
class RestrictedDescriptor : public AMQPDescriptor {
public :
RestrictedDescriptor() : AMQPDescriptor() { }
RestrictedDescriptor() = delete;
RestrictedDescriptor(const std::string & symbol_, int val_)
: AMQPDescriptor(symbol_, val_)

View File

@ -20,7 +20,7 @@ amqp::internal::
SchemaDescriptor::SchemaDescriptor (
const std::string & symbol_,
int val_
) : AMQPDescriptor(symbol_, val_) {
) : AMQPDescriptor (symbol_, val_) {
}
/******************************************************************************/
@ -45,7 +45,8 @@ SchemaDescriptor::build (pn_data_t * data_) const {
proton::auto_list_enter ale2 (data_);
while (pn_data_next(data_)) {
schemas.insert (
descriptors::dispatchDescribed<schema::AMQPTypeNotation>(data_));
descriptors::dispatchDescribed<schema::AMQPTypeNotation> (
data_));
}
}
}

View File

@ -12,7 +12,7 @@ namespace amqp::internal {
class SchemaDescriptor : public AMQPDescriptor {
public :
SchemaDescriptor() = default;
SchemaDescriptor() = delete;
SchemaDescriptor (const std::string &, int);
~SchemaDescriptor() final = default;

View File

@ -23,9 +23,8 @@ namespace amqp::internal::reader {
public :
CompositeReader (
std::string type_,
std::vector<std::weak_ptr<Reader>> & readers_
);
std::string,
std::vector<std::weak_ptr<Reader>> &);
~CompositeReader() override = default;
@ -47,8 +46,8 @@ namespace amqp::internal::reader {
private :
std::vector<std::unique_ptr<amqp::reader::IValue>> _dump (
pn_data_t * data_,
const SchemaType & schema_) const;
pn_data_t *,
const SchemaType &) const;
};
}

View File

@ -19,37 +19,35 @@
namespace {
using namespace amqp::internal::reader;
std::map<
std::string,
std::shared_ptr<amqp::internal::reader::PropertyReader>(*)()
> propertyMap = { // NOLINT
{
"int", []() -> std::shared_ptr<amqp::internal::reader::PropertyReader> {
return std::make_shared<amqp::internal::reader::IntPropertyReader> ();
"int", []() -> std::shared_ptr<PropertyReader> {
return std::make_shared<IntPropertyReader> ();
}
},
{
"string", []() -> std::shared_ptr<amqp::internal::reader::PropertyReader> {
return std::make_shared<amqp::internal::reader::StringPropertyReader> (
amqp::internal::reader::StringPropertyReader());
"string", []() -> std::shared_ptr<PropertyReader> {
return std::make_shared<StringPropertyReader> ();
}
},
{
"boolean", []() -> std::shared_ptr<amqp::internal::reader::PropertyReader> {
return std::make_shared<amqp::internal::reader::BoolPropertyReader> (
amqp::internal::reader::BoolPropertyReader());
"boolean", []() -> std::shared_ptr<PropertyReader> {
return std::make_shared<BoolPropertyReader> ();
}
},
{
"long", []() -> std::shared_ptr<amqp::internal::reader::PropertyReader> {
return std::make_shared<amqp::internal::reader::LongPropertyReader> (
amqp::internal::reader::LongPropertyReader());
"long", []() -> std::shared_ptr<PropertyReader> {
return std::make_shared<LongPropertyReader> ();
}
},
{
"double", []() -> std::shared_ptr<amqp::internal::reader::PropertyReader> {
return std::make_shared<amqp::internal::reader::DoublePropertyReader> (
amqp::internal::reader::DoublePropertyReader());
"double", []() -> std::shared_ptr<PropertyReader> {
return std::make_shared<DoublePropertyReader> ();
}
}
};

View File

@ -26,9 +26,9 @@ namespace amqp::internal::reader {
explicit RestrictedReader (std::string);
~RestrictedReader() override = default;
std::any read(pn_data_t *) const override ;
std::any read (pn_data_t *) const override ;
std::string readString(pn_data_t *) const override;
std::string readString (pn_data_t *) const override;
std::unique_ptr<amqp::reader::IValue> dump(
const std::string &,

View File

@ -9,16 +9,16 @@
******************************************************************************/
const std::string
amqp::internal::reader::
BoolPropertyReader::m_name { // NOLINT
amqp::internal::reader::
BoolPropertyReader::m_name { // NOLINT
"Bool Reader"
};
/******************************************************************************/
const std::string
amqp::internal::reader::
BoolPropertyReader::m_type { // NOLINT
amqp::internal::reader::
BoolPropertyReader::m_type { // NOLINT
"bool"
};

View File

@ -16,7 +16,7 @@ namespace amqp::internal::reader {
public :
~IntPropertyReader() override = default;
std::string readString(pn_data_t *) const override;
std::string readString (pn_data_t *) const override;
std::any read(pn_data_t *) const override;

View File

@ -9,16 +9,16 @@
******************************************************************************/
const std::string
amqp::internal::reader::
LongPropertyReader::m_name { // NOLINT
amqp::internal::reader::
LongPropertyReader::m_name { // NOLINT
"Long Reader"
};
/******************************************************************************/
const std::string
amqp::internal::reader::
LongPropertyReader::m_type { // NOLINT
amqp::internal::reader::
LongPropertyReader::m_type { // NOLINT
"long"
};

View File

@ -19,8 +19,8 @@ StringPropertyReader::m_type { // NOLINT
/******************************************************************************/
const std::string
amqp::internal::reader::
StringPropertyReader::m_name { // NOLINT
amqp::internal::reader::
StringPropertyReader::m_name { // NOLINT
"String Reader"
};

View File

@ -18,13 +18,13 @@ namespace amqp::internal::reader {
std::any read (pn_data_t *) const override;
uPtr <amqp::reader::IValue> dump (
uPtr<amqp::reader::IValue> dump (
const std::string &,
pn_data_t *,
const SchemaType &
) const override;
uPtr <amqp::reader::IValue> dump (
uPtr<amqp::reader::IValue> dump (
pn_data_t *,
const SchemaType &
) const override;

View File

@ -0,0 +1,95 @@
#include "EnumReader.h"
#include "amqp/reader/IReader.h"
#include "amqp/descriptors/AMQPDescriptorRegistory.h"
#include "proton/proton_wrapper.h"
/******************************************************************************/
amqp::internal::reader::
EnumReader::EnumReader (
std::string type_,
std::vector<std::string> choices_
) : RestrictedReader (std::move (type_))
, m_choices (std::move (choices_)
) {
}
/******************************************************************************/
namespace {
std::string
getValue (pn_data_t * data_) {
proton::is_described (data_);
{
proton::auto_enter ae (data_);
/*
* Referenced objects are added to a stream when the serialiser
* notices it's writing a value it's already written, so to save
* space it will just link back to that. Currently we have
* no mechanism for decoding that so just throw an error
*/
if (pn_data_type (data_) == PN_ULONG) {
if (amqp::stripCorda(pn_data_get_ulong(data_)) ==
amqp::internal::REFERENCED_OBJECT
) {
throw std::runtime_error (
"Currently don't support referenced objects");
}
}
auto fingerprint = proton::readAndNext<std::string>(data_);
proton::auto_list_enter ale (data_, true);
return proton::readAndNext<std::string>(data_);
/*
* After a string representation of the enumerated value
* the ordinal value is also encoded. We don't need that for
* just dumping things to a string but if I don't leave this
* here I'll forget its even a thing
*/
// auto idx = proton::readAndNext<int>(data_);
}
}
}
/******************************************************************************/
std::unique_ptr<amqp::reader::IValue>
amqp::internal::reader::
EnumReader::dump (
const std::string & name_,
pn_data_t * data_,
const SchemaType & schema_
) const {
proton::auto_next an (data_);
proton::is_described (data_);
return std::make_unique<TypedPair<std::string>> (
name_,
getValue(data_));
}
/******************************************************************************/
std::unique_ptr<amqp::reader::IValue>
amqp::internal::reader::
EnumReader::dump(
pn_data_t * data_,
const SchemaType & schema_
) const {
proton::auto_next an (data_);
proton::is_described (data_);
return std::make_unique<TypedSingle<std::string>> (getValue(data_));
}
/******************************************************************************/

View File

@ -0,0 +1,27 @@
#pragma once
#include "RestrictedReader.h"
/******************************************************************************/
namespace amqp::internal::reader {
class EnumReader : public RestrictedReader {
private :
std::vector<std::string> m_choices;
public :
EnumReader (std::string, std::vector<std::string>);
std::unique_ptr<amqp::reader::IValue> dump(
const std::string &,
pn_data_t *,
const SchemaType &) const override;
std::unique_ptr<amqp::reader::IValue> dump(
pn_data_t *,
const SchemaType &) const override;
};
}
/******************************************************************************/

View File

@ -58,7 +58,7 @@ ListReader::dump_(
{
proton::auto_enter ae (data_);
auto it = schema_.fromDescriptor (proton::readAndNext<std::string>(data_));
schema_.fromDescriptor (proton::readAndNext<std::string>(data_));
{
proton::auto_list_enter ale (data_, true);

View File

@ -33,7 +33,9 @@ namespace amqp::internal::schema {
: public AMQPDescribed, public OrderedTypeNotation
{
public :
friend std::ostream & operator << (std::ostream &, const AMQPTypeNotation &);
friend std::ostream & operator << (
std::ostream &,
const AMQPTypeNotation &);
enum Type { Composite, Restricted };
@ -43,10 +45,10 @@ namespace amqp::internal::schema {
public :
AMQPTypeNotation (
const std::string & name_,
std::unique_ptr<Descriptor> & descriptor_
) : m_name (name_)
, m_descriptor (std::move(descriptor_))
std::string name_,
std::unique_ptr<Descriptor> descriptor_
) : m_name (std::move (name_))
, m_descriptor (std::move (descriptor_))
{ }
const std::string & descriptor() const;

View File

@ -0,0 +1,20 @@
#include "Choice.h"
/******************************************************************************/
amqp::internal::schema::
Choice::Choice (std::string choice_)
: m_choice (std::move (choice_))
{
}
/******************************************************************************/
const std::string &
amqp::internal::schema::
Choice::choice() const {
return m_choice;
}
/******************************************************************************/

View File

@ -0,0 +1,23 @@
#pragma once
#include "AMQPTypeNotation.h"
/******************************************************************************/
namespace amqp::internal::schema {
class Choice : public AMQPDescribed {
private :
std::string m_choice;
public :
Choice() = delete;
explicit Choice (std::string);
const std::string & choice() const;
};
}
/******************************************************************************/

View File

@ -36,14 +36,16 @@ namespace amqp::internal::schema {
amqp::internal::schema::
Composite::Composite (
const std::string & name_,
std::string name_,
std::string label_,
const sList<std::string> & provides_,
uPtr<Descriptor> & descriptor_,
std::vector<uPtr<Field>> & fields_
) : AMQPTypeNotation (name_, descriptor_)
sList<std::string> provides_,
uPtr<Descriptor> descriptor_,
std::vector<uPtr<Field>> fields_
) : AMQPTypeNotation (
std::move (name_),
std::move (descriptor_))
, m_label (std::move (label_))
, m_provides (provides_)
, m_provides (std::move (provides_))
, m_fields (std::move (fields_))
{ }

View File

@ -41,7 +41,7 @@ namespace amqp::internal::schema {
*/
class Composite : public AMQPTypeNotation {
public :
friend std::ostream & operator << (std::ostream &, const Composite&);
friend std::ostream & operator << (std::ostream &, const Composite &);
private :
// could be null in the stream... not sure that information is
@ -62,11 +62,11 @@ namespace amqp::internal::schema {
public :
Composite (
const std::string & name_,
std::string name_,
std::string label_,
const std::list<std::string> & provides_,
std::unique_ptr<Descriptor> & descriptor_,
std::vector<std::unique_ptr<Field>> & fields_);
std::list<std::string> provides_,
std::unique_ptr<Descriptor> descriptor_,
std::vector<std::unique_ptr<Field>> fields_);
const std::vector<std::unique_ptr<Field>> & fields() const;

View File

@ -18,7 +18,10 @@
namespace amqp::internal::schema {
using SchemaMap = std::map<std::string, const std::reference_wrapper<const uPtr<AMQPTypeNotation>>>;
using SchemaMap = std::map<
std::string,
const std::reference_wrapper<const uPtr<AMQPTypeNotation>>>;
using ISchemaType = amqp::schema::ISchema<SchemaMap::const_iterator>;
class Schema
@ -35,7 +38,7 @@ namespace amqp::internal::schema {
SchemaMap m_typeToDescriptor;
public :
explicit Schema (OrderedTypeNotations<AMQPTypeNotation> types_);
explicit Schema (OrderedTypeNotations<AMQPTypeNotation>);
const OrderedTypeNotations<AMQPTypeNotation> & types() const;

View File

@ -0,0 +1,119 @@
#include "Enum.h"
#include <algorithm>
#include "List.h"
#include "Composite.h"
/******************************************************************************/
amqp::internal::schema::
Enum::Enum (
uPtr<Descriptor> descriptor_,
std::string name_,
std::string label_,
std::vector<std::string> provides_,
std::string source_,
std::vector<uPtr<Choice>> choices_
) : Restricted (
std::move (descriptor_),
std::move (name_),
std::move (label_),
std::move (provides_),
amqp::internal::schema::Restricted::RestrictedTypes::Enum)
, m_enum { name_ }
, m_choices (std::move (choices_))
{
}
/******************************************************************************/
std::vector<std::string>::const_iterator
amqp::internal::schema::
Enum::begin() const {
return m_enum.begin();
}
/******************************************************************************/
std::vector<std::string>::const_iterator
amqp::internal::schema::
Enum::end() const {
return m_enum.end();
}
/******************************************************************************/
int
amqp::internal::schema::
Enum::dependsOn (const amqp::internal::schema::Restricted & lhs_) const {
auto rtn { 0 };
switch (lhs_.restrictedType()) {
case RestrictedTypes::List : {
const auto & list { dynamic_cast<const class List &>(lhs_) };
// does the left hand side depend on us
// DBG (" L/L a) " << list.listOf() << " == " << name() << std::endl); // NOLINT
if (list.listOf() == name()) {
rtn = 1;
}
// do we depend on the lhs
//DBG (" L/L b) " << name() << " == " << list.name() << std::endl); // NOLINT
if (name() == list.name()) {
rtn = 2;
}
break;
}
case RestrictedTypes::Enum : {
break;
}
case RestrictedTypes::Map : {
}
}
return rtn;
}
/******************************************************************************/
int
amqp::internal::schema::
Enum::dependsOn (const amqp::internal::schema::Composite & lhs_) const {
auto rtn { 0 };
for (const auto & field : lhs_.fields()) {
// DBG (" L/C a) " << field->resolvedType() << " == " << name() << std::endl); // NOLINT
if (field->resolvedType() == name()) {
rtn = 1;
}
}
// DBG (" L/C b) " << name() << " == " << lhs_.name() << std::endl); // NOLINT
if (name() == lhs_.name()) {
rtn = 2;
}
return rtn;
}
/*********************************************************o*********************/
std::vector<std::string>
amqp::internal::schema::
Enum::makeChoices() const {
std::vector<std::string> rtn;
std::transform (
m_choices.begin(),
m_choices.end(),
std::back_inserter(rtn),
[](const uPtr<Choice> & c) -> std::string { return c->choice(); });
return rtn;
}
/*********************************************************o*********************/

View File

@ -0,0 +1,32 @@
#pragma once
#include "Restricted.h"
namespace amqp::internal::schema {
class Enum : public Restricted {
private :
std::vector<std::string> m_enum;
std::vector<uPtr<Choice>> m_choices;
public :
Enum (
uPtr<Descriptor> descriptor_,
std::string,
std::string,
std::vector<std::string>,
std::string,
std::vector<uPtr<Choice>>);
std::vector<std::string>::const_iterator begin() const override;
std::vector<std::string>::const_iterator end() const override;
int dependsOn (const Restricted &) const override;
int dependsOn (const class Composite &) const override;
std::vector<std::string> makeChoices() const;
};
}
/******************************************************************************/

View File

@ -16,7 +16,7 @@ namespace {
return std::make_pair (
std::string { list_.substr (0, pos) },
std::string { list_.substr(pos + 1, list_.size() - pos - 2) }
std::string { list_.substr(pos + 1, list_.size() - pos - 2) }
);
}
}
@ -25,16 +25,16 @@ namespace {
amqp::internal::schema::
List::List (
uPtr<Descriptor> & descriptor_,
const std::string & name_,
const std::string & label_,
const std::vector<std::string> & provides_,
const std::string & source_
uPtr<Descriptor> descriptor_,
std::string name_,
std::string label_,
std::vector<std::string> provides_,
std::string source_
) : Restricted (
descriptor_,
name_,
label_,
provides_,
std::move (descriptor_),
std::move (name_),
std::move (label_),
std::move (provides_),
amqp::internal::schema::Restricted::RestrictedTypes::List)
, m_listOf { listType(name_).second }
{

View File

@ -12,11 +12,11 @@ namespace amqp::internal::schema {
public :
List (
uPtr<Descriptor> & descriptor_,
const std::string &,
const std::string &,
const std::vector<std::string> &,
const std::string &);
uPtr<Descriptor> descriptor_,
std::string,
std::string,
std::vector<std::string>,
std::string);
std::vector<std::string>::const_iterator begin() const override;
std::vector<std::string>::const_iterator end() const override;

View File

@ -1,5 +1,6 @@
#include "Restricted.h"
#include "List.h"
#include "Enum.h"
#include <string>
#include <vector>
@ -49,6 +50,10 @@ operator << (
stream_ << "map";
break;
}
case Restricted::RestrictedTypes::Enum : {
stream_ << "enum";
break;
}
}
return stream_;
@ -75,15 +80,38 @@ operator << (
std::unique_ptr<amqp::internal::schema::Restricted>
amqp::internal::schema::
Restricted::make(
uPtr<Descriptor> & descriptor_,
const std::string & name_,
const std::string & label_,
const std::vector<std::string> & provides_,
const std::string & source_)
uPtr<Descriptor> descriptor_,
std::string name_,
std::string label_,
std::vector<std::string> provides_,
std::string source_,
std::vector<uPtr<Choice>> choices_)
{
/*
* Lists represent both actual lists and enumerations. We differentiate
* between them as enums have choices ans lists don't. Pretty certain
* things are done this was as AMQP doesn't really have the concept
* of an enum.
*/
if (source_ == "list") {
return std::make_unique<amqp::internal::schema::List> (
descriptor_, name_, label_, provides_, source_);
if (choices_.empty()) {
return std::make_unique<amqp::internal::schema::List>(
std::move (descriptor_),
std::move (name_),
std::move (label_),
std::move (provides_),
std::move (source_));
} else {
return std::make_unique<amqp::internal::schema::Enum>(
std::move (descriptor_),
std::move (name_),
std::move (label_),
std::move (provides_),
std::move (source_),
std::move (choices_));
}
} else if (source_ == "map") {
throw std::runtime_error ("maps not supported");
}
}
@ -91,14 +119,16 @@ Restricted::make(
amqp::internal::schema::
Restricted::Restricted (
uPtr<Descriptor> & descriptor_,
const std::string & name_,
uPtr<Descriptor> descriptor_,
std::string name_,
std::string label_,
const std::vector<std::string> & provides_,
const amqp::internal::schema::Restricted::RestrictedTypes & source_
) : AMQPTypeNotation (name_, descriptor_)
std::vector<std::string> provides_,
amqp::internal::schema::Restricted::RestrictedTypes source_
) : AMQPTypeNotation (
std::move (name_),
std::move (descriptor_))
, m_label (std::move (label_))
, m_provides (provides_)
, m_provides (std::move (provides_))
, m_source (source_)
{
}

View File

@ -7,9 +7,10 @@
#include <iosfwd>
#include <string>
#include "Field.h"
#include "Descriptor.h"
#include "AMQPTypeNotation.h"
#include "schema/Field.h"
#include "schema/Choice.h"
#include "schema/Descriptor.h"
#include "schema/AMQPTypeNotation.h"
#include "amqp/AMQPDescribed.h"
@ -34,7 +35,7 @@ namespace amqp::internal::schema {
public :
friend std::ostream & operator << (std::ostream &, const Restricted&);
enum RestrictedTypes { List, Map };
enum RestrictedTypes { List, Map, Enum };
private :
// could be null in the stream... not sure that information is
@ -58,19 +59,20 @@ namespace amqp::internal::schema {
* keep main constructor private to force use of the named constructor
*/
Restricted (
std::unique_ptr<Descriptor> & descriptor_,
const std::string &,
std::unique_ptr<Descriptor> descriptor_,
std::string,
const std::vector<std::string> &,
const RestrictedTypes &);
std::string,
std::vector<std::string>,
RestrictedTypes);
public :
static std::unique_ptr<Restricted> make(
std::unique_ptr<Descriptor> & descriptor_,
const std::string &,
const std::string &,
const std::vector<std::string> &,
const std::string &);
std::unique_ptr<Descriptor>,
std::string,
std::string,
std::vector<std::string>,
std::string,
std::vector<uPtr<Choice>>);
Restricted (Restricted&) = delete;