From 6fed281bac3c15cc2d9c175006009bf82a2444b4 Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Mon, 17 Dec 2007 04:57:15 +0000 Subject: [PATCH] adds struct (attribute-value map), some convenience contructors, and correct assignment operator git-svn-id: http://svn.berlios.de/svnroot/repos/sems/trunk@566 8eb893ce-cfd4-0310-b710-fb5ebe64c474 --- core/AmArg.cpp | 230 +++++++++++++++++++++++++++++++++++++++++++++---- core/AmArg.h | 158 ++++++++++++++++++++------------- 2 files changed, 309 insertions(+), 79 deletions(-) diff --git a/core/AmArg.cpp b/core/AmArg.cpp index bb9e762a..34a21058 100644 --- a/core/AmArg.cpp +++ b/core/AmArg.cpp @@ -28,27 +28,88 @@ #include "AmArg.h" #include "log.h" +const char* t2str(int type) { + switch (type) { + case 0: return "Undef"; + case 1: return "Int"; + case 2: return "Double"; + case 3: return "CStr"; + case 4: return "AObject"; + case 5: return "Blob"; + case 6: return "Array"; + case 7: return "Struct"; + default: return "unknown"; + } +} + AmArg::AmArg(const AmArg& v) -{ +{ type = Undef; + *this = v; +} + +AmArg& AmArg::operator=(const AmArg& v) { if (this != &v) { invalidate(); type = v.type; switch(type){ - case Int: { v_int = v.v_int; } break; + case Int: { v_int = v.v_int; } break; case Double: { v_double = v.v_double; } break; - case CStr: { v_cstr = strdup(v.v_cstr); } break; - case AObject:{ v_obj = v.v_obj; } break; + case CStr: { v_cstr = strdup(v.v_cstr); } break; + case AObject:{ v_obj = v.v_obj; } break; case Array: { v_array = new ValueArray(*v.v_array); } break; - case Blob: { - v_blob = new ArgBlob(*v.v_blob); - } break; + case Struct: { v_struct = new ValueStruct(*v.v_struct); } break; + case Blob: { v_blob = new ArgBlob(*v.v_blob); } break; case Undef: break; default: assert(0); } } + return *this; +} + +AmArg::AmArg(map& v) + : type(Undef) { + assertStruct(); + for (map::iterator it= + v.begin();it!= v.end();it++) + (*v_struct)[it->first] = AmArg(it->second.c_str()); +} + +AmArg::AmArg(map& v) + : type(Undef) { + assertStruct(); + for (map::iterator it= + v.begin();it!= v.end();it++) + (*v_struct)[it->first] = it->second; +} + +AmArg::AmArg(vector& v) + : type(Array) { + assertArray(0); + for (vector::iterator it + = v.begin(); it != v.end(); it++) { + push(AmArg(it->c_str())); + } +} + +AmArg::AmArg(const vector& v ) + : type(Array) { + assertArray(0); + for (vector::const_iterator it + = v.begin(); it != v.end(); it++) { + push(AmArg(*it)); + } +} + +AmArg::AmArg(const vector& v) + : type(Array) { + assertArray(0); + for (vector::const_iterator it + = v.begin(); it != v.end(); it++) { + push(AmArg(*it)); + } } void AmArg::assertArray() { @@ -79,9 +140,26 @@ void AmArg::assertArray(size_t s) { v_array->resize(s); } +void AmArg::assertStruct() { + if (Struct == type) + return; + if (Undef == type) { + type = Struct; + v_struct = new ValueStruct(); + return; + } + throw TypeMismatchException(); +} + +void AmArg::assertStruct() const { + if (Struct != type) + throw TypeMismatchException(); +} + void AmArg::invalidate() { if(type == CStr) { free((void*)v_cstr); } else if(type == Array) { delete v_array; } + else if(type == Struct) { delete v_struct; } else if(type == Blob) { delete v_blob; } type = Undef; } @@ -91,8 +169,20 @@ void AmArg::push(const AmArg& a) { v_array->push_back(a); } +void AmArg::concat(const AmArg& a) { + assertArray(); + if (a.getType() == Array) { + for (size_t i=0;ipush_back(a[i]); + } else { + v_array->push_back(a); + } +} + const size_t AmArg::size() const { - assertArray(); + if ((Array != type) && (Struct != type)) + throw TypeMismatchException(); + return v_array->size(); } @@ -117,18 +207,122 @@ AmArg& AmArg::operator[](size_t idx) { return (*v_array)[idx]; } +AmArg& AmArg::operator[](size_t idx) const { + assertArray(); + if (idx >= v_array->size()) + throw OutOfBoundsException(); + + return (*v_array)[idx]; +} + +AmArg& AmArg::operator[](int idx) { + if (idx<0) + throw OutOfBoundsException(); + + assertArray(idx+1); + return (*v_array)[idx]; +} + +AmArg& AmArg::operator[](int idx) const { + if (idx<0) + throw OutOfBoundsException(); + + assertArray(); + if ((size_t)idx >= v_array->size()) + throw OutOfBoundsException(); + + return (*v_array)[idx]; +} + +AmArg& AmArg::operator[](std::string key) { + assertStruct(); + return (*v_struct)[key]; +} + +AmArg& AmArg::operator[](std::string key) const { + assertStruct(); + return (*v_struct)[key]; +} + +AmArg& AmArg::operator[](const char* key) { + assertStruct(); + return (*v_struct)[key]; +} + +AmArg& AmArg::operator[](const char* key) const { + assertStruct(); + return (*v_struct)[key]; +} + +bool AmArg::hasMember(const char* name) const { + return type == Struct && v_struct->find(name) != v_struct->end(); +} + +bool AmArg::hasMember(const string& name) const { + return type == Struct && v_struct->find(name) != v_struct->end(); +} + +std::vector AmArg::enumerateKeys() const { + assertStruct(); + std::vector res; + for (ValueStruct::iterator it = + v_struct->begin(); it != v_struct->end(); it++) + res.push_back(it->first); + return res; +} + +AmArg::ValueStruct::const_iterator AmArg::begin() const { + assertStruct(); + return v_struct->begin(); +} + +AmArg::ValueStruct::const_iterator AmArg::end() const { + assertStruct(); + return v_struct->end(); +} + + void AmArg::assertArrayFmt(const char* format) const { size_t fmt_len = strlen(format); - for (size_t i=0;i AmArg::name() const { \ + vector res; \ + for (size_t i=0;i AmArg::asArgBlobVector() const { + vector res; + for (size_t i=0;i using std::vector; +#include +using std::string; + +#include +using std::map; + #include "log.h" -/** - * base for Objects as @see AmArg parameter, which are _not_owned_ by the AmArg object (!) - * - * this may e.g. used to pass an AmSession through DI API - */ +/** base for Objects as @see AmArg parameter, not owned by AmArg (!) */ class ArgObject { public: ArgObject() { } virtual ~ArgObject() { } }; -/** - * ArgBlob is a structure which holds and owns a binary data 'blob'. - */ - struct ArgBlob { char* data; int len; - ArgBlob() - : data(NULL),len(0) +ArgBlob() +: data(NULL),len(0) { } @@ -73,21 +71,11 @@ struct ArgBlob { if (data) memcpy(data, _data, len); } - + ~ArgBlob() { if (data) free(data); } }; -/** \brief variable type argument for DynInvoke APIs. - * - * This variant can have the following types: - * check type getter - * i - int asInt() - * f - double asDouble() - * s - cstr asCStr() - * o - object asObject - object not owned by the Arg - * b - blob asBlob - data (ArgBlob) owned by the Arg - * a - array get()/operator [] - */ +/** \brief variable type argument for DynInvoke APIs */ class AmArg { public: @@ -98,10 +86,11 @@ class AmArg Int, Double, CStr, - AObject, // for passing pointers to objects not owned by AmArg + AObject, // for passing pointers to objects not owned by AmArg Blob, - Array + Array, + Struct }; struct OutOfBoundsException { @@ -113,8 +102,10 @@ class AmArg }; typedef std::vector ValueArray; + typedef std::map ValueStruct; - private: // type + private: + // type short type; // value @@ -125,71 +116,88 @@ class AmArg ArgObject* v_obj; ArgBlob* v_blob; ValueArray* v_array; + ValueStruct* v_struct; }; void assertArray(); void assertArray() const; + void assertStruct(); + void assertStruct() const; + void invalidate(); public: - AmArg() - : type(Undef) - { } - + AmArg() + : type(Undef) + { } + AmArg(const AmArg& v); - AmArg(const int& v) - : type(Int), + AmArg(const int& v) + : type(Int), v_int(v) { } - - AmArg(const double& v) - : type(Double), + + AmArg(const double& v) + : type(Double), v_double(v) { } + + AmArg(const char* v) + : type(CStr) + { + v_cstr = strdup(v); + } + + AmArg(const ArgBlob v) + : type(Blob) + { + v_blob = new ArgBlob(v); + } - AmArg(const char* v) - : type(CStr) - { - v_cstr = strdup(v); - } - - AmArg(const ArgBlob v) - : type(Blob) - { - v_blob = new ArgBlob(v); - } - + // convenience constructors + AmArg(vector& v); + AmArg(const vector& v ); + AmArg(const vector& v); + AmArg(std::map& v); + AmArg(std::map& v); + ~AmArg() { invalidate(); } short getType() const { return type; } + AmArg& operator=(const AmArg& rhs); + #define isArgArray(a) (AmArg::Array == a.getType()) +#define isArgStruct(a)(AmArg::Struct == a.getType()) #define isArgDouble(a) (AmArg::Array == a.getType()) #define isArgInt(a) (AmArg::Int == a.getType()) #define isArgCStr(a) (AmArg::CStr == a.getType()) #define isArgAObject(a) (AmArg::AObject == a.getType()) #define isArgBlob(a) (AmArg::Blob == a.getType()) -#define assertArgArray(a) \ - if (!isArgArray(a)) \ +#define assertArgArray(a) \ + if (!isArgArray(a)) \ throw AmArg::TypeMismatchException(); -#define assertArgDouble(a) \ - if (!isArgDouble(a)) \ +#define assertArgDouble(a) \ + if (!isArgDouble(a)) \ throw AmArg::TypeMismatchException(); -#define assertArgInt(a) \ - if (!isArgInt(a)) \ +#define assertArgInt(a) \ + if (!isArgInt(a)) \ throw AmArg::TypeMismatchException(); -#define assertArgCStr(a) \ - if (!isArgCStr(a)) \ +#define assertArgCStr(a) \ + if (!isArgCStr(a)) \ throw AmArg::TypeMismatchException(); -#define assertArgAObject(a) \ - if (!isArgAObject(a)) \ +#define assertArgAObject(a) \ + if (!isArgAObject(a)) \ throw AmArg::TypeMismatchException(); -#define assertArgBlob(a) \ - if (!isArgBlob(a)) \ +#define assertArgBlob(a) \ + if (!isArgBlob(a)) \ + throw AmArg::TypeMismatchException(); +#define assertArgStruct(a) \ + if (!isArgStruct(a)) \ throw AmArg::TypeMismatchException(); void setBorrowedPointer(ArgObject* v) { @@ -203,10 +211,18 @@ class AmArg ArgObject* asObject() const { return v_obj; } ArgBlob* asBlob() const { return v_blob; } + vector asStringVector() const; + vector asIntVector() const; + vector asDoubleVector() const; + vector asArgObjectVector() const; + vector asArgBlobVector() const; + // operations on arrays void assertArray(size_t s); void push(const AmArg& a); + + void concat(const AmArg& a); const size_t size() const; @@ -218,10 +234,28 @@ class AmArg /** resizes array if too small */ AmArg& operator[](size_t idx); + /** throws OutOfBoundsException if array too small */ + AmArg& operator[](size_t idx) const; + + /** resizes array if too small */ + AmArg& operator[](int idx); + /** throws OutOfBoundsException if array too small */ + AmArg& operator[](int idx) const; + + AmArg& operator[](std::string key); + AmArg& operator[](std::string key) const; + AmArg& operator[](const char* key); + AmArg& operator[](const char* key) const; + + /** Check for the existence of a struct member by name. */ + bool hasMember(const std::string& name) const; + bool hasMember(const char* name) const; + + std::vector enumerateKeys() const; + ValueStruct::const_iterator begin() const; + ValueStruct::const_iterator end() const; /** - * check ArgArray for type correctness of the elements - * * throws exception if arg array does not conform to spec * i - int * f - double @@ -229,6 +263,7 @@ class AmArg * o - object * b - blob * a - array + * u - struct * * e.g. "ssif" -> [cstr, cstr, int, double] */ @@ -236,3 +271,4 @@ class AmArg }; #endif +