diff --git a/src/unpacked_fields.cc b/src/unpacked_fields.cc index 8db04b16..8cb364f4 100644 --- a/src/unpacked_fields.cc +++ b/src/unpacked_fields.cc @@ -68,6 +68,73 @@ namespace grpc_labview } } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + template + void CopyVarintBitValueField(bool isRepeated, int typeCode, size_t bits, const google::protobuf::UnknownField* field, int8_t* buffer) { + if (isRepeated) + { + // Labview output array (destArray). + auto destArray = (grpc_labview::LV1DArrayHandle*)buffer; + + // Get the encoded string of repeated datatype. + auto value = field->length_delimited(); + + // Decode and create a bitwise array (binarr) for the repeating datatype. + std::vector binarr; + size_t i = 0; + while (i < value.size()) { + std::string bin; + for (; i < value.size(); i++) { + int8_t ele = value[i]; + std::string tempbin; + for (size_t i = 0; i < 8; i++) { + tempbin.push_back(((ele >> i) & 1) + '0'); + } + if (tempbin.back() == '1') { + tempbin.pop_back(); + } + else { + while (tempbin.back() == '0' && tempbin.size() > 1) { + tempbin.pop_back(); + } + } + bin += tempbin; + if (((1 << 7) & ele) == 0) { + break; + } + } + if (bin.size() > bits) { + bin = bin.substr(0, bits); + } + binarr.push_back(bin); + i++; + } + + // Convert the bitwise array to unsigned integer array (arr). + size_t count = binarr.size(); + T* arr = new T[count]; + for (size_t i = 0; i < count; i++) { + // arr[i] = static_cast(stoll(binvec[i], nullptr, 2)); // have to reverse the string to make this work. + std::string t = binarr[i]; + T val = 0; + for (size_t i = 0; i < t.size(); i++) { + val += (t[i] - '0') * static_cast(std::pow(2ull, i)); + } + arr[i] = val; + } + + // Memcopy the unsigned integer array (arr) into the labview array (destArray). + grpc_labview::NumericArrayResize(typeCode, 1, destArray, count); + (**destArray)->cnt = count; + memcpy((**destArray)->bytes(), arr, count * sizeof(T)); + } + else + { + *(T*)buffer = field->varint(); + } + } + //--------------------------------------------------------------------- //--------------------------------------------------------------------- int32_t UnpackedFields::GetField(int protobufIndex, LVMessageMetadataType valueType, int isRepeated, int8_t* buffer) @@ -100,12 +167,12 @@ namespace grpc_labview case LVMessageMetadataType::Int32Value: case LVMessageMetadataType::UInt32Value: case LVMessageMetadataType::SInt32Value: - *(uint32_t*)buffer = field->varint(); + CopyVarintBitValueField(isRepeated, 0x03, 32, field, buffer); break; case LVMessageMetadataType::Int64Value: case LVMessageMetadataType::UInt64Value: case LVMessageMetadataType::SInt64Value: - *(uint64_t*)buffer = field->varint(); + CopyVarintBitValueField(isRepeated, 0x04, 64, field, buffer); break; case LVMessageMetadataType::FloatValue: CopyFixed32BitValueField(isRepeated, 0x09, field, buffer);