diff --git a/pvAccessApp/remote/blockingTCP.h b/pvAccessApp/remote/blockingTCP.h index 75c2d69..f974307 100644 --- a/pvAccessApp/remote/blockingTCP.h +++ b/pvAccessApp/remote/blockingTCP.h @@ -472,6 +472,18 @@ namespace epics { return &_introspectionRegistry; } + virtual void cachedSerialize( + const std::tr1::shared_ptr& field, epics::pvData::ByteBuffer* buffer) + { + getIntrospectionRegistry()->serialize(field, buffer, this); + } + + virtual std::tr1::shared_ptr + cachedDeserialize(epics::pvData::ByteBuffer* buffer) + { + return getIntrospectionRegistry()->deserialize(buffer, this); + } + /** * Acquires transport. * @param client client (channel) acquiring the transport @@ -651,6 +663,18 @@ namespace epics { return &_introspectionRegistry; } + virtual void cachedSerialize( + const std::tr1::shared_ptr& field, epics::pvData::ByteBuffer* buffer) + { + getIntrospectionRegistry()->serialize(field, buffer, this); + } + + virtual std::tr1::shared_ptr + cachedDeserialize(epics::pvData::ByteBuffer* buffer) + { + return getIntrospectionRegistry()->deserialize(buffer, this); + } + /** * Preallocate new channel SID. * @return new channel server id (SID). diff --git a/pvAccessApp/remote/blockingUDP.h b/pvAccessApp/remote/blockingUDP.h index 50d4c0c..e751293 100644 --- a/pvAccessApp/remote/blockingUDP.h +++ b/pvAccessApp/remote/blockingUDP.h @@ -16,6 +16,8 @@ #include #include +#include + #include #include #include @@ -140,6 +142,21 @@ namespace epics { _sendBuffer->align(alignment); } + virtual void cachedSerialize( + const std::tr1::shared_ptr& field, epics::pvData::ByteBuffer* buffer) + { + // no cache + field->serialize(buffer, this); + } + + virtual std::tr1::shared_ptr + cachedDeserialize(epics::pvData::ByteBuffer* buffer) + { + // no cache + // TODO + return epics::pvData::getFieldCreate()->deserialize(buffer, this); + } + /** * Set ignore list. * @param addresses list of ignored addresses. diff --git a/pvAccessApp/remote/simpleChannelSearchManagerImpl.h b/pvAccessApp/remote/simpleChannelSearchManagerImpl.h index 60de546..1e6519d 100644 --- a/pvAccessApp/remote/simpleChannelSearchManagerImpl.h +++ b/pvAccessApp/remote/simpleChannelSearchManagerImpl.h @@ -27,6 +27,12 @@ public: void ensureBuffer(int size) {} void alignBuffer(int alignment) {} void flushSerializeBuffer() {} + void cachedSerialize( + const std::tr1::shared_ptr& field, epics::pvData::ByteBuffer* buffer) + { + // no cache + field->serialize(buffer, this); + } }; diff --git a/pvAccessApp/utils/introspectionRegistry.cpp b/pvAccessApp/utils/introspectionRegistry.cpp index c311a79..b3af587 100644 --- a/pvAccessApp/utils/introspectionRegistry.cpp +++ b/pvAccessApp/utils/introspectionRegistry.cpp @@ -173,64 +173,15 @@ void IntrospectionRegistry::serialize(FieldConstPtr field, StructureConstPtr par buffer->putShort(key); } } - - // NOTE: high nibble is field.getType() ordinal, low nibble is scalar type ordinal; -1 is null - switch (field->getType()) - { - case epics::pvData::scalar: - { - ScalarConstPtr scalar = static_pointer_cast(field); - control->ensureBuffer(1); - buffer->putByte((int8)(epics::pvData::scalar << 4 | scalar->getScalarType())); - SerializeHelper::serializeString(field->getFieldName(), buffer, control); - break; - } - case epics::pvData::scalarArray: - { - ScalarArrayConstPtr array = static_pointer_cast(field); - control->ensureBuffer(1); - buffer->putByte((int8)(epics::pvData::scalarArray << 4 | array->getElementType())); - SerializeHelper::serializeString(field->getFieldName(), buffer, control); - break; - } - case epics::pvData::structure: - { - StructureConstPtr structure = static_pointer_cast(field); - control->ensureBuffer(1); - buffer->putByte((int8)(epics::pvData::structure << 4)); - serializeStructureField(buffer, control, registry, structure); - break; - } - case epics::pvData::structureArray: - { - StructureArrayConstPtr structureArray = static_pointer_cast(field); - control->ensureBuffer(1); - buffer->putByte((int8)(epics::pvData::structureArray << 4)); - SerializeHelper::serializeString(field->getFieldName(), buffer, control); - // we also need to serialize structure field... - StructureConstPtr structureElement = structureArray->getStructure(); - serializeStructureField(buffer, control, registry, structureElement); - break; - } - } - } -} - -void IntrospectionRegistry::serializeStructureField(ByteBuffer* buffer, SerializableControl* control, - IntrospectionRegistry* registry, StructureConstPtr structure) -{ - SerializeHelper::serializeString(structure->getFieldName(), buffer, control); - FieldConstPtrArray fields = structure->getFields(); - SerializeHelper::writeSize(structure->getNumberFields(), buffer, control); - for (int i = 0; i < structure->getNumberFields(); i++) - { - serialize(fields[i], structure, buffer, control, registry); + + field->serialize(buffer, control); } } FieldConstPtr IntrospectionRegistry::deserialize(ByteBuffer* buffer, DeserializableControl* control, IntrospectionRegistry* registry) { control->ensureData(1); + uintptr_t pos = buffer->getPosition(); const int8 typeCode = buffer->getByte(); if(typeCode == IntrospectionRegistry::NULL_TYPE_CODE) { @@ -254,62 +205,9 @@ FieldConstPtr IntrospectionRegistry::deserialize(ByteBuffer* buffer, Deserializa return field; } - - // high nibble means scalar/array/structure - const Type type = (Type)(typeCode >> 4); - switch (type) - { - case scalar: - { - const ScalarType scalar = (ScalarType)(typeCode & 0x0F); - const String scalarFieldName = SerializeHelper::deserializeString(buffer, control); - return static_cast(_fieldCreate->createScalar(scalarFieldName,scalar)); - } - case scalarArray: - { - const ScalarType element = (ScalarType)(typeCode & 0x0F); - const String arrayFieldName = SerializeHelper::deserializeString(buffer, control); - return static_cast(_fieldCreate->createScalarArray(arrayFieldName,element)); - } - case structure: - { - return static_cast(deserializeStructureField(buffer, control, registry)); - } - case structureArray: - { - const String structureArrayFieldName = SerializeHelper::deserializeString(buffer, control); - const StructureConstPtr arrayElement = deserializeStructureField(buffer, control, registry); - return static_cast(_fieldCreate->createStructureArray(structureArrayFieldName, arrayElement)); - } - default: - { - // TODO log - return FieldConstPtr(); - } - } -} - -StructureConstPtr IntrospectionRegistry::deserializeStructureField(ByteBuffer* buffer, DeserializableControl* control, IntrospectionRegistry* registry) -{ - const String structureFieldName = SerializeHelper::deserializeString(buffer, control); - const int32 size = SerializeHelper::readSize(buffer, control); - FieldConstPtrArray fields = NULL; - if (size > 0) - { - fields = new FieldConstPtr[size]; - for(int i = 0; i < size; i++) - { - try { - fields[i] = deserialize(buffer, control, registry); - } catch (...) { - delete[] fields; - throw; - } - } - } - - StructureConstPtr structure = _fieldCreate->createStructure(structureFieldName, size, fields); - return structure; + buffer->setPosition(pos); + // TODO + return getFieldCreate()->deserialize(buffer, control); } void IntrospectionRegistry::serializeStructure(ByteBuffer* buffer, SerializableControl* control, PVStructurePtr pvStructure) diff --git a/pvAccessApp/utils/introspectionRegistry.h b/pvAccessApp/utils/introspectionRegistry.h index ded0743..b99f5f0 100644 --- a/pvAccessApp/utils/introspectionRegistry.h +++ b/pvAccessApp/utils/introspectionRegistry.h @@ -136,14 +136,6 @@ typedef std::map registryMap_t; epics::pvData::SerializableControl* control, IntrospectionRegistry* registry); - /** - * @param buffer - * @param control - * @param registry - * @param structure - */ - static void serializeStructureField(epics::pvData::ByteBuffer* buffer, epics::pvData::SerializableControl* control, - IntrospectionRegistry* registry, epics::pvData::StructureConstPtr structure); /** * @param buffer @@ -153,15 +145,6 @@ typedef std::map registryMap_t; */ static epics::pvData::FieldConstPtr deserialize(epics::pvData::ByteBuffer* buffer, epics::pvData::DeserializableControl* control, IntrospectionRegistry* registry); - /** - * Deserialize Structure. - * @param buffer - * @param control - * @param registry - * @return deserialized Structure instance. - */ - static epics::pvData::StructureConstPtr deserializeStructureField(epics::pvData::ByteBuffer* buffer, epics::pvData::DeserializableControl* control, IntrospectionRegistry* registry); - /** * Serialize optional PVStructrue. * @param buffer data buffer.