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
sayer/1.4-spce2.6
Stefan Sayer 19 years ago
parent d5453745b2
commit 6fed281bac

@ -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<std::string, std::string>& v)
: type(Undef) {
assertStruct();
for (map<std::string, std::string>::iterator it=
v.begin();it!= v.end();it++)
(*v_struct)[it->first] = AmArg(it->second.c_str());
}
AmArg::AmArg(map<std::string, AmArg>& v)
: type(Undef) {
assertStruct();
for (map<std::string, AmArg>::iterator it=
v.begin();it!= v.end();it++)
(*v_struct)[it->first] = it->second;
}
AmArg::AmArg(vector<std::string>& v)
: type(Array) {
assertArray(0);
for (vector<std::string>::iterator it
= v.begin(); it != v.end(); it++) {
push(AmArg(it->c_str()));
}
}
AmArg::AmArg(const vector<int>& v )
: type(Array) {
assertArray(0);
for (vector<int>::const_iterator it
= v.begin(); it != v.end(); it++) {
push(AmArg(*it));
}
}
AmArg::AmArg(const vector<double>& v)
: type(Array) {
assertArray(0);
for (vector<double>::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;i<a.size();i++)
v_array->push_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<std::string> AmArg::enumerateKeys() const {
assertStruct();
std::vector<std::string> 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<fmt_len;i++) {
switch (format[i]) {
case 'i': assertArgInt(get(i)); break;
case 'f': assertArgDouble(get(i)); break;
case 's': assertArgCStr(get(i)); break;
case 'o': assertArgAObject(get(i)); break;
case 'a': assertArgArray(get(i)); break;
case 'b': assertArgBlob(get(i)); break;
default: ERROR("ignoring unknown format type '%c'\n",
format[i]); break;
string got;
try {
for (size_t i=0;i<fmt_len;i++) {
switch (format[i]) {
case 'i': assertArgInt(get(i)); got+='i'; break;
case 'f': assertArgDouble(get(i)); got+='f'; break;
case 's': assertArgCStr(get(i)); got+='s'; break;
case 'o': assertArgAObject(get(i)); got+='o'; break;
case 'a': assertArgArray(get(i)); got+='a'; break;
case 'b': assertArgBlob(get(i)); got+='b'; break;
case 'u': assertArgStruct(get(i)); got+='a'; break;
default: got+='?'; ERROR("ignoring unknown format type '%c'\n",
format[i]); break;
}
}
} catch (...) {
ERROR("parameter mismatch: expected '%s', got '%s...'\n",
format, got.c_str());
throw;
}
}
#define VECTOR_GETTER(type, name, getter) \
vector<type> AmArg::name() const { \
vector<type> res; \
for (size_t i=0;i<size();i++) \
res.push_back(get(i).getter()); \
return res; \
}
VECTOR_GETTER(string, asStringVector, asCStr)
VECTOR_GETTER(int, asIntVector, asInt)
VECTOR_GETTER(double, asDoubleVector, asDouble)
VECTOR_GETTER(ArgObject*, asArgObjectVector, asObject)
#undef VECTOR_GETTER
vector<ArgBlob> AmArg::asArgBlobVector() const {
vector<ArgBlob> res;
for (size_t i=0;i<size();i++)
res.push_back(*get(i).asBlob());
return res;
}

@ -34,29 +34,27 @@
#include <vector>
using std::vector;
#include <string>
using std::string;
#include <map>
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<AmArg> ValueArray;
typedef std::map<std::string, AmArg> 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<std::string>& v);
AmArg(const vector<int>& v );
AmArg(const vector<double>& v);
AmArg(std::map<std::string, std::string>& v);
AmArg(std::map<std::string, AmArg>& 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<string> asStringVector() const;
vector<int> asIntVector() const;
vector<double> asDoubleVector() const;
vector<ArgObject*> asArgObjectVector() const;
vector<ArgBlob> 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<std::string> 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

Loading…
Cancel
Save