From 59eeadcd1060febd6ac0ac5bb0752e1042e6eeb7 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Tue, 26 Oct 2010 06:12:44 -0400 Subject: [PATCH] BasePVStructure now complete --- configure/RELEASE | 2 +- pvDataApp/factory/AbstractPVField.h | 24 +- pvDataApp/factory/BasePVStructure.h | 395 +++++++++++++++++++++++++--- pvDataApp/factory/Convert.cpp | 3 +- pvDataApp/misc/epicsException.h | 4 +- pvDataApp/pv/pvData.h | 6 +- 6 files changed, 393 insertions(+), 41 deletions(-) diff --git a/configure/RELEASE b/configure/RELEASE index f767456..37d8c6d 100644 --- a/configure/RELEASE +++ b/configure/RELEASE @@ -22,7 +22,7 @@ TEMPLATE_TOP=$(EPICS_BASE)/templates/makeBaseApp/top #SNCSEQ=$(EPICS_BASE)/../modules/soft/seq # EPICS_BASE usually appears last so other apps can override stuff: -EPICS_BASE=/Users/msekoranja/Work/EPICS/base-3.14.11 +EPICS_BASE=/home/install/epics/base #Capfast users may need the following definitions #CAPFAST_TEMPLATES= diff --git a/pvDataApp/factory/AbstractPVField.h b/pvDataApp/factory/AbstractPVField.h index 826d80d..97ba0ec 100644 --- a/pvDataApp/factory/AbstractPVField.h +++ b/pvDataApp/factory/AbstractPVField.h @@ -117,8 +117,8 @@ void PVField::replacePVField(PVField * newPVField) { PVStructure *parent = getParent(); if(parent==0) { - String message("PVField::replacePVField no parent"); - throw std::invalid_argument(message); + String message("PVField::replacePVField no parent"); + throw std::invalid_argument(message); } PVFieldPtrArray pvFields = parent->getPVFields(); int index = -1; @@ -136,7 +136,7 @@ void PVField::replacePVField(PVField * newPVField) throw std::logic_error(message); } pvFields[index] = newPVField; - parent->replaceStructure(); + parent->replaceStructure(parent); } void PVField::renameField(String newName) @@ -266,5 +266,23 @@ void PVField::computeOffset(PVField * pvField,int offset) { pvField->pImpl->nextFieldOffset = nextOffset; } +void PVField::replaceStructure(PVStructure *pvStructure) +{ + PVFieldPtrArray pvFields = pvStructure->getPVFields(); + int length = pvStructure->getStructure()->getNumberFields(); + FieldConstPtrArray newFields = new FieldConstPtr[length]; + for(int i=0; igetField(); + } + StructureConstPtr newStructure = getFieldCreate()->createStructure( + pImpl->field->getFieldName(),length, newFields); + pImpl->field = newStructure; + PVStructure *parent = pImpl->parent; + if(parent!=0) { + parent->replaceStructure(parent); + } +} + + }} #endif /* ABSTRACTPVFIELD_H */ diff --git a/pvDataApp/factory/BasePVStructure.h b/pvDataApp/factory/BasePVStructure.h index 2ea1fce..b1a061b 100644 --- a/pvDataApp/factory/BasePVStructure.h +++ b/pvDataApp/factory/BasePVStructure.h @@ -30,16 +30,50 @@ namespace epics { namespace pvData { for(int i=0; igetNumberFields(); + int numberFields = structurePtr->getNumberFields(); + FieldConstPtrArray fields = structurePtr->getFields(); pImpl->numberFields = numberFields; pImpl->pvFields = new PVFieldPtr[numberFields]; + PVFieldPtrArray pvFields = pImpl->pvFields; + PVDataCreate *pvDataCreate = getPVDataCreate(); for(int i=0; igetType()) { + case scalar: { + ScalarConstPtr scalar = (ScalarConstPtr)field; + pvFields[i] = pvDataCreate->createPVScalar(this, + field->getFieldName(),scalar->getScalarType()); + break; + } + case scalarArray: { + ScalarArrayConstPtr array = (ScalarArrayConstPtr)field; + ScalarType elementType = array->getElementType(); + pvFields[i] = pvDataCreate->createPVScalarArray(this, + field->getFieldName(),elementType); + break; + } + case structure: { + StructureConstPtr structPtr = (StructureConstPtr)field; + int numberFields = structPtr->getNumberFields(); + pvFields[i] = pvDataCreate->createPVStructure(this, + field->getFieldName(), numberFields,structPtr->getFields()); + break; + } + case structureArray: { + StructureArrayConstPtr structArray = (StructureArrayConstPtr)field; + pvFields[i] = pvDataCreate->createPVStructureArray(this, + structArray); + break; + } + } } } @@ -60,102 +94,368 @@ namespace epics { namespace pvData { PVFieldPtr PVStructure::getSubField(String fieldName) { - throw std::logic_error(notImplemented); + return findSubField(fieldName,this); } PVFieldPtr PVStructure::getSubField(int fieldOffset) { - throw std::logic_error(notImplemented); + if(fieldOffset<=getFieldOffset()) { + if(fieldOffset==getFieldOffset()) return this; + return 0; + } + if(fieldOffset>getNextFieldOffset()) return 0; + int numFields = pImpl->numberFields; + PVFieldPtrArray pvFields = pImpl->pvFields; + for(int i=0; igetFieldOffset()==fieldOffset) return pvField; + if(pvField->getNextFieldOffset()<=fieldOffset) continue; + if(pvField->getField()->getType()==structure) { + return ((PVStructure*)pvField)->getSubField(fieldOffset); + } + } + String message("PVStructure.getSubField: Logic error"); + throw std::logic_error(message); } void PVStructure::appendPVField(PVFieldPtr pvField) { - throw std::logic_error(notImplemented); + int origLength = pImpl->numberFields; + PVFieldPtrArray oldPVFields = pImpl->pvFields; + PVFieldPtrArray newPVFields = new PVFieldPtr[origLength + 1]; + for(int i=0; ipvFields; + pImpl->pvFields = newPVFields; + pImpl->numberFields = origLength + 1; + PVField::replaceStructure(this); } - void PVStructure::appendPVFields(PVFieldPtrArray pvFields) + void PVStructure::appendPVFields(int numberNewFields,PVFieldPtrArray pvFields) { - throw std::logic_error(notImplemented); + int origLength = pImpl->numberFields; + PVFieldPtrArray oldPVFields = pImpl->pvFields; + int numberFields = origLength + numberNewFields; + PVFieldPtrArray newPVFields = new PVFieldPtr[numberFields]; + for(int i=0; ipvFields; + pImpl->pvFields = newPVFields; + pImpl->numberFields = numberFields; + PVField::replaceStructure(this); } void PVStructure::removePVField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = getSubField(fieldName); + if(pvField==0) { + String message("removePVField "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return; + } + int origLength = pImpl->numberFields; + int newLength = origLength - 1; + PVFieldPtrArray origPVFields = pImpl->pvFields; + PVFieldPtrArray newPVFields = new PVFieldPtr[newLength]; + int newIndex = 0; + for(int i=0; ipvFields; + pImpl->pvFields = newPVFields; + pImpl->numberFields = newLength; + PVField::replaceStructure(this); } PVBoolean *PVStructure::getBooleanField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvBoolean) { + return (PVBoolean*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type boolean "; + this->message(message, errorMessage); + return 0; } PVByte *PVStructure::getByteField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvByte) { + return (PVByte*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type byte "; + this->message(message, errorMessage); + return 0; } PVShort *PVStructure::getShortField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvShort) { + return (PVShort*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type short "; + this->message(message, errorMessage); + return 0; } PVInt *PVStructure::getIntField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvInt) { + return (PVInt*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type int "; + this->message(message, errorMessage); + return 0; } PVLong *PVStructure::getLongField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvLong) { + return (PVLong*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type long "; + this->message(message, errorMessage); + return 0; } PVFloat *PVStructure::getFloatField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvFloat) { + return (PVFloat*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type float "; + this->message(message, errorMessage); + return 0; } PVDouble *PVStructure::getDoubleField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvDouble) { + return (PVDouble*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type double "; + this->message(message, errorMessage); + return 0; } PVString *PVStructure::getStringField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==scalar) { + ScalarConstPtr scalar = (ScalarConstPtr)pvField->getField(); + if(scalar->getScalarType()==pvString) { + return (PVString*)pvField; + } + } + String message("fieldName "); + message += fieldName + " does not have type string "; + this->message(message, errorMessage); + return 0; } PVStructure *PVStructure::getStructureField(String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==structure) { + return((PVStructure *)pvField); + } + String message("fieldName "); + message += fieldName + " does not have type structure "; + this->message(message, errorMessage); + return 0; } PVScalarArray *PVStructure::getScalarArrayField( String fieldName,ScalarType elementType) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + FieldConstPtr field = pvField->getField(); + Type type = field->getType(); + if(type!=scalarArray) { + String message("fieldName "); + message += fieldName + " does not have type array "; + this->message(message, errorMessage); + return 0; + } + ScalarArrayConstPtr array = (ScalarArrayConstPtr)field; + if(array->getElementType()!=elementType) { + String message("fieldName "); + message += fieldName + " is array but does not have elementType "; + ScalarTypeFunc::toString(&message,elementType); + this->message(message, errorMessage); + return 0; + } + return (PVScalarArray*)pvField; } PVStructureArray *PVStructure::getStructureArrayField( String fieldName) { - throw std::logic_error(notImplemented); + PVField *pvField = findSubField(fieldName,this); + if(pvField==0) { + String message("fieldName "); + message += fieldName + " does not exist"; + this->message(message, errorMessage); + return 0; + } + if(pvField->getField()->getType()==structureArray) { + return((PVStructureArray *)pvField); + } + String message("fieldName "); + message += fieldName + " does not have type structureArray "; + this->message(message, errorMessage); + return 0; } String PVStructure::getExtendsStructureName() { - throw std::logic_error(notImplemented); + return pImpl->extendsStructureName; } bool PVStructure::putExtendsStructureName( String extendsStructureName) { - throw std::logic_error(notImplemented); + if(pImpl->extendsStructureName.length()!=0) return false; + pImpl->extendsStructureName = extendsStructureName; + return true; } - void PVStructure::toString(StringBuilder buf) {toString(buf,0);} + void PVStructure::toStringPvt(StringBuilder builder,int indentLevel) { + Convert *convert = getConvert(); + PVField::toString(builder,indentLevel); + if(pImpl->extendsStructureName.length()>0) { + *builder += " extends "; + *builder += pImpl->extendsStructureName; + } + convert->newLine(builder,indentLevel); + *builder += "{"; + int nFields = pImpl->numberFields; + PVFieldPtrArray pvFields = pImpl->pvFields; + for(int i=0; i < nFields; i++) { + PVField *pvField = pvFields[i]; + convert->newLine(builder,indentLevel + 1); + FieldConstPtr field = pvField->getField(); + *builder += field->getFieldName() + " = "; + pvField->toString(builder,indentLevel+1); + } + convert->newLine(builder,indentLevel); + *builder += "}"; + } + + void PVStructure::toString(StringBuilder buf) + { + *buf += "structure "; + *buf += getField()->getFieldName(); + toStringPvt(buf,0); + } void PVStructure::toString(StringBuilder buf,int indentLevel) { - throw std::logic_error(notImplemented); + *buf += "structure "; + toStringPvt(buf,0); } void PVStructure::serialize( @@ -188,19 +488,52 @@ namespace epics { namespace pvData { throw std::logic_error(notImplemented); } - bool PVStructure::operator==(PVField *pv) + bool PVStructure::operator==(PVField *obj) { - throw std::logic_error(notImplemented); + PVStructure *b = dynamic_cast(obj); + if(b==0) return false; + PVFieldPtrArray bFields = b->getPVFields(); + PVFieldPtrArray pvFields = pImpl->pvFields; + int len = b->getNumberFields(); + if (len == pImpl->numberFields) { + for (int i = 0; i < len; i++) { + if (!(pvFields[i]==bFields[i])) return false; + } + } + return true; } bool PVStructure::operator!=(PVField *pv) { - throw std::logic_error(notImplemented); + return !(this==pv); } - void PVStructure::replaceStructure() - { - throw std::logic_error(notImplemented); + static PVField *findSubField(String fieldName,PVStructure *pvStructure) { + if( fieldName.length()<1) return 0; + String::size_type index = fieldName.find('.'); + String name = fieldName; + String restOfName = String(); + if(index>0) { + name = fieldName.substr(0, index); + if(fieldName.length()>index) { + restOfName = fieldName.substr(index+1); + } + } + PVFieldPtrArray pvFields = pvStructure->getPVFields(); + PVField *pvField = 0; + int numFields = pvStructure->getStructure()->getNumberFields(); + for(int i=0; igetField()->getFieldName().compare(name); + if(result==0) { + pvField = pvf; + break; + } + } + if(pvField==0) return 0; + if(restOfName.length()==0) return pvField; + if(pvField->getField()->getType()!=structure) return 0; + return findSubField(restOfName,(PVStructure*)pvField); } class BasePVStructure : public PVStructure { diff --git a/pvDataApp/factory/Convert.cpp b/pvDataApp/factory/Convert.cpp index 2d48422..56a6d7b 100644 --- a/pvDataApp/factory/Convert.cpp +++ b/pvDataApp/factory/Convert.cpp @@ -3122,7 +3122,6 @@ void convertStructure(StringBuilder buffer,PVStructure *data,int indentLevel) { convert->newLine(buffer, indentLevel); *buffer += "structure {"; - char buff[30]; PVFieldPtrArray fieldsData = data->getPVFields(); if (fieldsData != 0) { int length = data->getStructure()->getNumberFields(); @@ -3130,6 +3129,8 @@ void convertStructure(StringBuilder buffer,PVStructure *data,int indentLevel) PVField *fieldField = fieldsData[i]; FieldConstPtr fieldnow = fieldField->getField(); convert->newLine(buffer, indentLevel + 1); + int size = fieldnow->getFieldName().length(); + char buff[size+2]; sprintf(buff,"%s = ",fieldnow->getFieldName().c_str()); *buffer += buff; convert->getString(buffer,fieldField,indentLevel + 1); diff --git a/pvDataApp/misc/epicsException.h b/pvDataApp/misc/epicsException.h index c7ed2bc..36ef646 100644 --- a/pvDataApp/misc/epicsException.h +++ b/pvDataApp/misc/epicsException.h @@ -132,12 +132,12 @@ public: { if (*p == '(') { // terminate module - *p = '\0' + *p = '\0'; fname = p+1; } else if (*p == '+') { // terminate fname - *p = '\0' + *p = '\0'; offset = p+1; } else if (*p == ')' && offset) { diff --git a/pvDataApp/pv/pvData.h b/pvDataApp/pv/pvData.h index 9807666..261f2f5 100644 --- a/pvDataApp/pv/pvData.h +++ b/pvDataApp/pv/pvData.h @@ -86,6 +86,7 @@ namespace epics { namespace pvData { virtual bool operator!=(PVField *pv) = 0; protected: PVField(PVStructure *parent,FieldConstPtr field); + void replaceStructure(PVStructure *pvStructure); private: class PVFieldPvt *pImpl; static void computeOffset(PVField *pvField); @@ -190,7 +191,7 @@ namespace epics { namespace pvData { PVField *getSubField(String fieldName); PVField *getSubField(int fieldOffset); void appendPVField(PVField *pvField); - void appendPVFields(PVFieldPtrArray pvFields); + void appendPVFields(int numberFields,PVFieldPtrArray pvFields); void removePVField(String fieldName); PVBoolean *getBooleanField(String fieldName); PVByte *getByteField(String fieldName); @@ -223,9 +224,8 @@ namespace epics { namespace pvData { DeserializableControl*pflusher,BitSet *pbitSet); protected: PVStructure(PVStructure *parent,StructureConstPtr structure); - void replaceStructure(); - friend class PVField; private: + void toStringPvt(StringBuilder buf,int indentLevel) ; class PVStructurePvt * pImpl; };