Commit b4953e9d authored by Kenton Varda's avatar Kenton Varda

Retrofit blob readers/builders on top of kj::ArrayPtr and kj::StringPtr.

parent 1b468272
......@@ -58,8 +58,8 @@ public:
static const char URL_PREFIX[] = "http://example.com/";
auto url = result.initUrl(urlSize + sizeof(URL_PREFIX));
strcpy(url.data(), URL_PREFIX);
char* pos = url.data() + strlen(URL_PREFIX);
strcpy(url.begin(), URL_PREFIX);
char* pos = url.begin() + strlen(URL_PREFIX);
for (int j = 0; j < urlSize; j++) {
*pos++ = 'a' + fastRand(26);
}
......@@ -85,7 +85,7 @@ public:
snippet.append(WORDS[fastRand(WORDS_COUNT)]);
}
result.setSnippet(snippet);
result.setSnippet(Text::Reader(snippet.c_str(), snippet.size()));
}
return goodCount;
......@@ -96,10 +96,10 @@ public:
for (auto result: request.getResults()) {
double score = result.getScore();
if (strstr(result.getSnippet().c_str(), " cat ") != nullptr) {
if (strstr(result.getSnippet().cStr(), " cat ") != nullptr) {
score *= 10000;
}
if (strstr(result.getSnippet().c_str(), " dog ") != nullptr) {
if (strstr(result.getSnippet().cStr(), " dog ") != nullptr) {
score /= 10000;
}
scoredResults.emplace_back(score, result);
......
......@@ -27,21 +27,21 @@
#include <string>
#include "test-util.h"
// TODO(test): This test is outdated -- it predates the retrofit of Text and Data on top of
// kj::ArrayPtr/kj::StringPtr. Clean it up.
namespace capnproto {
namespace {
TEST(Blob, Text) {
std::string str = "foo";
Text::Reader text = str;
Text::Reader text = str.c_str();
EXPECT_EQ("foo", text);
EXPECT_STREQ("foo", text.c_str());
EXPECT_STREQ("foo", text.data());
EXPECT_STREQ("foo", text.cStr());
EXPECT_STREQ("foo", text.begin());
EXPECT_EQ(3u, text.size());
std::string str2 = text.as<std::string>();
EXPECT_EQ("foo", str2);
Text::Reader text2 = "bar";
EXPECT_EQ("bar", text2);
......@@ -52,67 +52,67 @@ TEST(Blob, Text) {
Text::Builder builder(c, 3);
EXPECT_EQ("baz", builder);
EXPECT_EQ(Data::Reader("az"), builder.slice(1, 3));
EXPECT_EQ(kj::arrayPtr("az", 2), builder.slice(1, 3));
}
Data::Reader dataLit(const char* str) {
return Data::Reader(reinterpret_cast<const byte*>(str), strlen(str));
}
TEST(Blob, Data) {
std::string str = "foo";
Data::Reader data = str;
Data::Reader data = dataLit("foo");
EXPECT_EQ("foo", data);
EXPECT_EQ(dataLit("foo"), data);
EXPECT_EQ(3u, data.size());
std::string str2 = data.as<std::string>();
EXPECT_EQ("foo", str2);
Data::Reader data2 = "bar";
EXPECT_EQ("bar", data2.as<std::string>());
Data::Reader data2 = dataLit("bar");
EXPECT_EQ(dataLit("bar"), data2);
char c[4] = "baz";
Data::Reader data3(c);
EXPECT_EQ("baz", data3.as<std::string>());
byte c[4] = "baz";
Data::Reader data3(c, 3);
EXPECT_EQ(dataLit("baz"), data3);
Data::Builder builder(c, 3);
EXPECT_EQ("baz", builder.as<std::string>());
EXPECT_EQ(dataLit("baz"), builder);
EXPECT_EQ(Data::Reader("az"), builder.slice(1, 3));
EXPECT_EQ(dataLit("az"), builder.slice(1, 3));
}
TEST(Blob, Compare) {
EXPECT_TRUE (Data::Reader("foo") == Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foo") != Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("foo") <= Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("foo") >= Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foo") < Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foo") > Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foo") == Data::Reader("bar"));
EXPECT_TRUE (Data::Reader("foo") != Data::Reader("bar"));
EXPECT_FALSE(Data::Reader("foo") <= Data::Reader("bar"));
EXPECT_TRUE (Data::Reader("foo") >= Data::Reader("bar"));
EXPECT_FALSE(Data::Reader("foo") < Data::Reader("bar"));
EXPECT_TRUE (Data::Reader("foo") > Data::Reader("bar"));
EXPECT_FALSE(Data::Reader("bar") == Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("bar") != Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("bar") <= Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("bar") >= Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("bar") < Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("bar") > Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foobar") == Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("foobar") != Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foobar") <= Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("foobar") >= Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foobar") < Data::Reader("foo"));
EXPECT_TRUE (Data::Reader("foobar") > Data::Reader("foo"));
EXPECT_FALSE(Data::Reader("foo") == Data::Reader("foobar"));
EXPECT_TRUE (Data::Reader("foo") != Data::Reader("foobar"));
EXPECT_TRUE (Data::Reader("foo") <= Data::Reader("foobar"));
EXPECT_FALSE(Data::Reader("foo") >= Data::Reader("foobar"));
EXPECT_TRUE (Data::Reader("foo") < Data::Reader("foobar"));
EXPECT_FALSE(Data::Reader("foo") > Data::Reader("foobar"));
EXPECT_TRUE (Text::Reader("foo") == Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foo") != Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("foo") <= Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("foo") >= Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foo") < Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foo") > Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foo") == Text::Reader("bar"));
EXPECT_TRUE (Text::Reader("foo") != Text::Reader("bar"));
EXPECT_FALSE(Text::Reader("foo") <= Text::Reader("bar"));
EXPECT_TRUE (Text::Reader("foo") >= Text::Reader("bar"));
EXPECT_FALSE(Text::Reader("foo") < Text::Reader("bar"));
EXPECT_TRUE (Text::Reader("foo") > Text::Reader("bar"));
EXPECT_FALSE(Text::Reader("bar") == Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("bar") != Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("bar") <= Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("bar") >= Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("bar") < Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("bar") > Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foobar") == Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("foobar") != Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foobar") <= Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("foobar") >= Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foobar") < Text::Reader("foo"));
EXPECT_TRUE (Text::Reader("foobar") > Text::Reader("foo"));
EXPECT_FALSE(Text::Reader("foo") == Text::Reader("foobar"));
EXPECT_TRUE (Text::Reader("foo") != Text::Reader("foobar"));
EXPECT_TRUE (Text::Reader("foo") <= Text::Reader("foobar"));
EXPECT_FALSE(Text::Reader("foo") >= Text::Reader("foobar"));
EXPECT_TRUE (Text::Reader("foo") < Text::Reader("foobar"));
EXPECT_FALSE(Text::Reader("foo") > Text::Reader("foobar"));
}
} // namespace
......
This diff is collapsed.
......@@ -490,7 +490,7 @@ Text::Builder DynamicStruct::Builder::getObjectAsText(StructSchema::Member membe
auto field = member.getProto().getBody().getFieldMember();
KJ_REQUIRE(field.getType().getBody().which() == schema::Type::Body::OBJECT_TYPE,
"Expected an Object.");
return getObjectAsDataImpl(builder, member);
return getObjectAsTextImpl(builder, member);
}
}
......@@ -565,7 +565,7 @@ Text::Builder DynamicStruct::Builder::initObjectAsText(StructSchema::Member memb
auto field = member.getProto().getBody().getFieldMember();
KJ_REQUIRE(field.getType().getBody().which() == schema::Type::Body::OBJECT_TYPE,
"Expected an Object.");
return initFieldAsDataImpl(builder, member, size);
return initFieldAsTextImpl(builder, member, size);
}
}
......@@ -627,7 +627,7 @@ Text::Builder DynamicStruct::Builder::getObjectAsText(Text::Reader name) {
return getObjectAsText(schema.getMemberByName(name));
}
Data::Builder DynamicStruct::Builder::getObjectAsData(Text::Reader name) {
return getObjectAsText(schema.getMemberByName(name));
return getObjectAsData(schema.getMemberByName(name));
}
DynamicStruct::Builder DynamicStruct::Builder::initObject(
Text::Reader name, StructSchema type) {
......@@ -641,7 +641,7 @@ Text::Builder DynamicStruct::Builder::initObjectAsText(Text::Reader name, uint s
return initObjectAsText(schema.getMemberByName(name), size);
}
Data::Builder DynamicStruct::Builder::initObjectAsData(Text::Reader name, uint size) {
return initObjectAsText(schema.getMemberByName(name), size);
return initObjectAsData(schema.getMemberByName(name), size);
}
DynamicValue::Reader DynamicStruct::Reader::getImpl(
......@@ -691,14 +691,14 @@ DynamicValue::Reader DynamicStruct::Reader::getImpl(
Text::Reader typedDval = dval.getTextValue();
return DynamicValue::Reader(
reader.getBlobField<Text>(field.getOffset() * POINTERS,
typedDval.data(), typedDval.size() * BYTES));
typedDval.begin(), typedDval.size() * BYTES));
}
case schema::Type::Body::DATA_TYPE: {
Data::Reader typedDval = dval.getDataValue();
return DynamicValue::Reader(
reader.getBlobField<Data>(field.getOffset() * POINTERS,
typedDval.data(), typedDval.size() * BYTES));
typedDval.begin(), typedDval.size() * BYTES));
}
case schema::Type::Body::LIST_TYPE: {
......@@ -783,14 +783,14 @@ DynamicValue::Builder DynamicStruct::Builder::getImpl(
Text::Reader typedDval = dval.getTextValue();
return DynamicValue::Builder(
builder.getBlobField<Text>(field.getOffset() * POINTERS,
typedDval.data(), typedDval.size() * BYTES));
typedDval.begin(), typedDval.size() * BYTES));
}
case schema::Type::Body::DATA_TYPE: {
Data::Reader typedDval = dval.getDataValue();
return DynamicValue::Builder(
builder.getBlobField<Data>(field.getOffset() * POINTERS,
typedDval.data(), typedDval.size() * BYTES));
typedDval.begin(), typedDval.size() * BYTES));
}
case schema::Type::Body::LIST_TYPE: {
......@@ -1457,6 +1457,7 @@ BuilderFor<typeName> DynamicValue::Builder::AsImpl<typeName>::apply(Builder buil
HANDLE_TYPE(bool, BOOL, bool)
HANDLE_TYPE(text, TEXT, Text)
HANDLE_TYPE(data, DATA, Data)
HANDLE_TYPE(list, LIST, DynamicList)
HANDLE_TYPE(struct, STRUCT, DynamicStruct)
HANDLE_TYPE(enum, ENUM, DynamicEnum)
......@@ -1465,27 +1466,6 @@ HANDLE_TYPE(union, UNION, DynamicUnion)
#undef HANDLE_TYPE
Data::Reader DynamicValue::Reader::AsImpl<Data>::apply(Reader reader) {
if (reader.type == TEXT) {
// Implicitly convert from text.
return reader.textValue;
}
KJ_REQUIRE(reader.type == DATA, "Type mismatch when using DynamicValue::Reader::as().") {
return Data::Reader();
}
return reader.dataValue;
}
Data::Builder DynamicValue::Builder::AsImpl<Data>::apply(Builder builder) {
if (builder.type == TEXT) {
// Implicitly convert from text.
return builder.textValue;
}
KJ_REQUIRE(builder.type == DATA, "Type mismatch when using DynamicValue::Builder::as().") {
return Data::Builder();
}
return builder.dataValue;
}
// As in the header, HANDLE_TYPE(void, VOID, Void) crashes GCC 4.7.
Void DynamicValue::Reader::AsImpl<Void>::apply(Reader reader) {
KJ_REQUIRE(reader.type == VOID, "Type mismatch when using DynamicValue::Reader::as().") {
......
......@@ -556,7 +556,6 @@ public:
// - Integers can be converted to floating points. This may lose information, but won't throw.
// - Float32/Float64 can be converted between each other. Converting Float64 -> Float32 may lose
// information, but won't throw.
// - Text can be converted to Data (but not vice-versa).
// - Text can be converted to an enum, if the Text matches one of the enumerant names (but not
// vice-versa).
//
......
......@@ -148,9 +148,9 @@ TEST(Encoding, GenericObjects) {
EXPECT_EQ("foo", root.getObjectField<Text>());
EXPECT_EQ("foo", root.asReader().getObjectField<Text>());
root.setObjectField<Data>("foo");
EXPECT_EQ("foo", root.getObjectField<Data>());
EXPECT_EQ("foo", root.asReader().getObjectField<Data>());
root.setObjectField<Data>(data("foo"));
EXPECT_EQ(data("foo"), root.getObjectField<Data>());
EXPECT_EQ(data("foo"), root.asReader().getObjectField<Data>());
{
root.setObjectField<List<uint32_t>>({123, 456, 789});
......
......@@ -1226,7 +1226,8 @@ struct WireHelpers {
static KJ_ALWAYS_INLINE(void setTextPointer(
WirePointer* ref, SegmentBuilder* segment, Text::Reader value)) {
initTextPointer(ref, segment, value.size() * BYTES).copyFrom(value);
memcpy(initTextPointer(ref, segment, value.size() * BYTES).begin(),
value.begin(), value.size());
}
static KJ_ALWAYS_INLINE(Text::Builder getWritableTextPointer(
......@@ -1234,7 +1235,7 @@ struct WireHelpers {
const void* defaultValue, ByteCount defaultSize)) {
if (ref->isNull()) {
Text::Builder builder = initTextPointer(ref, segment, defaultSize);
builder.copyFrom(defaultValue);
memcpy(builder.begin(), defaultValue, defaultSize / BYTES);
return builder;
} else {
word* ptr = followFars(ref, segment);
......@@ -1258,12 +1259,13 @@ struct WireHelpers {
ref->listRef.set(FieldSize::BYTE, size * (1 * ELEMENTS / BYTES));
// Build the Data::Builder.
return Data::Builder(reinterpret_cast<char*>(ptr), size / BYTES);
return Data::Builder(reinterpret_cast<byte*>(ptr), size / BYTES);
}
static KJ_ALWAYS_INLINE(void setDataPointer(
WirePointer* ref, SegmentBuilder* segment, Data::Reader value)) {
initDataPointer(ref, segment, value.size() * BYTES).copyFrom(value);
memcpy(initDataPointer(ref, segment, value.size() * BYTES).begin(),
value.begin(), value.size());
}
static KJ_ALWAYS_INLINE(Data::Builder getWritableDataPointer(
......@@ -1271,7 +1273,7 @@ struct WireHelpers {
const void* defaultValue, ByteCount defaultSize)) {
if (ref->isNull()) {
Data::Builder builder = initDataPointer(ref, segment, defaultSize);
builder.copyFrom(defaultValue);
memcpy(builder.begin(), defaultValue, defaultSize / BYTES);
return builder;
} else {
word* ptr = followFars(ref, segment);
......@@ -1281,7 +1283,7 @@ struct WireHelpers {
KJ_REQUIRE(ref->listRef.elementSize() == FieldSize::BYTE,
"Called getData{Field,Element}() but existing list pointer is not byte-sized.");
return Data::Builder(reinterpret_cast<char*>(ptr), ref->listRef.elementCount() / ELEMENTS);
return Data::Builder(reinterpret_cast<byte*>(ptr), ref->listRef.elementCount() / ELEMENTS);
}
}
......@@ -1668,7 +1670,7 @@ struct WireHelpers {
const void* defaultValue, ByteCount defaultSize)) {
if (ref == nullptr || ref->isNull()) {
useDefault:
return Data::Reader(reinterpret_cast<const char*>(defaultValue), defaultSize / BYTES);
return Data::Reader(reinterpret_cast<const byte*>(defaultValue), defaultSize / BYTES);
} else {
const word* ptr = followFars(ref, segment);
......@@ -1695,7 +1697,7 @@ struct WireHelpers {
goto useDefault;
}
return Data::Reader(reinterpret_cast<const char*>(ptr), size);
return Data::Reader(reinterpret_cast<const byte*>(ptr), size);
}
}
......@@ -2022,7 +2024,7 @@ Data::Builder ListBuilder::asData() {
return Data::Builder();
}
return Data::Builder(reinterpret_cast<char*>(ptr), elementCount / ELEMENTS);
return Data::Builder(reinterpret_cast<byte*>(ptr), elementCount / ELEMENTS);
}
StructBuilder ListBuilder::getStructElement(ElementCount index) const {
......@@ -2143,7 +2145,7 @@ Data::Reader ListReader::asData() {
return Data::Reader();
}
return Data::Reader(reinterpret_cast<const char*>(ptr), elementCount / ELEMENTS);
return Data::Reader(reinterpret_cast<const byte*>(ptr), elementCount / ELEMENTS);
}
StructReader ListReader::getStructElement(ElementCount index) const {
......
......@@ -712,7 +712,7 @@ struct ObjectReader {
// Internal implementation details...
inline Data::Builder StructBuilder::getDataSectionAsBlob() {
return Data::Builder(reinterpret_cast<char*>(data), dataSize / BITS_PER_BYTE / BYTES);
return Data::Builder(reinterpret_cast<byte*>(data), dataSize / BITS_PER_BYTE / BYTES);
}
template <typename T>
......@@ -768,7 +768,7 @@ inline void StructBuilder::setDataField(
// -------------------------------------------------------------------
inline Data::Reader StructReader::getDataSectionAsBlob() {
return Data::Reader(reinterpret_cast<const char*>(data), dataSize / BITS_PER_BYTE / BYTES);
return Data::Reader(reinterpret_cast<const byte*>(data), dataSize / BITS_PER_BYTE / BYTES);
}
template <typename T>
......
......@@ -170,8 +170,8 @@ TEST(SchemaLoader, Upgrade) {
loadUnderAlternateTypeId<test::TestNewVersion>(loader, typeId<test::TestOldVersion>());
// The new version replaced the old.
EXPECT_STREQ(Schema::from<test::TestNewVersion>().getProto().getDisplayName(),
schema.getProto().getDisplayName());
EXPECT_EQ(Schema::from<test::TestNewVersion>().getProto().getDisplayName(),
schema.getProto().getDisplayName());
// But it is still usable as the old version.
schema.requireUsableAs<test::TestOldVersion>();
......@@ -189,8 +189,8 @@ TEST(SchemaLoader, Downgrade) {
loadUnderAlternateTypeId<test::TestOldVersion>(loader, typeId<test::TestNewVersion>());
// We kept the new version, because the replacement was older.
EXPECT_STREQ(Schema::from<test::TestNewVersion>().getProto().getDisplayName(),
schema.getProto().getDisplayName());
EXPECT_EQ(Schema::from<test::TestNewVersion>().getProto().getDisplayName(),
schema.getProto().getDisplayName());
schema.requireUsableAs<test::TestNewVersion>();
}
......
......@@ -466,81 +466,102 @@ TEST(Packed, RoundTripAllZeroEvenSegmentCountLazy) {
// =======================================================================================
TEST(Packed, RoundTripHugeString) {
kj::String huge = kj::heapString(5023);
memset(huge.begin(), 'x', 5023);
TestMessageBuilder builder(1);
builder.initRoot<TestAllTypes>().setTextField(std::string(5023, 'x'));
builder.initRoot<TestAllTypes>().setTextField(huge);
TestPipe pipe;
writePackedMessage(pipe, builder);
PackedMessageReader reader(pipe);
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == std::string(5023, 'x'));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == huge);
}
TEST(Packed, RoundTripHugeStringScratchSpace) {
kj::String huge = kj::heapString(5023);
memset(huge.begin(), 'x', 5023);
TestMessageBuilder builder(1);
builder.initRoot<TestAllTypes>().setTextField(std::string(5023, 'x'));
builder.initRoot<TestAllTypes>().setTextField(huge);
TestPipe pipe;
writePackedMessage(pipe, builder);
word scratch[1024];
PackedMessageReader reader(pipe, ReaderOptions(), kj::ArrayPtr<word>(scratch, 1024));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == std::string(5023, 'x'));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == huge);
}
TEST(Packed, RoundTripHugeStringLazy) {
kj::String huge = kj::heapString(5023);
memset(huge.begin(), 'x', 5023);
TestMessageBuilder builder(1);
builder.initRoot<TestAllTypes>().setTextField(std::string(5023, 'x'));
builder.initRoot<TestAllTypes>().setTextField(huge);
TestPipe pipe(1);
writePackedMessage(pipe, builder);
PackedMessageReader reader(pipe);
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == std::string(5023, 'x'));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == huge);
}
TEST(Packed, RoundTripHugeStringOddSegmentCount) {
kj::String huge = kj::heapString(5023);
memset(huge.begin(), 'x', 5023);
TestMessageBuilder builder(3);
builder.initRoot<TestAllTypes>().setTextField(std::string(5023, 'x'));
builder.initRoot<TestAllTypes>().setTextField(huge);
TestPipe pipe;
writePackedMessage(pipe, builder);
PackedMessageReader reader(pipe);
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == std::string(5023, 'x'));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == huge);
}
TEST(Packed, RoundTripHugeStringOddSegmentCountLazy) {
kj::String huge = kj::heapString(5023);
memset(huge.begin(), 'x', 5023);
TestMessageBuilder builder(3);
builder.initRoot<TestAllTypes>().setTextField(std::string(5023, 'x'));
builder.initRoot<TestAllTypes>().setTextField(huge);
TestPipe pipe(1);
writePackedMessage(pipe, builder);
PackedMessageReader reader(pipe);
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == std::string(5023, 'x'));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == huge);
}
TEST(Packed, RoundTripHugeStringEvenSegmentCount) {
kj::String huge = kj::heapString(5023);
memset(huge.begin(), 'x', 5023);
TestMessageBuilder builder(2);
builder.initRoot<TestAllTypes>().setTextField(std::string(5023, 'x'));
builder.initRoot<TestAllTypes>().setTextField(huge);
TestPipe pipe;
writePackedMessage(pipe, builder);
PackedMessageReader reader(pipe);
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == std::string(5023, 'x'));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == huge);
}
TEST(Packed, RoundTripHugeStringEvenSegmentCountLazy) {
kj::String huge = kj::heapString(5023);
memset(huge.begin(), 'x', 5023);
TestMessageBuilder builder(2);
builder.initRoot<TestAllTypes>().setTextField(std::string(5023, 'x'));
builder.initRoot<TestAllTypes>().setTextField(huge);
TestPipe pipe(1);
writePackedMessage(pipe, builder);
PackedMessageReader reader(pipe);
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == std::string(5023, 'x'));
EXPECT_TRUE(reader.getRoot<TestAllTypes>().getTextField() == huge);
}
// TODO(test): Test error cases.
......
......@@ -69,7 +69,15 @@ static void print(std::ostream& os, DynamicValue::Reader value,
case DynamicValue::TEXT:
case DynamicValue::DATA: {
os << '\"';
for (char c: value.as<Data>()) {
// TODO(someday): Data probably shouldn't be printed as a string.
kj::ArrayPtr<const char> chars;
if (value.getType() == DynamicValue::DATA) {
auto reader = value.as<Data>();
chars = kj::arrayPtr(reinterpret_cast<const char*>(reader.begin()), reader.size());
} else {
chars = value.as<Text>();
}
for (char c: chars) {
switch (c) {
case '\a': os << "\\a"; break;
case '\b': os << "\\b"; break;
......@@ -112,7 +120,7 @@ static void print(std::ostream& os, DynamicValue::Reader value,
case DynamicValue::ENUM: {
auto enumValue = value.as<DynamicEnum>();
KJ_IF_MAYBE(enumerant, enumValue.getEnumerant()) {
os << enumerant->getProto().getName().c_str();
os << enumerant->getProto().getName().cStr();
} else {
// Unknown enum value; output raw number.
os << enumValue.getRaw();
......@@ -130,7 +138,7 @@ static void print(std::ostream& os, DynamicValue::Reader value,
} else {
os << ", ";
}
os << member.getProto().getName().c_str() << " = ";
os << member.getProto().getName().cStr() << " = ";
auto memberBody = member.getProto().getBody();
switch (memberBody.which()) {
......@@ -150,7 +158,7 @@ static void print(std::ostream& os, DynamicValue::Reader value,
case DynamicValue::UNION: {
auto unionValue = value.as<DynamicUnion>();
KJ_IF_MAYBE(tag, unionValue.which()) {
os << tag->getProto().getName() << "(";
os << tag->getProto().getName().cStr() << "(";
print(os, unionValue.get(),
tag->getProto().getBody().getFieldMember().getType().getBody().which());
os << ")";
......
......@@ -44,7 +44,7 @@ void genericInitTestMessage(Builder builder) {
builder.setFloat32Field(1234.5);
builder.setFloat64Field(-123e45);
builder.setTextField("foo");
builder.setDataField("bar");
builder.setDataField(data("bar"));
{
auto subBuilder = builder.initStructField();
subBuilder.setVoidField(Void::VOID);
......@@ -60,7 +60,7 @@ void genericInitTestMessage(Builder builder) {
subBuilder.setFloat32Field(-1.25e-10);
subBuilder.setFloat64Field(345);
subBuilder.setTextField("baz");
subBuilder.setDataField("qux");
subBuilder.setDataField(data("qux"));
{
auto subSubBuilder = subBuilder.initStructField();
subSubBuilder.setTextField("nested");
......@@ -82,7 +82,7 @@ void genericInitTestMessage(Builder builder) {
subBuilder.setFloat32List({0, 1234567, 1e37, -1e37, 1e-37, -1e-37});
subBuilder.setFloat64List({0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306});
subBuilder.setTextList({"quux", "corge", "grault"});
subBuilder.setDataList({"garply", "waldo", "fred"});
subBuilder.setDataList({data("garply"), data("waldo"), data("fred")});
{
auto listBuilder = subBuilder.initStructList(3);
listBuilder[0].setTextField("x structlist 1");
......@@ -112,7 +112,7 @@ void genericInitTestMessage(Builder builder) {
-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::quiet_NaN()});
builder.setTextList({"plugh", "xyzzy", "thud"});
builder.setDataList({"oops", "exhausted", "rfc3092"});
builder.setDataList({data("oops"), data("exhausted"), data("rfc3092")});
{
auto listBuilder = builder.initStructList(3);
listBuilder[0].setTextField("structlist 1");
......@@ -136,7 +136,7 @@ void dynamicInitTestMessage(DynamicStruct::Builder builder) {
builder.set("float32Field", 1234.5);
builder.set("float64Field", -123e45);
builder.set("textField", "foo");
builder.set("dataField", "bar");
builder.set("dataField", data("bar"));
{
auto subBuilder = builder.init("structField").as<DynamicStruct>();
subBuilder.set("voidField", Void::VOID);
......@@ -152,7 +152,7 @@ void dynamicInitTestMessage(DynamicStruct::Builder builder) {
subBuilder.set("float32Field", -1.25e-10);
subBuilder.set("float64Field", 345);
subBuilder.set("textField", "baz");
subBuilder.set("dataField", "qux");
subBuilder.set("dataField", data("qux"));
{
auto subSubBuilder = subBuilder.init("structField").as<DynamicStruct>();
subSubBuilder.set("textField", "nested");
......@@ -174,7 +174,7 @@ void dynamicInitTestMessage(DynamicStruct::Builder builder) {
subBuilder.set("float32List", {0, 1234567, 1e37, -1e37, 1e-37, -1e-37});
subBuilder.set("float64List", {0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306});
subBuilder.set("textList", {"quux", "corge", "grault"});
subBuilder.set("dataList", {"garply", "waldo", "fred"});
subBuilder.set("dataList", {data("garply"), data("waldo"), data("fred")});
{
auto listBuilder = subBuilder.init("structList", 3).as<DynamicList>();
listBuilder[0].as<DynamicStruct>().set("textField", "x structlist 1");
......@@ -204,7 +204,7 @@ void dynamicInitTestMessage(DynamicStruct::Builder builder) {
-std::numeric_limits<double>::infinity(),
std::numeric_limits<double>::quiet_NaN()});
builder.set("textList", {"plugh", "xyzzy", "thud"});
builder.set("dataList", {"oops", "exhausted", "rfc3092"});
builder.set("dataList", {data("oops"), data("exhausted"), data("rfc3092")});
{
auto listBuilder = builder.init("structList", 3).as<DynamicList>();
listBuilder[0].as<DynamicStruct>().set("textField", "structlist 1");
......@@ -256,7 +256,7 @@ void genericCheckTestMessage(Reader reader) {
EXPECT_FLOAT_EQ(1234.5f, reader.getFloat32Field());
EXPECT_DOUBLE_EQ(-123e45, reader.getFloat64Field());
EXPECT_EQ("foo", reader.getTextField());
EXPECT_EQ("bar", reader.getDataField());
EXPECT_EQ(data("bar"), reader.getDataField());
{
auto subReader = reader.getStructField();
EXPECT_EQ(Void::VOID, subReader.getVoidField());
......@@ -272,7 +272,7 @@ void genericCheckTestMessage(Reader reader) {
EXPECT_FLOAT_EQ(-1.25e-10f, subReader.getFloat32Field());
EXPECT_DOUBLE_EQ(345, subReader.getFloat64Field());
EXPECT_EQ("baz", subReader.getTextField());
EXPECT_EQ("qux", subReader.getDataField());
EXPECT_EQ(data("qux"), subReader.getDataField());
{
auto subSubReader = subReader.getStructField();
EXPECT_EQ("nested", subSubReader.getTextField());
......@@ -294,7 +294,7 @@ void genericCheckTestMessage(Reader reader) {
checkList(subReader.getFloat32List(), {0.0f, 1234567.0f, 1e37f, -1e37f, 1e-37f, -1e-37f});
checkList(subReader.getFloat64List(), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306});
checkList(subReader.getTextList(), {"quux", "corge", "grault"});
checkList(subReader.getDataList(), {"garply", "waldo", "fred"});
checkList(subReader.getDataList(), {data("garply"), data("waldo"), data("fred")});
{
auto listReader = subReader.getStructList();
ASSERT_EQ(3u, listReader.size());
......@@ -333,7 +333,7 @@ void genericCheckTestMessage(Reader reader) {
EXPECT_TRUE(isNaN(listReader[3]));
}
checkList(reader.getTextList(), {"plugh", "xyzzy", "thud"});
checkList(reader.getDataList(), {"oops", "exhausted", "rfc3092"});
checkList(reader.getDataList(), {data("oops"), data("exhausted"), data("rfc3092")});
{
auto listReader = reader.getStructList();
ASSERT_EQ(3u, listReader.size());
......@@ -400,7 +400,7 @@ void dynamicCheckTestMessage(Reader reader) {
EXPECT_FLOAT_EQ(1234.5f, reader.get("float32Field").as<float>());
EXPECT_DOUBLE_EQ(-123e45, reader.get("float64Field").as<double>());
EXPECT_EQ("foo", reader.get("textField").as<Text>());
EXPECT_EQ("bar", reader.get("dataField").as<Data>());
EXPECT_EQ(data("bar"), reader.get("dataField").as<Data>());
{
auto subReader = reader.get("structField").as<DynamicStruct>();
EXPECT_EQ(Void::VOID, subReader.get("voidField").as<Void>());
......@@ -416,7 +416,7 @@ void dynamicCheckTestMessage(Reader reader) {
EXPECT_FLOAT_EQ(-1.25e-10f, subReader.get("float32Field").as<float>());
EXPECT_DOUBLE_EQ(345, subReader.get("float64Field").as<double>());
EXPECT_EQ("baz", subReader.get("textField").as<Text>());
EXPECT_EQ("qux", subReader.get("dataField").as<Data>());
EXPECT_EQ(data("qux"), subReader.get("dataField").as<Data>());
{
auto subSubReader = subReader.get("structField").as<DynamicStruct>();
EXPECT_EQ("nested", subSubReader.get("textField").as<Text>());
......@@ -439,7 +439,7 @@ void dynamicCheckTestMessage(Reader reader) {
checkList<float>(subReader.get("float32List"), {0.0f, 1234567.0f, 1e37f, -1e37f, 1e-37f, -1e-37f});
checkList<double>(subReader.get("float64List"), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306});
checkList<Text>(subReader.get("textList"), {"quux", "corge", "grault"});
checkList<Data>(subReader.get("dataList"), {"garply", "waldo", "fred"});
checkList<Data>(subReader.get("dataList"), {data("garply"), data("waldo"), data("fred")});
{
auto listReader = subReader.get("structList").as<DynamicList>();
ASSERT_EQ(3u, listReader.size());
......@@ -478,7 +478,7 @@ void dynamicCheckTestMessage(Reader reader) {
EXPECT_TRUE(isNaN(listReader[3].as<double>()));
}
checkList<Text>(reader.get("textList"), {"plugh", "xyzzy", "thud"});
checkList<Data>(reader.get("dataList"), {"oops", "exhausted", "rfc3092"});
checkList<Data>(reader.get("dataList"), {data("oops"), data("exhausted"), data("rfc3092")});
{
auto listReader = reader.get("structList").as<DynamicList>();
ASSERT_EQ(3u, listReader.size());
......@@ -506,7 +506,7 @@ void genericCheckTestMessageAllZero(Reader reader) {
EXPECT_FLOAT_EQ(0, reader.getFloat32Field());
EXPECT_DOUBLE_EQ(0, reader.getFloat64Field());
EXPECT_EQ("", reader.getTextField());
EXPECT_EQ("", reader.getDataField());
EXPECT_EQ(data(""), reader.getDataField());
{
auto subReader = reader.getStructField();
EXPECT_EQ(Void::VOID, subReader.getVoidField());
......@@ -522,7 +522,7 @@ void genericCheckTestMessageAllZero(Reader reader) {
EXPECT_FLOAT_EQ(0, subReader.getFloat32Field());
EXPECT_DOUBLE_EQ(0, subReader.getFloat64Field());
EXPECT_EQ("", subReader.getTextField());
EXPECT_EQ("", subReader.getDataField());
EXPECT_EQ(data(""), subReader.getDataField());
{
auto subSubReader = subReader.getStructField();
EXPECT_EQ("", subSubReader.getTextField());
......@@ -581,7 +581,7 @@ void dynamicCheckTestMessageAllZero(Reader reader) {
EXPECT_FLOAT_EQ(0, reader.get("float32Field").as<float>());
EXPECT_DOUBLE_EQ(0, reader.get("float64Field").as<double>());
EXPECT_EQ("", reader.get("textField").as<Text>());
EXPECT_EQ("", reader.get("dataField").as<Data>());
EXPECT_EQ(data(""), reader.get("dataField").as<Data>());
{
auto subReader = reader.get("structField").as<DynamicStruct>();
EXPECT_EQ(Void::VOID, subReader.get("voidField").as<Void>());
......@@ -597,7 +597,7 @@ void dynamicCheckTestMessageAllZero(Reader reader) {
EXPECT_FLOAT_EQ(0, subReader.get("float32Field").as<float>());
EXPECT_DOUBLE_EQ(0, subReader.get("float64Field").as<double>());
EXPECT_EQ("", subReader.get("textField").as<Text>());
EXPECT_EQ("", subReader.get("dataField").as<Data>());
EXPECT_EQ(data(""), subReader.get("dataField").as<Data>());
{
auto subSubReader = subReader.get("structField").as<DynamicStruct>();
EXPECT_EQ("", subSubReader.get("textField").as<Text>());
......
......@@ -32,16 +32,16 @@
namespace capnproto {
inline std::ostream& operator<<(std::ostream& os, const Data::Reader& value) {
return os.write(value.data(), value.size());
return os.write(reinterpret_cast<const char*>(value.begin()), value.size());
}
inline std::ostream& operator<<(std::ostream& os, const Data::Builder& value) {
return os.write(value.data(), value.size());
return os.write(reinterpret_cast<char*>(value.begin()), value.size());
}
inline std::ostream& operator<<(std::ostream& os, const Text::Reader& value) {
return os.write(value.data(), value.size());
return os.write(value.begin(), value.size());
}
inline std::ostream& operator<<(std::ostream& os, const Text::Builder& value) {
return os.write(value.data(), value.size());
return os.write(value.begin(), value.size());
}
inline std::ostream& operator<<(std::ostream& os, Void) {
return os << "void";
......@@ -49,6 +49,10 @@ inline std::ostream& operator<<(std::ostream& os, Void) {
namespace internal {
inline Data::Reader data(const char* str) {
return Data::Reader(reinterpret_cast<const byte*>(str), strlen(str));
}
namespace test = capnproto_test::capnproto::test;
// We don't use "using namespace" to pull these in because then things would still compile
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment