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 IntClass (val a: Int)
data class _is_ (val a: Int, val b: String) data class IntStrClass (val a: Int, val b: String)
data class _i_is__ (val a: Int, val b: _is_) data class IntIntStrClass (val a: Int, val b: IntStrClass)
data class _Li_ (val a: List<Int>) data class IntListClass (val a: List<Int>)
data class _Mis_ (val a: Map<Int, String>) 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>) { fun main (args: Array<String>) {
initialiseSerialization() 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/_i_is__").writeBytes(IntIntStrClass(1, IntStrClass (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/_Li_").writeBytes(IntListClass(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/_Mis_").writeBytes(IntStringMapClass(
mapOf (1 to "two", 3 to "four", 5 to "six")).serialize().bytes) 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 *> ( dynamic_cast<amqp::internal::schema::Envelope *> (
amqp::AMQPDescriptorRegistory[a]->build(d).release())); 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 << *envelope << std::endl); // NOLINT
} }

View File

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

View File

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

View File

@ -12,6 +12,8 @@
#include "amqp/schema/Envelope.h" #include "amqp/schema/Envelope.h"
#include "amqp/schema/Composite.h" #include "amqp/schema/Composite.h"
#include "amqp/reader/CompositeReader.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 ( std::shared_ptr<reader::Reader> processRestricted (
const schema::AMQPTypeNotation &); 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; 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 ( virtual void read (
pn_data_t *, pn_data_t *,

View File

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

View File

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

View File

@ -41,22 +41,6 @@ AMQPDescriptor::validateAndNext (pn_data_t * const data_) const {
pn_data_next (data_); 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> uPtr<amqp::AMQPDescribed>

View File

@ -39,7 +39,8 @@ namespace amqp::internal::descriptors {
auto id = pn_data_get_ulong(data_); auto id = pn_data_get_ulong(data_);
return uPtr<T>( 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 { 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> ( 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 { class CompositeDescriptor : public AMQPDescriptor {
public : public :
CompositeDescriptor() : AMQPDescriptor() { } CompositeDescriptor() = delete;
CompositeDescriptor (const std::string &, int); CompositeDescriptor (const std::string &, int);
~CompositeDescriptor() final = default; ~CompositeDescriptor() final = default;

View File

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

View File

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

View File

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

View File

@ -12,7 +12,7 @@ namespace amqp::internal {
class FieldDescriptor : public AMQPDescriptor { class FieldDescriptor : public AMQPDescriptor {
public : public :
FieldDescriptor(); FieldDescriptor() = delete;
FieldDescriptor (const std::string &, int); FieldDescriptor (const std::string &, int);
~FieldDescriptor() final = default; ~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 { class ObjectDescriptor : public AMQPDescriptor {
public : public :
ObjectDescriptor() : AMQPDescriptor() { } ObjectDescriptor() = delete;
ObjectDescriptor(const std::string & symbol_, int val_) ObjectDescriptor(const std::string &, int);
: AMQPDescriptor(symbol_, val_)
{ }
~ObjectDescriptor() final = default; ~ObjectDescriptor() final = default;

View File

@ -3,6 +3,7 @@
#include "types.h" #include "types.h"
#include "debug.h" #include "debug.h"
#include "amqp/schema/Choice.h"
#include "amqp/schema/restricted-types/Restricted.h" #include "amqp/schema/restricted-types/Restricted.h"
#include "amqp/descriptors/AMQPDescriptors.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 name = proton::readAndNext<std::string>(data_);
auto label = proton::readAndNext<std::string>(data_, true); auto label = proton::readAndNext<std::string>(data_, true);
DBG (" name: " << name << ", label: \"" << label << "\"" << std::endl);
std::vector<std::string> provides; std::vector<std::string> provides;
{ {
proton::auto_list_enter ae2 (data_); proton::auto_list_enter ae2 (data_);
while (pn_data_next(data_)) { while (pn_data_next(data_)) {
provides.push_back (proton::get_string (data_)); provides.push_back (proton::get_string (data_));
DBG (" provides: " << provides.back() << std::endl);
} }
} }
pn_data_next (data_); pn_data_next (data_);
auto source = proton::readAndNext<std::string> (data_); auto source = proton::readAndNext<std::string> (data_);
DBG ("source: " << source << std::endl);
auto descriptor = descriptors::dispatchDescribed<schema::Descriptor> (data_); auto descriptor = descriptors::dispatchDescribed<schema::Descriptor> (data_);
// SKIP the choices section **FOR NOW** pn_data_next (data_);
return schema::Restricted::make (descriptor, name, DBG ("choices: " << data_ << std::endl);
label, provides, source);
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 { class RestrictedDescriptor : public AMQPDescriptor {
public : public :
RestrictedDescriptor() : AMQPDescriptor() { } RestrictedDescriptor() = delete;
RestrictedDescriptor(const std::string & symbol_, int val_) RestrictedDescriptor(const std::string & symbol_, int val_)
: AMQPDescriptor(symbol_, val_) : AMQPDescriptor(symbol_, val_)

View File

@ -20,7 +20,7 @@ amqp::internal::
SchemaDescriptor::SchemaDescriptor ( SchemaDescriptor::SchemaDescriptor (
const std::string & symbol_, const std::string & symbol_,
int val_ 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_); proton::auto_list_enter ale2 (data_);
while (pn_data_next(data_)) { while (pn_data_next(data_)) {
schemas.insert ( 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 { class SchemaDescriptor : public AMQPDescriptor {
public : public :
SchemaDescriptor() = default; SchemaDescriptor() = delete;
SchemaDescriptor (const std::string &, int); SchemaDescriptor (const std::string &, int);
~SchemaDescriptor() final = default; ~SchemaDescriptor() final = default;

View File

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

View File

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

View File

@ -26,9 +26,9 @@ namespace amqp::internal::reader {
explicit RestrictedReader (std::string); explicit RestrictedReader (std::string);
~RestrictedReader() override = default; ~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( std::unique_ptr<amqp::reader::IValue> dump(
const std::string &, const std::string &,

View File

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

View File

@ -16,7 +16,7 @@ namespace amqp::internal::reader {
public : public :
~IntPropertyReader() override = default; ~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; std::any read(pn_data_t *) const override;

View File

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

View File

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

View File

@ -18,13 +18,13 @@ namespace amqp::internal::reader {
std::any read (pn_data_t *) const override; std::any read (pn_data_t *) const override;
uPtr <amqp::reader::IValue> dump ( uPtr<amqp::reader::IValue> dump (
const std::string &, const std::string &,
pn_data_t *, pn_data_t *,
const SchemaType & const SchemaType &
) const override; ) const override;
uPtr <amqp::reader::IValue> dump ( uPtr<amqp::reader::IValue> dump (
pn_data_t *, pn_data_t *,
const SchemaType & const SchemaType &
) const override; ) 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_); 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); proton::auto_list_enter ale (data_, true);

View File

@ -33,7 +33,9 @@ namespace amqp::internal::schema {
: public AMQPDescribed, public OrderedTypeNotation : public AMQPDescribed, public OrderedTypeNotation
{ {
public : public :
friend std::ostream & operator << (std::ostream &, const AMQPTypeNotation &); friend std::ostream & operator << (
std::ostream &,
const AMQPTypeNotation &);
enum Type { Composite, Restricted }; enum Type { Composite, Restricted };
@ -43,10 +45,10 @@ namespace amqp::internal::schema {
public : public :
AMQPTypeNotation ( AMQPTypeNotation (
const std::string & name_, std::string name_,
std::unique_ptr<Descriptor> & descriptor_ std::unique_ptr<Descriptor> descriptor_
) : m_name (name_) ) : m_name (std::move (name_))
, m_descriptor (std::move(descriptor_)) , m_descriptor (std::move (descriptor_))
{ } { }
const std::string & descriptor() const; 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:: amqp::internal::schema::
Composite::Composite ( Composite::Composite (
const std::string & name_, std::string name_,
std::string label_, std::string label_,
const sList<std::string> & provides_, sList<std::string> provides_,
uPtr<Descriptor> & descriptor_, uPtr<Descriptor> descriptor_,
std::vector<uPtr<Field>> & fields_ std::vector<uPtr<Field>> fields_
) : AMQPTypeNotation (name_, descriptor_) ) : AMQPTypeNotation (
std::move (name_),
std::move (descriptor_))
, m_label (std::move (label_)) , m_label (std::move (label_))
, m_provides (provides_) , m_provides (std::move (provides_))
, m_fields (std::move (fields_)) , m_fields (std::move (fields_))
{ } { }

View File

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

View File

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

@ -25,16 +25,16 @@ namespace {
amqp::internal::schema:: amqp::internal::schema::
List::List ( List::List (
uPtr<Descriptor> & descriptor_, uPtr<Descriptor> descriptor_,
const std::string & name_, std::string name_,
const std::string & label_, std::string label_,
const std::vector<std::string> & provides_, std::vector<std::string> provides_,
const std::string & source_ std::string source_
) : Restricted ( ) : Restricted (
descriptor_, std::move (descriptor_),
name_, std::move (name_),
label_, std::move (label_),
provides_, std::move (provides_),
amqp::internal::schema::Restricted::RestrictedTypes::List) amqp::internal::schema::Restricted::RestrictedTypes::List)
, m_listOf { listType(name_).second } , m_listOf { listType(name_).second }
{ {

View File

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

View File

@ -1,5 +1,6 @@
#include "Restricted.h" #include "Restricted.h"
#include "List.h" #include "List.h"
#include "Enum.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -49,6 +50,10 @@ operator << (
stream_ << "map"; stream_ << "map";
break; break;
} }
case Restricted::RestrictedTypes::Enum : {
stream_ << "enum";
break;
}
} }
return stream_; return stream_;
@ -75,15 +80,38 @@ operator << (
std::unique_ptr<amqp::internal::schema::Restricted> std::unique_ptr<amqp::internal::schema::Restricted>
amqp::internal::schema:: amqp::internal::schema::
Restricted::make( Restricted::make(
uPtr<Descriptor> & descriptor_, uPtr<Descriptor> descriptor_,
const std::string & name_, std::string name_,
const std::string & label_, std::string label_,
const std::vector<std::string> & provides_, std::vector<std::string> provides_,
const std::string & source_) 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") { if (source_ == "list") {
return std::make_unique<amqp::internal::schema::List> ( if (choices_.empty()) {
descriptor_, name_, label_, provides_, source_); 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:: amqp::internal::schema::
Restricted::Restricted ( Restricted::Restricted (
uPtr<Descriptor> & descriptor_, uPtr<Descriptor> descriptor_,
const std::string & name_, std::string name_,
std::string label_, std::string label_,
const std::vector<std::string> & provides_, std::vector<std::string> provides_,
const amqp::internal::schema::Restricted::RestrictedTypes & source_ amqp::internal::schema::Restricted::RestrictedTypes source_
) : AMQPTypeNotation (name_, descriptor_) ) : AMQPTypeNotation (
std::move (name_),
std::move (descriptor_))
, m_label (std::move (label_)) , m_label (std::move (label_))
, m_provides (provides_) , m_provides (std::move (provides_))
, m_source (source_) , m_source (source_)
{ {
} }

View File

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