diff --git a/pvDataApp/factory/FieldCreateFactory.cpp b/pvDataApp/factory/FieldCreateFactory.cpp index 36f2309..6a174b1 100644 --- a/pvDataApp/factory/FieldCreateFactory.cpp +++ b/pvDataApp/factory/FieldCreateFactory.cpp @@ -3,28 +3,26 @@ #include #include #include - #include - #include "pvData.h" namespace epics { namespace pvData { - static void newLine(std::string & buffer,int indentLevel) { - buffer += "\n"; - for(int i=0; igetFieldName(); + fieldNames[i] = fields[i]->getFieldName(); } } BaseStructure::~BaseStructure() { for(int i=0; icompare(*pfield->getFieldName()); + if(result==0) return pfield; } return 0; } - int BaseStructure::getFieldIndex(std::string const& fieldName) const { + int BaseStructure::getFieldIndex(StringConstPtr fieldName) const { for(int i=0; icompare(*pfield->getFieldName()); if(result==0) return i; } return -1; } - void BaseStructure::toString(std::string &buffer,int indentLevel) const{ + void BaseStructure::toString(StringPtr buffer,int indentLevel) const{ BaseField::toString(buffer,indentLevel); - buffer += " {"; + *buffer += " {"; for(int i=0; itoString(buffer,indentLevel+1); } newLine(buffer,indentLevel); - buffer += "}"; + *buffer += "}"; + } + + StructureArray::~StructureArray(){} + + class BaseStructureArray: private BaseField,public StructureArray { + public: + BaseStructureArray(StringConstPtr fieldName,StructureConstPtr structure); + virtual ~BaseStructureArray(); + virtual StringConstPtr getFieldName() const{ + return BaseField::getFieldName(); + } + virtual Type getType() const{return BaseField::getType();} + virtual StructureConstPtr getStructure() const { return pstructure; } + virtual void toString(StringPtr buf) const {toString(buf,0);} + virtual void toString(StringPtr buf,int indentLevel) const; + private: + StructureConstPtr pstructure; + }; + + BaseStructureArray::BaseStructureArray(StringConstPtr fieldName,StructureConstPtr structure) + : BaseField(fieldName,structureArray),pstructure(structure) {} + + BaseStructureArray::~BaseStructureArray() {} + + + void BaseStructureArray::toString(StringPtr buffer,int indentLevel) const { + BaseField::toString(buffer,indentLevel); + *buffer += " structure "; + pstructure->toString(buffer,indentLevel + 1); } static std::string notImplemented = "not implemented"; +static std::string logicError = "Logic Error. Should never get here"; FieldCreate::FieldCreate(){}; - Field const & FieldCreate::create(std::string const& fieldName, - Field const & field) const - { - throw std::invalid_argument(notImplemented); - } - Scalar const & FieldCreate::createScalar(std::string const& fieldName, + ScalarConstPtr FieldCreate::createScalar(StringConstPtr fieldName, ScalarType scalarType) const { BaseScalar *baseScalar = new BaseScalar(fieldName,scalarType); - return *baseScalar; + return baseScalar; } - ScalarArray const & FieldCreate::createScalarArray( - std::string const& fieldName,ScalarType elementType) const + ScalarArrayConstPtr FieldCreate::createScalarArray( + StringConstPtr fieldName,ScalarType elementType) const { BaseScalarArray *baseScalarArray = new BaseScalarArray(fieldName,elementType); - return *baseScalarArray; + return baseScalarArray; } - Structure const & FieldCreate::createStructure ( - std::string const& fieldName,int numberFields, - FieldPtrConst fields[]) const + StructureConstPtr FieldCreate::createStructure ( + StringConstPtr fieldName,int numberFields, + FieldConstPtr fields[]) const { BaseStructure *baseStructure = new BaseStructure( fieldName,numberFields,fields); - return *baseStructure; + return baseStructure; } - StructureArray const & FieldCreate::createStructureArray( - std::string const& fieldName,Structure const & structure) const + StructureArrayConstPtr FieldCreate::createStructureArray( + StringConstPtr fieldName,StructureConstPtr structure) const { throw std::invalid_argument(notImplemented); } + FieldConstPtr FieldCreate::create(StringConstPtr fieldName, + FieldConstPtr pfield) const + { + Type type = pfield->getType(); + switch(type) { + case scalar: { + ScalarConstPtr pscalar = dynamic_cast(pfield); + return createScalar(fieldName,pscalar->getScalarType()); + } + case scalarArray: { + ScalarArrayConstPtr pscalarArray = dynamic_cast(pfield); + return createScalarArray(fieldName,pscalarArray->getElementType()); + } + case structure: { + StructureConstPtr pstructure = dynamic_cast(pfield); + return createStructure(fieldName,pstructure->getNumberFields(),pstructure->getFields()); + } + case structureArray: { + StructureArrayConstPtr pstructureArray = dynamic_cast(pfield); + return createStructureArray(fieldName,pstructureArray->getStructure()); + } + } + throw std::logic_error(logicError); + } + static FieldCreate* instance = 0; class FieldCreateExt : public FieldCreate { @@ -220,9 +268,9 @@ static std::string notImplemented = "not implemented"; FieldCreateExt(): FieldCreate(){}; }; - FieldCreate & getFieldCreate() { + FieldCreate * getFieldCreate() { if(instance==0) instance = new FieldCreateExt(); - return *instance; + return instance; } }} diff --git a/pvDataApp/factory/TypeFunc.cpp b/pvDataApp/factory/TypeFunc.cpp index dcdee1e..829a75e 100644 --- a/pvDataApp/factory/TypeFunc.cpp +++ b/pvDataApp/factory/TypeFunc.cpp @@ -10,13 +10,13 @@ namespace epics { namespace pvData { - void TypeFunc::toString(std::string &buf,const Type type) { + void TypeFunc::toString(StringPtr buf,const Type type) { static const std::string unknownString = "logic error unknown Type"; switch(type) { - case scalar : buf += "scalar"; break; - case scalarArray : buf += "scalarArray"; break; - case structure : buf += "structure"; break; - case structureArray : buf += "structureArray"; break; + case scalar : *buf += "scalar"; break; + case scalarArray : *buf += "scalarArray"; break; + case structure : *buf += "structure"; break; + case structureArray : *buf += "structureArray"; break; default: throw std::invalid_argument(unknownString); } @@ -38,29 +38,29 @@ namespace epics { namespace pvData { return false; } - ScalarType ScalarTypeFunc::getScalarType(std::string const& pvalue) { + ScalarType ScalarTypeFunc::getScalarType(StringConstPtr pvalue) { static const std::string unknownString = "error unknown ScalarType"; - if(pvalue.compare("boolean")==0) return pvBoolean; - if(pvalue.compare("byte")==0) return pvByte; - if(pvalue.compare("short")==0) return pvShort; - if(pvalue.compare("int")==0) return pvInt; - if(pvalue.compare("long")==0) return pvLong; - if(pvalue.compare("float")==0) return pvFloat; - if(pvalue.compare("double")==0) return pvDouble; - if(pvalue.compare("string")==0) return pvString; + if(pvalue->compare("boolean")==0) return pvBoolean; + if(pvalue->compare("byte")==0) return pvByte; + if(pvalue->compare("short")==0) return pvShort; + if(pvalue->compare("int")==0) return pvInt; + if(pvalue->compare("long")==0) return pvLong; + if(pvalue->compare("float")==0) return pvFloat; + if(pvalue->compare("double")==0) return pvDouble; + if(pvalue->compare("string")==0) return pvString; throw std::invalid_argument(unknownString); } - void ScalarTypeFunc::toString(std::string &buf,const ScalarType scalarType) { + void ScalarTypeFunc::toString(StringPtr buf,const ScalarType scalarType) { static const std::string unknownString = "logic error unknown ScalarType"; switch(scalarType) { - case pvBoolean : buf += "pvBoolean"; return; - case pvByte : buf += "pvByte"; return;; - case pvShort : buf += "pvShort"; return; - case pvInt : buf += "pvInt"; return; - case pvLong : buf += "pvLong"; return; - case pvFloat : buf += "pvFloat"; return; - case pvDouble : buf += "pvDouble"; return; - case pvString : buf += "pvString"; return; + case pvBoolean : *buf += "pvBoolean"; return; + case pvByte : *buf += "pvByte"; return;; + case pvShort : *buf += "pvShort"; return; + case pvInt : *buf += "pvInt"; return; + case pvLong : *buf += "pvLong"; return; + case pvFloat : *buf += "pvFloat"; return; + case pvDouble : *buf += "pvDouble"; return; + case pvString : *buf += "pvString"; return; } throw std::invalid_argument(unknownString); } diff --git a/pvDataApp/pv/Makefile b/pvDataApp/pv/Makefile index 2ecf1d4..5051490 100644 --- a/pvDataApp/pv/Makefile +++ b/pvDataApp/pv/Makefile @@ -2,6 +2,7 @@ TOP=../.. include $(TOP)/configure/CONFIG +INC += pvIntrospect.h INC += pvData.h include $(TOP)/configure/RULES diff --git a/pvDataApp/pv/pvData.h b/pvDataApp/pv/pvData.h index 2c674ee..064e008 100644 --- a/pvDataApp/pv/pvData.h +++ b/pvDataApp/pv/pvData.h @@ -1,103 +1,10 @@ /* pvData.h */ #include #include -#ifndef TYPE_H -#define TYPE_H +#ifndef PVDATA_H +#define PVDATA_H +#include "pvIntrospect.h" namespace epics { namespace pvData { - enum Type { - scalar, - scalarArray, - structure, - structureArray - }; - - class TypeFunc { - public: - static void toString(std::string &buf,const Type type); - }; - - enum ScalarType { - pvBoolean, - pvByte, - pvShort, - pvInt, - pvLong, - pvFloat, - pvDouble, - pvString - }; - - class ScalarTypeFunc { - public: - static bool isInteger(ScalarType type); - static bool isNumeric(ScalarType type); - static bool isPrimitive(ScalarType type); - static ScalarType getScalarType(std::string const& value); - static void toString(std::string &buf,const ScalarType scalarType); - }; - - class Field { - public: - virtual ~Field(); - virtual std::string const& getFieldName() const = 0; - virtual Type getType() const = 0; - virtual void toString(std::string &buf) const = 0; - virtual void toString(std::string &buf,int indentLevel) const = 0; - }; - - class Field; - class Scalar; - class ScalarArray; - class Structure; - class StructureArray; - - class Scalar : public Field{ - public: - virtual ~Scalar(); - virtual ScalarType getScalarType() const = 0; - }; - - class ScalarArray : public Field{ - public: - virtual ~ScalarArray(); - virtual ScalarType getElementType() const = 0; - }; - - typedef Field const * FieldPtrConst; - typedef FieldPtrConst * FieldPtrConstArray; - typedef std::string const * StringPtrConst; - typedef StringPtrConst * StringPtrConstArray; - - class Structure : public Field { - public: - virtual ~Structure(); - virtual int const getNumberFields() const = 0; - virtual StringPtrConstArray getFieldNames() const = 0; - virtual FieldPtrConst getField(std::string const& fieldName) const = 0; - virtual int getFieldIndex(std::string const& fieldName) const = 0; - virtual FieldPtrConstArray getFields() const = 0; - }; - - class StructureArray : public Field{ - public: - virtual ~StructureArray(); - virtual Structure const & getStructure() const = 0; - }; - - - class FieldCreate { - public: - Field const & create(std::string const& fieldName,Field const & field) const; - Scalar const & createScalar(std::string const& fieldName,ScalarType scalarType) const; - ScalarArray const & createScalarArray(std::string const& fieldName,ScalarType elementType) const; - Structure const & createStructure (std::string const& fieldName,int numberFields,FieldPtrConstArray fields) const; - StructureArray const & createStructureArray(std::string const& fieldName,Structure const & structure) const; - protected: - FieldCreate(); - }; - - extern FieldCreate & getFieldCreate(); - }} -#endif /* TYPE_H */ +#endif /* PVDATA_H */ diff --git a/pvDataApp/pv/pvIntrospect.h b/pvDataApp/pv/pvIntrospect.h new file mode 100644 index 0000000..0a7e6c1 --- /dev/null +++ b/pvDataApp/pv/pvIntrospect.h @@ -0,0 +1,111 @@ +/* pvData.h */ +#include +#include +#ifndef PVINTROSPECT_H +#define PVINTROSPECT_H +namespace epics { namespace pvData { + class Field; + class Scalar; + class ScalarArray; + class Structure; + class StructureArray; + typedef std::string * StringPtr; + typedef std::string const * StringConstPtr; //pointer to constant string + typedef StringConstPtr * StringConstPtrArray;//array of pointers to constant string + typedef Field const * FieldConstPtr; //pointer to constant field + typedef FieldConstPtr * FieldConstPtrArray; //array of pointers to const field + typedef Scalar const * ScalarConstPtr; //pointer to constant field + typedef ScalarArray const * ScalarArrayConstPtr; + typedef Structure const * StructureConstPtr; + typedef StructureArray const * StructureArrayConstPtr; + + enum Type { + scalar, + scalarArray, + structure, + structureArray + }; + + class TypeFunc { + public: + static void toString(StringPtr buf,const Type type); + }; + + enum ScalarType { + pvBoolean, + pvByte, + pvShort, + pvInt, + pvLong, + pvFloat, + pvDouble, + pvString + }; + + class ScalarTypeFunc { + public: + static bool isInteger(ScalarType type); + static bool isNumeric(ScalarType type); + static bool isPrimitive(ScalarType type); + static ScalarType getScalarType(StringConstPtr value); + static void toString(StringPtr buf,const ScalarType scalarType); + }; + + class Field { + public: + virtual ~Field(); + virtual StringConstPtr getFieldName() const = 0; + virtual Type getType() const = 0; + virtual void toString(StringPtr buf) const = 0; + virtual void toString(StringPtr buf,int indentLevel) const = 0; + }; + + + class Scalar : public Field{ + public: + virtual ~Scalar(); + virtual ScalarType getScalarType() const = 0; + }; + + class ScalarArray : public Field{ + public: + virtual ~ScalarArray(); + virtual ScalarType getElementType() const = 0; + }; + + + class Structure : public Field { + public: + virtual ~Structure(); + virtual int const getNumberFields() const = 0; + virtual StringConstPtrArray getFieldNames() const = 0; + virtual FieldConstPtr getField(StringConstPtr fieldName) const = 0; + virtual int getFieldIndex(StringConstPtr fieldName) const = 0; + virtual FieldConstPtrArray getFields() const = 0; + }; + + class StructureArray : public Field{ + public: + virtual ~StructureArray(); + virtual StructureConstPtr getStructure() const = 0; + }; + + + class FieldCreate { + public: + FieldConstPtr create(StringConstPtr fieldName,FieldConstPtr field) const; + ScalarConstPtr createScalar(StringConstPtr fieldName,ScalarType scalarType) const; + ScalarArrayConstPtr createScalarArray(StringConstPtr fieldName, + ScalarType elementType) const; + StructureConstPtr createStructure (StringConstPtr fieldName, + int numberFields,FieldConstPtrArray fields) const; + StructureArrayConstPtr createStructureArray(StringConstPtr fieldName, + StructureConstPtr structure) const; + protected: + FieldCreate(); + }; + + extern FieldCreate * getFieldCreate(); + +}} +#endif /* PVINTROSPECT_H */ diff --git a/pvDataApp/test/test.cpp b/pvDataApp/test/test.cpp index 372fbaf..8e8c1b6 100644 --- a/pvDataApp/test/test.cpp +++ b/pvDataApp/test/test.cpp @@ -19,43 +19,44 @@ int main(int argc,char *argv[]) bool value = ScalarTypeFunc::isNumeric(scalarType); printf("isNumeric %s\n",(value ? "true" : "false")); std::string* myString= new std::string("type "); - TypeFunc::toString(*myString,type); + TypeFunc::toString(myString,type); *myString += " scalarType "; - ScalarTypeFunc::toString(*myString,scalarType); + ScalarTypeFunc::toString(myString,scalarType); printf("%s\n",myString->c_str()); - FieldCreate &fieldCreate = getFieldCreate(); + FieldCreate * pfieldCreate = getFieldCreate(); std::string valueName("value"); - Scalar const & scalar = fieldCreate.createScalar(valueName,scalarType); - type = scalar.getType(); + ScalarConstPtr pscalar = pfieldCreate->createScalar(&valueName,scalarType); + type = pscalar->getType(); myString->clear(); *myString += "type "; - TypeFunc::toString(*myString,type); + TypeFunc::toString(myString,type); printf("%s\n",myString->c_str()); myString->clear(); *myString += "fieldName "; - std::string const & fieldName = scalar.getFieldName(); - *myString += fieldName; + StringConstPtr pfieldName = pscalar->getFieldName(); + *myString += *pfieldName; printf("%s\n",myString->c_str()); myString->clear(); - scalar.toString(*myString); + pscalar->toString(myString); printf("%s\n",myString->c_str()); - ScalarArray const & scalarArray = fieldCreate.createScalarArray(valueName,pvString); + ScalarArrayConstPtr pscalarArray = pfieldCreate->createScalarArray(&valueName,pvString); myString->clear(); - scalarArray.toString(*myString); + pscalarArray->toString(myString); printf("%s\n",myString->c_str()); int numberFields = 2; - FieldPtrConst fields[numberFields]; + FieldConstPtr fields[numberFields]; std::string name0("high"); std::string name1("low"); - fields[0] = &fieldCreate.createScalar(name0,pvDouble); - fields[1] = &fieldCreate.createScalar(name1,pvDouble); - Structure const & structure = fieldCreate.createStructure(valueName,numberFields,fields); + fields[0] = pfieldCreate->createScalar(&name0,pvDouble); + fields[1] = pfieldCreate->createScalar(&name1,pvDouble); + StructureConstPtr pstructure = pfieldCreate->createStructure( + &valueName,numberFields,fields); myString->clear(); - structure.toString(*myString); + pstructure->toString(myString); printf("%s\n",myString->c_str()); - Field const & field = structure; + FieldConstPtr pfield = pstructure; myString->clear(); - field.toString(*myString); + pfield->toString(myString); printf("as Field\n%s/n",myString->c_str()); return(0); }