Skip to content

Commit

Permalink
Added unpacking support for varints (#369)
Browse files Browse the repository at this point in the history
  • Loading branch information
yash-ni authored Jul 26, 2024
1 parent 80b6f39 commit f6ef366
Showing 1 changed file with 69 additions and 2 deletions.
71 changes: 69 additions & 2 deletions src/unpacked_fields.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,73 @@ namespace grpc_labview
}
}

//---------------------------------------------------------------------
//---------------------------------------------------------------------
template<typename T>
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<std::string> 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<int32_t>(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<T>(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<T>(), arr, count * sizeof(T));
}
else
{
*(T*)buffer = field->varint();
}
}

//---------------------------------------------------------------------
//---------------------------------------------------------------------
int32_t UnpackedFields::GetField(int protobufIndex, LVMessageMetadataType valueType, int isRepeated, int8_t* buffer)
Expand Down Expand Up @@ -100,12 +167,12 @@ namespace grpc_labview
case LVMessageMetadataType::Int32Value:
case LVMessageMetadataType::UInt32Value:
case LVMessageMetadataType::SInt32Value:
*(uint32_t*)buffer = field->varint();
CopyVarintBitValueField<uint32_t>(isRepeated, 0x03, 32, field, buffer);
break;
case LVMessageMetadataType::Int64Value:
case LVMessageMetadataType::UInt64Value:
case LVMessageMetadataType::SInt64Value:
*(uint64_t*)buffer = field->varint();
CopyVarintBitValueField<uint64_t>(isRepeated, 0x04, 64, field, buffer);
break;
case LVMessageMetadataType::FloatValue:
CopyFixed32BitValueField(isRepeated, 0x09, field, buffer);
Expand Down

0 comments on commit f6ef366

Please sign in to comment.