2019-08-15 20:16:20 +00:00
|
|
|
#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>
|
|
|
|
|
|
|
|
#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"
|
2019-08-17 15:11:58 +00:00
|
|
|
#include "amqp/CompositeFactory.h"
|
2019-08-15 20:16:20 +00:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
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::cout << std::endl << "Types in schema: " << std::endl
|
|
|
|
<< *envelope << std::endl); // NOLINT
|
|
|
|
}
|
|
|
|
|
2019-08-17 15:11:58 +00:00
|
|
|
amqp::internal::CompositeFactory cf;
|
2019-08-15 20:16:20 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|