diff --git a/.github/workflows/build_on_linux.yml b/.github/workflows/build_on_linux.yml index 0ec3bf7f..4ee03436 100644 --- a/.github/workflows/build_on_linux.yml +++ b/.github/workflows/build_on_linux.yml @@ -14,14 +14,14 @@ jobs: # well on Windows or Mac. You can convert this to a matrix build if you need # cross-platform coverage. # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - + - name: Update Submodules shell: bash - working-directory: ${{runner.workspace}}/grpc-labview + working-directory: ${{runner.workspace}}/grpc-labview run: git submodule update --init --recursive - name: Create Build Environment @@ -34,8 +34,8 @@ jobs: # access regardless of the host operating system shell: bash working-directory: ${{runner.workspace}}/cmake/build - # Note the current convention is to use the -S and -B options here to specify source - # and build directories, but this is only available with CMake 3.13 and higher. + # Note the current convention is to use the -S and -B options here to specify source + # and build directories, but this is only available with CMake 3.13 and higher. # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE @@ -72,7 +72,7 @@ jobs: tar -czvf liblabview-grpc-server-linux.tar.gz -C ${{runner.workspace}}/cmake/build liblabview_grpc_server.so liblabview_grpc_generator.so - + - name: Upload Build Artifacts uses: actions/upload-artifact@v4 with: diff --git a/src/cluster_copier.cc b/src/cluster_copier.cc index c5b83e75..7b8da7cb 100644 --- a/src/cluster_copier.cc +++ b/src/cluster_copier.cc @@ -16,28 +16,14 @@ namespace grpc_labview { // cluster: Pointer to the cluster created by LabVIEW void ClusterDataCopier::CopyToCluster(const LVMessage& message, int8_t* cluster) { - std::map oneof_containerToSelectedIndexMap; - for (auto val : message._metadata->_mappedElements) + for (auto& indexAndValue : message._values) { - auto fieldMetadata = val.second; - auto start = cluster + fieldMetadata->clusterOffset; - std::shared_ptr value; - for (auto v : message._values) - { - if (v.second->_protobufId == fieldMetadata->protobufIndex) - { - value = v.second; - break; - } - } - if (value != nullptr) + auto& value = indexAndValue.second; + auto it = message._metadata->_mappedElements.find(value->_protobufId); + if (it != message._metadata->_mappedElements.end()) { - if (fieldMetadata->isInOneof) - { - // set the map of the selected index for the "oneofContainer" to this protobuf Index - assert(oneof_containerToSelectedIndexMap.find(fieldMetadata->oneofContainerName) == oneof_containerToSelectedIndexMap.end()); - oneof_containerToSelectedIndexMap.insert(std::pair(fieldMetadata->oneofContainerName, fieldMetadata->protobufIndex)); - } + auto& fieldMetadata = it->second; + auto start = cluster + fieldMetadata->clusterOffset;; switch (fieldMetadata->type) { case LVMessageMetadataType::StringValue: @@ -95,52 +81,41 @@ namespace grpc_labview { } } - // second pass to fill the oneof selected_index. We can do this in one pass when we push the selected_field to the end of the oneof cluster! - // TODO: Skip the entire loop if the message has no oneof. It's a bool in the metadata. - for (auto val : message._metadata->_mappedElements) - { - auto fieldMetadata = val.second; - if (fieldMetadata->isInOneof && fieldMetadata->protobufIndex < 0) - { - // This field is the selected_index field of a oneof - if (oneof_containerToSelectedIndexMap.find(fieldMetadata->oneofContainerName) != oneof_containerToSelectedIndexMap.end()) - { - auto start = cluster + fieldMetadata->clusterOffset; - *(int*)start = oneof_containerToSelectedIndexMap[fieldMetadata->oneofContainerName]; - } - } - } + // Second pass to fill the oneof selected_index. We can do this in one pass when we push the selected_field to the end of the oneof cluster! + message.CopyOneofIndicesToCluster(cluster); } //--------------------------------------------------------------------- //--------------------------------------------------------------------- void ClusterDataCopier::CopyFromCluster(LVMessage& message, int8_t* cluster) { - message._values.clear(); - std::map oneof_containerToSelectedIndexMap; // Needed to serialize only the field related to the selected_index - for (auto val : message._metadata->_mappedElements) + message.Clear(); + for (auto& fieldMetadata : message._metadata->_elements) { - auto fieldMetadata = val.second; - if (fieldMetadata->isInOneof) + if (fieldMetadata->isInOneof && fieldMetadata->protobufIndex < 0) { - if (fieldMetadata->protobufIndex < 0) - { - // set the map of the selected index for the "oneofContainer" to this protobuf Index - assert(oneof_containerToSelectedIndexMap.find(fieldMetadata->oneofContainerName) == oneof_containerToSelectedIndexMap.end()); - auto selected_index = *(int*)(cluster + fieldMetadata->clusterOffset); - oneof_containerToSelectedIndexMap.insert(std::pair(fieldMetadata->oneofContainerName, selected_index)); - } + // set the map of the selected index for the "oneofContainer" to this protobuf Index + assert(message._oneofContainerToSelectedIndexMap.find(fieldMetadata->oneofContainerName) == message._oneofContainerToSelectedIndexMap.end()); + auto selected_index = *(int*)(cluster + fieldMetadata->clusterOffset); + message._oneofContainerToSelectedIndexMap.insert({ fieldMetadata->oneofContainerName, selected_index }); } } + for (auto val : message._metadata->_mappedElements) { auto fieldMetadata = val.second; if (fieldMetadata->isInOneof) { - if (fieldMetadata->protobufIndex >= 0) + if (fieldMetadata->protobufIndex < 0) + { + // Do not serialize the selected_index field of a oneof. This is used for internal book keeping + // and is not really a part of the message data that should go across the wire. + continue; + } + else { - auto it = oneof_containerToSelectedIndexMap.find(fieldMetadata->oneofContainerName); - assert(it != oneof_containerToSelectedIndexMap.end()); + auto it = message._oneofContainerToSelectedIndexMap.find(fieldMetadata->oneofContainerName); + assert(it != message._oneofContainerToSelectedIndexMap.end()); auto selected_index = it->second; if (selected_index != fieldMetadata->protobufIndex) { diff --git a/src/grpc_client.cc b/src/grpc_client.cc index e626a47b..4e68c9f8 100644 --- a/src/grpc_client.cc +++ b/src/grpc_client.cc @@ -375,10 +375,8 @@ LIBRARY_EXPORT int32_t ClientUnaryCall2( if (clientCall->_useLVEfficientMessage) { - clientCall->_request = std::make_shared(requestMetadata); - clientCall->_response = std::make_shared(responseMetadata); - clientCall->_request->SetLVClusterHandle(reinterpret_cast(requestCluster)); - clientCall->_response->SetLVClusterHandle(reinterpret_cast(responseCluster)); + clientCall->_request = std::make_shared(requestMetadata, requestCluster); + clientCall->_response = std::make_shared(responseMetadata, responseCluster); } else { diff --git a/src/lv_message.cc b/src/lv_message.cc index e8db3a79..4910bdcc 100644 --- a/src/lv_message.cc +++ b/src/lv_message.cc @@ -83,6 +83,7 @@ namespace grpc_labview void LVMessage::Clear() { _values.clear(); + _oneofContainerToSelectedIndexMap.clear(); } //--------------------------------------------------------------------- @@ -105,8 +106,16 @@ namespace grpc_labview auto fieldIt = _metadata->_mappedElements.find(index); if (fieldIt != _metadata->_mappedElements.end()) { - auto fieldInfo = (*fieldIt).second; + auto& fieldInfo = (*fieldIt).second; LVMessageMetadataType dataType = fieldInfo->type; + + if (fieldInfo->isInOneof) + { + // set the map of the selected index for the "oneofContainer" to this protobuf Index + assert(_oneofContainerToSelectedIndexMap.find(fieldInfo->oneofContainerName) == _oneofContainerToSelectedIndexMap.end()); + _oneofContainerToSelectedIndexMap.insert({ fieldInfo->oneofContainerName, fieldInfo->protobufIndex }); + } + switch (dataType) { case LVMessageMetadataType::Int32Value: @@ -665,6 +674,31 @@ namespace grpc_labview assert(false); // not expected to be called } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void LVMessage::CopyOneofIndicesToCluster(int8_t* cluster) const + { + if (_oneofContainerToSelectedIndexMap.size() > 0) + { + // Must iterate over _elements and not _mappedElements since all oneof selected_index fields use -1 for the field number + // and there can be multiple oneof fields in a message. + for (auto& fieldMetadata : _metadata->_elements) + { + if (fieldMetadata->isInOneof && fieldMetadata->protobufIndex < 0) + { + // This field is the selected_index field of a oneof. This field only exists in the cluster + // and is not a field in the message. + auto it = _oneofContainerToSelectedIndexMap.find(fieldMetadata->oneofContainerName); + if (it != _oneofContainerToSelectedIndexMap.end()) + { + auto selectedIndexPtr = reinterpret_cast(cluster + fieldMetadata->clusterOffset); + *selectedIndexPtr = it->second; + } + } + } + } + } + //--------------------------------------------------------------------- //--------------------------------------------------------------------- void LVMessage::InternalSwap(LVMessage *other) diff --git a/src/lv_message.h b/src/lv_message.h index a1c6eebe..7e9c1877 100644 --- a/src/lv_message.h +++ b/src/lv_message.h @@ -42,27 +42,20 @@ namespace grpc_labview void MergeFrom(const LVMessage &from); void CopyFrom(const google::protobuf::Message &from) final; void CopyFrom(const LVMessage &from); + void CopyOneofIndicesToCluster(int8_t* cluster) const; void InternalSwap(LVMessage *other); google::protobuf::Metadata GetMetadata() const final; bool ParseFromByteBuffer(const grpc::ByteBuffer& buffer); std::unique_ptr SerializeToByteBuffer(); - void SetLVClusterHandle(const char* lvClusterHandle) { - _LVClusterHandle = lvClusterHandle; - }; - - const char* GetLVClusterHandleSharedPtr() { - return _LVClusterHandle; - }; - std::map> _values; std::shared_ptr _metadata; + std::map _oneofContainerToSelectedIndexMap; protected: mutable google::protobuf::internal::CachedSize _cached_size_; google::protobuf::UnknownFieldSet _unknownFields; - const char* _LVClusterHandle; virtual const char *ParseBoolean(const MessageElementMetadata& fieldInfo, uint32_t index, const char *ptr, google::protobuf::internal::ParseContext *ctx); virtual const char *ParseInt32(const MessageElementMetadata& fieldInfo, uint32_t index, const char *ptr, google::protobuf::internal::ParseContext *ctx); diff --git a/src/lv_message_efficient.cc b/src/lv_message_efficient.cc index 78d51dbd..578ba1c4 100644 --- a/src/lv_message_efficient.cc +++ b/src/lv_message_efficient.cc @@ -57,7 +57,6 @@ namespace grpc_labview DEFINE_PARSE_FUNCTION(uint64_t, UInt64, UINT64, UInt64) DEFINE_PARSE_FUNCTION(float, Float, FLOAT, Float) DEFINE_PARSE_FUNCTION(double, Double, DOUBLE, Double) - DEFINE_PARSE_FUNCTION_SPECIAL(int32_t, Enum, ENUM, Enum) DEFINE_PARSE_FUNCTION_SPECIAL(int32_t, SInt32, SINT32, SInt32) DEFINE_PARSE_FUNCTION_SPECIAL(int64_t, SInt64, SINT64, SInt64) DEFINE_PARSE_FUNCTION_SPECIAL(uint32_t, Fixed32, FIXED32, Fixed32) @@ -67,10 +66,46 @@ namespace grpc_labview //--------------------------------------------------------------------- //--------------------------------------------------------------------- - const char* LVMessageEfficient::ParseString(google::protobuf::uint32 tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* protobuf_ptr, ParseContext* ctx) + const char* LVMessageEfficient::ParseEnum(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, ParseContext* ctx) { - const char* lv_ptr = (this->GetLVClusterHandleSharedPtr()) + fieldInfo.clusterOffset; + std::shared_ptr enumMetadata = fieldInfo._owner->FindEnumMetadata(fieldInfo.embeddedMessageName); + auto lv_ptr = _LVClusterHandle + fieldInfo.clusterOffset; + + if (fieldInfo.isRepeated) + { + auto repeatedEnum = std::make_shared(index); + ptr = PackedEnumParser(&(repeatedEnum->_value), ptr, ctx); + + int count = repeatedEnum->_value.size(); + for (size_t i = 0; i < count; i++) + { + auto enumValueFromProtobuf = repeatedEnum->_value[i]; + repeatedEnum->_value[i] = enumMetadata->GetLVEnumValueFromProtoValue(enumValueFromProtobuf); + } + + if (count != 0) + { + auto messageTypeSize = sizeof(int32_t); + NumericArrayResize(GetTypeCodeForSize(messageTypeSize), 1, reinterpret_cast(lv_ptr), count); + auto array = *(LV1DArrayHandle*)lv_ptr; + (*array)->cnt = count; + auto byteCount = count * sizeof(int32_t); + memcpy((*array)->bytes(), repeatedEnum->_value.data(), byteCount); + } + } + else + { + int32_t enumValueFromProtobuf; + ptr = ReadENUM(ptr, &enumValueFromProtobuf); + *(int32_t*)lv_ptr = enumMetadata->GetLVEnumValueFromProtoValue(enumValueFromProtobuf); + } + return ptr; + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + const char* LVMessageEfficient::ParseString(google::protobuf::uint32 tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* protobuf_ptr, ParseContext* ctx) + { if (fieldInfo.isRepeated) { auto repeatedStringValuesIt = _repeatedStringValuesMap.find(fieldInfo.fieldName); @@ -97,6 +132,7 @@ namespace grpc_labview { auto str = std::string(); protobuf_ptr = InlineGreedyStringParser(&str, protobuf_ptr, ctx); + auto lv_ptr = _LVClusterHandle + fieldInfo.clusterOffset; SetLVString((LStrHandle*)lv_ptr, str); } return protobuf_ptr; @@ -146,7 +182,6 @@ namespace grpc_labview do { protobuf_ptr += tagSize; - LVMessageEfficient nestedMessage(metadata); // Resize the vector if we need more memory if (elementIndex >= numElements - 1) @@ -156,9 +191,9 @@ namespace grpc_labview repeatedMessageValuesIt->second.get()->_buffer.Resize(arraySize, _fillData); } - auto vectorPtr = repeatedMessageValuesIt->second.get()->_buffer.data(); - vectorPtr = vectorPtr + (elementIndex * clusterSize); - nestedMessage.SetLVClusterHandle(vectorPtr); + auto nestedMessageCluster = reinterpret_cast(const_cast(repeatedMessageValuesIt->second.get()->_buffer.data())); + nestedMessageCluster = nestedMessageCluster + (elementIndex * clusterSize); + LVMessageEfficient nestedMessage(metadata, nestedMessageCluster); protobuf_ptr = ctx->ParseMessage(&nestedMessage, protobuf_ptr); elementIndex++; @@ -173,16 +208,19 @@ namespace grpc_labview } else { - LVMessageEfficient nestedMessage(metadata); - const char* lv_ptr = (this->GetLVClusterHandleSharedPtr()) + fieldInfo.clusterOffset; - nestedMessage.SetLVClusterHandle(lv_ptr); + auto nestedClusterPtr = _LVClusterHandle + fieldInfo.clusterOffset; + LVMessageEfficient nestedMessage(metadata, nestedClusterPtr); protobuf_ptr = ctx->ParseMessage(&nestedMessage, protobuf_ptr); } return protobuf_ptr; } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- void LVMessageEfficient::PostInteralParseAction() { + CopyOneofIndicesToCluster(_LVClusterHandle); + for (auto nestedMessage : _repeatedMessageValuesMap) { auto& fieldInfo = nestedMessage.second.get()->_fieldInfo; @@ -190,7 +228,7 @@ namespace grpc_labview auto numClusters = nestedMessage.second.get()->_numElements; auto metadata = fieldInfo._owner->FindMetadata(fieldInfo.embeddedMessageName); - const char* lv_ptr = (this->GetLVClusterHandleSharedPtr()) + fieldInfo.clusterOffset; + auto lv_ptr = _LVClusterHandle + fieldInfo.clusterOffset; auto clusterSize = metadata->clusterSize; auto alignment = metadata->alignmentRequirement; @@ -202,22 +240,22 @@ namespace grpc_labview { alignedElementSize++; } - NumericArrayResize(GetTypeCodeForSize(alignment), 1, reinterpret_cast(const_cast(lv_ptr)), alignedElementSize); + NumericArrayResize(GetTypeCodeForSize(alignment), 1, reinterpret_cast(lv_ptr), alignedElementSize); auto arrayHandle = *(LV1DArrayHandle*)lv_ptr; (*arrayHandle)->cnt = numClusters; - auto _vectorDataPtr = buffer.data(); - auto _lvArrayDataPtr = (*arrayHandle)->bytes(0, alignment); - memcpy(_lvArrayDataPtr, _vectorDataPtr, byteSize); + auto vectorDataPtr = buffer.data(); + auto lvArrayDataPtr = (*arrayHandle)->bytes(0, alignment); + memcpy(lvArrayDataPtr, vectorDataPtr, byteSize); } for (auto repeatedStringValue : _repeatedStringValuesMap) { auto& fieldInfo = repeatedStringValue.second.get()->_fieldInfo; auto& repeatedString = repeatedStringValue.second.get()->_repeatedString; - const char* lv_ptr = (this->GetLVClusterHandleSharedPtr()) + fieldInfo.clusterOffset; + auto lv_ptr = _LVClusterHandle + fieldInfo.clusterOffset; - NumericArrayResize(GetTypeCodeForSize(sizeof(char*)), 1, reinterpret_cast(const_cast(lv_ptr)), repeatedString.size()); + NumericArrayResize(GetTypeCodeForSize(sizeof(char*)), 1, reinterpret_cast(lv_ptr), repeatedString.size()); auto arrayHandle = *(LV1DArrayHandle*)lv_ptr; (*arrayHandle)->cnt = repeatedString.size(); diff --git a/src/lv_message_efficient.h b/src/lv_message_efficient.h index 359e005e..8c98a624 100644 --- a/src/lv_message_efficient.h +++ b/src/lv_message_efficient.h @@ -18,11 +18,12 @@ namespace grpc_labview class LVMessageEfficient : public LVMessage { public: - LVMessageEfficient(std::shared_ptr metadata) : LVMessage(metadata) {} + LVMessageEfficient(std::shared_ptr metadata, int8_t* cluster) : LVMessage(metadata), _LVClusterHandle(cluster) {} ~LVMessageEfficient() {} Message* New(google::protobuf::Arena* arena) const override; void PostInteralParseAction() override; + int8_t* GetLVClusterHandle() { return _LVClusterHandle; }; protected: struct RepeatedMessageValue { @@ -47,34 +48,36 @@ namespace grpc_labview std::unordered_map> _repeatedStringValuesMap; protected: - const char* ParseBoolean(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseInt32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseUInt32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseEnum(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseInt64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseUInt64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseFloat(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseDouble(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseSInt32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseSInt64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseFixed32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseFixed64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseSFixed32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseSFixed64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseString(unsigned int tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseBytes(unsigned int tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); - const char* ParseNestedMessage(google::protobuf::uint32 tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx); + int8_t* _LVClusterHandle; + + const char* ParseBoolean(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseInt32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseUInt32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseEnum(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseInt64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseUInt64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseFloat(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseDouble(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseSInt32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseSInt64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseFixed32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseFixed64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseSFixed32(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseSFixed64(const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseString(unsigned int tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseBytes(unsigned int tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; + const char* ParseNestedMessage(google::protobuf::uint32 tag, const MessageElementMetadata& fieldInfo, uint32_t index, const char* ptr, google::protobuf::internal::ParseContext* ctx) override; }; template class SinglePassMessageParser { private: - LVMessage& _message; - const char* _lv_ptr; + LVMessageEfficient& _message; + int8_t* _lv_ptr; public: // Constructor and other necessary member functions - SinglePassMessageParser(LVMessage& message, const MessageElementMetadata& fieldInfo) : _message(message) { - _lv_ptr = reinterpret_cast(_message.GetLVClusterHandleSharedPtr()) + fieldInfo.clusterOffset; + SinglePassMessageParser(LVMessageEfficient& message, const MessageElementMetadata& fieldInfo) : _message(message) { + _lv_ptr = _message.GetLVClusterHandle() + fieldInfo.clusterOffset; } // Parse and copy message in a single pass. @@ -93,7 +96,7 @@ namespace grpc_labview if (numElements != 0) { auto messageTypeSize = sizeof(MessageType); - NumericArrayResize(GetTypeCodeForSize(messageTypeSize), 1, reinterpret_cast(const_cast(_lv_ptr)), numElements); + NumericArrayResize(GetTypeCodeForSize(messageTypeSize), 1, _lv_ptr, numElements); auto array = *(LV1DArrayHandle*)_lv_ptr; (*array)->cnt = numElements; auto byteCount = numElements * messageTypeSize; @@ -109,7 +112,7 @@ namespace grpc_labview } const char* ParseAndCopyMessage(const char* ptr) { - ptr = ReadMessageType(ptr, reinterpret_cast(const_cast(_lv_ptr))); + ptr = ReadMessageType(ptr, reinterpret_cast(_lv_ptr)); return ptr; }