/*FieldCreateFactory.cpp*/ #include #include #include #include #include #include "pvIntrospect.h" #include "factory.h" namespace epics { namespace pvData { static DebugLevel debugLevel = lowDebug; static void newLine(StringBuilder buffer, int indentLevel) { *buffer += "\n"; for(int i=0; igetFieldName(); // look for duplicates for(int j=i+1; jgetFieldName(); int result = name.compare(otherName); if(result==0) { String message("duplicate fieldName "); message += name; throw std::invalid_argument(message); } } // inc reference counter fields[i]->incReferenceCount(); } } BaseStructure::~BaseStructure() { if(debugLevel==highDebug) printf("~BaseStructure %s\n",BaseField::getFieldName().c_str()); for(int i=0; idecReferenceCount(); } } FieldConstPtr BaseStructure::getField(String fieldName) const { for(int i=0; igetFieldName()); if(result==0) return pfield; } return 0; } int BaseStructure::getFieldIndex(String fieldName) const { for(int i=0; igetFieldName()); if(result==0) return i; } return -1; } void BaseStructure::toString(StringBuilder buffer,int indentLevel) const{ BaseField::toString(buffer,indentLevel); *buffer += " {"; for(int i=0; itoString(buffer,indentLevel+1); } newLine(buffer,indentLevel); *buffer += "}"; } StructureArray::~StructureArray(){} class BaseStructureArray: private BaseField,public StructureArray { public: BaseStructureArray(String fieldName,StructureConstPtr structure); virtual ~BaseStructureArray(); virtual void incReferenceCount() const {BaseField::incReferenceCount();} virtual void decReferenceCount() const {BaseField::decReferenceCount();} virtual int getReferenceCount() const {return BaseField::getReferenceCount();} virtual String getFieldName() const{ return BaseField::getFieldName(); } virtual Type getType() const{return BaseField::getType();} virtual StructureConstPtr getStructure() const { return pstructure; } virtual void toString(StringBuilder buf) const {toString(buf,0);} virtual void toString(StringBuilder buf,int indentLevel) const; private: StructureConstPtr pstructure; }; BaseStructureArray::BaseStructureArray(String fieldName,StructureConstPtr structure) : BaseField(fieldName,structureArray),pstructure(structure) { pstructure->incReferenceCount(); } BaseStructureArray::~BaseStructureArray() { if(debugLevel==highDebug) printf("~BaseStructureArray\n"); pstructure->decReferenceCount(); } void BaseStructureArray::toString(StringBuilder buffer,int indentLevel) const { BaseField::toString(buffer,indentLevel); *buffer += " structure "; pstructure->toString(buffer,indentLevel + 1); } FieldCreate::FieldCreate(){}; ScalarConstPtr FieldCreate::createScalar(String fieldName, ScalarType scalarType) const { BaseScalar *baseScalar = new BaseScalar(fieldName,scalarType); return baseScalar; } ScalarArrayConstPtr FieldCreate::createScalarArray( String fieldName,ScalarType elementType) const { BaseScalarArray *baseScalarArray = new BaseScalarArray(fieldName,elementType); return baseScalarArray; } StructureConstPtr FieldCreate::createStructure ( String fieldName,int numberFields, FieldConstPtr fields[]) const { BaseStructure *baseStructure = new BaseStructure( fieldName,numberFields,fields); return baseStructure; } StructureArrayConstPtr FieldCreate::createStructureArray( String fieldName,StructureConstPtr structure) const { BaseStructureArray *baseStructureArray = new BaseStructureArray(fieldName,structure); return baseStructureArray; } FieldConstPtr FieldCreate::create(String 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()); } } String message("field "); message += fieldName; throw std::logic_error(message); } static FieldCreate* instance = 0; class FieldCreateExt : public FieldCreate { public: FieldCreateExt(): FieldCreate(){}; }; FieldCreate * getFieldCreate() { static Mutex mutex = Mutex(); Lock xx(&mutex); if(instance==0) instance = new FieldCreateExt(); return instance; } }}