mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
NOTICK: Add BlobWriter and Schema Dumper
The Blob Writer is a small kotlin app that allows arbitrary things to be serialized and then those bytes written to a file, quite useful for working on non JVM parsing of such things. Along a similar vein, add a schema dumper alongside the blob-inspector to highlight the contents of the header
This commit is contained in:
parent
dbce25b575
commit
7b308eb45f
27
experimental/blobwriter/build.gradle
Normal file
27
experimental/blobwriter/build.gradle
Normal file
@ -0,0 +1,27 @@
|
||||
apply plugin : 'kotlin'
|
||||
apply plugin : 'application'
|
||||
|
||||
mainClassName = "net.corda.blobwriter.BlobWriter.kt"
|
||||
|
||||
dependencies {
|
||||
compile project(':tools:cliutils')
|
||||
compile project(":common-logging")
|
||||
compile project(':serialization')
|
||||
|
||||
compile "org.slf4j:jul-to-slf4j:$slf4j_version"
|
||||
compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
|
||||
}
|
||||
|
||||
jar {
|
||||
from (configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }) {
|
||||
exclude "META-INF/*.SF"
|
||||
exclude "META-INF/*.DSA"
|
||||
exclude "META-INF/*.RSA"
|
||||
}
|
||||
baseName = "blobwriter"
|
||||
manifest {
|
||||
attributes(
|
||||
'Main-Class': 'net.corda.blobwriter.BlobWriterKt'
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package net.corda.blobwriter
|
||||
|
||||
import net.corda.core.serialization.SerializationContext
|
||||
import net.corda.core.serialization.SerializationDefaults
|
||||
import net.corda.core.serialization.internal.SerializationEnvironment
|
||||
import net.corda.core.serialization.internal._contextSerializationEnv
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.serialization.internal.*
|
||||
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
|
||||
import net.corda.serialization.internal.amqp.amqpMagic
|
||||
import java.io.File
|
||||
|
||||
object AMQPInspectorSerializationScheme : AbstractAMQPSerializationScheme(emptyList()) {
|
||||
override fun canDeserializeVersion (
|
||||
magic: CordaSerializationMagic,
|
||||
target: SerializationContext.UseCase
|
||||
): Boolean {
|
||||
return magic == amqpMagic
|
||||
}
|
||||
|
||||
override fun rpcClientSerializerFactory(context: SerializationContext) = throw UnsupportedOperationException()
|
||||
override fun rpcServerSerializerFactory(context: SerializationContext) = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
val BLOB_WRITER_CONTEXT = SerializationContextImpl(
|
||||
amqpMagic,
|
||||
SerializationDefaults.javaClass.classLoader,
|
||||
AllWhitelist,
|
||||
emptyMap(),
|
||||
true,
|
||||
SerializationContext.UseCase.P2P,
|
||||
null
|
||||
)
|
||||
|
||||
fun initialiseSerialization() {
|
||||
_contextSerializationEnv.set (
|
||||
SerializationEnvironment.with (
|
||||
SerializationFactoryImpl().apply {
|
||||
registerScheme (AMQPInspectorSerializationScheme)
|
||||
},
|
||||
p2pContext = BLOB_WRITER_CONTEXT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
data class _i_ (val a: Int)
|
||||
data class _is_ (val a: Int, val b: String)
|
||||
data class _i_is__ (val a: Int, val b: _is_)
|
||||
data class _Li_ (val a: List<Int>)
|
||||
data class _Mis_ (val a: Map<Int, String>)
|
||||
|
||||
fun main (args: Array<String>) {
|
||||
initialiseSerialization()
|
||||
|
||||
File("../cpp-serializer/bin/blob-inspector/test/_i_is__").writeBytes(_i_is__(1, _is_ (2, "three")).serialize().bytes)
|
||||
File("../cpp-serializer/bin/blob-inspector/test/_Li_").writeBytes(_Li_(listOf (1, 2, 3, 4, 5, 6)).serialize().bytes)
|
||||
File("../cpp-serializer/bin/blob-inspector/test/_Mis_").writeBytes(_Mis_(
|
||||
mapOf (1 to "two", 3 to "four", 5 to "six")).serialize().bytes)
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,2 @@
|
||||
include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src)
|
||||
include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src/amqp)
|
||||
|
||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/amqp)
|
||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/proton)
|
||||
|
||||
add_executable (blob-inspector main)
|
||||
|
||||
target_link_libraries (blob-inspector amqp proton qpid-proton)
|
||||
ADD_SUBDIRECTORY (blob-inspector)
|
||||
ADD_SUBDIRECTORY (schema-dumper)
|
||||
|
@ -0,0 +1,9 @@
|
||||
include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src)
|
||||
include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src/amqp)
|
||||
|
||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/amqp)
|
||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/proton)
|
||||
|
||||
add_executable (blob-inspector main)
|
||||
|
||||
target_link_libraries (blob-inspector amqp proton qpid-proton)
|
@ -75,7 +75,6 @@ data_and_stop(std::ifstream & f_, ssize_t sz) {
|
||||
<< reader->dump ("{ Parsed", d, envelope->schema())->dump()
|
||||
<< " }" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,7 +103,9 @@ main (int argc, char **argv) {
|
||||
if (encoding == amqp::DATA_AND_STOP) {
|
||||
data_and_stop(f, results.st_size - 8);
|
||||
} else {
|
||||
std::cerr << "BAD ENCODING " << encoding << " != " << amqp::DATA_AND_STOP << std::endl;
|
||||
std::cerr << "BAD ENCODING " << encoding << " != "
|
||||
<< amqp::DATA_AND_STOP << std::endl;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
1
experimental/cpp-serializer/bin/schema-dumper/.gitignore
vendored
Normal file
1
experimental/cpp-serializer/bin/schema-dumper/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
schema-dumper
|
@ -0,0 +1,9 @@
|
||||
include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src)
|
||||
include_directories (${BLOB-INSPECTOR_SOURCE_DIR}/src/amqp)
|
||||
|
||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/amqp)
|
||||
link_directories (${BLOB-INSPECTOR_BINARY_DIR}/src/proton)
|
||||
|
||||
add_executable (schema-dumper main)
|
||||
|
||||
target_link_libraries (schema-dumper proton amqp qpid-proton)
|
92
experimental/cpp-serializer/bin/schema-dumper/main.cxx
Normal file
92
experimental/cpp-serializer/bin/schema-dumper/main.cxx
Normal file
@ -0,0 +1,92 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <cstddef>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <proton/types.h>
|
||||
#include <proton/codec.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sstream>
|
||||
|
||||
#import "debug.h"
|
||||
|
||||
#include "proton/proton_wrapper.h"
|
||||
|
||||
#include "amqp/AMQPHeader.h"
|
||||
#include "amqp/AMQPSectionId.h"
|
||||
#include "amqp/descriptors/AMQPDescriptorRegistory.h"
|
||||
|
||||
#include "amqp/schema/Envelope.h"
|
||||
#include "amqp/CompositeFactory.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
printNode (pn_data_t * d_) {
|
||||
std::stringstream ss;
|
||||
|
||||
if (pn_data_is_described (d_)) {
|
||||
amqp::AMQPDescriptorRegistory[22UL]->read (d_, ss);
|
||||
}
|
||||
|
||||
std::cout << ss.str() << std::endl;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
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);
|
||||
|
||||
printNode (d);
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
int
|
||||
main (int argc, char **argv) {
|
||||
struct stat results { };
|
||||
|
||||
if (stat(argv[1], &results) != 0) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::ifstream f (argv[1], std::ios::in | std::ios::binary);
|
||||
std::array<char, 7> header { };
|
||||
f.read(header.data(), 7);
|
||||
|
||||
if (header != amqp::AMQP_HEADER) {
|
||||
std::cerr << "Bad Header in blob" << 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 {
|
||||
std::cerr << "BAD ENCODING " << encoding << " != "
|
||||
<< amqp::DATA_AND_STOP << std::endl;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -12,7 +12,7 @@ namespace amqp {
|
||||
* The 8th byte is used to store weather the stream is compressed or
|
||||
* not
|
||||
*/
|
||||
std::array<char, 7> AMQP_HEADER = { { 'c', 'o', 'r', 'd', 'a', 1, 0 } };
|
||||
std::array<char, 7> AMQP_HEADER { { 'c', 'o', 'r', 'd', 'a', 1, 0 } };
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,15 @@ include_directories (.)
|
||||
|
||||
set (amqp_sources
|
||||
CompositeFactory.cxx
|
||||
descriptors/AMQPDescriptor.cxx
|
||||
descriptors/AMQPDescriptors.cxx
|
||||
descriptors/AMQPDescriptorRegistory.cxx
|
||||
descriptors/corda-descriptors/FieldDescriptor.cxx
|
||||
descriptors/corda-descriptors/SchemaDescriptor.cxx
|
||||
descriptors/corda-descriptors/ObjectDescriptor.cxx
|
||||
descriptors/corda-descriptors/EnvelopeDescriptor.cxx
|
||||
descriptors/corda-descriptors/CompositeDescriptor.cxx
|
||||
descriptors/corda-descriptors/RestrictedDescriptor.cxx
|
||||
schema/Schema.cxx
|
||||
schema/Field.cxx
|
||||
schema/Envelope.cxx
|
||||
@ -16,14 +23,14 @@ set (amqp_sources
|
||||
schema/restricted-types/List.cxx
|
||||
schema/AMQPTypeNotation.cxx
|
||||
reader/Reader.cxx
|
||||
reader/RestrictedReader.cxx
|
||||
reader/CompositeReader.cxx
|
||||
reader/PropertyReader.cxx
|
||||
reader/property-readers/StringPropertyReader.cxx
|
||||
reader/CompositeReader.cxx
|
||||
reader/RestrictedReader.cxx
|
||||
reader/property-readers/IntPropertyReader.cxx
|
||||
reader/property-readers/DoublePropertyReader.cxx
|
||||
reader/property-readers/LongPropertyReader.cxx
|
||||
reader/property-readers/BoolPropertyReader.cxx
|
||||
reader/property-readers/DoublePropertyReader.cxx
|
||||
reader/property-readers/StringPropertyReader.cxx
|
||||
reader/restricted-readers/ListReader.cxx
|
||||
)
|
||||
|
||||
|
@ -0,0 +1,102 @@
|
||||
#include "AMQPDescriptor.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <amqp/descriptors/corda-descriptors/EnvelopeDescriptor.h>
|
||||
|
||||
#include "proton/proton_wrapper.h"
|
||||
#include "AMQPDescriptorRegistory.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
std::ostream &
|
||||
operator<<(std::ostream &stream_, const amqp::internal::AutoIndent &ai_) {
|
||||
stream_ << ai_.indent;
|
||||
return stream_;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const std::string &
|
||||
amqp::internal::
|
||||
AMQPDescriptor::symbol() const {
|
||||
return m_symbol;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
std::unique_ptr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
AMQPDescriptor::build (pn_data_t *) const {
|
||||
throw std::runtime_error ("Should never be called");
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
inline void
|
||||
amqp::internal::
|
||||
AMQPDescriptor::read (
|
||||
pn_data_t * data_,
|
||||
std::stringstream & ss_
|
||||
) const {
|
||||
return read (data_, ss_, AutoIndent());
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
amqp::internal::
|
||||
AMQPDescriptor::read (
|
||||
pn_data_t * data_,
|
||||
std::stringstream & ss_,
|
||||
const AutoIndent & ai_
|
||||
) const {
|
||||
switch (pn_data_type (data_)) {
|
||||
case PN_DESCRIBED : {
|
||||
ss_ << ai_ << "DESCRIBED: " << std::endl;
|
||||
{
|
||||
AutoIndent ai { ai_ } ; // NOLINT
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
switch (pn_data_type (data_)) {
|
||||
case PN_ULONG : {
|
||||
auto key = proton::readAndNext<u_long>(data_);
|
||||
|
||||
ss_ << ai << "key : "
|
||||
<< key << " :: " << amqp::stripCorda(key)
|
||||
<< " -> "
|
||||
<< amqp::describedToString ((uint64_t )key)
|
||||
<< std::endl;
|
||||
|
||||
proton::is_list (data_);
|
||||
ss_ << ai << "list : entries: "
|
||||
<< pn_data_get_list(data_)
|
||||
<< std::endl;
|
||||
|
||||
AMQPDescriptorRegistory[key]->read (data_, ss_, ai);
|
||||
break;
|
||||
}
|
||||
case PN_SYMBOL : {
|
||||
ss_ << ai << "blob: bytes: "
|
||||
<< pn_data_get_symbol(data_).size
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
throw std::runtime_error (
|
||||
"Described type should only contain long or blob");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
throw std::runtime_error ("Can only dispatch described objects");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -16,6 +16,30 @@
|
||||
|
||||
struct pn_data_t;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::AMQPDescribed
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class AutoIndent {
|
||||
private :
|
||||
std::string indent;
|
||||
public :
|
||||
AutoIndent() : indent { "" } { }
|
||||
|
||||
AutoIndent (const AutoIndent & ai_)
|
||||
: indent { ai_.indent + " "}
|
||||
{ }
|
||||
|
||||
friend std::ostream &
|
||||
operator << (std::ostream & stream_, const AutoIndent & ai_);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::AMQPDescriptor
|
||||
@ -35,18 +59,27 @@ namespace amqp::internal {
|
||||
, m_val (-1)
|
||||
{ }
|
||||
|
||||
AMQPDescriptor(std::string symbol_, int val_)
|
||||
AMQPDescriptor (std::string symbol_, int val_)
|
||||
: m_symbol (std::move (symbol_))
|
||||
, m_val (val_)
|
||||
{ }
|
||||
|
||||
virtual ~AMQPDescriptor() = default;
|
||||
|
||||
const std::string & symbol() const { return m_symbol; }
|
||||
const std::string & symbol() const;
|
||||
|
||||
void validateAndNext (pn_data_t *) const;
|
||||
|
||||
virtual std::unique_ptr<AMQPDescribed> build (pn_data_t * data_) const = 0;
|
||||
virtual std::unique_ptr<AMQPDescribed> build (pn_data_t * data_) const;
|
||||
|
||||
virtual void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &) const;
|
||||
|
||||
virtual void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &,
|
||||
const AutoIndent &) const;
|
||||
};
|
||||
|
||||
}
|
@ -1,6 +1,13 @@
|
||||
#include "AMQPDescriptorRegistory.h"
|
||||
#include "AMQPDescriptors.h"
|
||||
|
||||
#include "corda-descriptors/FieldDescriptor.h"
|
||||
#include "corda-descriptors/SchemaDescriptor.h"
|
||||
#include "corda-descriptors/ObjectDescriptor.h"
|
||||
#include "corda-descriptors/EnvelopeDescriptor.h"
|
||||
#include "corda-descriptors/CompositeDescriptor.h"
|
||||
#include "corda-descriptors/RestrictedDescriptor.h"
|
||||
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
|
||||
@ -8,8 +15,7 @@
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
|
||||
const uint64_t DESCRIPTOR_TOP_32BITS = 0xc562L << (32 + 16);
|
||||
constexpr uint64_t DESCRIPTOR_TOP_32BITS = 0xc562UL << (unsigned int)(32 + 16);
|
||||
|
||||
}
|
||||
|
||||
@ -41,77 +47,83 @@ namespace amqp {
|
||||
std::map<uint64_t, std::shared_ptr<internal::AMQPDescriptor>>
|
||||
AMQPDescriptorRegistory = {
|
||||
{
|
||||
1L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
22UL,
|
||||
std::make_shared<internal::AMQPDescriptor> (
|
||||
"DESCRIBED",
|
||||
-1)
|
||||
},
|
||||
{
|
||||
1UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::EnvelopeDescriptor> (
|
||||
internal::EnvelopeDescriptor (
|
||||
"ENVELOPE",
|
||||
internal::ENVELOPE))
|
||||
},
|
||||
{
|
||||
2L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
2UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::SchemaDescriptor> (
|
||||
internal::SchemaDescriptor (
|
||||
"SCHEMA",
|
||||
internal::SCHEMA))
|
||||
},
|
||||
{
|
||||
3L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
3UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::ObjectDescriptor> (
|
||||
internal::ObjectDescriptor (
|
||||
"OBJECT_DESCRIPTOR",
|
||||
internal::OBJECT))
|
||||
},
|
||||
{
|
||||
4L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
4UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::FieldDescriptor> (
|
||||
internal::FieldDescriptor (
|
||||
"FIELD",
|
||||
internal::FIELD))
|
||||
},
|
||||
{
|
||||
5L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
5UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::CompositeDescriptor> (
|
||||
internal::CompositeDescriptor (
|
||||
"COMPOSITE_TYPE",
|
||||
internal::COMPOSITE_TYPE))
|
||||
},
|
||||
{
|
||||
6L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
6UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::RestrictedDescriptor> (
|
||||
internal::RestrictedDescriptor (
|
||||
"RESTRICTED_TYPE",
|
||||
internal::RESTRICTED_TYPE))
|
||||
},
|
||||
{
|
||||
7L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
7UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::ChoiceDescriptor> (
|
||||
internal::ChoiceDescriptor (
|
||||
"CHOICE",
|
||||
internal::CHOICE))
|
||||
},
|
||||
{
|
||||
8L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
8UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::ReferencedObjectDescriptor> (
|
||||
internal::ReferencedObjectDescriptor (
|
||||
"REFERENCED_OBJECT",
|
||||
internal::REFERENCED_OBJECT))
|
||||
},
|
||||
{
|
||||
9L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
9UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::TransformSchemaDescriptor> (
|
||||
internal::TransformSchemaDescriptor (
|
||||
"TRANSFORM_SCHEMA",
|
||||
internal::TRANSFORM_SCHEMA))
|
||||
},
|
||||
{
|
||||
10L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
10UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::TransformElementDescriptor> (
|
||||
internal::TransformElementDescriptor (
|
||||
"TRANSFORM_ELEMENT",
|
||||
internal::TRANSFORM_ELEMENT))
|
||||
},
|
||||
{
|
||||
11L | internal::DESCRIPTOR_TOP_32BITS,
|
||||
11UL | internal::DESCRIPTOR_TOP_32BITS,
|
||||
std::make_shared<internal::TransformElementKeyDescriptor> (
|
||||
internal::TransformElementKeyDescriptor (
|
||||
"TRANSFORM_ELEMENT_KEY",
|
||||
@ -132,19 +144,19 @@ amqp::stripCorda (uint64_t id) {
|
||||
std::string
|
||||
amqp::describedToString (uint64_t val_) {
|
||||
switch (val_) {
|
||||
case (1L | internal::DESCRIPTOR_TOP_32BITS) : return "ENVELOPE";
|
||||
case (2L | internal::DESCRIPTOR_TOP_32BITS) : return "SCHEMA";
|
||||
case (3L | internal::DESCRIPTOR_TOP_32BITS) : return "OBJECT_DESCRIPTOR";
|
||||
case (4L | internal::DESCRIPTOR_TOP_32BITS) : return "FIELD";
|
||||
case (5L | internal::DESCRIPTOR_TOP_32BITS) : return "COMPOSITE_TYPE";
|
||||
case (6L | internal::DESCRIPTOR_TOP_32BITS) : return "RESTRICTED_TYPE";
|
||||
case (7L | internal::DESCRIPTOR_TOP_32BITS) : return "CHOICE";
|
||||
case (8L | internal::DESCRIPTOR_TOP_32BITS) : return "REFERENCED_OBJECT";
|
||||
case (9L | internal::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_SCHEMA";
|
||||
case (10L | internal::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_ELEMENT";
|
||||
case (11L | internal::DESCRIPTOR_TOP_32BITS) : return "TRANSFORM_ELEMENT_KEY";
|
||||
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";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#include "amqp/AMQPDescriptor.h"
|
||||
#include "AMQPDescriptor.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -25,31 +25,6 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Look up a described type by its ID in the AMQPDescriptorRegistry and
|
||||
* return the corresponding schema type. Specialised below to avoid
|
||||
* the cast and re-owning of the unigue pointer when we're happy
|
||||
* with a simple uPtr<AMQPDescribed>
|
||||
*/
|
||||
template<class T>
|
||||
uPtr<T>
|
||||
dispatchDescribed (pn_data_t * data_) {
|
||||
proton::is_described(data_);
|
||||
proton::auto_enter p (data_);
|
||||
proton::is_ulong(data_);
|
||||
|
||||
auto id = pn_data_get_ulong(data_);
|
||||
|
||||
return uPtr<T> (
|
||||
static_cast<T *>(amqp::AMQPDescriptorRegistory[id]->build(data_).release()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
amqp::internal::
|
||||
AMQPDescriptor::validateAndNext (pn_data_t * const data_) const {
|
||||
@ -63,272 +38,7 @@ AMQPDescriptor::validateAndNext (pn_data_t * const data_) const {
|
||||
throw std::runtime_error ("Invalid Type");
|
||||
}
|
||||
|
||||
pn_data_next(data_);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace {
|
||||
const std::string
|
||||
consumeBlob (pn_data_t * data_) {
|
||||
proton::is_described (data_);
|
||||
proton::auto_enter p (data_);
|
||||
return proton::get_symbol<std::string> (data_);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::EnvelopeDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
EnvelopeDescriptor::build(pn_data_t * data_) const {
|
||||
DBG ("ENVELOPE" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
/*
|
||||
* The actual blob... if this was java we would use the type symbols
|
||||
* in the blob to look up serialisers in the cache... but we don't
|
||||
* have any so we are actually going to need to use the schema
|
||||
* which we parse *after* this to be able to read any data!
|
||||
*/
|
||||
std::string outerType = consumeBlob(data_);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/*
|
||||
* The schema
|
||||
*/
|
||||
auto schema = dispatchDescribed<schema::Schema> (data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/*
|
||||
* The transforms schema
|
||||
*/
|
||||
// Skip for now
|
||||
// dispatchDescribed (data_);
|
||||
|
||||
return std::make_unique<schema::Envelope> (schema::Envelope (schema, outerType));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
SchemaDescriptor::build(pn_data_t * data_) const {
|
||||
DBG ("SCHEMA" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
schema::OrderedTypeNotations<schema::AMQPTypeNotation> schemas;
|
||||
|
||||
/*
|
||||
* The Schema is stored as a list of lists of described objects
|
||||
*/
|
||||
{
|
||||
proton::auto_list_enter ale (data_);
|
||||
|
||||
for (int i { 1 } ; pn_data_next(data_) ; ++i) {
|
||||
DBG (" " << i << "/" << ale.elements() << std::endl); // NOLINT
|
||||
proton::auto_list_enter ale2 (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
schemas.insert (dispatchDescribed<schema::AMQPTypeNotation>(data_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_unique<schema::Schema> (std::move (schemas));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::ObjectDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
ObjectDescriptor::build(pn_data_t * data_) const {
|
||||
DBG ("DESCRIPTOR" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
auto symbol = proton::get_symbol<std::string> (data_);
|
||||
|
||||
return std::make_unique<schema::Descriptor> (symbol);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::FieldDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
FieldDescriptor::build(pn_data_t * data_) const {
|
||||
DBG ("FIELD" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter ae (data_);
|
||||
|
||||
/* name: String */
|
||||
auto name = proton::get_string (data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* type: String */
|
||||
auto type = proton::get_string (data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* requires: List<String> */
|
||||
std::list<std::string> requires;
|
||||
{
|
||||
proton::auto_list_enter ale (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
requires.push_back (proton::get_string(data_));
|
||||
}
|
||||
}
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* default: String? */
|
||||
auto def = proton::get_string (data_, true);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* label: String? */
|
||||
auto label = proton::get_string (data_, true);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* mandatory: Boolean - copes with the Kotlin concept of nullability.
|
||||
If something is mandatory then it cannot be null */
|
||||
auto mandatory = proton::get_boolean (data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* multiple: Boolean */
|
||||
auto multiple = proton::get_boolean(data_);
|
||||
|
||||
return std::make_unique<schema::Field> (name, type, requires, def, label,
|
||||
mandatory, multiple);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::CompositeDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
CompositeDescriptor::build (pn_data_t * data_) const {
|
||||
DBG ("COMPOSITE" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
/* Class Name - String */
|
||||
auto name = proton::get_string(data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* Label Name - Nullable String */
|
||||
auto label = proton::get_string (data_, true);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* provides: List<String> */
|
||||
std::list<std::string> provides;
|
||||
{
|
||||
proton::auto_list_enter p2 (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
provides.push_back (proton::get_string (data_));
|
||||
}
|
||||
}
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* descriptor: Descriptor */
|
||||
auto descriptor = dispatchDescribed<schema::Descriptor>(data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* fields: List<Described>*/
|
||||
std::vector<uPtr<schema::Field>> fields;
|
||||
fields.reserve (pn_data_get_list (data_));
|
||||
{
|
||||
proton::auto_list_enter p2 (data_);
|
||||
while (pn_data_next (data_)) {
|
||||
fields.emplace_back (dispatchDescribed<schema::Field>(data_));
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_unique<schema::Composite> (
|
||||
schema::Composite (name, label, provides, descriptor, fields));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Restricted types represent lists and maps
|
||||
*
|
||||
* NOTE: The Corda serialization scheme doesn't support all container classes
|
||||
* as it has the requiremnt that iteration order be deterministic for purposes
|
||||
* of signing over data.
|
||||
*
|
||||
* name : String
|
||||
* label : String?
|
||||
* provides : List<String>
|
||||
* source : String
|
||||
* descriptor : Descriptor
|
||||
* choices : List<Choice>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
RestrictedDescriptor::build (pn_data_t * data_) const {
|
||||
DBG ("RESTRICTED" << std::endl); // NOLINT
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter ae (data_);
|
||||
|
||||
auto name = proton::readAndNext<std::string>(data_);
|
||||
auto label = proton::readAndNext<std::string>(data_, true);
|
||||
|
||||
std::vector<std::string> provides;
|
||||
{
|
||||
proton::auto_list_enter ae2 (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
provides.push_back (proton::get_string (data_));
|
||||
}
|
||||
}
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
auto source = proton::readAndNext<std::string> (data_);
|
||||
auto descriptor = dispatchDescribed<schema::Descriptor> (data_);
|
||||
|
||||
// SKIP the choices section **FOR NOW**
|
||||
|
||||
return schema::Restricted::make (descriptor, name,
|
||||
label, provides, source);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -396,3 +106,4 @@ TransformElementKeyDescriptor::build (pn_data_t * data_) const {
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -8,9 +8,12 @@
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include "types.h"
|
||||
#include "amqp/AMQPDescribed.h"
|
||||
#include "amqp/AMQPDescriptor.h"
|
||||
#include "AMQPDescriptor.h"
|
||||
#include "amqp/schema/Descriptor.h"
|
||||
#include "proton/proton_wrapper.h"
|
||||
#include "AMQPDescriptorRegistory.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
@ -18,116 +21,26 @@ struct pn_data_t;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
namespace amqp::internal::descriptors {
|
||||
|
||||
class EnvelopeDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
EnvelopeDescriptor() : AMQPDescriptor() { }
|
||||
/**
|
||||
* Look up a described type by its ID in the AMQPDescriptorRegistry and
|
||||
* return the corresponding schema type. Specialised below to avoid
|
||||
* the cast and re-owning of the unigue pointer when we're happy
|
||||
* with a simple uPtr<AMQPDescribed>
|
||||
*/
|
||||
template<class T>
|
||||
uPtr <T>
|
||||
dispatchDescribed(pn_data_t *data_) {
|
||||
proton::is_described(data_);
|
||||
proton::auto_enter p(data_);
|
||||
proton::is_ulong(data_);
|
||||
|
||||
EnvelopeDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~EnvelopeDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class SchemaDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
SchemaDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
SchemaDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~SchemaDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class ObjectDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
ObjectDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
ObjectDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~ObjectDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class FieldDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
FieldDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
FieldDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~FieldDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class CompositeDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
CompositeDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
CompositeDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~CompositeDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class RestrictedDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
RestrictedDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
RestrictedDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~RestrictedDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
};
|
||||
auto id = pn_data_get_ulong(data_);
|
||||
|
||||
return uPtr<T>(
|
||||
static_cast<T *>(amqp::AMQPDescriptorRegistory[id]->build(data_).release()));
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -0,0 +1,146 @@
|
||||
#include "CompositeDescriptor.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "proton/proton_wrapper.h"
|
||||
|
||||
#include "amqp/descriptors/AMQPDescriptors.h"
|
||||
|
||||
#include "amqp/schema/Field.h"
|
||||
#include "amqp/schema/Composite.h"
|
||||
#include "amqp/schema/Descriptor.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::CompositeDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
amqp::internal::
|
||||
CompositeDescriptor::CompositeDescriptor (
|
||||
const std::string & symbol_,
|
||||
int val_
|
||||
) : AMQPDescriptor (symbol_, val_) {
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
CompositeDescriptor::build (pn_data_t * data_) const {
|
||||
DBG ("COMPOSITE" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
/* Class Name - String */
|
||||
auto name = proton::get_string(data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* Label Name - Nullable String */
|
||||
auto label = proton::get_string (data_, true);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/* provides: List<String> */
|
||||
std::list<std::string> provides;
|
||||
{
|
||||
proton::auto_list_enter p2 (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
provides.push_back (proton::get_string (data_));
|
||||
}
|
||||
}
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* descriptor: Descriptor */
|
||||
auto descriptor = descriptors::dispatchDescribed<schema::Descriptor>(data_);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* fields: List<Described>*/
|
||||
std::vector<uPtr<schema::Field>> fields;
|
||||
fields.reserve (pn_data_get_list (data_));
|
||||
{
|
||||
proton::auto_list_enter p2 (data_);
|
||||
while (pn_data_next (data_)) {
|
||||
fields.emplace_back (descriptors::dispatchDescribed<schema::Field>(data_));
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_unique<schema::Composite> (
|
||||
schema::Composite (name, label, provides, descriptor, fields));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
amqp::internal::
|
||||
CompositeDescriptor::read (
|
||||
pn_data_t * data_,
|
||||
std::stringstream & ss_,
|
||||
const AutoIndent & ai_
|
||||
) const {
|
||||
proton::is_list(data_);
|
||||
|
||||
{
|
||||
AutoIndent ai { ai_ };
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
proton::is_string (data_);
|
||||
ss_ << ai
|
||||
<< "1] String: ClassName: "
|
||||
<< proton::readAndNext<std::string>(data_)
|
||||
<< std::endl;
|
||||
|
||||
proton::is_string (data_);
|
||||
ss_ << ai
|
||||
<< "2] String: Label: \""
|
||||
<< proton::readAndNext<std::string>(data_, true)
|
||||
<< "\"" << std::endl;
|
||||
|
||||
proton::is_list (data_);
|
||||
|
||||
ss_ << ai << "3] List: Provides: [ ";
|
||||
{
|
||||
proton::auto_list_enter ale (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
ss_ << ai << (proton::get_string (data_)) << " ";
|
||||
}
|
||||
}
|
||||
ss_ << "]" << std::endl;
|
||||
|
||||
pn_data_next (data_);
|
||||
proton::is_described (data_);
|
||||
|
||||
ss_ << ai << "4] Descriptor:" << std::endl;
|
||||
|
||||
AMQPDescriptorRegistory[pn_data_type(data_)]->read (
|
||||
(pn_data_t *)proton::auto_next(data_), ss_, AutoIndent { ai });
|
||||
|
||||
ss_ << ai << "5] List: Fields: " << std::endl;
|
||||
{
|
||||
AutoIndent ai2 { ai };
|
||||
|
||||
proton::auto_list_enter ale (data_);
|
||||
for (int i { 1 } ; pn_data_next (data_) ; ++i) {
|
||||
ss_ << ai2 << i << "/"
|
||||
<< ale.elements() << "]"
|
||||
<< std::endl;
|
||||
|
||||
AMQPDescriptorRegistory[pn_data_type(data_)]->read (
|
||||
data_, ss_, AutoIndent { ai2 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "amqp/descriptors/AMQPDescriptor.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class CompositeDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
CompositeDescriptor() : AMQPDescriptor() { }
|
||||
CompositeDescriptor (const std::string &, int);
|
||||
|
||||
~CompositeDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
|
||||
void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &,
|
||||
const AutoIndent &) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,114 @@
|
||||
#include "EnvelopeDescriptor.h"
|
||||
|
||||
#include "amqp/schema/Schema.h"
|
||||
#include "amqp/schema/Envelope.h"
|
||||
#include "proton/proton_wrapper.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace {
|
||||
|
||||
const std::string
|
||||
consumeBlob (pn_data_t * data_) {
|
||||
proton::is_described (data_);
|
||||
proton::auto_enter p (data_);
|
||||
return proton::get_symbol<std::string> (data_);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::EnvelopeDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* Described types are a pair of a key and a list of elements. Having
|
||||
* parsed this as such a type we should be in the stack at the point
|
||||
* where we found the list and don't expect to have entered it before
|
||||
* calling this
|
||||
*/
|
||||
void
|
||||
amqp::internal::
|
||||
EnvelopeDescriptor::read (
|
||||
pn_data_t * data_, std::stringstream & ss_, const AutoIndent & ai_
|
||||
) const {
|
||||
// lets just make sure we haven't entered this already
|
||||
proton::is_list (data_);
|
||||
|
||||
{
|
||||
AutoIndent ai { ai_ };
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
ss_ << ai << "1]" << std::endl;
|
||||
AMQPDescriptorRegistory[pn_data_type(data_)]->read (
|
||||
(pn_data_t *)proton::auto_next (data_), ss_, AutoIndent { ai });
|
||||
|
||||
|
||||
ss_ << ai << "2]" << std::endl;
|
||||
AMQPDescriptorRegistory[pn_data_type(data_)]->read (
|
||||
(pn_data_t *)proton::auto_next(data_), ss_, AutoIndent { ai });
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
amqp::internal::
|
||||
EnvelopeDescriptor::EnvelopeDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
amqp::internal::
|
||||
EnvelopeDescriptor::EnvelopeDescriptor (
|
||||
const std::string & symbol_,
|
||||
int val_
|
||||
) : AMQPDescriptor (symbol_, val_) {
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
EnvelopeDescriptor::build (pn_data_t * data_) const {
|
||||
DBG ("ENVELOPE" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
/*
|
||||
* The actual blob... if this was java we would use the type symbols
|
||||
* in the blob to look up serialisers in the cache... but we don't
|
||||
* have any so we are actually going to need to use the schema
|
||||
* which we parse *after* this to be able to read any data!
|
||||
*/
|
||||
std::string outerType = consumeBlob(data_);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/*
|
||||
* The schema
|
||||
*/
|
||||
auto schema = descriptors::dispatchDescribed<schema::Schema> (data_);
|
||||
|
||||
pn_data_next(data_);
|
||||
|
||||
/*
|
||||
* The transforms schema
|
||||
*/
|
||||
// Skip for now
|
||||
// dispatchDescribed (data_);
|
||||
|
||||
return std::make_unique<schema::Envelope> (schema::Envelope (schema, outerType));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "AMQPDescriptors.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Forward Class Declarations
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
struct pn_data_t;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* class amqp::internal::EnvelopeDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class EnvelopeDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
EnvelopeDescriptor();
|
||||
EnvelopeDescriptor (const std::string &, int);
|
||||
|
||||
~EnvelopeDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
|
||||
void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &,
|
||||
const AutoIndent &) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,138 @@
|
||||
#include "FieldDescriptor.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "proton/proton_wrapper.h"
|
||||
|
||||
#include "amqp/schema/Field.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::FieldDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
amqp::internal::
|
||||
FieldDescriptor::FieldDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
amqp::internal::
|
||||
FieldDescriptor::FieldDescriptor (
|
||||
const std::string & symbol_,
|
||||
int val_
|
||||
) : AMQPDescriptor(symbol_, val_) {
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
FieldDescriptor::build(pn_data_t * data_) const {
|
||||
DBG ("FIELD" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter ae (data_);
|
||||
|
||||
/* name: String */
|
||||
auto name = proton::get_string (data_);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* type: String */
|
||||
auto type = proton::get_string (data_);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* requires: List<String> */
|
||||
std::list<std::string> requires;
|
||||
{
|
||||
proton::auto_list_enter ale (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
requires.push_back (proton::get_string(data_));
|
||||
}
|
||||
}
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* default: String? */
|
||||
auto def = proton::get_string (data_, true);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* label: String? */
|
||||
auto label = proton::get_string (data_, true);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* mandatory: Boolean - copes with the Kotlin concept of nullability.
|
||||
If something is mandatory then it cannot be null */
|
||||
auto mandatory = proton::get_boolean (data_);
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
/* multiple: Boolean */
|
||||
auto multiple = proton::get_boolean(data_);
|
||||
|
||||
return std::make_unique<schema::Field> (
|
||||
name, type, requires, def, label, mandatory, multiple);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
amqp::internal::
|
||||
FieldDescriptor::read (
|
||||
pn_data_t * data_,
|
||||
std::stringstream & ss_,
|
||||
const AutoIndent & ai_
|
||||
) const {
|
||||
proton::is_list (data_);
|
||||
|
||||
proton::auto_list_enter ale (data_, true);
|
||||
AutoIndent ai { ai_ };
|
||||
|
||||
ss_ << ai << "1/7] String: Name: "
|
||||
<< proton::get_string ((pn_data_t *)proton::auto_next (data_))
|
||||
<< std::endl;
|
||||
ss_ << ai << "2/7] String: Type: "
|
||||
<< proton::get_string ((pn_data_t *)proton::auto_next (data_))
|
||||
<< std::endl;
|
||||
|
||||
{
|
||||
proton::auto_list_enter ale2 (data_);
|
||||
|
||||
ss_ << ai << "3/7] List: Requires: elements " << ale2.elements()
|
||||
<< std::endl;
|
||||
|
||||
AutoIndent ai2 { ai };
|
||||
|
||||
while (pn_data_next(data_)) {
|
||||
ss_ << ai2 << proton::get_string (data_) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
proton::is_string (data_, true);
|
||||
|
||||
ss_ << ai << "4/7] String: Default: "
|
||||
<< proton::get_string ((pn_data_t *)proton::auto_next (data_), true)
|
||||
<< std::endl;
|
||||
ss_ << ai << "5/7] String: Label: "
|
||||
<< proton::get_string ((pn_data_t *)proton::auto_next (data_), true)
|
||||
<< std::endl;
|
||||
ss_ << ai << "6/7] Boolean: Mandatory: "
|
||||
<< proton::get_boolean ((pn_data_t *)proton::auto_next (data_))
|
||||
<< std::endl;
|
||||
ss_ << ai << "7/7] Boolean: Multiple: "
|
||||
<< proton::get_boolean ((pn_data_t *)proton::auto_next (data_))
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#include "proton/codec.h"
|
||||
#include "amqp/AMQPDescribed.h"
|
||||
#include "amqp/descriptors/AMQPDescriptor.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class FieldDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
FieldDescriptor();
|
||||
FieldDescriptor (const std::string &, int);
|
||||
|
||||
~FieldDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
|
||||
void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &,
|
||||
const AutoIndent &) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,59 @@
|
||||
#include "ObjectDescriptor.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "proton/proton_wrapper.h"
|
||||
#include "amqp/schema/Descriptor.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* amqp::internal::ObjectDescriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
ObjectDescriptor::build(pn_data_t * data_) const {
|
||||
DBG ("DESCRIPTOR" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext (data_);
|
||||
|
||||
proton::auto_enter p (data_);
|
||||
|
||||
auto symbol = proton::get_symbol<std::string> (data_);
|
||||
|
||||
return std::make_unique<schema::Descriptor> (symbol);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
amqp::internal::
|
||||
ObjectDescriptor::read (
|
||||
pn_data_t * data_,
|
||||
std::stringstream & ss_,
|
||||
const AutoIndent & ai_
|
||||
) const {
|
||||
proton::is_list (data_);
|
||||
|
||||
{
|
||||
AutoIndent ai { ai_ };
|
||||
proton::auto_list_enter ale (data_);
|
||||
pn_data_next(data_);
|
||||
|
||||
ss_ << ai << "1/2] "
|
||||
<< proton::get_symbol<std::string>(
|
||||
(pn_data_t *)proton::auto_next (data_))
|
||||
<< std::endl;
|
||||
|
||||
ss_ << ai << "2/2] " << data_ << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#include "amqp/descriptors/AMQPDescriptor.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct pn_data_t;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class ObjectDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
ObjectDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
ObjectDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~ObjectDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
|
||||
void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &,
|
||||
const AutoIndent &) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,98 @@
|
||||
#include "RestrictedDescriptor.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "amqp/schema/restricted-types/Restricted.h"
|
||||
#include "amqp/descriptors/AMQPDescriptors.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Restricted types represent lists and maps
|
||||
*
|
||||
* NOTE: The Corda serialization scheme doesn't support all container classes
|
||||
* as it has the requiremnt that iteration order be deterministic for purposes
|
||||
* of signing over data.
|
||||
*
|
||||
* name : String
|
||||
* label : String?
|
||||
* provides : List<String>
|
||||
* source : String
|
||||
* descriptor : Descriptor
|
||||
* choices : List<Choice>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
RestrictedDescriptor::build (pn_data_t * data_) const {
|
||||
DBG ("RESTRICTED" << std::endl); // NOLINT
|
||||
validateAndNext(data_);
|
||||
|
||||
proton::auto_enter ae (data_);
|
||||
|
||||
auto name = proton::readAndNext<std::string>(data_);
|
||||
auto label = proton::readAndNext<std::string>(data_, true);
|
||||
|
||||
std::vector<std::string> provides;
|
||||
{
|
||||
proton::auto_list_enter ae2 (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
provides.push_back (proton::get_string (data_));
|
||||
}
|
||||
}
|
||||
|
||||
pn_data_next (data_);
|
||||
|
||||
auto source = proton::readAndNext<std::string> (data_);
|
||||
auto descriptor = descriptors::dispatchDescribed<schema::Descriptor> (data_);
|
||||
|
||||
// SKIP the choices section **FOR NOW**
|
||||
|
||||
return schema::Restricted::make (descriptor, name,
|
||||
label, provides, source);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void
|
||||
amqp::internal::
|
||||
RestrictedDescriptor::read (
|
||||
pn_data_t * data_,
|
||||
std::stringstream & ss_,
|
||||
const AutoIndent & ai_
|
||||
) const {
|
||||
proton::is_list (data_);
|
||||
proton::auto_enter ae (data_);
|
||||
AutoIndent ai { ai_ };
|
||||
|
||||
ss_ << ai << "1] String: Name: "
|
||||
<< proton::readAndNext<std::string> (data_)
|
||||
<< std::endl;
|
||||
ss_ << ai << "2] String: Label: "
|
||||
<< proton::readAndNext<std::string> (data_, true)
|
||||
<< std::endl;
|
||||
ss_ << ai << "3] List: Provides: [ ";
|
||||
|
||||
{
|
||||
proton::auto_list_enter ae2 (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
ss_ << proton::get_string (data_) << " ";
|
||||
}
|
||||
ss_ << "]" << std::endl;
|
||||
}
|
||||
|
||||
pn_data_next (data_);
|
||||
ss_ << ai << "4] String: Source: "
|
||||
<< proton::readAndNext<std::string> (data_)
|
||||
<< std::endl;
|
||||
|
||||
ss_ << ai << "5] Descriptor:" << std::endl;
|
||||
|
||||
AMQPDescriptorRegistory[pn_data_type(data_)]->read (
|
||||
(pn_data_t *)proton::auto_next(data_), ss_, AutoIndent { ai });
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "amqp/descriptors/AMQPDescriptor.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class RestrictedDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
RestrictedDescriptor() : AMQPDescriptor() { }
|
||||
|
||||
RestrictedDescriptor(const std::string & symbol_, int val_)
|
||||
: AMQPDescriptor(symbol_, val_)
|
||||
{ }
|
||||
|
||||
~RestrictedDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
|
||||
void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &,
|
||||
const AutoIndent &) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -0,0 +1,93 @@
|
||||
#include "SchemaDescriptor.h"
|
||||
|
||||
#include "types.h"
|
||||
#include "debug.h"
|
||||
#include "AMQPDescriptor.h"
|
||||
|
||||
#include "proton/codec.h"
|
||||
#include "proton/proton_wrapper.h"
|
||||
#include "amqp/AMQPDescribed.h"
|
||||
#include "amqp/descriptors/AMQPDescriptors.h"
|
||||
#include "amqp/schema/Schema.h"
|
||||
#include "amqp/schema/OrderedTypeNotations.h"
|
||||
#include "amqp/schema/AMQPTypeNotation.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
amqp::internal::
|
||||
SchemaDescriptor::SchemaDescriptor (
|
||||
const std::string & symbol_,
|
||||
int val_
|
||||
) : AMQPDescriptor(symbol_, val_) {
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uPtr<amqp::AMQPDescribed>
|
||||
amqp::internal::
|
||||
SchemaDescriptor::build (pn_data_t * data_) const {
|
||||
DBG ("SCHEMA" << std::endl); // NOLINT
|
||||
|
||||
validateAndNext(data_);
|
||||
|
||||
schema::OrderedTypeNotations<schema::AMQPTypeNotation> schemas;
|
||||
|
||||
/*
|
||||
* The Schema is stored as a list of lists of described objects
|
||||
*/
|
||||
{
|
||||
proton::auto_list_enter ale (data_);
|
||||
|
||||
for (int i { 1 } ; pn_data_next(data_) ; ++i) {
|
||||
DBG (" " << i << "/" << ale.elements() << std::endl); // NOLINT
|
||||
proton::auto_list_enter ale2 (data_);
|
||||
while (pn_data_next(data_)) {
|
||||
schemas.insert (
|
||||
descriptors::dispatchDescribed<schema::AMQPTypeNotation>(data_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_unique<schema::Schema> (std::move (schemas));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
||||
void
|
||||
amqp::internal::
|
||||
SchemaDescriptor::read (
|
||||
pn_data_t * data_,
|
||||
std::stringstream & ss_,
|
||||
const AutoIndent & ai_
|
||||
) const {
|
||||
proton::is_list (data_);
|
||||
|
||||
{
|
||||
AutoIndent ai { ai_ };
|
||||
proton::auto_list_enter ale (data_);
|
||||
|
||||
for (int i { 1 } ; pn_data_next (data_) ; ++i) {
|
||||
proton::is_list (data_);
|
||||
ss_ << ai << i << "/" << ale.elements() <<"]";
|
||||
|
||||
AutoIndent ai2 { ai };
|
||||
|
||||
proton::auto_list_enter ale2 (data_);
|
||||
ss_ << " list: entries: " << ale2.elements() << std::endl;
|
||||
|
||||
for (int j { 1 } ; pn_data_next (data_) ; ++j) {
|
||||
ss_ << ai2 << i << ":" << j << "/" << ale2.elements()
|
||||
<< "] " << std::endl;
|
||||
|
||||
AMQPDescriptorRegistory[pn_data_type(data_)]->read (
|
||||
data_, ss_,
|
||||
AutoIndent { ai2 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "amqp/descriptors/AMQPDescriptor.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
struct pn_data_t;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
namespace amqp::internal {
|
||||
|
||||
class SchemaDescriptor : public AMQPDescriptor {
|
||||
public :
|
||||
SchemaDescriptor() = default;
|
||||
SchemaDescriptor (const std::string &, int);
|
||||
~SchemaDescriptor() final = default;
|
||||
|
||||
std::unique_ptr<AMQPDescribed> build (pn_data_t *) const override;
|
||||
|
||||
void read (
|
||||
pn_data_t *,
|
||||
std::stringstream &,
|
||||
const AutoIndent &) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
@ -31,7 +31,7 @@ namespace amqp::internal::reader {
|
||||
|
||||
std::any read (pn_data_t *) const override;
|
||||
|
||||
std::string readString(pn_data_t *) const override;
|
||||
std::string readString (pn_data_t *) const override;
|
||||
|
||||
std::unique_ptr<amqp::reader::IValue> dump(
|
||||
const std::string &,
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
std::ostream&
|
||||
operator << (std::ostream& stream, pn_data_t * data_) {
|
||||
auto type = pn_data_type(data_);
|
||||
auto type = pn_data_type (data_);
|
||||
stream << std::setw (2) << type << " " << pn_type_name (type);
|
||||
|
||||
switch (type) {
|
||||
@ -89,14 +89,14 @@ proton::is_ulong (pn_data_t * data_) {
|
||||
auto t = pn_data_type(data_);
|
||||
if (t != PN_ULONG) {
|
||||
std::stringstream ss;
|
||||
ss << "Expected an unsigned long but recieved " << pn_type_name (t);
|
||||
ss << "Expected an unsigned long but received " << pn_type_name (t);
|
||||
throw std::runtime_error (ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
inline void
|
||||
void
|
||||
proton::is_symbol (pn_data_t * data_) {
|
||||
if (pn_data_type(data_) != PN_SYMBOL) {
|
||||
throw std::runtime_error ("Expected an unsigned long");
|
||||
@ -114,7 +114,7 @@ proton::is_list (pn_data_t * data_) {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
inline void
|
||||
void
|
||||
proton::is_string (pn_data_t * data_, bool allowNull) {
|
||||
if (pn_data_type(data_) != PN_STRING) {
|
||||
if (allowNull && pn_data_type(data_) != PN_NULL) {
|
||||
@ -141,9 +141,9 @@ proton::get_string (pn_data_t * data_, bool allowNull) {
|
||||
template<>
|
||||
std::string
|
||||
proton::get_symbol<std::string> (pn_data_t * data_) {
|
||||
is_symbol (data_);
|
||||
auto symbol = pn_data_get_symbol(data_);
|
||||
return std::string (symbol.start, symbol.size);
|
||||
is_symbol (data_);
|
||||
auto symbol = pn_data_get_symbol(data_);
|
||||
return std::string (symbol.start, symbol.size);
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -173,8 +173,8 @@ proton::
|
||||
auto_enter::auto_enter (pn_data_t * data_, bool next_)
|
||||
: m_data (data_)
|
||||
{
|
||||
proton::pn_data_enter(m_data);
|
||||
if (next_) pn_data_next(m_data);
|
||||
proton::pn_data_enter (m_data);
|
||||
if (next_) pn_data_next (m_data);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -224,7 +224,7 @@ auto_list_enter::auto_list_enter (pn_data_t * data_, bool next_)
|
||||
|
||||
proton::
|
||||
auto_list_enter::~auto_list_enter() {
|
||||
pn_data_exit(m_data);
|
||||
pn_data_exit (m_data);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
@ -321,3 +321,16 @@ readAndNext<long> (
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
template<>
|
||||
u_long
|
||||
proton::
|
||||
readAndNext<u_long > (
|
||||
pn_data_t * data_,
|
||||
bool tolerateDeviance_
|
||||
) {
|
||||
long rtn = pn_data_get_ulong (data_);
|
||||
pn_data_next(data_);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -46,7 +46,7 @@ namespace proton {
|
||||
pn_data_t * m_data;
|
||||
|
||||
public :
|
||||
auto_enter (pn_data_t *, bool next_ = false);
|
||||
explicit auto_enter (pn_data_t *, bool next_ = false);
|
||||
~auto_enter();
|
||||
};
|
||||
|
||||
@ -55,9 +55,13 @@ namespace proton {
|
||||
pn_data_t * m_data;
|
||||
|
||||
public :
|
||||
auto_next (pn_data_t *);
|
||||
explicit auto_next (pn_data_t *);
|
||||
auto_next (const auto_next &) = delete;
|
||||
|
||||
explicit operator pn_data_t *() {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
~auto_next();
|
||||
};
|
||||
|
||||
@ -67,7 +71,7 @@ namespace proton {
|
||||
pn_data_t * m_data;
|
||||
|
||||
public :
|
||||
auto_list_enter (pn_data_t *, bool next_ = false);
|
||||
explicit auto_list_enter (pn_data_t *, bool next_ = false);
|
||||
~auto_list_enter();
|
||||
|
||||
size_t elements() const;
|
||||
@ -81,7 +85,7 @@ namespace proton {
|
||||
|
||||
template<typename T>
|
||||
T
|
||||
readAndNext (pn_data_t * data_, bool tolerateDeviance_ = false) {
|
||||
readAndNext (pn_data_t *, bool tolerateDeviance_ = false) {
|
||||
return T{};
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ include 'webserver'
|
||||
include 'webserver:webcapsule'
|
||||
include 'experimental'
|
||||
include 'experimental:avalanche'
|
||||
include 'experimental:blobwriter'
|
||||
include 'experimental:quasar-hook'
|
||||
include 'experimental:corda-utils'
|
||||
include 'experimental:nodeinfo'
|
||||
|
Loading…
Reference in New Issue
Block a user