diff --git a/pvDataApp/factory/AbstractPVField.h b/pvDataApp/factory/AbstractPVField.h index a04ff81..826d80d 100644 --- a/pvDataApp/factory/AbstractPVField.h +++ b/pvDataApp/factory/AbstractPVField.h @@ -10,206 +10,261 @@ namespace epics { namespace pvData { - static String notImplemented("not implemented"); - class PVFieldPvt { - public: - PVFieldPvt(PVStructure *parent,FieldConstPtr field); - ~PVFieldPvt(); - PVStructure *parent; - FieldConstPtr field; - int fieldOffset; - int nextFieldOffset; - PVAuxInfo *pvAuxInfo; - bool immutable; - Requester *requester; - PostHandler *postHandler; - }; +class PVFieldPvt { +public: + PVFieldPvt(PVStructure *parent,FieldConstPtr field); + ~PVFieldPvt(); + PVStructure *parent; + FieldConstPtr field; + int fieldOffset; + int nextFieldOffset; + PVAuxInfo *pvAuxInfo; + bool immutable; + Requester *requester; + PostHandler *postHandler; +}; - PVFieldPvt::PVFieldPvt(PVStructure *parent,FieldConstPtr field) - : parent(parent),field(field), - fieldOffset(0), nextFieldOffset(0), - pvAuxInfo(0), - immutable(epicsFalse),requester(0),postHandler(0) - { - delete pvAuxInfo; - field->incReferenceCount(); - } +PVFieldPvt::PVFieldPvt(PVStructure *parent,FieldConstPtr field) +: parent(parent),field(field), + fieldOffset(0), nextFieldOffset(0), + pvAuxInfo(0), + immutable(epicsFalse),requester(0),postHandler(0) +{ + delete pvAuxInfo; + field->incReferenceCount(); +} - PVFieldPvt::~PVFieldPvt() - { - field->decReferenceCount(); - } +PVFieldPvt::~PVFieldPvt() +{ + field->decReferenceCount(); +} - PVField::PVField(PVStructure *parent,FieldConstPtr field) - : pImpl(new PVFieldPvt(parent,field)) - {} +PVField::PVField(PVStructure *parent,FieldConstPtr field) +: pImpl(new PVFieldPvt(parent,field)) +{} - PVField::~PVField() - { - delete pImpl; - } +PVField::~PVField() +{ + delete pImpl; +} - String PVField::getRequesterName() - { - static String none("none"); - if(pImpl->requester!=0) return pImpl->requester->getRequesterName(); - return none; - } +String PVField::getRequesterName() +{ +static String none("none"); +if(pImpl->requester!=0) return pImpl->requester->getRequesterName(); +return none; +} - void PVField::message(String message,MessageType messageType) - { - if(pImpl->requester) { - pImpl->requester->message(message,messageType); - } else { - printf("%s %s %s\n", - messageTypeName[messageType].c_str(), - pImpl->field->getFieldName().c_str(), - message.c_str()); - } - } - void PVField::setRequester(Requester *prequester) - { - static String requesterPresent = - "Logic Error. requester is already present"; - if(pImpl->requester==0) { - pImpl->requester = prequester; - return; - } - throw std::logic_error(requesterPresent); - } +void PVField::message(String message,MessageType messageType) +{ +if(pImpl->requester) { + pImpl->requester->message(message,messageType); +} else { + printf("%s %s %s\n", + messageTypeName[messageType].c_str(), + pImpl->field->getFieldName().c_str(), + message.c_str()); +} +} +void PVField::setRequester(Requester *prequester) +{ +static String requesterPresent = + "Logic Error. requester is already present"; +if(pImpl->requester==0) { + pImpl->requester = prequester; + return; +} +throw std::logic_error(requesterPresent); +} - int PVField::getFieldOffset() - { - if(pImpl->nextFieldOffset==0) computeOffset(this); - return pImpl->fieldOffset; - } +int PVField::getFieldOffset() +{ +if(pImpl->nextFieldOffset==0) computeOffset(this); +return pImpl->fieldOffset; +} - int PVField::getNextFieldOffset() - { - if(pImpl->nextFieldOffset==0) computeOffset(this); - return pImpl->nextFieldOffset; - } +int PVField::getNextFieldOffset() +{ +if(pImpl->nextFieldOffset==0) computeOffset(this); +return pImpl->nextFieldOffset; +} - int PVField::getNumberFields() - { - if(pImpl->nextFieldOffset==0) computeOffset(this); - return (pImpl->nextFieldOffset - pImpl->fieldOffset); - } +int PVField::getNumberFields() +{ +if(pImpl->nextFieldOffset==0) computeOffset(this); +return (pImpl->nextFieldOffset - pImpl->fieldOffset); +} - PVAuxInfo * PVField::getPVAuxInfo(){ - if(pImpl->pvAuxInfo==0) { - pImpl->pvAuxInfo = new PVAuxInfo(this); - } - return pImpl->pvAuxInfo; - } +PVAuxInfo * PVField::getPVAuxInfo(){ +if(pImpl->pvAuxInfo==0) { + pImpl->pvAuxInfo = new PVAuxInfo(this); +} +return pImpl->pvAuxInfo; +} - bool PVField::isImmutable() {return pImpl->immutable;} +bool PVField::isImmutable() {return pImpl->immutable;} - void PVField::setImmutable() {pImpl->immutable = epicsTrue;} +void PVField::setImmutable() {pImpl->immutable = epicsTrue;} - FieldConstPtr PVField::getField() {return pImpl->field;} +FieldConstPtr PVField::getField() {return pImpl->field;} - PVStructure * PVField::getParent() {return pImpl->parent;} +PVStructure * PVField::getParent() {return pImpl->parent;} - void PVField::replacePVField(PVField * newPVField) - { - throw std::logic_error(notImplemented); - } +void PVField::replacePVField(PVField * newPVField) +{ + PVStructure *parent = getParent(); + if(parent==0) { + String message("PVField::replacePVField no parent"); + throw std::invalid_argument(message); + } + PVFieldPtrArray pvFields = parent->getPVFields(); + int index = -1; + String fieldName = pImpl->field->getFieldName(); + int length = parent->getStructure()->getNumberFields(); + for(int i=0; igetField()->getFieldName().compare(fieldName) ==0) { + index = i; + break; + } + } + if(index==-1) { + String message("PVField::replacePVField did not find field in parent"); + throw std::logic_error(message); + } + pvFields[index] = newPVField; + parent->replaceStructure(); +} - void PVField::renameField(String newName) - { - throw std::logic_error(notImplemented); - } - - void PVField::postPut() - { - if(pImpl->postHandler!=0) pImpl->postHandler->postPut(); - } - - void PVField::setPostHandler(PostHandler *ppostHandler) - { - throw std::logic_error(notImplemented); - } - - void PVField::toString(StringBuilder buf) {toString(buf,0);} - - void PVField::toString(StringBuilder buf,int indentLevel) - { - if(pImpl->pvAuxInfo==0) return; - pImpl->pvAuxInfo->toString(buf,indentLevel); - } - - void PVField::computeOffset(PVField * pvField) { - PVStructure *pvTop = pvField->getParent(); - Type type = pvField->getField()->getType(); - if(type!=structure) { - pvField->pImpl->nextFieldOffset = 1; - return; +void PVField::renameField(String newName) +{ + FieldCreate *fieldCreate = getFieldCreate(); + switch(pImpl->field->getType()) { + case scalar: { + ScalarConstPtr scalar = (ScalarConstPtr)pImpl->field; + scalar = fieldCreate->createScalar(newName, scalar->getScalarType()); + pImpl->field = scalar; + break; } - if(pvTop==0) { - pvTop = (PVStructure *)pvField; - } else { - while(pvTop->getParent()!=0) { - pvTop = pvTop->getParent(); - } - } - int offset = 0; - int nextOffset = 1; - PVFieldPtrArray pvFields = pvTop->getPVFields(); - for(int i=0; i < pvTop->getStructure()->getNumberFields(); i++) { - offset = nextOffset; - PVField *pvField = pvFields[i]; - FieldConstPtr field = pvField->getField(); - switch(field->getType()) { - case scalar: - case scalarArray: - case structureArray:{ - nextOffset++; - pvField->pImpl->fieldOffset = offset; - pvField->pImpl->nextFieldOffset = nextOffset; - break; - } - case structure: { - pvField->computeOffset(pvField,offset); - nextOffset = pvField->getNextFieldOffset(); - } - } + case scalarArray: { + ScalarArrayConstPtr array = (ScalarArrayConstPtr)pImpl->field; + array = fieldCreate->createScalarArray(newName, array->getElementType()); + pImpl->field = array; + break; } - PVField *top = (PVField *)pvTop; - top->pImpl->fieldOffset = 0; - top->pImpl->nextFieldOffset = nextOffset; - } + case structure: { + StructureConstPtr structure = (StructureConstPtr)pImpl->field; + FieldConstPtrArray origFields = structure->getFields(); + int numberFields = structure->getNumberFields(); + structure = fieldCreate->createStructure(newName,numberFields,origFields); + pImpl->field = structure; + break; + } + case structureArray: { + StructureArrayConstPtr structureArray = (StructureArrayConstPtr)pImpl->field; + structureArray = fieldCreate->createStructureArray(newName, + structureArray->getStructure()); + pImpl->field = structureArray; + } + } + String message("PVField::renameField logic error. should not get here"); + throw std::logic_error(message); +} - void PVField::computeOffset(PVField * pvField,int offset) { - int beginOffset = offset; - int nextOffset = offset + 1; - PVStructure *pvStructure = (PVStructure *)pvField; - PVFieldPtrArray pvFields = pvStructure->getPVFields(); - for(int i=0; i < pvStructure->getStructure()->getNumberFields(); i++) { - offset = nextOffset; - PVField *pvSubField = pvFields[i]; - FieldConstPtr field = pvSubField->getField(); - switch(field->getType()) { - case scalar: - case scalarArray: - case structureArray: { - nextOffset++; - pvSubField->pImpl->fieldOffset = offset; - pvSubField->pImpl->nextFieldOffset = nextOffset; - break; - } - case structure: { - pvSubField->computeOffset(pvSubField,offset); - nextOffset = pvSubField->getNextFieldOffset(); - } - } - } - pvField->pImpl->fieldOffset = beginOffset; - pvField->pImpl->nextFieldOffset = nextOffset; - } +void PVField::postPut() +{ + if(pImpl->postHandler!=0) pImpl->postHandler->postPut(); +} + +void PVField::setPostHandler(PostHandler *postHandler) +{ + if(pImpl->postHandler!=0) { + if(postHandler==pImpl->postHandler) return; + String message("PVField::setPostHandler a postHandler is already registered"); + throw std::logic_error(message); + } + pImpl->postHandler = postHandler; +} + +void PVField::toString(StringBuilder buf) {toString(buf,0);} + +void PVField::toString(StringBuilder buf,int indentLevel) +{ + if(pImpl->pvAuxInfo==0) return; + pImpl->pvAuxInfo->toString(buf,indentLevel); +} + +void PVField::computeOffset(PVField * pvField) { + PVStructure *pvTop = pvField->getParent(); + Type type = pvField->getField()->getType(); + if(type!=structure) { + pvField->pImpl->nextFieldOffset = 1; + return; + } + if(pvTop==0) { + pvTop = (PVStructure *)pvField; + } else { + while(pvTop->getParent()!=0) { + pvTop = pvTop->getParent(); + } + } + int offset = 0; + int nextOffset = 1; + PVFieldPtrArray pvFields = pvTop->getPVFields(); + for(int i=0; i < pvTop->getStructure()->getNumberFields(); i++) { + offset = nextOffset; + PVField *pvField = pvFields[i]; + FieldConstPtr field = pvField->getField(); + switch(field->getType()) { + case scalar: + case scalarArray: + case structureArray:{ + nextOffset++; + pvField->pImpl->fieldOffset = offset; + pvField->pImpl->nextFieldOffset = nextOffset; + break; + } + case structure: { + pvField->computeOffset(pvField,offset); + nextOffset = pvField->getNextFieldOffset(); + } + } + } + PVField *top = (PVField *)pvTop; + top->pImpl->fieldOffset = 0; + top->pImpl->nextFieldOffset = nextOffset; +} + +void PVField::computeOffset(PVField * pvField,int offset) { + int beginOffset = offset; + int nextOffset = offset + 1; + PVStructure *pvStructure = (PVStructure *)pvField; + PVFieldPtrArray pvFields = pvStructure->getPVFields(); + for(int i=0; i < pvStructure->getStructure()->getNumberFields(); i++) { + offset = nextOffset; + PVField *pvSubField = pvFields[i]; + FieldConstPtr field = pvSubField->getField(); + switch(field->getType()) { + case scalar: + case scalarArray: + case structureArray: { + nextOffset++; + pvSubField->pImpl->fieldOffset = offset; + pvSubField->pImpl->nextFieldOffset = nextOffset; + break; + } + case structure: { + pvSubField->computeOffset(pvSubField,offset); + nextOffset = pvSubField->getNextFieldOffset(); + } + } + } + pvField->pImpl->fieldOffset = beginOffset; + pvField->pImpl->nextFieldOffset = nextOffset; +} }} #endif /* ABSTRACTPVFIELD_H */ diff --git a/pvDataApp/factory/BasePVStructure.h b/pvDataApp/factory/BasePVStructure.h index 1f05ee1..2ea1fce 100644 --- a/pvDataApp/factory/BasePVStructure.h +++ b/pvDataApp/factory/BasePVStructure.h @@ -198,6 +198,11 @@ namespace epics { namespace pvData { throw std::logic_error(notImplemented); } + void PVStructure::replaceStructure() + { + throw std::logic_error(notImplemented); + } + class BasePVStructure : public PVStructure { public: BasePVStructure(PVStructure *parent,StructureConstPtr structure); diff --git a/pvDataApp/factory/Convert.cpp b/pvDataApp/factory/Convert.cpp index 275a81d..2d48422 100644 --- a/pvDataApp/factory/Convert.cpp +++ b/pvDataApp/factory/Convert.cpp @@ -12,6 +12,7 @@ namespace epics { namespace pvData { static Convert* convert = 0; +static PVDataCreate* pvDataCreate = 0; static String trueString("true"); static String falseString("false"); @@ -592,7 +593,7 @@ void Convert::copyStructureArray( } else { if(toArray[i]==0) { StructureConstPtr structure = to->getStructureArray()->getStructure(); - toArray[i] = getPVDataCreate()->createPVStructure(0,structure); + toArray[i] = pvDataCreate->createPVStructure(0,structure); } copyStructure(fromArray[i],toArray[i]); } @@ -3567,6 +3568,7 @@ Convert * getConvert() { if(convert==0){ convert = new ConvertExt(); + pvDataCreate = getPVDataCreate(); } return convert; } diff --git a/pvDataApp/factory/PVAuxInfoImpl.cpp b/pvDataApp/factory/PVAuxInfoImpl.cpp index e99d82b..9fbd9d9 100644 --- a/pvDataApp/factory/PVAuxInfoImpl.cpp +++ b/pvDataApp/factory/PVAuxInfoImpl.cpp @@ -9,72 +9,72 @@ namespace epics { namespace pvData { - class PVAuxInfoPvt { - public: - PVAuxInfoPvt(PVField *pvField) - : pvField(pvField), - theMap(std::map()) - {} - PVField *pvField; - std::map theMap; - }; +class PVAuxInfoPvt { +public: + PVAuxInfoPvt(PVField *pvField) + : pvField(pvField), + theMap(std::map()) + {} + PVField *pvField; + std::map theMap; +}; - PVAuxInfo::PVAuxInfo(PVField *pvField) - : pImpl(new PVAuxInfoPvt(pvField)) - { } +PVAuxInfo::PVAuxInfo(PVField *pvField) +: pImpl(new PVAuxInfoPvt(pvField)) +{ } - PVAuxInfo::~PVAuxInfo() { delete pImpl;} - - PVField * PVAuxInfo::getPVField() { - return pImpl->pvField; +PVAuxInfo::~PVAuxInfo() { delete pImpl;} + +PVField * PVAuxInfo::getPVField() { + return pImpl->pvField; +} + +typedef std::map::const_iterator map_iterator; + +PVScalar * PVAuxInfo::createInfo(String key,ScalarType scalarType) +{ + map_iterator i = pImpl->theMap.find(key); + if(i!=pImpl->theMap.end()) { + String message("AuxoInfo:create key "); + message += key.c_str(); + message += " already exists with scalarType "; + ScalarTypeFunc::toString(&message,scalarType); + pImpl->pvField->message(message,errorMessage); } + PVScalar *pvScalar = getPVDataCreate()->createPVScalar(0,key,scalarType); + pImpl->theMap.insert(std::pair(key, pvScalar)); + return pvScalar; - typedef std::map::const_iterator map_iterator; +} - PVScalar * PVAuxInfo::createInfo(String key,ScalarType scalarType) - { - map_iterator i = pImpl->theMap.find(key); - if(i!=pImpl->theMap.end()) { - String message("AuxoInfo:create key "); - message += key.c_str(); - message += " already exists with scalarType "; - ScalarTypeFunc::toString(&message,scalarType); - pImpl->pvField->message(message,errorMessage); - } - PVScalar *pvScalar = getPVDataCreate()->createPVScalar(0,key,scalarType); - pImpl->theMap.insert(std::pair(key, pvScalar)); - return pvScalar; +PVScalarMap PVAuxInfo::getInfos() +{ + return pImpl->theMap; +} +PVScalar * PVAuxInfo::getInfo(String key) +{ + map_iterator i = pImpl->theMap.find(key); + if(i!=pImpl->theMap.end()) return i->second; + return 0; +} + +void PVAuxInfo::toString(StringBuilder buf) +{ + return PVAuxInfo::toString(buf,0); +} + +void PVAuxInfo::toString(StringBuilder buf,int indentLevel) +{ + map_iterator i = pImpl->theMap.begin(); + while(i!=pImpl->theMap.end()) { + String key = i->first; + PVScalar *value = i->second; + *buf += " "; + *buf += key.c_str(); + *buf += " "; + value->toString(buf); + i++; } - - PVScalarMap PVAuxInfo::getInfos() - { - return pImpl->theMap; - } - - PVScalar * PVAuxInfo::getInfo(String key) - { - map_iterator i = pImpl->theMap.find(key); - if(i!=pImpl->theMap.end()) return i->second; - return 0; - } - - void PVAuxInfo::toString(StringBuilder buf) - { - return PVAuxInfo::toString(buf,0); - } - - void PVAuxInfo::toString(StringBuilder buf,int indentLevel) - { - map_iterator i = pImpl->theMap.begin(); - while(i!=pImpl->theMap.end()) { - String key = i->first; - PVScalar *value = i->second; - *buf += " "; - *buf += key.c_str(); - *buf += " "; - value->toString(buf); - i++; - } - } +} }} diff --git a/pvDataApp/factory/PVDataCreateFactory.cpp b/pvDataApp/factory/PVDataCreateFactory.cpp index 03629e2..2f15f57 100644 --- a/pvDataApp/factory/PVDataCreateFactory.cpp +++ b/pvDataApp/factory/PVDataCreateFactory.cpp @@ -109,7 +109,6 @@ PVScalar *PVDataCreate::createPVScalar(PVStructure *parent,ScalarConstPtr scalar PVScalar *PVDataCreate::createPVScalar(PVStructure *parent, String fieldName,ScalarType scalarType) { - if(fieldCreate==0) fieldCreate = getFieldCreate(); ScalarConstPtr scalar = fieldCreate->createScalar(fieldName,scalarType); return createPVScalar(parent,scalar); } @@ -118,7 +117,6 @@ PVScalar *PVDataCreate::createPVScalar(PVStructure *parent, PVScalar *PVDataCreate::createPVScalar(PVStructure *parent, String fieldName,PVScalar * scalarToClone) { - if(convert==0) convert = getConvert(); PVScalar *pvScalar = createPVScalar(parent,fieldName, scalarToClone->getScalar()->getScalarType()); convert->copyScalar(scalarToClone, pvScalar); @@ -156,14 +154,14 @@ PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent, case pvString: return new BasePVStringArray(parent,scalarArray); } - throw std::logic_error(notImplemented); + String message("PVDataCreate::createPVScalarArray should never get here"); + throw std::logic_error(message); } PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent, String fieldName,ScalarType elementType) { - if(fieldCreate==0) fieldCreate = getFieldCreate(); return createPVScalarArray(parent, fieldCreate->createScalarArray(fieldName, elementType)); } @@ -171,7 +169,6 @@ PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent, PVScalarArray *PVDataCreate::createPVScalarArray(PVStructure *parent, String fieldName,PVScalarArray * arrayToClone) { - if(convert==0) convert = getConvert(); PVScalarArray *pvArray = createPVScalarArray(parent,fieldName, arrayToClone->getScalarArray()->getElementType()); convert->copyScalarArray(arrayToClone,0, pvArray,0,arrayToClone->getLength()); @@ -203,7 +200,6 @@ PVStructure *PVDataCreate::createPVStructure(PVStructure *parent, PVStructure *PVDataCreate::createPVStructure(PVStructure *parent, String fieldName,int numberFields,FieldConstPtrArray fields) { - if(fieldCreate==0) fieldCreate = getFieldCreate(); StructureConstPtr structure = fieldCreate->createStructure( fieldName,numberFields, fields); return new BasePVStructure(parent,structure); @@ -212,8 +208,6 @@ PVStructure *PVDataCreate::createPVStructure(PVStructure *parent, PVStructure *PVDataCreate::createPVStructure(PVStructure *parent, String fieldName,PVStructure *structToClone) { - if(fieldCreate==0) fieldCreate = getFieldCreate(); - if(convert==0) convert = getConvert(); FieldConstPtrArray fields = 0; int numberFields = 0; if(structToClone==0) { @@ -238,7 +232,11 @@ public: static Mutex mutex = Mutex(); Lock xx(&mutex); - if(pvDataCreate==0) pvDataCreate = new PVDataCreateExt(); + if(pvDataCreate==0){ + pvDataCreate = new PVDataCreateExt(); + convert = getConvert(); + fieldCreate = getFieldCreate(); + } return pvDataCreate; } diff --git a/pvDataApp/factory/StandardField.cpp b/pvDataApp/factory/StandardField.cpp index 7d0d72d..6ae349f 100644 --- a/pvDataApp/factory/StandardField.cpp +++ b/pvDataApp/factory/StandardField.cpp @@ -10,72 +10,78 @@ namespace epics { namespace pvData { static String notImplemented("not implemented"); +static FieldCreate* fieldCreate = 0; +static PVDataCreate* pvDataCreate = 0; - StandardField::StandardField(){} +StandardField::StandardField(){} - StandardField::~StandardField(){} +StandardField::~StandardField(){} - PVScalar * StandardField::scalarValue(ScalarType scalarType) - { - ScalarConstPtr scalar = getFieldCreate()->createScalar( - String("value"),scalarType); - return getPVDataCreate()->createPVScalar(0,scalar); +PVScalar * StandardField::scalarValue(ScalarType scalarType) +{ + ScalarConstPtr scalar = fieldCreate->createScalar( + String("value"),scalarType); + return getPVDataCreate()->createPVScalar(0,scalar); +} + +PVScalarArray * StandardField::scalarArrayValue(ScalarType elementType) +{ + ScalarArrayConstPtr scalarArray = fieldCreate->createScalarArray( + String("value"),elementType); + return pvDataCreate->createPVScalarArray(0,scalarArray); +} + +PVStructure * StandardField::scalarValue(ScalarType type,String properties) +{ + throw std::logic_error(notImplemented); +} + +PVStructure * StandardField::scalarArrayValue(ScalarType elementType, + String properties) +{ + throw std::logic_error(notImplemented); +} + +PVStructure * StandardField::enumeratedValue(StringArray choices) +{ + throw std::logic_error(notImplemented); +} + +PVStructure * StandardField::enumeratedValue(StringArray choices, + String properties) +{ + throw std::logic_error(notImplemented); +} + +PVStructure * StandardField::alarm() +{ + throw std::logic_error(notImplemented); +} + +PVStructure * StandardField::timeStamp() +{ + throw std::logic_error(notImplemented); +} + + +static StandardField* instance = 0; + + +class StandardFieldExt : public StandardField { +public: + StandardFieldExt(): StandardField(){}; +}; + +StandardField * getStandardField() { + static Mutex mutex = Mutex(); + Lock xx(&mutex); + + if(instance==0) { + instance = new StandardFieldExt(); + fieldCreate = getFieldCreate(); + pvDataCreate = getPVDataCreate(); } + return instance; +} - PVScalarArray * StandardField::scalarArrayValue(ScalarType elementType) - { - ScalarArrayConstPtr scalarArray = getFieldCreate()->createScalarArray( - String("value"),elementType); - return getPVDataCreate()->createPVScalarArray(0,scalarArray); - } - - PVStructure * StandardField::scalarValue(ScalarType type,String properties) - { - throw std::logic_error(notImplemented); - } - - PVStructure * StandardField::scalarArrayValue(ScalarType elementType, - String properties) - { - throw std::logic_error(notImplemented); - } - - PVStructure * StandardField::enumeratedValue(StringArray choices) - { - throw std::logic_error(notImplemented); - } - - PVStructure * StandardField::enumeratedValue(StringArray choices, - String properties) - { - throw std::logic_error(notImplemented); - } - - PVStructure * StandardField::alarm() - { - throw std::logic_error(notImplemented); - } - - PVStructure * StandardField::timeStamp() - { - throw std::logic_error(notImplemented); - } - - - static StandardField* instance = 0; - - - class StandardFieldExt : public StandardField { - public: - StandardFieldExt(): StandardField(){}; - }; - - StandardField * getStandardField() { - static Mutex mutex = Mutex(); - Lock xx(&mutex); - - if(instance==0) instance = new StandardFieldExt(); - return instance; - } - }} diff --git a/pvDataApp/misc/epicsException.h b/pvDataApp/misc/epicsException.h index f1b5e59..80ff76f 100644 --- a/pvDataApp/misc/epicsException.h +++ b/pvDataApp/misc/epicsException.h @@ -1,10 +1,11 @@ /* * epicsException.hpp * - * Created on: Oct 18, 2010 - * Author: miha_vitorovic + * Created on: Oct 20, 2010 + * Author: Matej Sekoranja */ +#include #ifndef EPICSEXCEPTION_H_ #define EPICSEXCEPTION_H_ @@ -15,6 +16,62 @@ namespace epics { namespace pvData { + +class BaseException : + public std::exception { +public: + BaseException(const char* message, const char* file, int line, std::exception* cause = 0) + : m_msg(message), m_file(file), m_line(line), m_cause(cause) + { + } + + virtual ~BaseException() throw() + { + if (m_cause) delete m_cause; + } + + virtual const char* what() const throw() { return m_msg.c_str(); } + + const char* getFile() const { return m_file.c_str(); } + int getLine() const { return m_line; } + + void toString(std::string& str) { + str.append("BaseException: "); + str.append(m_msg); + str.append("\n\tat "); + str.append(m_file); + str.append(":"); + char sline[10]; + snprintf(sline, 10, "%d", m_line); + str.append(sline); + if (m_cause) + { + str.append("\ncaused by: "); + BaseException *be = dynamic_cast(m_cause); + if (be) + be->toString(str); + else + str.append(m_cause->what()); + } + } + +private: + std::string m_msg; + std::string m_file; + int m_line; + std::exception* m_cause; +}; + + +#define THROW_BASE_EXCEPTION(msg) throw new BaseException(msg, __FILE__, __LINE__) +#define THROW_BASE_EXCEPTION_CAUSE(msg, cause) throw new BaseException(msg, __FILE__, __LINE__, cause) + +/* + /// Construct with file, line info and printf-type arguments. + GenericException(const char *sourcefile, size_t line, const char *format, ...) + __attribute__ ((format (printf, 4, 5))); +*/ + /** Base Epics Exception */ class EpicsException : public std::logic_error { public: diff --git a/pvDataApp/pv/pvData.h b/pvDataApp/pv/pvData.h index e17e4fd..9807666 100644 --- a/pvDataApp/pv/pvData.h +++ b/pvDataApp/pv/pvData.h @@ -86,7 +86,6 @@ namespace epics { namespace pvData { virtual bool operator!=(PVField *pv) = 0; protected: PVField(PVStructure *parent,FieldConstPtr field); - void replaceStructure(); private: class PVFieldPvt *pImpl; static void computeOffset(PVField *pvField); @@ -224,6 +223,8 @@ namespace epics { namespace pvData { DeserializableControl*pflusher,BitSet *pbitSet); protected: PVStructure(PVStructure *parent,StructureConstPtr structure); + void replaceStructure(); + friend class PVField; private: class PVStructurePvt * pImpl; }; diff --git a/pvDataApp/test/Makefile b/pvDataApp/test/Makefile index 302435a..61be128 100644 --- a/pvDataApp/test/Makefile +++ b/pvDataApp/test/Makefile @@ -31,6 +31,10 @@ PROD_HOST += testByteBuffer testByteBuffer_SRCS += testByteBuffer.cpp testByteBuffer_LIBS += pvMisc Com +PROD_HOST += testBaseException +testBaseException_SRCS += testBaseException.cpp +testBaseException_LIBS += pvMisc + include $(TOP)/configure/RULES #---------------------------------------- # ADD RULES AFTER THIS LINE diff --git a/pvDataApp/test/testBaseException.cpp b/pvDataApp/test/testBaseException.cpp new file mode 100644 index 0000000..9a2c6be --- /dev/null +++ b/pvDataApp/test/testBaseException.cpp @@ -0,0 +1,52 @@ +/* testBaseException.cpp */ +/* Author: Matej Sekoranja Date: 2010.10.18 */ + +#include +#include +#include +#include +#include +#include "epicsException.h" + + +#include + +using namespace epics::pvData; + +void testBaseException() { + printf("testBaseException... "); + + try { + THROW_BASE_EXCEPTION("all is OK"); + } catch (BaseException *be) { + std::string str; + be->toString(str); + printf("\n\n%s\n\n", str.c_str()); + } + + try { + try { + try { + THROW_BASE_EXCEPTION("the root cause"); + } catch (BaseException *be3) { + THROW_BASE_EXCEPTION_CAUSE("exception 1", be3); + } + } catch (BaseException *be2) { + THROW_BASE_EXCEPTION_CAUSE("excepton 2", be2); + } + } catch (BaseException *be) { + std::string str; + be->toString(str); + printf("\n\n%s\n\n", str.c_str()); + delete be; + } + + printf("PASSED\n"); +} + +int main(int argc,char *argv[]) +{ + testBaseException(); + return(0); +} +