mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
NOTICK - Add C++ Serialiser Support for Maps and Arrays (#5775)
Adds support for understanding both Maps and Arrays Irritatingly, whilst arrays are mostly serialized as lists, we cannot simply use a restricted List reader to deserialize them because there are subtle differences in the way we need to work out if its actually a restricted type or not. Rather than add a bunch of random logic into the factory method I've isolated it in the class hierarchy. So a little bit more code makes the implementations a lot neater. We also need to deal with the fact arras of unboxed primitives exist, which whilst Java really gets excited about, we don't need to care about. An int, is an int, is an int!. Map support required we add a slightly better Value dumper, essentially the "key" component of the KV pair needs to be more flexible than a simple string when we're dumping out param:value pairs. Testing Added a lot more unit tests to both the ordered type notation code to ensure we build up the schema dependency struct in the correct order. Quite important as we rely on that in the composite factory to be strictly ordered to ensure we're not constructing a reader for a type we don't yet understand... and there were some small bugs in the version that predates this PR Also added a lot higher level tests to ensure actual reading out of the blob works
This commit is contained in:
parent
79b41fe5ed
commit
8f7346f84c
@ -1,3 +1,5 @@
|
|||||||
|
@file:Suppress("ClassNaming", "MagicNumber")
|
||||||
|
|
||||||
package net.corda.blobwriter
|
package net.corda.blobwriter
|
||||||
|
|
||||||
import net.corda.core.serialization.SerializationContext
|
import net.corda.core.serialization.SerializationContext
|
||||||
@ -43,27 +45,108 @@ fun initialiseSerialization() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class IntClass (val a: Int)
|
data class _i_ (val a: Int)
|
||||||
data class IntStrClass (val a: Int, val b: String)
|
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
|
||||||
data class IntIntStrClass (val a: Int, val b: IntStrClass)
|
data class _Oi_ (val a: Integer)
|
||||||
data class IntListClass (val a: List<Int>)
|
data class _l_ (val x: Long)
|
||||||
data class IntStringMapClass (val a: Map<Int, String>)
|
data class _Ai_ (val z : Array<Int>)
|
||||||
|
data class _Ci_ (val z : IntArray)
|
||||||
|
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 _Mi_is__ (val a: Map<Int, _is_>)
|
||||||
|
data class _MiLs_ (val a: Map<Int, List<String>>)
|
||||||
|
data class __i_LMis_l__ (val z : _i_, val x : List<Map<Int, String>>, val y : _l_ )
|
||||||
|
data class _LAi_ (val l : List<Array<Int>>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum class E {
|
enum class E {
|
||||||
A, B, C
|
A, B, C
|
||||||
}
|
}
|
||||||
data class EnumClass (val e: E)
|
|
||||||
data class EnumListClass (val listy: List<E>)
|
data class _Pls_ (val a : Pair<Long, String>)
|
||||||
|
|
||||||
|
data class _e_ (val e: E)
|
||||||
|
data class _Le_ (val listy: List<E>)
|
||||||
|
data class _L_i__ (val listy: List<_i_>)
|
||||||
|
|
||||||
|
data class _ALd_ (val a: Array<List<Double>>)
|
||||||
|
|
||||||
fun main (args: Array<String>) {
|
fun main (args: Array<String>) {
|
||||||
initialiseSerialization()
|
initialiseSerialization()
|
||||||
|
val path = "../cpp-serializer/bin/test-files";
|
||||||
|
File("$path/_i_").writeBytes (_i_ (69).serialize().bytes)
|
||||||
|
File("$path/_Oi_").writeBytes (_Oi_ (Integer (1)).serialize().bytes)
|
||||||
|
File("$path/_l_").writeBytes (_l_ (100000000000L).serialize().bytes)
|
||||||
|
File("$path/_Li_").writeBytes (_Li_(listOf (1, 2, 3, 4, 5, 6)).serialize().bytes)
|
||||||
|
File("$path/_Ai_").writeBytes (_Ai_(arrayOf (1, 2, 3, 4, 5, 6)).serialize().bytes)
|
||||||
|
|
||||||
File("../cpp-serializer/bin/blob-inspector/test/_i_is__").writeBytes(IntIntStrClass(1, IntStrClass (2, "three")).serialize().bytes)
|
val v = IntArray(3)
|
||||||
File("../cpp-serializer/bin/blob-inspector/test/_Li_").writeBytes(IntListClass(listOf (1, 2, 3, 4, 5, 6)).serialize().bytes)
|
v[0] = 1; v[1] = 2; v[2] = 3
|
||||||
File("../cpp-serializer/bin/blob-inspector/test/_Mis_").writeBytes(IntStringMapClass(
|
|
||||||
|
File("$path/_Ci_").writeBytes (_Ci_(v).serialize().bytes)
|
||||||
|
|
||||||
|
File("$path/_Le_").writeBytes (_Le_(listOf (E.A, E.B, E.C)).serialize().bytes)
|
||||||
|
File("$path/_Le_2").writeBytes (_Le_(listOf (E.A, E.B, E.C, E.B, E.A)).serialize().bytes)
|
||||||
|
File("$path/_L_i__").writeBytes(
|
||||||
|
_L_i__(listOf (
|
||||||
|
_i_ (1),
|
||||||
|
_i_ (2),
|
||||||
|
_i_ (3))
|
||||||
|
).serialize().bytes)
|
||||||
|
|
||||||
|
File("$path/_ALd_").writeBytes( _ALd_ (arrayOf(
|
||||||
|
listOf (10.1, 11.2, 12.3),
|
||||||
|
listOf (),
|
||||||
|
listOf (13.4)
|
||||||
|
)).serialize().bytes)
|
||||||
|
|
||||||
|
|
||||||
|
File ("$path/_i_is__").writeBytes(_i_is__(1, _is_ (2, "three")).serialize().bytes)
|
||||||
|
File ("$path/_Mis_").writeBytes(_Mis_(
|
||||||
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 ("$path/_e_").writeBytes(_e_(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)
|
File ("$path/_Pls_").writeBytes(_Pls_(Pair (1, "two")).serialize().bytes)
|
||||||
|
File ("$path/_Mi_is__").writeBytes(
|
||||||
|
_Mi_is__ (mapOf (
|
||||||
|
1 to _is_ (2, "three"),
|
||||||
|
4 to _is_ (5, "six"),
|
||||||
|
7 to _is_ (8, "nine")
|
||||||
|
)
|
||||||
|
).serialize().bytes)
|
||||||
|
|
||||||
|
File ("$path/_MiLs_").writeBytes(
|
||||||
|
_MiLs_ (mapOf (
|
||||||
|
1 to listOf ("two", "three", "four"),
|
||||||
|
5 to listOf ("six"),
|
||||||
|
7 to listOf ()
|
||||||
|
)
|
||||||
|
).serialize().bytes)
|
||||||
|
|
||||||
|
|
||||||
|
File ("$path/__i_LMis_l__").writeBytes (
|
||||||
|
__i_LMis_l__ (
|
||||||
|
_i_ (666),
|
||||||
|
listOf (
|
||||||
|
mapOf (
|
||||||
|
1 to "two",
|
||||||
|
3 to "four",
|
||||||
|
5 to "six"
|
||||||
|
),
|
||||||
|
mapOf (
|
||||||
|
7 to "eight",
|
||||||
|
9 to "ten"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_l_ (1000000L)
|
||||||
|
).serialize().bytes
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1
experimental/cpp-serializer/bin/.gitignore
vendored
Normal file
1
experimental/cpp-serializer/bin/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.a
|
@ -1 +1,3 @@
|
|||||||
blob-inspector
|
blob-inspector
|
||||||
|
|
||||||
|
*.a
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
#include "BlobInspector.h"
|
||||||
|
#include "CordaBytes.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "proton/codec.h"
|
||||||
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
|
#include "amqp/schema/descriptors/AMQPDescriptorRegistory.h"
|
||||||
|
|
||||||
|
#include "amqp/CompositeFactory.h"
|
||||||
|
#include "amqp/schema/described-types/Envelope.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
BlobInspector::BlobInspector (CordaBytes & cb_)
|
||||||
|
: m_data { pn_data (cb_.size()) }
|
||||||
|
{
|
||||||
|
// returns how many bytes we processed which right now we don't care
|
||||||
|
// about but I assume there is a case where it doesn't process the
|
||||||
|
// entire file
|
||||||
|
auto rtn = pn_data_decode (m_data, cb_.bytes(), cb_.size());
|
||||||
|
assert (rtn == cb_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::string
|
||||||
|
BlobInspector::dump() {
|
||||||
|
std::unique_ptr<amqp::internal::schema::Envelope> envelope;
|
||||||
|
|
||||||
|
if (pn_data_is_described (m_data)) {
|
||||||
|
proton::auto_enter p (m_data);
|
||||||
|
|
||||||
|
auto a = pn_data_get_ulong(m_data);
|
||||||
|
|
||||||
|
envelope.reset (
|
||||||
|
dynamic_cast<amqp::internal::schema::Envelope *> (
|
||||||
|
amqp::internal::AMQPDescriptorRegistory[a]->build(m_data).release()));
|
||||||
|
}
|
||||||
|
|
||||||
|
amqp::internal::CompositeFactory cf;
|
||||||
|
|
||||||
|
cf.process (envelope->schema());
|
||||||
|
|
||||||
|
auto reader = cf.byDescriptor (envelope->descriptor());
|
||||||
|
assert (reader);
|
||||||
|
|
||||||
|
{
|
||||||
|
// move to the actual blob entry in the tree - ideally we'd have
|
||||||
|
// saved this on the Envelope but that's not easily doable as we
|
||||||
|
// can't grab an actual copy of our data pointer
|
||||||
|
proton::auto_enter p (m_data);
|
||||||
|
pn_data_next (m_data);
|
||||||
|
proton::is_list (m_data);
|
||||||
|
assert (pn_data_get_list (m_data) == 3);
|
||||||
|
{
|
||||||
|
proton::auto_enter p (m_data);
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
// We wrap our output like this to make sure it's valid JSON to
|
||||||
|
// facilitate easy pretty printing
|
||||||
|
ss << reader->dump ("{ Parsed", m_data, envelope->schema())->dump()
|
||||||
|
<< " }";
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -1,24 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include "CordaBytes.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
struct pn_data_t;
|
struct pn_data_t;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp {
|
class BlobInspector {
|
||||||
namespace internal {
|
private :
|
||||||
namespace serialiser {
|
pn_data_t * m_data;
|
||||||
|
|
||||||
class ProtonReader {
|
public :
|
||||||
public :
|
BlobInspector (CordaBytes &);
|
||||||
template<typename T>
|
|
||||||
virtual T read (pn_data_t *) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
std::string dump();
|
||||||
}
|
|
||||||
}
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
@ -4,6 +4,18 @@ include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src/amqp)
|
|||||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/amqp)
|
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/amqp)
|
||||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/proton)
|
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/proton)
|
||||||
|
|
||||||
add_executable (blob-inspector main)
|
set (blob-inspector-sources
|
||||||
|
BlobInspector.cxx
|
||||||
|
CordaBytes.cxx)
|
||||||
|
|
||||||
|
|
||||||
|
add_executable (blob-inspector main.cxx ${blob-inspector-sources})
|
||||||
|
|
||||||
target_link_libraries (blob-inspector amqp proton qpid-proton)
|
target_link_libraries (blob-inspector amqp proton qpid-proton)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Unit tests for the blob inspector. For this to work we also need to create
|
||||||
|
# a linkable library from the code here to link into our test.
|
||||||
|
#
|
||||||
|
add_library (blob-inspector-lib ${blob-inspector-sources} )
|
||||||
|
ADD_SUBDIRECTORY (test)
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
#include "CordaBytes.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "amqp/AMQPHeader.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
CordaBytes::CordaBytes (const std::string & file_)
|
||||||
|
: m_blob { nullptr }
|
||||||
|
{
|
||||||
|
std::ifstream file { file_, std::ios::in | std::ios::binary };
|
||||||
|
struct stat results { };
|
||||||
|
|
||||||
|
if (::stat(file_.c_str(), &results) != 0) {
|
||||||
|
throw std::runtime_error ("Not a file");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disregard the Corda header
|
||||||
|
m_size = results.st_size - (amqp::AMQP_HEADER.size() + 1);
|
||||||
|
|
||||||
|
std::array<char, 7> header { };
|
||||||
|
file.read (header.data(), 7);
|
||||||
|
|
||||||
|
if (header != amqp::AMQP_HEADER) {
|
||||||
|
throw std::runtime_error ("Not a Corda stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
file.read (reinterpret_cast<char *>(&m_encoding), 1);
|
||||||
|
|
||||||
|
m_blob = new char[m_size];
|
||||||
|
|
||||||
|
memset (m_blob, 0, m_size);
|
||||||
|
file.read (m_blob, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
31
experimental/cpp-serializer/bin/blob-inspector/CordaBytes.h
Normal file
31
experimental/cpp-serializer/bin/blob-inspector/CordaBytes.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "string"
|
||||||
|
#include <fstream>
|
||||||
|
#include "amqp/AMQPSectionId.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
class CordaBytes {
|
||||||
|
private :
|
||||||
|
amqp::amqp_section_id_t m_encoding;
|
||||||
|
size_t m_size;
|
||||||
|
char * m_blob;
|
||||||
|
|
||||||
|
public :
|
||||||
|
explicit CordaBytes (const std::string &);
|
||||||
|
|
||||||
|
~CordaBytes() {
|
||||||
|
delete [] m_blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
const decltype (m_encoding) & encoding() const {
|
||||||
|
return m_encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
decltype (m_size) size() const { return m_size; }
|
||||||
|
|
||||||
|
const char * const bytes() const { return m_blob; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -9,74 +9,18 @@
|
|||||||
#include <proton/codec.h>
|
#include <proton/codec.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#import "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include "proton/proton_wrapper.h"
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
#include "amqp/AMQPHeader.h"
|
#include "amqp/AMQPHeader.h"
|
||||||
#include "amqp/AMQPSectionId.h"
|
#include "amqp/AMQPSectionId.h"
|
||||||
#include "amqp/descriptors/AMQPDescriptorRegistory.h"
|
#include "amqp/schema/descriptors/AMQPDescriptorRegistory.h"
|
||||||
|
|
||||||
#include "amqp/schema/Envelope.h"
|
#include "amqp/schema/described-types/Envelope.h"
|
||||||
#include "amqp/CompositeFactory.h"
|
#include "amqp/CompositeFactory.h"
|
||||||
|
#include "CordaBytes.h"
|
||||||
/******************************************************************************/
|
#include "BlobInspector.h"
|
||||||
|
|
||||||
void
|
|
||||||
data_and_stop(std::ifstream & f_, ssize_t sz) {
|
|
||||||
char * blob = new char[sz];
|
|
||||||
memset (blob, 0, sz);
|
|
||||||
f_.read(blob, sz);
|
|
||||||
|
|
||||||
pn_data_t * d = pn_data(sz);
|
|
||||||
|
|
||||||
// returns how many bytes we processed which right now we don't care
|
|
||||||
// about but I assume there is a case where it doesn't process the
|
|
||||||
// entire file
|
|
||||||
auto rtn = pn_data_decode (d, blob, sz);
|
|
||||||
assert (rtn == sz);
|
|
||||||
|
|
||||||
std::unique_ptr<amqp::internal::schema::Envelope> envelope;
|
|
||||||
|
|
||||||
if (pn_data_is_described(d)) {
|
|
||||||
proton::auto_enter p (d);
|
|
||||||
|
|
||||||
auto a = pn_data_get_ulong(d);
|
|
||||||
|
|
||||||
envelope.reset (
|
|
||||||
dynamic_cast<amqp::internal::schema::Envelope *> (
|
|
||||||
amqp::AMQPDescriptorRegistory[a]->build(d).release()));
|
|
||||||
|
|
||||||
DBG (std::endl << "Types in schema: " << std::endl
|
|
||||||
<< *envelope << std::endl); // NOLINT
|
|
||||||
}
|
|
||||||
|
|
||||||
amqp::internal::CompositeFactory cf;
|
|
||||||
|
|
||||||
cf.process (envelope->schema());
|
|
||||||
|
|
||||||
auto reader = cf.byDescriptor (envelope->descriptor());
|
|
||||||
assert (reader);
|
|
||||||
|
|
||||||
{
|
|
||||||
// move to the actual blob entry in the tree - ideally we'd have
|
|
||||||
// saved this on the Envelope but that's not easily doable as we
|
|
||||||
// can't grab an actual copy of our data pointer
|
|
||||||
proton::auto_enter p (d);
|
|
||||||
pn_data_next (d);
|
|
||||||
proton::is_list (d);
|
|
||||||
assert (pn_data_get_list (d) == 3);
|
|
||||||
{
|
|
||||||
proton::auto_enter p (d);
|
|
||||||
|
|
||||||
// We wrap our output like this to make sure it's valid JSON to
|
|
||||||
// facilitate easy pretty printing
|
|
||||||
std::cout
|
|
||||||
<< reader->dump ("{ Parsed", d, envelope->schema())->dump()
|
|
||||||
<< " }" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -88,22 +32,14 @@ main (int argc, char **argv) {
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream f (argv[1], std::ios::in | std::ios::binary);
|
CordaBytes cb (argv[1]);
|
||||||
std::array<char, 7> header { };
|
|
||||||
f.read(header.data(), 7);
|
if (cb.encoding() == amqp::DATA_AND_STOP) {
|
||||||
|
BlobInspector blobInspector (cb);
|
||||||
if (header != amqp::AMQP_HEADER) {
|
auto val = blobInspector.dump();
|
||||||
std::cerr << "Bad Header in blob" << std::endl;
|
std::cout << val << std::endl;
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
amqp::amqp_section_id_t encoding;
|
|
||||||
f.read((char *)&encoding, 1);
|
|
||||||
|
|
||||||
if (encoding == amqp::DATA_AND_STOP) {
|
|
||||||
data_and_stop(f, results.st_size - 8);
|
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "BAD ENCODING " << encoding << " != "
|
std::cerr << "BAD ENCODING " << cb.encoding() << " != "
|
||||||
<< amqp::DATA_AND_STOP << std::endl;
|
<< amqp::DATA_AND_STOP << std::endl;
|
||||||
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
1
experimental/cpp-serializer/bin/blob-inspector/test/.gitignore
vendored
Normal file
1
experimental/cpp-serializer/bin/blob-inspector/test/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
blob-inspector-test
|
@ -0,0 +1,17 @@
|
|||||||
|
set (EXE "blob-inspector-test")
|
||||||
|
|
||||||
|
set (blob-inspector-test-sources
|
||||||
|
main.cxx
|
||||||
|
blob-inspector-test.cxx
|
||||||
|
)
|
||||||
|
|
||||||
|
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/bin/blob-inspector)
|
||||||
|
include_directories (${BLOB-INSPECTOR_BINARY_DIR}/bin/blob-inspector)
|
||||||
|
|
||||||
|
add_executable (${EXE} ${blob-inspector-test-sources})
|
||||||
|
|
||||||
|
target_link_libraries (${EXE} gtest amqp blob-inspector-lib)
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
target_link_libraries (${EXE} pthread qpid-proton proton)
|
||||||
|
endif (UNIX)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,171 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include "CordaBytes.h"
|
||||||
|
#include "BlobInspector.h"
|
||||||
|
|
||||||
|
const std::string filepath ("../../test-files/"); // NOLINT
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* mapType Tests
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
test (const std::string & file_, const std::string & result_) {
|
||||||
|
auto path { filepath + file_ } ;
|
||||||
|
CordaBytes cb (path);
|
||||||
|
auto val = BlobInspector (cb).dump();
|
||||||
|
ASSERT_EQ(result_, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _i_) { // NOLINT
|
||||||
|
test ("_i_", "{ Parsed : { a : 69 } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* long
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _l_) { // NOLINT
|
||||||
|
test ("_l_", "{ Parsed : { x : 100000000000 } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _Oi_) { // NOLINT
|
||||||
|
test ("_Oi_", "{ Parsed : { a : 1 } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _Ai_) { // NOLINT
|
||||||
|
test ("_Ai_", "{ Parsed : { z : [ 1, 2, 3, 4, 5, 6 ] } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of ints
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _Li_) { // NOLINT
|
||||||
|
test ("_Li_", "{ Parsed : { a : [ 1, 2, 3, 4, 5, 6 ] } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of a class with a single int property
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _L_i__) { // NOLINT
|
||||||
|
test (
|
||||||
|
"_L_i__",
|
||||||
|
"{ Parsed : { listy : [ { a : 1 }, { a : 2 }, { a : 3 } ] } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEST (BlobInspector, _Le_) { // NOLINT
|
||||||
|
test ("_Le_", "{ Parsed : { listy : [ A, B, C ] } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEST (BlobInspector,_Le_2) { // NOLINT
|
||||||
|
EXPECT_THROW (
|
||||||
|
{
|
||||||
|
test ("_Le_2", "");
|
||||||
|
},
|
||||||
|
std::runtime_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of ints to strings
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _Mis_) { // NOLINT
|
||||||
|
test ("_Mis_",
|
||||||
|
R"({ Parsed : { a : { 1 : "two", 3 : "four", 5 : "six" } } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of ints to lists of Strings
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _MiLs_) { // NOLINT
|
||||||
|
test ("_MiLs_",
|
||||||
|
R"({ Parsed : { a : { 1 : [ "two", "three", "four" ], 5 : [ "six" ], 7 : [ ] } } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a map of ints to a composite with a n int and string property
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, _Mi_is__) { // NOLINT
|
||||||
|
test ("_Mi_is__",
|
||||||
|
R"({ Parsed : { a : { 1 : { a : 2, b : "three" }, 4 : { a : 5, b : "six" }, 7 : { a : 8, b : "nine" } } } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEST (BlobInspector,_Pls_) { // NOLINT
|
||||||
|
test ("_Pls_",
|
||||||
|
R"({ Parsed : { a : { first : 1, second : "two" } } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEST (BlobInspector, _e_) { // NOLINT
|
||||||
|
test ("_e_", "{ Parsed : { e : A } }");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEST (BlobInspector, _i_is__) { // NOLINT
|
||||||
|
test ("_i_is__",
|
||||||
|
R"({ Parsed : { a : 1, b : { a : 2, b : "three" } } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
// Array of unboxed integers
|
||||||
|
TEST (BlobInspector, _Ci_) { // NOLINT
|
||||||
|
test ("_Ci_",
|
||||||
|
R"({ Parsed : { z : [ 1, 2, 3 ] } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composite with
|
||||||
|
* * one int property
|
||||||
|
* * one long property
|
||||||
|
* * one list property that is a list of Maps of int to strings
|
||||||
|
*/
|
||||||
|
TEST (BlobInspector, __i_LMis_l__) { // NOLINT
|
||||||
|
test ("__i_LMis_l__",
|
||||||
|
R"({ Parsed : { x : [ { 1 : "two", 3 : "four", 5 : "six" }, { 7 : "eight", 9 : "ten" } ], y : { x : 1000000 }, z : { a : 666 } } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
TEST (BlobInspector, _ALd_) { // NOLINT
|
||||||
|
test ("_ALd_",
|
||||||
|
R"({ Parsed : { a : [ [ 10.100000, 11.200000, 12.300000 ], [ ], [ 13.400000 ] ] } })");
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -0,0 +1,7 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char ** argv){
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
Binary file not shown.
@ -10,15 +10,15 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#import "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include "proton/proton_wrapper.h"
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
#include "amqp/AMQPHeader.h"
|
#include "amqp/AMQPHeader.h"
|
||||||
#include "amqp/AMQPSectionId.h"
|
#include "amqp/AMQPSectionId.h"
|
||||||
#include "amqp/descriptors/AMQPDescriptorRegistory.h"
|
#include "amqp/schema/descriptors/AMQPDescriptorRegistory.h"
|
||||||
|
|
||||||
#include "amqp/schema/Envelope.h"
|
#include "amqp/schema/described-types/Envelope.h"
|
||||||
#include "amqp/CompositeFactory.h"
|
#include "amqp/CompositeFactory.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -28,7 +28,7 @@ printNode (pn_data_t * d_) {
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
|
||||||
if (pn_data_is_described (d_)) {
|
if (pn_data_is_described (d_)) {
|
||||||
amqp::AMQPDescriptorRegistory[22UL]->read (d_, ss);
|
amqp::internal::AMQPDescriptorRegistory[22UL]->read (d_, ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << ss.str() << std::endl;
|
std::cout << ss.str() << std::endl;
|
||||||
|
BIN
experimental/cpp-serializer/bin/test-files/_ALd_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_ALd_
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_Ai_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_Ai_
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_Ci_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_Ci_
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_L_i__
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_L_i__
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_MiLs_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_MiLs_
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_Mi_is__
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_Mi_is__
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_Oi_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_Oi_
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_Pls_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_Pls_
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/__i_LMis_l__
Normal file
BIN
experimental/cpp-serializer/bin/test-files/__i_LMis_l__
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_i_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_i_
Normal file
Binary file not shown.
BIN
experimental/cpp-serializer/bin/test-files/_l_
Normal file
BIN
experimental/cpp-serializer/bin/test-files/_l_
Normal file
Binary file not shown.
@ -12,7 +12,7 @@ namespace amqp {
|
|||||||
* The 8th byte is used to store weather the stream is compressed or
|
* The 8th byte is used to store weather the stream is compressed or
|
||||||
* not
|
* not
|
||||||
*/
|
*/
|
||||||
std::array<char, 7> AMQP_HEADER { { 'c', 'o', 'r', 'd', 'a', 1, 0 } };
|
const std::array<char, 7> AMQP_HEADER { { 'c', 'o', 'r', 'd', 'a', 1, 0 } };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "amqp/AMQPDescribed.h"
|
#include "amqp/AMQPDescribed.h"
|
||||||
|
|
||||||
#include "amqp/schema/Schema.h"
|
#include "amqp/schema/described-types/Schema.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* R3 AMQP assigned enterprise number
|
||||||
|
*
|
||||||
|
* see [here](https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers)
|
||||||
|
*
|
||||||
|
* Repeated here for brevity:
|
||||||
|
* 50530 - R3 - Mike Hearn - mike&r3.com
|
||||||
|
*/
|
||||||
|
namespace amqp::schema::descriptors {
|
||||||
|
|
||||||
|
constexpr uint64_t DESCRIPTOR_TOP_32BITS = 0xc562UL << (unsigned int)(32 + 16);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace amqp::schema::descriptors {
|
||||||
|
|
||||||
|
extern const int ENVELOPE;
|
||||||
|
extern const int SCHEMA;
|
||||||
|
extern const int OBJECT;
|
||||||
|
extern const int FIELD;
|
||||||
|
extern const int COMPOSITE_TYPE;
|
||||||
|
extern const int RESTRICTED_TYPE;
|
||||||
|
extern const int CHOICE;
|
||||||
|
extern const int REFERENCED_OBJECT;
|
||||||
|
extern const int TRANSFORM_SCHEMA;
|
||||||
|
extern const int TRANSFORM_ELEMENT;
|
||||||
|
extern const int TRANSFORM_ELEMENT_KEY;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace amqp::serializable {
|
||||||
|
|
||||||
|
class ISerializable {
|
||||||
|
public :
|
||||||
|
virtual char * serialize() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -7,7 +7,7 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
#if defined AMQP_DEBUG && AMQP_DEBUG >= 1
|
#if defined AMQP_DEBUG && AMQP_DEBUG >= 1
|
||||||
#define DBG(X) std::cout << X
|
#define DBG(X) std::cout << __FILE__ << "::" << __LINE__ << "] " << X
|
||||||
#else
|
#else
|
||||||
#define DBG(X)
|
#define DBG(X)
|
||||||
#endif
|
#endif
|
||||||
|
2
experimental/cpp-serializer/lines
Executable file
2
experimental/cpp-serializer/lines
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
wc -l $(find -E . -regex ".*/*.(cxx|h)")
|
@ -9,9 +9,13 @@ function cmake_rem_func {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rm -f BLOB-INSPECTOR.cbp
|
rm -f BLOB-INSPECTOR.cbp
|
||||||
|
rm -rf cmake-build-debug
|
||||||
|
|
||||||
cmake_rem_func .
|
cmake_rem_func .
|
||||||
cmake_rem_func ./bin
|
cmake_rem_func ./bin
|
||||||
|
cmake_rem_func ./bin/blob-inspector
|
||||||
|
cmake_rem_func ./bin/blob-inspector/test
|
||||||
|
cmake_rem_func ./bin/schema-dumper
|
||||||
cmake_rem_func ./src
|
cmake_rem_func ./src
|
||||||
cmake_rem_func ./src/amqp
|
cmake_rem_func ./src/amqp
|
||||||
cmake_rem_func ./src/amqp/test
|
cmake_rem_func ./src/amqp/test
|
||||||
|
@ -2,5 +2,4 @@ include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src)
|
|||||||
|
|
||||||
ADD_SUBDIRECTORY (proton)
|
ADD_SUBDIRECTORY (proton)
|
||||||
ADD_SUBDIRECTORY (amqp)
|
ADD_SUBDIRECTORY (amqp)
|
||||||
ADD_SUBDIRECTORY (serialiser)
|
|
||||||
|
|
||||||
|
@ -1,30 +1,42 @@
|
|||||||
include_directories (descriptors)
|
include_directories (schema/descriptors)
|
||||||
|
include_directories (schema/field-types)
|
||||||
|
include_directories (schema/described-types)
|
||||||
include_directories (schema)
|
include_directories (schema)
|
||||||
include_directories (reader)
|
include_directories (reader)
|
||||||
include_directories (.)
|
include_directories (.)
|
||||||
|
|
||||||
set (amqp_sources
|
set (amqp_schema_sources
|
||||||
CompositeFactory.cxx
|
schema/descriptors/AMQPDescriptor.cxx
|
||||||
descriptors/AMQPDescriptor.cxx
|
schema/descriptors/AMQPDescriptors.cxx
|
||||||
descriptors/AMQPDescriptors.cxx
|
schema/descriptors/AMQPDescriptorRegistory.cxx
|
||||||
descriptors/AMQPDescriptorRegistory.cxx
|
schema/descriptors/corda-descriptors/FieldDescriptor.cxx
|
||||||
descriptors/corda-descriptors/FieldDescriptor.cxx
|
schema/descriptors/corda-descriptors/SchemaDescriptor.cxx
|
||||||
descriptors/corda-descriptors/SchemaDescriptor.cxx
|
schema/descriptors/corda-descriptors/ObjectDescriptor.cxx
|
||||||
descriptors/corda-descriptors/ObjectDescriptor.cxx
|
schema/descriptors/corda-descriptors/ChoiceDescriptor.cxx
|
||||||
descriptors/corda-descriptors/ChoiceDescriptor.cxx
|
schema/descriptors/corda-descriptors/EnvelopeDescriptor.cxx
|
||||||
descriptors/corda-descriptors/EnvelopeDescriptor.cxx
|
schema/descriptors/corda-descriptors/CompositeDescriptor.cxx
|
||||||
descriptors/corda-descriptors/CompositeDescriptor.cxx
|
schema/descriptors/corda-descriptors/RestrictedDescriptor.cxx
|
||||||
descriptors/corda-descriptors/RestrictedDescriptor.cxx
|
schema/field-types/Field.cxx
|
||||||
schema/Field.cxx
|
schema/field-types/PrimitiveField.cxx
|
||||||
schema/Schema.cxx
|
schema/field-types/CompositeField.cxx
|
||||||
schema/Choice.cxx
|
schema/field-types/RestrictedField.cxx
|
||||||
schema/Envelope.cxx
|
schema/field-types/ArrayField.cxx
|
||||||
schema/Composite.cxx
|
schema/described-types/Schema.cxx
|
||||||
schema/Descriptor.cxx
|
schema/described-types/Choice.cxx
|
||||||
schema/AMQPTypeNotation.cxx
|
schema/described-types/Envelope.cxx
|
||||||
|
schema/described-types/Composite.cxx
|
||||||
|
schema/described-types/Descriptor.cxx
|
||||||
schema/restricted-types/Restricted.cxx
|
schema/restricted-types/Restricted.cxx
|
||||||
schema/restricted-types/List.cxx
|
schema/restricted-types/List.cxx
|
||||||
schema/restricted-types/Enum.cxx
|
schema/restricted-types/Enum.cxx
|
||||||
|
schema/restricted-types/Map.cxx
|
||||||
|
schema/restricted-types/Array.cxx
|
||||||
|
schema/AMQPTypeNotation.cxx
|
||||||
|
schema/Descriptors.cxx
|
||||||
|
)
|
||||||
|
|
||||||
|
set (amqp_sources
|
||||||
|
CompositeFactory.cxx
|
||||||
reader/Reader.cxx
|
reader/Reader.cxx
|
||||||
reader/PropertyReader.cxx
|
reader/PropertyReader.cxx
|
||||||
reader/CompositeReader.cxx
|
reader/CompositeReader.cxx
|
||||||
@ -34,10 +46,12 @@ set (amqp_sources
|
|||||||
reader/property-readers/BoolPropertyReader.cxx
|
reader/property-readers/BoolPropertyReader.cxx
|
||||||
reader/property-readers/DoublePropertyReader.cxx
|
reader/property-readers/DoublePropertyReader.cxx
|
||||||
reader/property-readers/StringPropertyReader.cxx
|
reader/property-readers/StringPropertyReader.cxx
|
||||||
|
reader/restricted-readers/MapReader.cxx
|
||||||
reader/restricted-readers/ListReader.cxx
|
reader/restricted-readers/ListReader.cxx
|
||||||
|
reader/restricted-readers/ArrayReader.cxx
|
||||||
reader/restricted-readers/EnumReader.cxx
|
reader/restricted-readers/EnumReader.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_LIBRARY ( amqp ${amqp_sources} )
|
ADD_LIBRARY ( amqp ${amqp_sources} ${amqp_schema_sources})
|
||||||
|
|
||||||
ADD_SUBDIRECTORY (test)
|
ADD_SUBDIRECTORY (test)
|
||||||
|
@ -16,11 +16,15 @@
|
|||||||
#include "reader/Reader.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/MapReader.h"
|
||||||
#include "reader/restricted-readers/ListReader.h"
|
#include "reader/restricted-readers/ListReader.h"
|
||||||
|
#include "reader/restricted-readers/ArrayReader.h"
|
||||||
#include "reader/restricted-readers/EnumReader.h"
|
#include "reader/restricted-readers/EnumReader.h"
|
||||||
|
|
||||||
|
#include "schema/restricted-types/Map.h"
|
||||||
#include "schema/restricted-types/List.h"
|
#include "schema/restricted-types/List.h"
|
||||||
#include "schema/restricted-types/Enum.h"
|
#include "schema/restricted-types/Enum.h"
|
||||||
|
#include "schema/restricted-types/Array.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -40,11 +44,12 @@ namespace {
|
|||||||
|
|
||||||
if (it == map_.end()) {
|
if (it == map_.end()) {
|
||||||
DBG ("ComputeIfAbsent \"" << k_ << "\" - missing" << std::endl); // NOLINT
|
DBG ("ComputeIfAbsent \"" << k_ << "\" - missing" << std::endl); // NOLINT
|
||||||
map_[k_] = std::move(f_());
|
map_[k_] = std::move (f_());
|
||||||
DBG (" \"" << k_ << "\" - RTN: " << map_[k_]->name() << " : " << map_[k_]->type()
|
DBG (" \"" << k_ << "\" - RTN: " << map_[k_]->name() << " : " << map_[k_]->type()
|
||||||
<< std::endl); // NOLINT
|
<< std::endl); // NOLINT
|
||||||
assert (map_[k_]);
|
assert (map_[k_]);
|
||||||
assert (map_[k_] != nullptr);
|
assert (map_[k_] != nullptr);
|
||||||
|
DBG (k_ << " =?= " << map_[k_]->type() << std::endl);
|
||||||
assert (k_ == map_[k_]->type());
|
assert (k_ == map_[k_]->type());
|
||||||
|
|
||||||
return map_[k_];
|
return map_[k_];
|
||||||
@ -70,18 +75,20 @@ namespace {
|
|||||||
*
|
*
|
||||||
* Walk through the types in a Schema and produce readers for them.
|
* Walk through the types in a Schema and produce readers for them.
|
||||||
*
|
*
|
||||||
* We are making the large assumption that the contents of [schema_]
|
* We are making the assumption that the contents of [schema_]
|
||||||
* are strictly ordered by dependency so we can construct types
|
* are strictly ordered by dependency so we can construct types
|
||||||
* as we go without needing to provide look ahead for types
|
* as we go without needing to provide look ahead for types
|
||||||
* we haven't built yet
|
* we haven't built yet.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
amqp::internal::
|
amqp::internal::
|
||||||
CompositeFactory::process (const SchemaType & schema_) {
|
CompositeFactory::process (const SchemaType & schema_) {
|
||||||
|
DBG ("process schema" << std::endl);
|
||||||
|
|
||||||
for (const auto & i : dynamic_cast<const schema::Schema &>(schema_)) {
|
for (const auto & i : dynamic_cast<const schema::Schema &>(schema_)) {
|
||||||
for (const auto & j : i) {
|
for (const auto & j : i) {
|
||||||
process(*j);
|
process (*j);
|
||||||
m_readersByDescriptor[j->descriptor()] = m_readersByType[j->name()];
|
m_readersByDescriptor[j->descriptor()] = m_readersByType[j->name()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,17 +99,19 @@ 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_)
|
||||||
{
|
{
|
||||||
|
DBG ("process::" << schema_.name() << std::endl);
|
||||||
|
|
||||||
return computeIfAbsent<reader::Reader> (
|
return computeIfAbsent<reader::Reader> (
|
||||||
m_readersByType,
|
m_readersByType,
|
||||||
schema_.name(),
|
schema_.name(),
|
||||||
[& 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 schema::AMQPTypeNotation::composite_t : {
|
||||||
return processComposite (schema_);
|
return processComposite (schema_);
|
||||||
}
|
}
|
||||||
case amqp::internal::schema::AMQPTypeNotation::Restricted : {
|
case schema::AMQPTypeNotation::restricted_t : {
|
||||||
return processRestricted (schema_);
|
return processRestricted (schema_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,48 +125,38 @@ amqp::internal::
|
|||||||
CompositeFactory::processComposite (
|
CompositeFactory::processComposite (
|
||||||
const amqp::internal::schema::AMQPTypeNotation & type_
|
const amqp::internal::schema::AMQPTypeNotation & type_
|
||||||
) {
|
) {
|
||||||
|
DBG ("processComposite - " << type_.name() << std::endl);
|
||||||
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 schema::Composite &> (
|
||||||
type_).fields();
|
type_).fields();
|
||||||
|
|
||||||
readers.reserve(fields.size());
|
readers.reserve (fields.size());
|
||||||
|
|
||||||
for (const auto & field : fields) {
|
for (const auto & field : fields) {
|
||||||
DBG (" Field: " << field->name() << ": " << field->type() << std::endl); // NOLINT
|
DBG (" Field: " << field->name() << ": \"" << field->type()
|
||||||
|
<< "\" {" << field->resolvedType() << "} "
|
||||||
|
<< field->fieldType() << std::endl); // NOLINT
|
||||||
|
|
||||||
switch (field->fieldType()) {
|
decltype (m_readersByType)::mapped_type reader;
|
||||||
case schema::FieldType::PrimitiveProperty : {
|
|
||||||
auto reader = computeIfAbsent<reader::Reader>(
|
|
||||||
m_readersByType,
|
|
||||||
field->type(),
|
|
||||||
[&field]() -> std::shared_ptr<reader::PropertyReader> {
|
|
||||||
return reader::PropertyReader::make(field);
|
|
||||||
});
|
|
||||||
|
|
||||||
assert (reader);
|
if (field->primitive()) {
|
||||||
readers.emplace_back(reader);
|
reader = computeIfAbsent<reader::Reader> (
|
||||||
assert (readers.back().lock());
|
m_readersByType,
|
||||||
break;
|
field->resolvedType(),
|
||||||
}
|
[&field]() -> std::shared_ptr<reader::PropertyReader> {
|
||||||
case amqp::internal::schema::FieldType::CompositeProperty : {
|
return reader::PropertyReader::make (field);
|
||||||
auto reader = m_readersByType[field->type()];
|
});
|
||||||
|
}
|
||||||
assert (reader);
|
else {
|
||||||
readers.emplace_back(reader);
|
// Insertion sorting ensures any type we depend on will have
|
||||||
assert (readers.back().lock());
|
// already been created and thus exist in the map
|
||||||
break;
|
reader = m_readersByType[field->resolvedType()];
|
||||||
}
|
|
||||||
case schema::FieldType::RestrictedProperty : {
|
|
||||||
auto reader = m_readersByType[field->requires().front()];
|
|
||||||
|
|
||||||
assert (reader);
|
|
||||||
readers.emplace_back(reader);
|
|
||||||
assert (readers.back().lock());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
assert (reader);
|
||||||
|
readers.emplace_back (reader);
|
||||||
assert (readers.back().lock());
|
assert (readers.back().lock());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,8 +173,55 @@ CompositeFactory::processEnum (
|
|||||||
DBG ("Processing Enum - " << enum_.name() << std::endl); // NOLINT
|
DBG ("Processing Enum - " << enum_.name() << std::endl); // NOLINT
|
||||||
|
|
||||||
return std::make_shared<reader::EnumReader> (
|
return std::make_shared<reader::EnumReader> (
|
||||||
enum_.name(),
|
enum_.name(),
|
||||||
enum_.makeChoices());
|
enum_.makeChoices());
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::shared_ptr<amqp::internal::reader::Reader>
|
||||||
|
amqp::internal::
|
||||||
|
CompositeFactory::fetchReaderForRestricted (const std::string & type_) {
|
||||||
|
decltype(m_readersByType)::mapped_type rtn;
|
||||||
|
|
||||||
|
DBG ("fetchReaderForRestricted - " << type_ << std::endl);
|
||||||
|
|
||||||
|
if (schema::Field::typeIsPrimitive(type_)) {
|
||||||
|
DBG ("It's primitive" << std::endl);
|
||||||
|
rtn = computeIfAbsent<reader::Reader>(
|
||||||
|
m_readersByType,
|
||||||
|
type_,
|
||||||
|
[& type_]() -> std::shared_ptr<reader::PropertyReader> {
|
||||||
|
return reader::PropertyReader::make (type_);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
rtn = m_readersByType[type_];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rtn) {
|
||||||
|
throw std::runtime_error ("Missing type in map");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::shared_ptr<amqp::internal::reader::Reader>
|
||||||
|
amqp::internal::
|
||||||
|
CompositeFactory::processMap (
|
||||||
|
const amqp::internal::schema::Map & map_
|
||||||
|
) {
|
||||||
|
DBG ("Processing Map - "
|
||||||
|
<< map_.mapOf().first.get() << " "
|
||||||
|
<< map_.mapOf().second.get() << std::endl); // NOLINT
|
||||||
|
|
||||||
|
const auto types = map_.mapOf();
|
||||||
|
|
||||||
|
return std::make_shared<reader::MapReader> (
|
||||||
|
map_.name(),
|
||||||
|
fetchReaderForRestricted (types.first),
|
||||||
|
fetchReaderForRestricted (types.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -187,22 +233,23 @@ CompositeFactory::processList (
|
|||||||
) {
|
) {
|
||||||
DBG ("Processing List - " << list_.listOf() << std::endl); // NOLINT
|
DBG ("Processing List - " << list_.listOf() << std::endl); // NOLINT
|
||||||
|
|
||||||
if (schema::Field::typeIsPrimitive (list_.listOf())) {
|
return std::make_shared<reader::ListReader> (
|
||||||
DBG (" List of Primitives" << std::endl); // NOLINT
|
list_.name(),
|
||||||
auto reader = computeIfAbsent<reader::Reader>(
|
fetchReaderForRestricted (list_.listOf()));
|
||||||
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::processArray (
|
||||||
|
const amqp::internal::schema::Array & array_
|
||||||
|
) {
|
||||||
|
DBG ("Processing Array - " << array_.name() << " " << array_.arrayOf() << std::endl); // NOLINT
|
||||||
|
|
||||||
|
return std::make_shared<reader::ArrayReader> (
|
||||||
|
array_.name(),
|
||||||
|
fetchReaderForRestricted (array_.arrayOf()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -213,24 +260,29 @@ CompositeFactory::processRestricted (
|
|||||||
const amqp::internal::schema::AMQPTypeNotation & type_)
|
const amqp::internal::schema::AMQPTypeNotation & type_)
|
||||||
{
|
{
|
||||||
DBG ("processRestricted - " << type_.name() << std::endl); // NOLINT
|
DBG ("processRestricted - " << type_.name() << std::endl); // NOLINT
|
||||||
const auto & restricted = dynamic_cast<const amqp::internal::schema::Restricted &> (
|
const auto & restricted = dynamic_cast<const schema::Restricted &> (
|
||||||
type_);
|
type_);
|
||||||
|
|
||||||
switch (restricted.restrictedType()) {
|
switch (restricted.restrictedType()) {
|
||||||
case schema::Restricted::RestrictedTypes::List : {
|
case schema::Restricted::RestrictedTypes::list_t : {
|
||||||
return processList (
|
return processList (
|
||||||
dynamic_cast<const amqp::internal::schema::List &> (restricted));
|
dynamic_cast<const schema::List &> (restricted));
|
||||||
}
|
}
|
||||||
case schema::Restricted::RestrictedTypes::Enum : {
|
case schema::Restricted::RestrictedTypes::enum_t : {
|
||||||
return processEnum (
|
return processEnum (
|
||||||
dynamic_cast<const amqp::internal::schema::Enum &> (restricted));
|
dynamic_cast<const schema::Enum &> (restricted));
|
||||||
}
|
}
|
||||||
case schema::Restricted::RestrictedTypes::Map :{
|
case schema::Restricted::RestrictedTypes::map_t : {
|
||||||
throw std::runtime_error ("Cannot process maps");
|
return processMap (
|
||||||
|
dynamic_cast<const schema::Map &> (restricted));
|
||||||
|
}
|
||||||
|
case schema::Restricted::RestrictedTypes::array_t : {
|
||||||
|
DBG (" array_t" << std::endl);
|
||||||
|
return processArray (
|
||||||
|
dynamic_cast<const schema::Array &> (restricted));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DBG (" ProcessRestricted: Returning nullptr"); // NOLINT
|
DBG (" ProcessRestricted: Returning nullptr"); // NOLINT
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,12 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include "amqp/ICompositeFactory.h"
|
#include "amqp/ICompositeFactory.h"
|
||||||
#include "amqp/schema/Schema.h"
|
#include "amqp/schema/described-types/Schema.h"
|
||||||
#include "amqp/schema/Envelope.h"
|
#include "amqp/schema/described-types/Envelope.h"
|
||||||
#include "amqp/schema/Composite.h"
|
#include "amqp/schema/described-types/Composite.h"
|
||||||
#include "amqp/reader/CompositeReader.h"
|
#include "amqp/reader/CompositeReader.h"
|
||||||
|
#include "amqp/schema/restricted-types/Map.h"
|
||||||
|
#include "amqp/schema/restricted-types/Array.h"
|
||||||
#include "amqp/schema/restricted-types/List.h"
|
#include "amqp/schema/restricted-types/List.h"
|
||||||
#include "amqp/schema/restricted-types/Enum.h"
|
#include "amqp/schema/restricted-types/Enum.h"
|
||||||
|
|
||||||
@ -56,6 +58,15 @@ namespace amqp::internal {
|
|||||||
|
|
||||||
std::shared_ptr<reader::Reader> processEnum (
|
std::shared_ptr<reader::Reader> processEnum (
|
||||||
const schema::Enum &);
|
const schema::Enum &);
|
||||||
|
|
||||||
|
std::shared_ptr<reader::Reader> processMap (
|
||||||
|
const schema::Map &);
|
||||||
|
|
||||||
|
std::shared_ptr<reader::Reader> processArray (
|
||||||
|
const schema::Array &);
|
||||||
|
|
||||||
|
decltype(m_readersByType)::mapped_type
|
||||||
|
fetchReaderForRestricted (const std::string &);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,156 +0,0 @@
|
|||||||
#include "AMQPDescriptorRegistory.h"
|
|
||||||
#include "AMQPDescriptors.h"
|
|
||||||
|
|
||||||
#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"
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <climits>
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
namespace amqp::internal {
|
|
||||||
|
|
||||||
constexpr uint64_t DESCRIPTOR_TOP_32BITS = 0xc562UL << (unsigned int)(32 + 16);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
namespace amqp::internal {
|
|
||||||
|
|
||||||
const int ENVELOPE = 1;
|
|
||||||
const int SCHEMA = 2;
|
|
||||||
const int OBJECT = 3;
|
|
||||||
const int FIELD = 4;
|
|
||||||
const int COMPOSITE_TYPE = 5;
|
|
||||||
const int RESTRICTED_TYPE = 6;
|
|
||||||
const int CHOICE = 7;
|
|
||||||
const int REFERENCED_OBJECT = 8;
|
|
||||||
const int TRANSFORM_SCHEMA = 9;
|
|
||||||
const int TRANSFORM_ELEMENT = 10;
|
|
||||||
const int TRANSFORM_ELEMENT_KEY = 11;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
namespace amqp {
|
|
||||||
|
|
||||||
std::map<uint64_t, std::shared_ptr<internal::AMQPDescriptor>>
|
|
||||||
AMQPDescriptorRegistory = {
|
|
||||||
{
|
|
||||||
22UL,
|
|
||||||
std::make_shared<internal::AMQPDescriptor> ("DESCRIBED", -1)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
1UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::EnvelopeDescriptor> ("ENVELOPE", internal::ENVELOPE)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
2UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::SchemaDescriptor> ("SCHEMA", internal::SCHEMA)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
3UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::ObjectDescriptor> ("OBJECT_DESCRIPTOR", internal::OBJECT)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
4UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::FieldDescriptor> (
|
|
||||||
internal::FieldDescriptor (
|
|
||||||
"FIELD",
|
|
||||||
internal::FIELD))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
5UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::CompositeDescriptor> (
|
|
||||||
internal::CompositeDescriptor (
|
|
||||||
"COMPOSITE_TYPE",
|
|
||||||
internal::COMPOSITE_TYPE))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
6UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::RestrictedDescriptor> (
|
|
||||||
internal::RestrictedDescriptor (
|
|
||||||
"RESTRICTED_TYPE",
|
|
||||||
internal::RESTRICTED_TYPE))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
7UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::ChoiceDescriptor> ("CHOICE", internal::CHOICE)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
8UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::ReferencedObjectDescriptor> (
|
|
||||||
internal::ReferencedObjectDescriptor (
|
|
||||||
"REFERENCED_OBJECT",
|
|
||||||
internal::REFERENCED_OBJECT))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
9UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::TransformSchemaDescriptor> (
|
|
||||||
internal::TransformSchemaDescriptor (
|
|
||||||
"TRANSFORM_SCHEMA",
|
|
||||||
internal::TRANSFORM_SCHEMA))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
10UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::TransformElementDescriptor> (
|
|
||||||
internal::TransformElementDescriptor (
|
|
||||||
"TRANSFORM_ELEMENT",
|
|
||||||
internal::TRANSFORM_ELEMENT))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
11UL | internal::DESCRIPTOR_TOP_32BITS,
|
|
||||||
std::make_shared<internal::TransformElementKeyDescriptor> (
|
|
||||||
internal::TransformElementKeyDescriptor (
|
|
||||||
"TRANSFORM_ELEMENT_KEY",
|
|
||||||
internal::TRANSFORM_ELEMENT_KEY))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
amqp::stripCorda (uint64_t id) {
|
|
||||||
return static_cast<uint32_t>(id & (uint64_t)UINT_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
std::string
|
|
||||||
amqp::describedToString (uint64_t val_) {
|
|
||||||
switch (val_) {
|
|
||||||
case (1UL | internal::DESCRIPTOR_TOP_32BITS) : return "ENVELOPE";
|
|
||||||
case (2UL | internal::DESCRIPTOR_TOP_32BITS) : return "SCHEMA";
|
|
||||||
case (3UL | internal::DESCRIPTOR_TOP_32BITS) : return "OBJECT_DESCRIPTOR";
|
|
||||||
case (4UL | internal::DESCRIPTOR_TOP_32BITS) : return "FIELD";
|
|
||||||
case (5UL | internal::DESCRIPTOR_TOP_32BITS) : return "COMPOSITE_TYPE";
|
|
||||||
case (6UL | internal::DESCRIPTOR_TOP_32BITS) : return "RESTRICTED_TYPE";
|
|
||||||
case (7UL | internal::DESCRIPTOR_TOP_32BITS) : return "CHOICE";
|
|
||||||
case (8UL | internal::DESCRIPTOR_TOP_32BITS) : return "REFERENCED_OBJECT";
|
|
||||||
case (9UL | internal::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_SCHEMA";
|
|
||||||
case (10UL | internal::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_ELEMENT";
|
|
||||||
case (11UL | internal::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_ELEMENT_KEY";
|
|
||||||
default : return "UNKNOWN";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
std::string
|
|
||||||
amqp::describedToString (uint32_t val_) {
|
|
||||||
return describedToString(val_ | internal::DESCRIPTOR_TOP_32BITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
@ -84,12 +84,20 @@ CompositeReader::_dump (
|
|||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_
|
const SchemaType & schema_
|
||||||
) const {
|
) const {
|
||||||
DBG ("Read Composite: " << m_name << " : " << type() << std::endl); // NOLINT
|
DBG ("Read Composite: "
|
||||||
|
<< m_name
|
||||||
|
<< " : "
|
||||||
|
<< type()
|
||||||
|
<< std::endl); // NOLINT
|
||||||
|
|
||||||
proton::is_described (data_);
|
proton::is_described (data_);
|
||||||
proton::auto_enter ae (data_);
|
proton::auto_enter ae (data_);
|
||||||
|
|
||||||
const auto & it = schema_.fromDescriptor (proton::get_symbol<std::string>(data_));
|
const auto & it = schema_.fromDescriptor (
|
||||||
auto & fields = dynamic_cast<schema::Composite &>(*(it->second.get())).fields();
|
proton::get_symbol<std::string>(data_));
|
||||||
|
|
||||||
|
auto & fields = dynamic_cast<schema::Composite &> (
|
||||||
|
*(it->second.get())).fields();
|
||||||
|
|
||||||
assert (fields.size() == m_readers.size());
|
assert (fields.size() == m_readers.size());
|
||||||
|
|
||||||
@ -104,13 +112,14 @@ CompositeReader::_dump (
|
|||||||
|
|
||||||
for (int i (0) ; i < m_readers.size() ; ++i) {
|
for (int i (0) ; i < m_readers.size() ; ++i) {
|
||||||
if (auto l = m_readers[i].lock()) {
|
if (auto l = m_readers[i].lock()) {
|
||||||
DBG (fields[i]->name() << " " << (l ? "true" : "false") << std::endl); // NOLINT
|
DBG (fields[i]->name() << " "
|
||||||
|
<< (l ? "true" : "false") << std::endl); // NOLINT
|
||||||
|
|
||||||
read.emplace_back(l->dump(fields[i]->name(), data_, schema_));
|
read.emplace_back (l->dump (fields[i]->name(), data_, schema_));
|
||||||
} else {
|
} else {
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "null field reader: " << fields[i]->name();
|
s << "null field reader: " << fields[i]->name();
|
||||||
throw std::runtime_error(s.str());
|
throw std::runtime_error (s.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,6 +136,8 @@ CompositeReader::dump (
|
|||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
|
proton::auto_next an (data_);
|
||||||
|
|
||||||
return std::make_unique<TypedPair<sVec<uPtr<amqp::reader::IValue>>>> (
|
return std::make_unique<TypedPair<sVec<uPtr<amqp::reader::IValue>>>> (
|
||||||
name_,
|
name_,
|
||||||
_dump(data_, schema_));
|
_dump(data_, schema_));
|
||||||
@ -143,6 +154,8 @@ CompositeReader::dump (
|
|||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
|
proton::auto_next an (data_);
|
||||||
|
|
||||||
return std::make_unique<TypedSingle<sVec<uPtr<amqp::reader::IValue>>>> (
|
return std::make_unique<TypedSingle<sVec<uPtr<amqp::reader::IValue>>>> (
|
||||||
_dump (data_, schema_));
|
_dump (data_, schema_));
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <any>
|
#include <any>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <amqp/schema/Schema.h>
|
#include <amqp/schema/described-types/Schema.h>
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
@ -54,11 +54,12 @@ namespace {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Static methods
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* Static factory method
|
|
||||||
*/
|
|
||||||
std::shared_ptr<amqp::internal::reader::PropertyReader>
|
std::shared_ptr<amqp::internal::reader::PropertyReader>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
PropertyReader::make (const FieldPtr & field_) {
|
PropertyReader::make (const FieldPtr & field_) {
|
||||||
@ -75,4 +76,10 @@ PropertyReader::make (const std::string & type_) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::shared_ptr<amqp::internal::reader::PropertyReader>
|
||||||
|
amqp::internal::reader::
|
||||||
|
PropertyReader::make (const internal::schema::Field & field_) {
|
||||||
|
return propertyMap[field_.type()]();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "Reader.h"
|
#include "Reader.h"
|
||||||
|
|
||||||
#include "amqp/schema/Field.h"
|
#include "amqp/schema/field-types/Field.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -18,13 +18,14 @@ namespace amqp::internal::reader {
|
|||||||
/**
|
/**
|
||||||
* Static Factory method for creating appropriate derived types
|
* Static Factory method for creating appropriate derived types
|
||||||
*/
|
*/
|
||||||
|
static std::shared_ptr<PropertyReader> make (const internal::schema::Field &);
|
||||||
static std::shared_ptr<PropertyReader> make (const FieldPtr &);
|
static std::shared_ptr<PropertyReader> make (const FieldPtr &);
|
||||||
static std::shared_ptr<PropertyReader> make (const std::string &);
|
static std::shared_ptr<PropertyReader> make (const std::string &);
|
||||||
|
|
||||||
PropertyReader() = default;
|
PropertyReader() = default;
|
||||||
~PropertyReader() override = default;
|
~PropertyReader() override = default;
|
||||||
|
|
||||||
std::string readString(pn_data_t *) const override = 0;
|
std::string readString (pn_data_t *) const override = 0;
|
||||||
|
|
||||||
std::any read (pn_data_t *) const override = 0;
|
std::any read (pn_data_t *) const override = 0;
|
||||||
|
|
||||||
|
@ -56,9 +56,11 @@ namespace {
|
|||||||
{
|
{
|
||||||
Auto am (name_, rtn);
|
Auto am (name_, rtn);
|
||||||
|
|
||||||
rtn << (*(begin_))->dump();
|
if (begin_ != end_) {
|
||||||
for (auto it(std::next(begin_)) ; it != end_; ++it) {
|
rtn << (*(begin_))->dump();
|
||||||
rtn << ", " << (*it)->dump();
|
for (auto it(std::next(begin_)); it != end_; ++it) {
|
||||||
|
rtn << ", " << (*it)->dump();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,9 +74,11 @@ namespace {
|
|||||||
{
|
{
|
||||||
Auto am (rtn);
|
Auto am (rtn);
|
||||||
|
|
||||||
rtn << (*(begin_))->dump();
|
if (begin_ != end_) {
|
||||||
for (auto it (std::next(begin_)) ; it != end_; ++it) {
|
rtn << (*(begin_))->dump();
|
||||||
rtn << ", " << (*it)->dump();
|
for (auto it(std::next(begin_)); it != end_; ++it) {
|
||||||
|
rtn << ", " << (*it)->dump();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +89,23 @@ namespace {
|
|||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
|
* amqp::internal::reader::TypedValuePair
|
||||||
*
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
std::string
|
||||||
|
amqp::internal::reader::
|
||||||
|
ValuePair::dump() const {
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << m_key->dump() << " : " << m_value->dump();
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* amqp::internal::reader::TypedPair
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "amqp/schema/Schema.h"
|
#include "amqp/schema/described-types/Schema.h"
|
||||||
#include "amqp/reader/IReader.h"
|
#include "amqp/reader/IReader.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -22,6 +22,19 @@ namespace amqp::internal::reader {
|
|||||||
~Value() override = default;
|
~Value() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A Single represents some value read out of a proton tree that
|
||||||
|
* exists without an association. The canonical example is an
|
||||||
|
* element of a list. The list itself would be a pair,
|
||||||
|
*
|
||||||
|
* e.g. a : [ ]
|
||||||
|
*
|
||||||
|
* but the values of the list
|
||||||
|
*
|
||||||
|
* e.g. a : [ A, B, C ]
|
||||||
|
*
|
||||||
|
* are Singles
|
||||||
|
*/
|
||||||
class Single : public Value {
|
class Single : public Value {
|
||||||
public :
|
public :
|
||||||
std::string dump() const override = 0;
|
std::string dump() const override = 0;
|
||||||
@ -57,13 +70,19 @@ namespace amqp::internal::reader {
|
|||||||
std::string dump() const override;
|
std::string dump() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A Pair represents an association between a property and
|
||||||
|
* the value of the property, i.e. a : b where property
|
||||||
|
* a has value b
|
||||||
|
*/
|
||||||
class Pair : public Value {
|
class Pair : public Value {
|
||||||
protected :
|
protected :
|
||||||
std::string m_property;
|
std::string m_property;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Pair (std::string property_)
|
explicit Pair (std::string property_)
|
||||||
: m_property (std::move (property_))
|
: Value()
|
||||||
|
, m_property (std::move (property_))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Pair() override = default;
|
~Pair() override = default;
|
||||||
@ -104,6 +123,29 @@ namespace amqp::internal::reader {
|
|||||||
std::string dump() const override;
|
std::string dump() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to [Pair] where k : v relationships are modelled. In this
|
||||||
|
* case, however, rather than modelling a property : value relationship
|
||||||
|
* we are modelling a key : value one. The primary difference is that
|
||||||
|
* keys need not be simple strings.
|
||||||
|
*/
|
||||||
|
class ValuePair : public Value {
|
||||||
|
private :
|
||||||
|
uPtr<amqp::reader::IValue> m_key;
|
||||||
|
uPtr<amqp::reader::IValue> m_value;
|
||||||
|
|
||||||
|
public :
|
||||||
|
ValuePair (
|
||||||
|
decltype (m_key) key_,
|
||||||
|
decltype (m_value) value_
|
||||||
|
) : Value ()
|
||||||
|
, m_key (std::move (key_))
|
||||||
|
, m_value (std::move (value_))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
std::string dump() const override;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -116,7 +158,7 @@ template<typename T>
|
|||||||
inline std::string
|
inline std::string
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
TypedSingle<T>::dump() const {
|
TypedSingle<T>::dump() const {
|
||||||
return std::to_string(m_value);
|
return std::to_string (m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -176,7 +218,6 @@ std::string
|
|||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
TypedPair<sList<uPtr<amqp::reader::IValue>>>::dump() const;
|
TypedPair<sList<uPtr<amqp::reader::IValue>>>::dump() const;
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
std::string
|
std::string
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
@ -191,13 +232,23 @@ TypedPair<sList<uPtr<amqp::internal::reader::Pair>>>::dump() const;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal::reader {
|
namespace amqp::internal::reader {
|
||||||
|
|
||||||
using IReader = amqp::reader::IReader<schema::SchemaMap::const_iterator>;
|
using IReader = amqp::reader::IReader<schema::SchemaMap::const_iterator>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface that represents an object that has the ability to consume
|
||||||
|
* the payload of a Corda serialized blob in a way defined by some
|
||||||
|
* prior construction. This construction will usually come from
|
||||||
|
* analysis of the schema, although in the JVM versions it will come
|
||||||
|
* from reflection of the type definitions.
|
||||||
|
*
|
||||||
|
* In other words, when encountering a graph of nodes with values, an
|
||||||
|
* instance of [Reader] will give a sub tree of that graph contextual
|
||||||
|
* meaning.
|
||||||
|
*/
|
||||||
class Reader : public IReader {
|
class Reader : public IReader {
|
||||||
public :
|
public :
|
||||||
~Reader() override = default;
|
~Reader() override = default;
|
||||||
|
@ -31,7 +31,7 @@ BoolPropertyReader::m_type { // NOLINT
|
|||||||
std::any
|
std::any
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
BoolPropertyReader::read (pn_data_t * data_) const {
|
BoolPropertyReader::read (pn_data_t * data_) const {
|
||||||
return std::any (true);
|
return std::any (proton::readAndNext<bool> (data_));
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -29,7 +29,7 @@ DoublePropertyReader::m_type { // NOLINT
|
|||||||
std::any
|
std::any
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
DoublePropertyReader::read (pn_data_t * data_) const {
|
DoublePropertyReader::read (pn_data_t * data_) const {
|
||||||
return std::any (10.0);
|
return std::any { proton::readAndNext<double> (data_) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -45,9 +45,9 @@ DoublePropertyReader::readString (pn_data_t * data_) const {
|
|||||||
uPtr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
DoublePropertyReader::dump (
|
DoublePropertyReader::dump (
|
||||||
const std::string & name_,
|
const std::string & name_,
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
return std::make_unique<TypedPair<std::string>> (
|
return std::make_unique<TypedPair<std::string>> (
|
||||||
name_,
|
name_,
|
||||||
|
@ -37,7 +37,7 @@ IntPropertyReader::m_type { // NOLINT
|
|||||||
std::any
|
std::any
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
IntPropertyReader::read (pn_data_t * data_) const {
|
IntPropertyReader::read (pn_data_t * data_) const {
|
||||||
return std::any (1);
|
return std::any { proton::readAndNext<int> (data_) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -53,9 +53,9 @@ IntPropertyReader::readString (pn_data_t * data_) const {
|
|||||||
uPtr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
IntPropertyReader::dump (
|
IntPropertyReader::dump (
|
||||||
const std::string & name_,
|
const std::string & name_,
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
return std::make_unique<TypedPair<std::string>> (
|
return std::make_unique<TypedPair<std::string>> (
|
||||||
name_,
|
name_,
|
||||||
@ -67,8 +67,8 @@ IntPropertyReader::dump (
|
|||||||
uPtr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
IntPropertyReader::dump (
|
IntPropertyReader::dump (
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
return std::make_unique<TypedSingle<std::string>> (
|
return std::make_unique<TypedSingle<std::string>> (
|
||||||
std::to_string (proton::readAndNext<int> (data_)));
|
std::to_string (proton::readAndNext<int> (data_)));
|
||||||
|
@ -31,7 +31,7 @@ LongPropertyReader::m_type { // NOLINT
|
|||||||
std::any
|
std::any
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
LongPropertyReader::read (pn_data_t * data_) const {
|
LongPropertyReader::read (pn_data_t * data_) const {
|
||||||
return std::any (10L);
|
return std::any { proton::readAndNext<long> (data_) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -47,9 +47,9 @@ LongPropertyReader::readString (pn_data_t * data_) const {
|
|||||||
uPtr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
LongPropertyReader::dump (
|
LongPropertyReader::dump (
|
||||||
const std::string & name_,
|
const std::string & name_,
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
return std::make_unique<TypedPair<std::string>> (
|
return std::make_unique<TypedPair<std::string>> (
|
||||||
name_,
|
name_,
|
||||||
@ -61,8 +61,8 @@ LongPropertyReader::dump (
|
|||||||
uPtr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
LongPropertyReader::dump (
|
LongPropertyReader::dump (
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
return std::make_unique<TypedSingle<std::string>> (
|
return std::make_unique<TypedSingle<std::string>> (
|
||||||
std::to_string (proton::readAndNext<long> (data_)));
|
std::to_string (proton::readAndNext<long> (data_)));
|
||||||
|
@ -33,7 +33,7 @@ StringPropertyReader::m_name { // NOLINT
|
|||||||
std::any
|
std::any
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
StringPropertyReader::read (pn_data_t * data_) const {
|
StringPropertyReader::read (pn_data_t * data_) const {
|
||||||
return std::any ("hello");
|
return std::any { proton::readAndNext<std::string> (data_) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -49,9 +49,9 @@ StringPropertyReader::readString (pn_data_t * data_) const {
|
|||||||
uPtr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
StringPropertyReader::dump (
|
StringPropertyReader::dump (
|
||||||
const std::string & name_,
|
const std::string & name_,
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
const SchemaType & schema_) const
|
const SchemaType & schema_) const
|
||||||
{
|
{
|
||||||
return std::make_unique<TypedPair<std::string>> (
|
return std::make_unique<TypedPair<std::string>> (
|
||||||
name_,
|
name_,
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
#include "ArrayReader.h"
|
||||||
|
|
||||||
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* class ArrayReader
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
amqp::internal::reader::
|
||||||
|
ArrayReader::ArrayReader (
|
||||||
|
std::string type_,
|
||||||
|
std::weak_ptr<Reader> reader_
|
||||||
|
) : RestrictedReader (std::move (type_))
|
||||||
|
, m_reader (std::move (reader_))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
amqp::internal::schema::Restricted::RestrictedTypes
|
||||||
|
amqp::internal::reader::
|
||||||
|
ArrayReader::restrictedType() const {
|
||||||
|
return internal::schema::Restricted::RestrictedTypes::array_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uPtr<amqp::reader::IValue>
|
||||||
|
amqp::internal::reader::
|
||||||
|
ArrayReader::dump (
|
||||||
|
const std::string & name_,
|
||||||
|
pn_data_t * data_,
|
||||||
|
const SchemaType & schema_
|
||||||
|
) const {
|
||||||
|
proton::auto_next an (data_);
|
||||||
|
|
||||||
|
return std::make_unique<TypedPair<sList<uPtr<amqp::reader::IValue>>>>(
|
||||||
|
name_,
|
||||||
|
dump_ (data_, schema_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uPtr<amqp::reader::IValue>
|
||||||
|
amqp::internal::reader::
|
||||||
|
ArrayReader::dump(
|
||||||
|
pn_data_t * data_,
|
||||||
|
const SchemaType & schema_
|
||||||
|
) const {
|
||||||
|
proton::auto_next an (data_);
|
||||||
|
|
||||||
|
return std::make_unique<TypedSingle<sList<uPtr<amqp::reader::IValue>>>>(
|
||||||
|
dump_ (data_, schema_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
sList<uPtr<amqp::reader::IValue>>
|
||||||
|
amqp::internal::reader::
|
||||||
|
ArrayReader::dump_(
|
||||||
|
pn_data_t * data_,
|
||||||
|
const SchemaType & schema_
|
||||||
|
) const {
|
||||||
|
proton::is_described (data_);
|
||||||
|
|
||||||
|
decltype (dump_ (data_, schema_)) read;
|
||||||
|
|
||||||
|
{
|
||||||
|
proton::auto_enter ae (data_);
|
||||||
|
schema_.fromDescriptor (proton::readAndNext<std::string>(data_));
|
||||||
|
|
||||||
|
{
|
||||||
|
proton::auto_list_enter ale (data_, true);
|
||||||
|
|
||||||
|
for (size_t i { 0 } ; i < ale.elements() ; ++i) {
|
||||||
|
read.emplace_back (m_reader.lock()->dump (data_, schema_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#include "RestrictedReader.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
namespace amqp::internal::reader {
|
||||||
|
|
||||||
|
class ArrayReader : public RestrictedReader {
|
||||||
|
private :
|
||||||
|
// How to read the underlying types
|
||||||
|
std::weak_ptr<Reader> m_reader;
|
||||||
|
|
||||||
|
std::list<uPtr<amqp::reader::IValue>> dump_(
|
||||||
|
pn_data_t *,
|
||||||
|
const SchemaType &) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cope with the fact Java can box primitives
|
||||||
|
*/
|
||||||
|
std::string m_primType;
|
||||||
|
|
||||||
|
public :
|
||||||
|
ArrayReader (std::string, std::weak_ptr<Reader>);
|
||||||
|
|
||||||
|
~ArrayReader() final = default;
|
||||||
|
|
||||||
|
internal::schema::Restricted::RestrictedTypes restrictedType() const;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -1,7 +1,8 @@
|
|||||||
#include "EnumReader.h"
|
#include "EnumReader.h"
|
||||||
|
|
||||||
#include "amqp/reader/IReader.h"
|
#include "amqp/reader/IReader.h"
|
||||||
#include "amqp/descriptors/AMQPDescriptorRegistory.h"
|
#include "amqp/schema/Descriptors.h"
|
||||||
|
#include "amqp/schema/descriptors/AMQPDescriptorRegistory.h"
|
||||||
#include "proton/proton_wrapper.h"
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -19,6 +20,7 @@ EnumReader::EnumReader (
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
getValue (pn_data_t * data_) {
|
getValue (pn_data_t * data_) {
|
||||||
proton::is_described (data_);
|
proton::is_described (data_);
|
||||||
@ -34,7 +36,7 @@ namespace {
|
|||||||
*/
|
*/
|
||||||
if (pn_data_type (data_) == PN_ULONG) {
|
if (pn_data_type (data_) == PN_ULONG) {
|
||||||
if (amqp::stripCorda(pn_data_get_ulong(data_)) ==
|
if (amqp::stripCorda(pn_data_get_ulong(data_)) ==
|
||||||
amqp::internal::REFERENCED_OBJECT
|
amqp::schema::descriptors::REFERENCED_OBJECT
|
||||||
) {
|
) {
|
||||||
throw std::runtime_error (
|
throw std::runtime_error (
|
||||||
"Currently don't support referenced objects");
|
"Currently don't support referenced objects");
|
||||||
@ -54,9 +56,7 @@ namespace {
|
|||||||
* here I'll forget its even a thing
|
* here I'll forget its even a thing
|
||||||
*/
|
*/
|
||||||
// auto idx = proton::readAndNext<int>(data_);
|
// auto idx = proton::readAndNext<int>(data_);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +89,6 @@ EnumReader::dump(
|
|||||||
proton::is_described (data_);
|
proton::is_described (data_);
|
||||||
|
|
||||||
return std::make_unique<TypedSingle<std::string>> (getValue(data_));
|
return std::make_unique<TypedSingle<std::string>> (getValue(data_));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
amqp::internal::schema::Restricted::RestrictedTypes
|
amqp::internal::schema::Restricted::RestrictedTypes
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
ListReader::restrictedType() const {
|
ListReader::restrictedType() const {
|
||||||
return internal::schema::Restricted::RestrictedTypes::List;
|
return internal::schema::Restricted::RestrictedTypes::list_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
std::unique_ptr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
ListReader::dump (
|
ListReader::dump (
|
||||||
const std::string & name_,
|
const std::string & name_,
|
||||||
@ -32,7 +32,7 @@ ListReader::dump (
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
std::unique_ptr<amqp::reader::IValue>
|
uPtr<amqp::reader::IValue>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
ListReader::dump(
|
ListReader::dump(
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
@ -46,7 +46,7 @@ ListReader::dump(
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
std::list<std::unique_ptr<amqp::reader::IValue>>
|
sList<uPtr<amqp::reader::IValue>>
|
||||||
amqp::internal::reader::
|
amqp::internal::reader::
|
||||||
ListReader::dump_(
|
ListReader::dump_(
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
@ -54,7 +54,7 @@ ListReader::dump_(
|
|||||||
) const {
|
) const {
|
||||||
proton::is_described (data_);
|
proton::is_described (data_);
|
||||||
|
|
||||||
std::list<std::unique_ptr<amqp::reader::IValue>> read;
|
decltype (dump_(data_, schema_)) read;
|
||||||
|
|
||||||
{
|
{
|
||||||
proton::auto_enter ae (data_);
|
proton::auto_enter ae (data_);
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
#include "MapReader.h"
|
||||||
|
|
||||||
|
#include "Reader.h"
|
||||||
|
#include "amqp/reader/IReader.h"
|
||||||
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
amqp::internal::schema::Restricted::RestrictedTypes
|
||||||
|
amqp::internal::reader::
|
||||||
|
MapReader::restrictedType() const {
|
||||||
|
return schema::Restricted::Restricted::map_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
sVec<uPtr<amqp::reader::IValue>>
|
||||||
|
amqp::internal::reader::
|
||||||
|
MapReader::dump_(
|
||||||
|
pn_data_t * data_,
|
||||||
|
const SchemaType & schema_
|
||||||
|
) const {
|
||||||
|
proton::is_described (data_);
|
||||||
|
proton::auto_enter ae (data_);
|
||||||
|
|
||||||
|
// gloss over fetching the descriptor from the schema since
|
||||||
|
// we don't need it, we know the types this is a reader for
|
||||||
|
// and don't need context from the schema as there isn't
|
||||||
|
// any. Maps have a Key and a Value, they aren't named
|
||||||
|
// parameters, unlike composite types.
|
||||||
|
schema_.fromDescriptor (proton::readAndNext<std::string>(data_));
|
||||||
|
|
||||||
|
{
|
||||||
|
proton::auto_map_enter am (data_, true);
|
||||||
|
|
||||||
|
decltype (dump_(data_, schema_)) rtn;
|
||||||
|
rtn.reserve (am.elements() / 2);
|
||||||
|
|
||||||
|
for (int i {0} ; i < am.elements() ; i += 2) {
|
||||||
|
rtn.emplace_back (
|
||||||
|
std::make_unique<ValuePair> (
|
||||||
|
m_keyReader.lock()->dump (data_, schema_),
|
||||||
|
m_valueReader.lock()->dump (data_, schema_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uPtr<amqp::reader::IValue>
|
||||||
|
amqp::internal::reader::
|
||||||
|
MapReader::dump(
|
||||||
|
const std::string & name_,
|
||||||
|
pn_data_t * data_,
|
||||||
|
const SchemaType & schema_
|
||||||
|
) const {
|
||||||
|
proton::auto_next an (data_);
|
||||||
|
|
||||||
|
return std::make_unique<TypedPair<sVec<uPtr<amqp::reader::IValue>>>>(
|
||||||
|
name_,
|
||||||
|
dump_ (data_, schema_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::unique_ptr<amqp::reader::IValue>
|
||||||
|
amqp::internal::reader::
|
||||||
|
MapReader::dump(
|
||||||
|
pn_data_t * data_,
|
||||||
|
const SchemaType & schema_
|
||||||
|
) const {
|
||||||
|
proton::auto_next an (data_);
|
||||||
|
|
||||||
|
return std::make_unique<TypedSingle<sVec<uPtr<amqp::reader::IValue>>>>(
|
||||||
|
dump_ (data_, schema_));
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
#include "RestrictedReader.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
namespace amqp::internal::reader {
|
||||||
|
|
||||||
|
class MapReader : public RestrictedReader {
|
||||||
|
private :
|
||||||
|
// How to read the underlying types
|
||||||
|
std::weak_ptr<Reader> m_keyReader;
|
||||||
|
std::weak_ptr<Reader> m_valueReader;
|
||||||
|
|
||||||
|
sVec<uPtr<amqp::reader::IValue>> dump_(
|
||||||
|
pn_data_t *,
|
||||||
|
const SchemaType &) const;
|
||||||
|
|
||||||
|
public :
|
||||||
|
MapReader (
|
||||||
|
const std::string & type_,
|
||||||
|
std::weak_ptr<Reader> keyReader_,
|
||||||
|
std::weak_ptr<Reader> valueReader_
|
||||||
|
) : RestrictedReader (type_)
|
||||||
|
, m_keyReader (std::move (keyReader_))
|
||||||
|
, m_valueReader (std::move (valueReader_))
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~MapReader() final = default;
|
||||||
|
|
||||||
|
internal::schema::Restricted::RestrictedTypes restrictedType() const;
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "colours.h"
|
#include "colours.h"
|
||||||
|
|
||||||
#include "Composite.h"
|
#include "amqp/schema/described-types/Composite.h"
|
||||||
#include "amqp/schema/restricted-types/Restricted.h"
|
#include "amqp/schema/restricted-types/Restricted.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -25,11 +25,11 @@ namespace amqp::internal::schema {
|
|||||||
std::ostream &
|
std::ostream &
|
||||||
operator << (std::ostream & stream_, const AMQPTypeNotation & clazz_) {
|
operator << (std::ostream & stream_, const AMQPTypeNotation & clazz_) {
|
||||||
switch (clazz_.type()) {
|
switch (clazz_.type()) {
|
||||||
case AMQPTypeNotation::Type::Composite : {
|
case AMQPTypeNotation::Type::composite_t : {
|
||||||
stream_ << dynamic_cast<const Composite &>(clazz_);
|
stream_ << dynamic_cast<const Composite &>(clazz_);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AMQPTypeNotation::Type::Restricted : {
|
case AMQPTypeNotation::Type::restricted_t : {
|
||||||
stream_ << dynamic_cast<const Restricted &>(clazz_);
|
stream_ << dynamic_cast<const Restricted &>(clazz_);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#include "Descriptor.h"
|
#include "amqp/schema/described-types/Descriptor.h"
|
||||||
#include "OrderedTypeNotations.h"
|
#include "OrderedTypeNotations.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -37,16 +37,16 @@ namespace amqp::internal::schema {
|
|||||||
std::ostream &,
|
std::ostream &,
|
||||||
const AMQPTypeNotation &);
|
const AMQPTypeNotation &);
|
||||||
|
|
||||||
enum Type { Composite, Restricted };
|
enum Type { composite_t, restricted_t };
|
||||||
|
|
||||||
private :
|
private :
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
std::unique_ptr<Descriptor> m_descriptor;
|
uPtr<Descriptor> m_descriptor;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
AMQPTypeNotation (
|
AMQPTypeNotation (
|
||||||
std::string name_,
|
std::string name_,
|
||||||
std::unique_ptr<Descriptor> descriptor_
|
uPtr<Descriptor> descriptor_
|
||||||
) : m_name (std::move (name_))
|
) : m_name (std::move (name_))
|
||||||
, m_descriptor (std::move (descriptor_))
|
, m_descriptor (std::move (descriptor_))
|
||||||
{ }
|
{ }
|
||||||
@ -57,9 +57,8 @@ namespace amqp::internal::schema {
|
|||||||
|
|
||||||
virtual Type type() const = 0;
|
virtual Type type() const = 0;
|
||||||
|
|
||||||
int dependsOn (const OrderedTypeNotation &) const override = 0;
|
virtual int dependsOnRHS (const Restricted &) const = 0;
|
||||||
virtual int dependsOn (const class Restricted &) const = 0;
|
virtual int dependsOnRHS (const Composite &) const = 0;
|
||||||
virtual int dependsOn (const class Composite &) const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
21
experimental/cpp-serializer/src/amqp/schema/Descriptors.cxx
Normal file
21
experimental/cpp-serializer/src/amqp/schema/Descriptors.cxx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#include "amqp/schema/Descriptors.h"
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
namespace amqp::schema::descriptors {
|
||||||
|
|
||||||
|
const int ENVELOPE = 1;
|
||||||
|
const int SCHEMA = 2;
|
||||||
|
const int OBJECT = 3;
|
||||||
|
const int FIELD = 4;
|
||||||
|
const int COMPOSITE_TYPE = 5;
|
||||||
|
const int RESTRICTED_TYPE = 6;
|
||||||
|
const int CHOICE = 7;
|
||||||
|
const int REFERENCED_OBJECT = 8;
|
||||||
|
const int TRANSFORM_SCHEMA = 9;
|
||||||
|
const int TRANSFORM_ELEMENT = 10;
|
||||||
|
const int TRANSFORM_ELEMENT_KEY = 11;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -1,109 +0,0 @@
|
|||||||
#include "Field.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
namespace amqp::internal::schema {
|
|
||||||
|
|
||||||
std::ostream &
|
|
||||||
operator << (std::ostream & stream_, const Field & field_) {
|
|
||||||
std::stringstream ss;
|
|
||||||
for (auto &i: field_.m_requires) { ss << i; }
|
|
||||||
|
|
||||||
stream_ << field_.m_name << " : " << field_.m_type.first << " : [" << ss.str() << "]" << std::endl;
|
|
||||||
|
|
||||||
return stream_;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::Field (
|
|
||||||
const std::string & name_,
|
|
||||||
const std::string & type_,
|
|
||||||
const std::list<std::string> & requires_,
|
|
||||||
const std::string & default_,
|
|
||||||
const std::string & label_,
|
|
||||||
bool mandatory_,
|
|
||||||
bool multiple_
|
|
||||||
) : m_name (name_)
|
|
||||||
, m_requires (requires_)
|
|
||||||
, m_default (default_)
|
|
||||||
, m_label (label_)
|
|
||||||
, m_mandatory (mandatory_)
|
|
||||||
, m_multiple (multiple_)
|
|
||||||
{
|
|
||||||
if (typeIsPrimitive(type_)) {
|
|
||||||
m_type = std::make_pair(type_, FieldType::PrimitiveProperty);
|
|
||||||
} else if (type_ == "*") {
|
|
||||||
m_type = std::make_pair(type_, FieldType::RestrictedProperty);
|
|
||||||
} else {
|
|
||||||
m_type = std::make_pair(type_, FieldType::CompositeProperty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
bool
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::typeIsPrimitive(const std::string & type_) {
|
|
||||||
return (type_ == "string" ||
|
|
||||||
type_ == "long" ||
|
|
||||||
type_ == "boolean" ||
|
|
||||||
type_ == "int" ||
|
|
||||||
type_ == "double");
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
const std::string &
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::name() const {
|
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
const std::string &
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::type() const {
|
|
||||||
return m_type.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
const std::string &
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::resolvedType() const {
|
|
||||||
return (type() == "*") ? requires().front() : type();
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
amqp::internal::schema::FieldType
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::fieldType() const {
|
|
||||||
return m_type.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
const std::list<std::string> &
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::requires() const {
|
|
||||||
return m_requires;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
bool
|
|
||||||
amqp::internal::schema::
|
|
||||||
Field::primitive() const {
|
|
||||||
return m_type.second == PrimitiveProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
@ -1,63 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
#include "Descriptor.h"
|
|
||||||
#include "amqp/AMQPDescribed.h"
|
|
||||||
|
|
||||||
#include <list>
|
|
||||||
#include <string>
|
|
||||||
#include <iosfwd>
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
namespace amqp::internal::schema {
|
|
||||||
|
|
||||||
enum FieldType { PrimitiveProperty, CompositeProperty, RestrictedProperty };
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* A Corda AMQP Scehma Field type has:
|
|
||||||
* - name : String
|
|
||||||
* - type : String
|
|
||||||
* - requires : List<String>
|
|
||||||
* - default : nullable String
|
|
||||||
* - label : nullable String
|
|
||||||
* - mandatory : Boolean
|
|
||||||
* - multiple : Boolean
|
|
||||||
*/
|
|
||||||
class Field : public AMQPDescribed {
|
|
||||||
public :
|
|
||||||
friend std::ostream & operator << (std::ostream &, const Field &);
|
|
||||||
|
|
||||||
static bool typeIsPrimitive(const std::string &);
|
|
||||||
|
|
||||||
private :
|
|
||||||
std::string m_name;
|
|
||||||
std::pair<std::string, FieldType> m_type;
|
|
||||||
std::list<std::string> m_requires;
|
|
||||||
std::string m_default;
|
|
||||||
std::string m_label;
|
|
||||||
bool m_mandatory;
|
|
||||||
bool m_multiple;
|
|
||||||
|
|
||||||
public :
|
|
||||||
Field (const std::string & name_,
|
|
||||||
const std::string & type_,
|
|
||||||
const std::list<std::string> & requires_,
|
|
||||||
const std::string & default_,
|
|
||||||
const std::string & label_,
|
|
||||||
bool mandatory_,
|
|
||||||
bool multiple_);
|
|
||||||
|
|
||||||
const std::string & name() const;
|
|
||||||
const std::string & type() const;
|
|
||||||
const std::string & resolvedType() const;
|
|
||||||
FieldType fieldType() const;
|
|
||||||
const std::list<std::string> & requires() const;
|
|
||||||
bool primitive() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "debug.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "colours.h"
|
#include "colours.h"
|
||||||
|
|
||||||
@ -60,18 +61,18 @@ namespace amqp::internal::schema {
|
|||||||
typename std::list<std::list<uPtr<T>>>::iterator &);
|
typename std::list<std::list<uPtr<T>>>::iterator &);
|
||||||
|
|
||||||
public :
|
public :
|
||||||
void insert(uPtr<T> && ptr);
|
void insert (uPtr<T> && ptr);
|
||||||
|
|
||||||
friend std::ostream & ::operator << <> (
|
friend std::ostream & ::operator << <> (
|
||||||
std::ostream &,
|
std::ostream &,
|
||||||
const amqp::internal::schema::OrderedTypeNotations<T> &);
|
const amqp::internal::schema::OrderedTypeNotations<T> &);
|
||||||
|
|
||||||
decltype (m_schemas.crbegin()) begin() const {
|
decltype (m_schemas.cbegin()) begin() const {
|
||||||
return m_schemas.crbegin();
|
return m_schemas.cbegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
decltype (m_schemas.crend()) end() const {
|
decltype (m_schemas.cend()) end() const {
|
||||||
return m_schemas.crend();
|
return m_schemas.cend();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ operator << (
|
|||||||
std::ostream &stream_,
|
std::ostream &stream_,
|
||||||
const amqp::internal::schema::OrderedTypeNotations<T> &otn_
|
const amqp::internal::schema::OrderedTypeNotations<T> &otn_
|
||||||
) {
|
) {
|
||||||
int idx1{0};
|
int idx1 {0};
|
||||||
for (const auto &i : otn_.m_schemas) {
|
for (const auto &i : otn_.m_schemas) {
|
||||||
stream_ << "level " << ++idx1 << std::endl;
|
stream_ << "level " << ++idx1 << std::endl;
|
||||||
for (const auto &j : i) {
|
for (const auto &j : i) {
|
||||||
@ -145,6 +146,7 @@ OrderedTypeNotations<T>::insert (
|
|||||||
uPtr<T> && ptr,
|
uPtr<T> && ptr,
|
||||||
amqp::internal::schema::OrderedTypeNotations<T>::iterator l_
|
amqp::internal::schema::OrderedTypeNotations<T>::iterator l_
|
||||||
) {
|
) {
|
||||||
|
DBG ("Insert: " << ptr->name() << std::endl);
|
||||||
/*
|
/*
|
||||||
* First we find where this element needs to be added
|
* First we find where this element needs to be added
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,16 @@
|
|||||||
#include "Choice.h"
|
#include "Choice.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::ostream &
|
||||||
|
amqp::internal::schema::
|
||||||
|
operator << (std::ostream & os_, const amqp::internal::schema::Choice & choice_) {
|
||||||
|
os_ << choice_.m_choice;
|
||||||
|
return os_;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
amqp::internal::schema::
|
amqp::internal::schema::
|
@ -1,14 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AMQPTypeNotation.h"
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#include "schema/AMQPTypeNotation.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal::schema {
|
namespace amqp::internal::schema {
|
||||||
|
|
||||||
class Choice : public AMQPDescribed {
|
class Choice : public AMQPDescribed {
|
||||||
|
public :
|
||||||
|
friend std::ostream & operator << (std::ostream &, const Choice &);
|
||||||
|
|
||||||
private :
|
private :
|
||||||
std::string m_choice;
|
std::string m_choice;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
Choice() = delete;
|
Choice() = delete;
|
||||||
|
|
@ -62,7 +62,7 @@ Composite::fields() const {
|
|||||||
amqp::internal::schema::AMQPTypeNotation::Type
|
amqp::internal::schema::AMQPTypeNotation::Type
|
||||||
amqp::internal::schema::
|
amqp::internal::schema::
|
||||||
Composite::type() const {
|
Composite::type() const {
|
||||||
return AMQPTypeNotation::Type::Composite;
|
return AMQPTypeNotation::Type::composite_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -87,64 +87,66 @@ Composite::type() const {
|
|||||||
int
|
int
|
||||||
amqp::internal::schema::
|
amqp::internal::schema::
|
||||||
Composite::dependsOn (const OrderedTypeNotation & rhs) const {
|
Composite::dependsOn (const OrderedTypeNotation & rhs) const {
|
||||||
return dynamic_cast<const AMQPTypeNotation &>(rhs).dependsOn(*this);
|
return dynamic_cast<const AMQPTypeNotation &>(rhs).dependsOnRHS(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
amqp::internal::schema::
|
amqp::internal::schema::
|
||||||
Composite::dependsOn (const amqp::internal::schema::Restricted & lhs_) const {
|
Composite::dependsOnRHS (
|
||||||
// does the left hand side depend on us
|
const amqp::internal::schema::Restricted & lhs_
|
||||||
auto rtn { 0 };
|
) const {
|
||||||
|
|
||||||
for (const auto i : lhs_) {
|
|
||||||
DBG (" C/R a) " << i << " == " << name() << std::endl); // NOLINT
|
|
||||||
if (i == name()) {
|
|
||||||
rtn = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// does this depend on the left hand side
|
// does this depend on the left hand side
|
||||||
for (auto const & field : m_fields) {
|
for (auto const & field : m_fields) {
|
||||||
DBG (" C/R b) " << field->resolvedType() << " == " << lhs_.name() << std::endl); // NOLINT
|
DBG (" C/R b) " << field->resolvedType() << " == " << lhs_.name() << std::endl); // NOLINT
|
||||||
|
|
||||||
if (field->resolvedType() == lhs_.name()) {
|
if (field->resolvedType() == lhs_.name()) {
|
||||||
rtn = 2;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rtn;
|
// does the left hand side depend on us
|
||||||
|
for (const auto i : lhs_) {
|
||||||
|
DBG (" C/R a) " << i << " == " << name() << std::endl); // NOLINT
|
||||||
|
if (i == name()) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************o*********************/
|
/*********************************************************o*********************/
|
||||||
|
|
||||||
int
|
int
|
||||||
amqp::internal::schema::
|
amqp::internal::schema::
|
||||||
Composite::dependsOn (const amqp::internal::schema::Composite & lhs_) const {
|
Composite::dependsOnRHS (
|
||||||
auto rtn { 0 };
|
const amqp::internal::schema::Composite & lhs_
|
||||||
|
) const {
|
||||||
|
DBG (name() << " ?Depends on " << lhs_.name() << std::endl);
|
||||||
|
|
||||||
// do we depend on the lhs, i.e. is one of our fields it
|
// do we depend on the lhs
|
||||||
for (auto const & field : lhs_) {
|
|
||||||
DBG (" C/C a) " << field->resolvedType() << " == " << name() << std::endl); // NOLINT
|
|
||||||
if (field->resolvedType() == name()) {
|
|
||||||
rtn = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// does the left hand side depend on us. i.e. is one of it's fields
|
|
||||||
// us
|
|
||||||
for (const auto & field : m_fields) {
|
for (const auto & field : m_fields) {
|
||||||
DBG (" C/C b) " << field->resolvedType() << " == " << lhs_.name() << std::endl); // NOLINT
|
DBG ("FIELD - " << name() << "::" << type() << std::endl);
|
||||||
|
DBG (" C/C a) " << field->resolvedType() << " == " << lhs_.name() << std::endl); // NOLINT
|
||||||
|
|
||||||
if (field->resolvedType() == lhs_.name()) {
|
if (field->resolvedType() == lhs_.name()) {
|
||||||
rtn = 2;
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// does it depend on us
|
||||||
|
for (auto const & field : lhs_) {
|
||||||
|
DBG ("FIELD - " << name() << "::" << type() << std::endl);
|
||||||
|
DBG (" C/C b) " << field->resolvedType() << " == " << name() << std::endl); // NOLINT
|
||||||
|
if (field->resolvedType() == name()) {
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return rtn;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
@ -8,9 +8,9 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
#include "Field.h"
|
#include "schema/field-types/Field.h"
|
||||||
#include "Descriptor.h"
|
#include "Descriptor.h"
|
||||||
#include "AMQPTypeNotation.h"
|
#include "schema/AMQPTypeNotation.h"
|
||||||
|
|
||||||
#include "amqp/AMQPDescribed.h"
|
#include "amqp/AMQPDescribed.h"
|
||||||
|
|
||||||
@ -73,8 +73,8 @@ namespace amqp::internal::schema {
|
|||||||
Type type() const override;
|
Type type() const override;
|
||||||
|
|
||||||
int dependsOn (const OrderedTypeNotation &) const override;
|
int dependsOn (const OrderedTypeNotation &) const override;
|
||||||
int dependsOn (const class Restricted &) const override;
|
int dependsOnRHS (const class Restricted &) const override;
|
||||||
int dependsOn (const Composite &) const override;
|
int dependsOnRHS (const Composite &) const override;
|
||||||
|
|
||||||
decltype(m_fields)::const_iterator begin() const { return m_fields.cbegin();}
|
decltype(m_fields)::const_iterator begin() const { return m_fields.cbegin();}
|
||||||
decltype(m_fields)::const_iterator end() const { return m_fields.cend(); }
|
decltype(m_fields)::const_iterator end() const { return m_fields.cend(); }
|
@ -19,8 +19,6 @@ namespace amqp::internal::schema {
|
|||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
Descriptor() = default;
|
|
||||||
|
|
||||||
explicit Descriptor (std::string);
|
explicit Descriptor (std::string);
|
||||||
|
|
||||||
const std::string & name() const;
|
const std::string & name() const;
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "amqp/schema/Schema.h"
|
#include "amqp/schema/described-types/Schema.h"
|
||||||
#include "amqp/schema/ISchema.h"
|
#include "amqp/schema/ISchema.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "amqp/AMQPDescribed.h"
|
#include "amqp/AMQPDescribed.h"
|
||||||
|
|
||||||
#include "Schema.h"
|
#include "amqp/schema/described-types/Schema.h"
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
@ -9,7 +9,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "Composite.h"
|
#include "Composite.h"
|
||||||
#include "Descriptor.h"
|
#include "Descriptor.h"
|
||||||
#include "OrderedTypeNotations.h"
|
#include "schema/OrderedTypeNotations.h"
|
||||||
|
|
||||||
#include "amqp/AMQPDescribed.h"
|
#include "amqp/AMQPDescribed.h"
|
||||||
#include "amqp/schema/ISchema.h"
|
#include "amqp/schema/ISchema.h"
|
||||||
@ -20,10 +20,16 @@ namespace amqp::internal::schema {
|
|||||||
|
|
||||||
using SchemaMap = std::map<
|
using SchemaMap = std::map<
|
||||||
std::string,
|
std::string,
|
||||||
const std::reference_wrapper<const uPtr<AMQPTypeNotation>>>;
|
const std::reference_wrapper<const uPtr <AMQPTypeNotation>>>;
|
||||||
|
|
||||||
using ISchemaType = amqp::schema::ISchema<SchemaMap::const_iterator>;
|
using ISchemaType = amqp::schema::ISchema<SchemaMap::const_iterator>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
namespace amqp::internal::schema {
|
||||||
|
|
||||||
class Schema
|
class Schema
|
||||||
: public amqp::schema::ISchema<SchemaMap::const_iterator>
|
: public amqp::schema::ISchema<SchemaMap::const_iterator>
|
||||||
, public amqp::AMQPDescribed
|
, public amqp::AMQPDescribed
|
@ -1,17 +1,17 @@
|
|||||||
#include "AMQPDescriptor.h"
|
#include "AMQPDescriptor.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <amqp/descriptors/corda-descriptors/EnvelopeDescriptor.h>
|
#include <amqp/schema/descriptors/corda-descriptors/EnvelopeDescriptor.h>
|
||||||
|
|
||||||
#include "proton/proton_wrapper.h"
|
#include "proton/proton_wrapper.h"
|
||||||
#include "AMQPDescriptorRegistory.h"
|
#include "AMQPDescriptorRegistory.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
std::ostream &
|
std::ostream &
|
||||||
operator<<(std::ostream &stream_, const amqp::internal::AutoIndent &ai_) {
|
operator<<(std::ostream &stream_, const AutoIndent &ai_) {
|
||||||
stream_ << ai_.indent;
|
stream_ << ai_.indent;
|
||||||
return stream_;
|
return stream_;
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ namespace amqp::internal {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const std::string &
|
const std::string &
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
AMQPDescriptor::symbol() const {
|
AMQPDescriptor::symbol() const {
|
||||||
return m_symbol;
|
return m_symbol;
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ AMQPDescriptor::symbol() const {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
std::unique_ptr<amqp::AMQPDescribed>
|
std::unique_ptr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
AMQPDescriptor::build (pn_data_t *) const {
|
AMQPDescriptor::build (pn_data_t *) const {
|
||||||
throw std::runtime_error ("Should never be called");
|
throw std::runtime_error ("Should never be called");
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ AMQPDescriptor::build (pn_data_t *) const {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
AMQPDescriptor::read (
|
AMQPDescriptor::read (
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
std::stringstream & ss_
|
std::stringstream & ss_
|
||||||
@ -48,7 +48,7 @@ AMQPDescriptor::read (
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void
|
void
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
AMQPDescriptor::read (
|
AMQPDescriptor::read (
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
std::stringstream & ss_,
|
std::stringstream & ss_,
|
@ -23,22 +23,21 @@ struct pn_data_t;
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
class AutoIndent {
|
class AutoIndent {
|
||||||
private :
|
private :
|
||||||
std::string indent;
|
std::string indent;
|
||||||
public :
|
public :
|
||||||
AutoIndent() : indent { "" } { }
|
AutoIndent() : indent { "" } { }
|
||||||
|
|
||||||
AutoIndent (const AutoIndent & ai_)
|
AutoIndent (const AutoIndent & ai_)
|
||||||
: indent { ai_.indent + " "}
|
: indent { ai_.indent + " "}
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
friend std::ostream &
|
friend std::ostream &
|
||||||
operator << (std::ostream & stream_, const AutoIndent & ai_);
|
operator << (std::ostream & stream_, const AutoIndent & ai_);
|
||||||
|
};
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
@ -47,7 +46,7 @@ namespace amqp::internal {
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
class AMQPDescriptor {
|
class AMQPDescriptor {
|
||||||
protected :
|
protected :
|
@ -0,0 +1,133 @@
|
|||||||
|
#include "AMQPDescriptorRegistory.h"
|
||||||
|
#include "AMQPDescriptors.h"
|
||||||
|
|
||||||
|
#include "amqp/schema/Descriptors.h"
|
||||||
|
|
||||||
|
#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"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
namespace amqp::internal {
|
||||||
|
|
||||||
|
std::map<uint64_t, std::shared_ptr<internal::schema::descriptors::AMQPDescriptor>>
|
||||||
|
AMQPDescriptorRegistory = {
|
||||||
|
{
|
||||||
|
22UL,
|
||||||
|
std::make_shared<internal::schema::descriptors::AMQPDescriptor> ("DESCRIBED", -1)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
1UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::EnvelopeDescriptor> (
|
||||||
|
"ENVELOPE",
|
||||||
|
::amqp::schema::descriptors::ENVELOPE)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
2UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::SchemaDescriptor> (
|
||||||
|
"SCHEMA",
|
||||||
|
::amqp::schema::descriptors::SCHEMA)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
3UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::ObjectDescriptor> (
|
||||||
|
"OBJECT_DESCRIPTOR",
|
||||||
|
::amqp::schema::descriptors::OBJECT)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
4UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::FieldDescriptor> (
|
||||||
|
"FIELD",
|
||||||
|
::amqp::schema::descriptors::FIELD)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
5UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::CompositeDescriptor> (
|
||||||
|
"COMPOSITE_TYPE",
|
||||||
|
::amqp::schema::descriptors::COMPOSITE_TYPE)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
6UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::RestrictedDescriptor> (
|
||||||
|
"RESTRICTED_TYPE",
|
||||||
|
::amqp::schema::descriptors::RESTRICTED_TYPE)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
7UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::ChoiceDescriptor> (
|
||||||
|
"CHOICE",
|
||||||
|
::amqp::schema::descriptors::CHOICE)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
8UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::ReferencedObjectDescriptor> (
|
||||||
|
"REFERENCED_OBJECT",
|
||||||
|
::amqp::schema::descriptors::REFERENCED_OBJECT)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
9UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::TransformSchemaDescriptor> (
|
||||||
|
"TRANSFORM_SCHEMA",
|
||||||
|
::amqp::schema::descriptors::TRANSFORM_SCHEMA)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
10UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::TransformElementDescriptor> (
|
||||||
|
"TRANSFORM_ELEMENT",
|
||||||
|
::amqp::schema::descriptors::TRANSFORM_ELEMENT)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
11UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS,
|
||||||
|
std::make_shared<internal::schema::descriptors::TransformElementKeyDescriptor> (
|
||||||
|
"TRANSFORM_ELEMENT_KEY",
|
||||||
|
::amqp::schema::descriptors::TRANSFORM_ELEMENT_KEY)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
amqp::stripCorda (uint64_t id) {
|
||||||
|
return static_cast<uint32_t>(id & (uint64_t)UINT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::string
|
||||||
|
amqp::describedToString (uint64_t val_) {
|
||||||
|
switch (val_) {
|
||||||
|
case (1UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "ENVELOPE";
|
||||||
|
case (2UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "SCHEMA";
|
||||||
|
case (3UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "OBJECT_DESCRIPTOR";
|
||||||
|
case (4UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "FIELD";
|
||||||
|
case (5UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "COMPOSITE_TYPE";
|
||||||
|
case (6UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "RESTRICTED_TYPE";
|
||||||
|
case (7UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "CHOICE";
|
||||||
|
case (8UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "REFERENCED_OBJECT";
|
||||||
|
case (9UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_SCHEMA";
|
||||||
|
case (10UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_ELEMENT";
|
||||||
|
case (11UL | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_ELEMENT_KEY";
|
||||||
|
default : return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
std::string
|
||||||
|
amqp::describedToString (uint32_t val_) {
|
||||||
|
return describedToString(val_ | ::amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
@ -11,46 +11,15 @@
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* R3 AMQP assigned enterprise number
|
|
||||||
*
|
|
||||||
* see [here](https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers)
|
|
||||||
*
|
|
||||||
* Repeated here for brevity:
|
|
||||||
* 50530 - R3 - Mike Hearn - mike&r3.com
|
|
||||||
*/
|
|
||||||
namespace amqp::internal {
|
|
||||||
|
|
||||||
extern const uint64_t DESCRIPTOR_TOP_32BITS;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
namespace amqp::internal {
|
|
||||||
|
|
||||||
extern const int ENVELOPE;
|
|
||||||
extern const int SCHEMA;
|
|
||||||
extern const int OBJECT_DESCRIPTOR;
|
|
||||||
extern const int FIELD;
|
|
||||||
extern const int COMPOSITE_TYPE;
|
|
||||||
extern const int RESTRICTED_TYPE;
|
|
||||||
extern const int CHOICE;
|
|
||||||
extern const int REFERENCED_OBJECT;
|
|
||||||
extern const int TRANSFORM_SCHEMA;
|
|
||||||
extern const int TRANSFORM_ELEMENT;
|
|
||||||
extern const int TRANSFORM_ELEMENT_KEY;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
namespace amqp {
|
namespace amqp::internal {
|
||||||
|
|
||||||
extern std::map<uint64_t, std::shared_ptr<internal::AMQPDescriptor>> AMQPDescriptorRegistory;
|
extern std::map<uint64_t, std::shared_ptr<internal::schema::descriptors::AMQPDescriptor>> AMQPDescriptorRegistory;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
#include "AMQPDescriptors.h"
|
#include "AMQPDescriptors.h"
|
||||||
#include "AMQPDescriptorRegistory.h"
|
#include "AMQPDescriptorRegistory.h"
|
||||||
|
#include "amqp/schema/Descriptors.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -8,10 +9,10 @@
|
|||||||
#include "colours.h"
|
#include "colours.h"
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "Field.h"
|
#include "field-types/Field.h"
|
||||||
#include "Schema.h"
|
#include "amqp/schema/described-types/Schema.h"
|
||||||
#include "Envelope.h"
|
#include "amqp/schema/described-types/Envelope.h"
|
||||||
#include "Composite.h"
|
#include "amqp/schema/described-types/Composite.h"
|
||||||
#include "amqp/schema/restricted-types/Restricted.h"
|
#include "amqp/schema/restricted-types/Restricted.h"
|
||||||
#include "amqp/schema/OrderedTypeNotations.h"
|
#include "amqp/schema/OrderedTypeNotations.h"
|
||||||
#include "amqp/AMQPDescribed.h"
|
#include "amqp/AMQPDescribed.h"
|
||||||
@ -26,14 +27,14 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void
|
void
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
AMQPDescriptor::validateAndNext (pn_data_t * const data_) const {
|
AMQPDescriptor::validateAndNext (pn_data_t * const data_) const {
|
||||||
if (pn_data_type(data_) != PN_ULONG) {
|
if (pn_data_type(data_) != PN_ULONG) {
|
||||||
throw std::runtime_error ("Bad type for a descriptor");
|
throw std::runtime_error ("Bad type for a descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (m_val == -1)
|
if ( (m_val == -1)
|
||||||
|| (pn_data_get_ulong(data_) != (static_cast<uint32_t>(m_val) | amqp::internal::DESCRIPTOR_TOP_32BITS)))
|
|| (pn_data_get_ulong(data_) != (static_cast<uint32_t>(m_val) | amqp::schema::descriptors::DESCRIPTOR_TOP_32BITS)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error ("Invalid Type");
|
throw std::runtime_error ("Invalid Type");
|
||||||
}
|
}
|
||||||
@ -44,7 +45,7 @@ AMQPDescriptor::validateAndNext (pn_data_t * const data_) const {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uPtr<amqp::AMQPDescribed>
|
uPtr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
ReferencedObjectDescriptor::build (pn_data_t * data_) const {
|
ReferencedObjectDescriptor::build (pn_data_t * data_) const {
|
||||||
validateAndNext (data_);
|
validateAndNext (data_);
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ ReferencedObjectDescriptor::build (pn_data_t * data_) const {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uPtr<amqp::AMQPDescribed>
|
uPtr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
TransformSchemaDescriptor::build (pn_data_t * data_) const {
|
TransformSchemaDescriptor::build (pn_data_t * data_) const {
|
||||||
validateAndNext (data_);
|
validateAndNext (data_);
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ TransformSchemaDescriptor::build (pn_data_t * data_) const {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uPtr<amqp::AMQPDescribed>
|
uPtr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
TransformElementDescriptor::build (pn_data_t * data_) const {
|
TransformElementDescriptor::build (pn_data_t * data_) const {
|
||||||
validateAndNext (data_);
|
validateAndNext (data_);
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ TransformElementDescriptor::build (pn_data_t * data_) const {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uPtr<amqp::AMQPDescribed>
|
uPtr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
TransformElementKeyDescriptor::build (pn_data_t * data_) const {
|
TransformElementKeyDescriptor::build (pn_data_t * data_) const {
|
||||||
validateAndNext (data_);
|
validateAndNext (data_);
|
||||||
|
|
@ -11,7 +11,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "amqp/AMQPDescribed.h"
|
#include "amqp/AMQPDescribed.h"
|
||||||
#include "AMQPDescriptor.h"
|
#include "AMQPDescriptor.h"
|
||||||
#include "amqp/schema/Descriptor.h"
|
#include "amqp/schema/described-types/Descriptor.h"
|
||||||
#include "proton/proton_wrapper.h"
|
#include "proton/proton_wrapper.h"
|
||||||
#include "AMQPDescriptorRegistory.h"
|
#include "AMQPDescriptorRegistory.h"
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ struct pn_data_t;
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal::descriptors {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up a described type by its ID in the AMQPDescriptorRegistry and
|
* Look up a described type by its ID in the AMQPDescriptorRegistry and
|
||||||
@ -40,20 +40,13 @@ namespace amqp::internal::descriptors {
|
|||||||
|
|
||||||
return uPtr<T>(
|
return uPtr<T>(
|
||||||
static_cast<T *>(
|
static_cast<T *>(
|
||||||
amqp::AMQPDescriptorRegistory[id]->build(data_).release()));
|
AMQPDescriptorRegistory[id]->build(data_).release()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
namespace amqp::internal {
|
|
||||||
|
|
||||||
class ReferencedObjectDescriptor : public AMQPDescriptor {
|
class ReferencedObjectDescriptor : public AMQPDescriptor {
|
||||||
public :
|
public :
|
||||||
@ -72,7 +65,7 @@ namespace amqp::internal {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
class TransformSchemaDescriptor : public AMQPDescriptor {
|
class TransformSchemaDescriptor : public AMQPDescriptor {
|
||||||
public :
|
public :
|
||||||
@ -91,7 +84,7 @@ namespace amqp::internal {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
class TransformElementDescriptor : public AMQPDescriptor {
|
class TransformElementDescriptor : public AMQPDescriptor {
|
||||||
public :
|
public :
|
||||||
@ -110,7 +103,7 @@ namespace amqp::internal {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
class TransformElementKeyDescriptor : public AMQPDescriptor {
|
class TransformElementKeyDescriptor : public AMQPDescriptor {
|
||||||
public :
|
public :
|
@ -1,4 +1,4 @@
|
|||||||
#include "amqp/schema/Choice.h"
|
#include "amqp/schema/described-types/Choice.h"
|
||||||
#include "ChoiceDescriptor.h"
|
#include "ChoiceDescriptor.h"
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
@ -7,17 +7,17 @@
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
ChoiceDescriptor::ChoiceDescriptor (
|
ChoiceDescriptor::ChoiceDescriptor (
|
||||||
const std::string & symbol_,
|
std::string symbol_,
|
||||||
int val_
|
int val_
|
||||||
) : AMQPDescriptor (symbol_, val_) {
|
) : AMQPDescriptor (std::move (symbol_), val_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
std::unique_ptr<amqp::AMQPDescribed>
|
std::unique_ptr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
ChoiceDescriptor::build (pn_data_t * data_) const {
|
ChoiceDescriptor::build (pn_data_t * data_) const {
|
||||||
validateAndNext (data_);
|
validateAndNext (data_);
|
||||||
proton::auto_enter ae (data_);
|
proton::auto_enter ae (data_);
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "amqp/descriptors/AMQPDescriptor.h"
|
#include "amqp/schema/descriptors/AMQPDescriptor.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
@ -8,13 +8,13 @@
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
class ChoiceDescriptor : public AMQPDescriptor {
|
class ChoiceDescriptor : public AMQPDescriptor {
|
||||||
public :
|
public :
|
||||||
ChoiceDescriptor() = delete;
|
ChoiceDescriptor() = delete;
|
||||||
|
|
||||||
ChoiceDescriptor (const std::string &, int);
|
ChoiceDescriptor (std::string, int);
|
||||||
|
|
||||||
~ChoiceDescriptor() final = default;
|
~ChoiceDescriptor() final = default;
|
||||||
|
|
@ -9,30 +9,30 @@
|
|||||||
|
|
||||||
#include "proton/proton_wrapper.h"
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
#include "amqp/descriptors/AMQPDescriptors.h"
|
#include "amqp/schema/descriptors/AMQPDescriptors.h"
|
||||||
|
|
||||||
#include "amqp/schema/Field.h"
|
#include "amqp/schema/field-types/Field.h"
|
||||||
#include "amqp/schema/Composite.h"
|
#include "amqp/schema/described-types/Composite.h"
|
||||||
#include "amqp/schema/Descriptor.h"
|
#include "amqp/schema/described-types/Descriptor.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* amqp::internal::CompositeDescriptor
|
* amqp::internal::schema::descriptors::CompositeDescriptor
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
CompositeDescriptor::CompositeDescriptor (
|
CompositeDescriptor::CompositeDescriptor (
|
||||||
const std::string & symbol_,
|
std::string symbol_,
|
||||||
int val_
|
int val_
|
||||||
) : AMQPDescriptor (symbol_, val_) {
|
) : AMQPDescriptor (std::move (symbol_), val_) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uPtr<amqp::AMQPDescribed>
|
uPtr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
CompositeDescriptor::build (pn_data_t * data_) const {
|
CompositeDescriptor::build (pn_data_t * data_) const {
|
||||||
DBG ("COMPOSITE" << std::endl); // NOLINT
|
DBG ("COMPOSITE" << std::endl); // NOLINT
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ CompositeDescriptor::build (pn_data_t * data_) const {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void
|
void
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
CompositeDescriptor::read (
|
CompositeDescriptor::read (
|
||||||
pn_data_t * data_,
|
pn_data_t * data_,
|
||||||
std::stringstream & ss_,
|
std::stringstream & ss_,
|
@ -1,15 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "amqp/descriptors/AMQPDescriptor.h"
|
#include "amqp/schema/descriptors/AMQPDescriptor.h"
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
namespace amqp::internal {
|
namespace amqp::internal::schema::descriptors {
|
||||||
|
|
||||||
class CompositeDescriptor : public AMQPDescriptor {
|
class CompositeDescriptor : public AMQPDescriptor {
|
||||||
public :
|
public :
|
||||||
CompositeDescriptor() = delete;
|
CompositeDescriptor() = delete;
|
||||||
CompositeDescriptor (const std::string &, int);
|
CompositeDescriptor (std::string, int);
|
||||||
|
|
||||||
~CompositeDescriptor() final = default;
|
~CompositeDescriptor() final = default;
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
#include "EnvelopeDescriptor.h"
|
#include "EnvelopeDescriptor.h"
|
||||||
|
|
||||||
#include "amqp/schema/Schema.h"
|
#include "amqp/schema/described-types/Schema.h"
|
||||||
#include "amqp/schema/Envelope.h"
|
#include "amqp/schema/described-types/Envelope.h"
|
||||||
#include "proton/proton_wrapper.h"
|
#include "proton/proton_wrapper.h"
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
@ -24,7 +24,7 @@ namespace {
|
|||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* amqp::internal::EnvelopeDescriptor
|
* amqp::internal::schema::descriptors::EnvelopeDescriptor
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
@ -35,9 +35,11 @@ namespace {
|
|||||||
* calling this
|
* calling this
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
EnvelopeDescriptor::read (
|
EnvelopeDescriptor::read (
|
||||||
pn_data_t * data_, std::stringstream & ss_, const AutoIndent & ai_
|
pn_data_t * data_,
|
||||||
|
std::stringstream & ss_,
|
||||||
|
const AutoIndent & ai_
|
||||||
) const {
|
) const {
|
||||||
// lets just make sure we haven't entered this already
|
// lets just make sure we haven't entered this already
|
||||||
proton::is_list (data_);
|
proton::is_list (data_);
|
||||||
@ -60,18 +62,18 @@ EnvelopeDescriptor::read (
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
EnvelopeDescriptor::EnvelopeDescriptor (
|
EnvelopeDescriptor::EnvelopeDescriptor (
|
||||||
const std::string & symbol_,
|
std::string symbol_,
|
||||||
int val_
|
int val_
|
||||||
) : AMQPDescriptor (symbol_, val_) {
|
) : AMQPDescriptor (std::move (symbol_), val_) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uPtr<amqp::AMQPDescribed>
|
uPtr<amqp::AMQPDescribed>
|
||||||
amqp::internal::
|
amqp::internal::schema::descriptors::
|
||||||
EnvelopeDescriptor::build (pn_data_t * data_) const {
|
EnvelopeDescriptor::build (pn_data_t * data_) const {
|
||||||
DBG ("ENVELOPE" << std::endl); // NOLINT
|
DBG ("ENVELOPE" << std::endl); // NOLINT
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user