Skip to content

Commit b2775e8

Browse files
Merge pull request #985 from leapmotion/config/unsigned-marshal
Fix marshaling of unsigned ints and 0
2 parents 52311f3 + 9585eca commit b2775e8

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

src/autowiring/marshaller.h

+12-15
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
#include <cmath>
66
#include <limits>
77
#include <stdexcept>
8+
89
#include <string>
910
#include <string.h>
11+
#include <stdlib.h>
1012
#include TYPE_TRAITS_HEADER
1113

1214
namespace autowiring {
@@ -107,6 +109,9 @@ namespace autowiring {
107109
std::string marshal(const void* ptr) const override {
108110
std::string retVal;
109111
type val = *static_cast<const type*>(ptr);
112+
if (val == 0)
113+
return "0";
114+
110115
bool pos = 0 < val;
111116
if (!pos)
112117
val *= ~0;
@@ -120,28 +125,20 @@ namespace autowiring {
120125
auto first = retVal.begin(), last = retVal.end();
121126
(first != last) && (first != --last);
122127
++first
123-
)
128+
)
124129
std::swap(*first, *last);
125130
return retVal;
126131
}
127132

128133
void unmarshal(void* ptr, const char* szValue) const override {
129134
type& value = *static_cast<type*>(ptr);
130-
bool negative = *szValue == '-';
131-
if(negative) {
132-
// Skip over the sign, verify we aren't assigning to the wrong field type
133-
szValue++;
134-
if (std::is_unsigned<type>::value)
135-
throw std::range_error("Attempted to set a signed value on an unsigned calibration field");
136-
}
135+
char* end = nullptr;
136+
const auto llvalue = strtoll(szValue, &end, 10);
137137

138-
for (value = 0; *szValue; szValue++) {
139-
if (*szValue < '0' || '9' < *szValue)
140-
throw std::invalid_argument("String value is not an integer");
141-
value = *szValue - '0' + value * 10;
142-
}
143-
if(negative)
144-
value *= -1;
138+
if (llvalue > std::numeric_limits<type>::max() || llvalue < std::numeric_limits<type>::min())
139+
throw std::range_error("Overflow error, value is outside the range representable by this type.");
140+
141+
value = static_cast<type>(llvalue);
145142
}
146143

147144
void copy(void* lhs, const void* rhs) const override {

src/autowiring/test/MarshallerTest.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,28 @@ TEST_F(MarshallerTest, NegativeValues) {
2424
int y = 0xCDCDCDCD;
2525
std::string valY = b.marshal(&y);
2626
ASSERT_STREQ("-842150451", valY.c_str());
27+
28+
int z = 0;
29+
std::string valZ = b.marshal(&z);
30+
ASSERT_STREQ("0", valZ.c_str());
31+
}
32+
33+
TEST_F(MarshallerTest, UnsignedValues) {
34+
autowiring::marshaller<unsigned int> b;
35+
36+
int x = 0;
37+
std::string valX = b.marshal(&x);
38+
ASSERT_STREQ("0", valX.c_str());
2739
}
2840

41+
TEST_F(MarshallerTest, RoundTripTest) {
42+
autowiring::marshaller<unsigned int> b;
43+
44+
unsigned int x = 20;
45+
std::string valX = b.marshal(&x);
46+
47+
unsigned int outX = 0;
48+
b.unmarshal(&outX, valX.c_str());
49+
50+
ASSERT_EQ(outX, x);
51+
}

0 commit comments

Comments
 (0)