/*FieldCreateFactory.cpp*/ /** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS pvDataCPP is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include #include #include #include #include "pvIntrospect.h" #include "convert.h" #include "factory.h" #include "CDRMonitor.h" namespace epics { namespace pvData { static DebugLevel debugLevel = lowDebug; static void newLine(StringBuilder buffer, int indentLevel) { *buffer += "\n"; for(int i=0; ifieldName.c_str()); delete pImpl; pImpl = 0; } int Field::getReferenceCount() const { Lock xx(&refCountMutex); return pImpl->referenceCount; } String Field::getFieldName() const {return pImpl->fieldName;} Type Field::getType() const {return pImpl->type;} void Field::renameField(String newName) { pImpl->fieldName = newName; } void Field::incReferenceCount() const { field_node.incRef(); Lock xx(&refCountMutex); pImpl->referenceCount++; if(pImpl->type!=structure) return; StructureConstPtr structure = static_cast(this); FieldConstPtrArray fields = structure->getFields(); int numberFields = structure->getNumberFields(); for(int i=0; iincReferenceCount(); } } void Field::decReferenceCount() const { field_node.decRef(); Lock xx(&refCountMutex); if(pImpl->referenceCount<=0) { String message("logicError field "); message += pImpl->fieldName; throw std::logic_error(message); } pImpl->referenceCount--; if(pImpl->type!=structure) { if(pImpl->referenceCount==0) { delete this; } return; } StructureConstPtr structure = static_cast(this); FieldConstPtrArray fields = structure->getFields(); int numberFields = structure->getNumberFields(); for(int i=0; idecReferenceCount(); } if(pImpl->referenceCount==0) { delete this; } } void Field:: dumpReferenceCount(StringBuilder buffer,int indentLevel) const { *buffer += getFieldName(); char buf[40]; sprintf(buf," referenceCount %d",getReferenceCount()); *buffer += buf; if(pImpl->type!=structure) return; Convert *convert = getConvert(); StructureConstPtr structure = static_cast(this); FieldConstPtrArray fields = structure->getFields(); int numberFields = structure->getNumberFields(); for(int i=0; inewLine(buffer,indentLevel+1); fields[i]->dumpReferenceCount(buffer,indentLevel +1); } } void Field::toString(StringBuilder buffer,int indentLevel) const{ *buffer += " "; *buffer += pImpl->fieldName.c_str(); } static bool fieldEquals(FieldConstPtr a,FieldConstPtr b); inline bool scalarFieldEquals(ScalarConstPtr a,ScalarConstPtr b) { ScalarType ascalarType = a->getScalarType(); ScalarType bscalarType = b->getScalarType(); if(ascalarType != bscalarType) { return false; } return true; } inline bool scalarArrayFieldEquals(ScalarArrayConstPtr a,ScalarArrayConstPtr b) { ScalarType aType = a->getElementType(); ScalarType bType = b->getElementType(); if(aType != bType) { return false; } return true; } inline bool structureFieldEquals(StructureConstPtr a,StructureConstPtr b) { int length = a->getNumberFields(); if(length != b->getNumberFields()) return false; FieldConstPtrArray aFields = a->getFields(); FieldConstPtrArray bFields = b->getFields(); for(int i=0; igetStructure(); StructureConstPtr bStruct = b->getStructure(); return fieldEquals(aStruct,bStruct); } static bool fieldEquals(FieldConstPtr a,FieldConstPtr b) { const void * avoid = static_cast(a); const void * bvoid = static_cast(b); if(avoid == bvoid) return true; if(a->getFieldName() != b->getFieldName()) return false; Type atype = a->getType(); Type btype = b->getType(); if(atype!=btype) return false; if(atype==scalar) return scalarFieldEquals( static_cast(a),static_cast(b)); if(atype==scalarArray) return scalarArrayFieldEquals( static_cast(a),static_cast(b)); if(atype==structureArray) return structureArrayFieldEquals( static_cast(a),static_cast(b)); if(atype==structure) return structureFieldEquals( static_cast(a),static_cast(b)); String message("should not get here"); throw std::logic_error(message); } bool Field::operator==(const Field& field) const { return fieldEquals(this, &field); } bool Field::operator!=(const Field& field) const { return !fieldEquals(this, &field); } Scalar::Scalar(String fieldName,ScalarType scalarType) : Field(fieldName,scalar),scalarType(scalarType){} Scalar::~Scalar(){} void Scalar::toString(StringBuilder buffer,int indentLevel) const{ ScalarTypeFunc::toString(buffer,scalarType); Field::toString(buffer,indentLevel); } ScalarArray::ScalarArray(String fieldName,ScalarType elementType) : Field(fieldName,scalarArray),elementType(elementType){} ScalarArray::~ScalarArray() {} void ScalarArray::toString(StringBuilder buffer,int indentLevel) const{ ScalarTypeFunc::toString(buffer,elementType); *buffer += "[]"; Field::toString(buffer,indentLevel); } StructureArray::StructureArray(String fieldName,StructureConstPtr structure) : Field(fieldName,structureArray),pstructure(structure) { } StructureArray::~StructureArray() { if(debugLevel==highDebug) printf("~StructureArray\n"); pstructure->decReferenceCount(); } void StructureArray::toString(StringBuilder buffer,int indentLevel) const { *buffer += "structure[]"; Field::toString(buffer,indentLevel); newLine(buffer,indentLevel + 1); pstructure->toString(buffer,indentLevel + 1); } Structure::Structure (String fieldName, int numberFields, FieldConstPtrArray infields) : Field(fieldName,structure), numberFields(numberFields), fields(infields) { 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); } } } } Structure::~Structure() { if(debugLevel==highDebug) printf("~Structure %s\n",Field::getFieldName().c_str()); for(int i=0; igetFieldName()); if(result==0) return pfield; } return 0; } int Structure::getFieldIndex(String fieldName) const { for(int i=0; igetFieldName()); if(result==0) return i; } return -1; } void Structure::appendField(FieldConstPtr field) { FieldConstPtr *newFields = new FieldConstPtr[numberFields+1]; for(int i=0; i=numberFields) { throw std::invalid_argument( String("Structure::removeField index out of bounds")); } FieldConstPtr *newFields = new FieldConstPtr[numberFields-1]; fields[index]->decReferenceCount(); int ind=0; for(int i=0; itoString(buffer,indentLevel+1); if(igetType(); switch(type) { case scalar: { ScalarConstPtr pscalar = static_cast(pfield); return createScalar(fieldName,pscalar->getScalarType()); } case scalarArray: { ScalarArrayConstPtr pscalarArray = static_cast(pfield); return createScalarArray(fieldName,pscalarArray->getElementType()); } case structure: { StructureConstPtr pstructure = static_cast(pfield); return createStructure(fieldName,pstructure->getNumberFields(),pstructure->getFields()); } case structureArray: { StructureArrayConstPtr pstructureArray = static_cast(pfield); return createStructureArray(fieldName,pstructureArray->getStructure()); } } String message("field "); message += fieldName; throw std::logic_error(message); } static FieldCreate* fieldCreate = 0; FieldCreate::FieldCreate() { } FieldCreate * getFieldCreate() { static Mutex mutex; Lock xx(&mutex); if(fieldCreate==0) fieldCreate = new FieldCreate(); return fieldCreate; } }}