Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
b4953e9d
Commit
b4953e9d
authored
Jun 05, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Retrofit blob readers/builders on top of kj::ArrayPtr and kj::StringPtr.
parent
1b468272
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
252 additions
and
303 deletions
+252
-303
capnproto-catrank.c++
c++/src/capnproto/benchmark/capnproto-catrank.c++
+5
-5
blob-test.c++
c++/src/capnproto/blob-test.c++
+54
-54
blob.h
c++/src/capnproto/blob.h
+88
-153
dynamic.c++
c++/src/capnproto/dynamic.c++
+9
-29
dynamic.h
c++/src/capnproto/dynamic.h
+0
-1
encoding-test.c++
c++/src/capnproto/encoding-test.c++
+3
-3
layout.c++
c++/src/capnproto/layout.c++
+12
-10
layout.h
c++/src/capnproto/layout.h
+2
-2
schema-loader-test.c++
c++/src/capnproto/schema-loader-test.c++
+4
-4
serialize-packed-test.c++
c++/src/capnproto/serialize-packed-test.c++
+35
-14
stringify.c++
c++/src/capnproto/stringify.c++
+12
-4
test-util.c++
c++/src/capnproto/test-util.c++
+20
-20
test-util.h
c++/src/capnproto/test-util.h
+8
-4
No files found.
c++/src/capnproto/benchmark/capnproto-catrank.c++
View file @
b4953e9d
...
...
@@ -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
_s
tr
(),
" cat "
)
!=
nullptr
)
{
if
(
strstr
(
result
.
getSnippet
().
c
S
tr
(),
" cat "
)
!=
nullptr
)
{
score
*=
10000
;
}
if
(
strstr
(
result
.
getSnippet
().
c
_s
tr
(),
" dog "
)
!=
nullptr
)
{
if
(
strstr
(
result
.
getSnippet
().
c
S
tr
(),
" dog "
)
!=
nullptr
)
{
score
/=
10000
;
}
scoredResults
.
emplace_back
(
score
,
result
);
...
...
c++/src/capnproto/blob-test.c++
View file @
b4953e9d
...
...
@@ -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
_s
tr
());
EXPECT_STREQ
(
"foo"
,
text
.
data
());
EXPECT_STREQ
(
"foo"
,
text
.
c
S
tr
());
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
...
...
c++/src/capnproto/blob.h
View file @
b4953e9d
...
...
@@ -41,204 +41,139 @@ struct Text {
class
Builder
;
};
template
<
size_t
size
>
struct
InlineData
:
public
Data
{};
// Alias for Data used specifically for InlineData fields. This primarily exists so that
// List<InlineData<n>> can be specialized.
class
Data
::
Reader
{
class
Data
::
Reader
:
public
kj
::
ArrayPtr
<
const
byte
>
{
// Points to a blob of bytes. The usual Reader rules apply -- Data::Reader behaves like a simple
// pointer which does not own its target, can be passed by value, etc.
//
// Data::Reader can be implicitly converted to any type which has a constructor that takes a
// (const char*, size) pair, and can be implicitly constructed from any type that has data()
// and size() methods. Many types follow this pattern, such as std::string. Data::Reader can
// also be implicitly constructed from a NUL-terminated char*.
public
:
typedef
Data
Reads
;
inline
Reader
()
:
bytes
(
nullptr
),
size_
(
0
)
{}
inline
Reader
(
const
char
*
bytes
)
:
bytes
(
bytes
),
size_
(
strlen
(
bytes
))
{}
inline
Reader
(
char
*
bytes
)
:
bytes
(
bytes
),
size_
(
strlen
(
bytes
))
{}
inline
Reader
(
const
char
*
bytes
,
uint
size
)
:
bytes
(
bytes
),
size_
(
size
)
{}
template
<
typename
T
>
inline
Reader
(
const
T
&
other
)
:
bytes
(
other
.
data
()),
size_
(
other
.
size
())
{}
// Primarily intended for converting from std::string.
template
<
typename
T
>
inline
T
as
()
const
{
return
T
(
bytes
,
size_
);
}
// Explicitly converts to the desired type, which must have a (const char*, size) constructor.
inline
const
char
*
data
()
const
{
return
bytes
;
}
inline
uint
size
()
const
{
return
size_
;
}
inline
const
char
operator
[](
uint
index
)
const
{
return
bytes
[
index
];
}
inline
Reader
slice
(
uint
start
,
uint
end
)
const
{
KJ_IREQUIRE
(
start
<=
end
&&
end
<=
size_
,
"Out-of-bounds slice."
);
return
Reader
(
bytes
+
start
,
end
-
start
);
}
inline
bool
operator
==
(
const
Reader
&
other
)
const
{
return
size_
==
other
.
size_
&&
memcmp
(
bytes
,
other
.
bytes
,
size_
)
==
0
;
}
inline
bool
operator
<=
(
const
Reader
&
other
)
const
{
bool
shorter
=
size_
<=
other
.
size_
;
int
cmp
=
memcmp
(
bytes
,
other
.
bytes
,
shorter
?
size_
:
other
.
size_
);
return
cmp
<
0
?
true
:
cmp
>
0
?
false
:
size_
<=
other
.
size_
;
}
inline
bool
operator
!=
(
const
Reader
&
other
)
const
{
return
!
(
*
this
==
other
);
}
inline
bool
operator
>=
(
const
Reader
&
other
)
const
{
return
other
<=
*
this
;
}
inline
bool
operator
<
(
const
Reader
&
other
)
const
{
return
!
(
other
<=
*
this
);
}
inline
bool
operator
>
(
const
Reader
&
other
)
const
{
return
!
(
*
this
<=
other
);
}
inline
const
char
*
begin
()
const
{
return
bytes
;
}
inline
const
char
*
end
()
const
{
return
bytes
+
size_
;
}
private
:
const
char
*
bytes
;
uint
size_
;
Reader
()
=
default
;
inline
Reader
(
decltype
(
nullptr
))
:
ArrayPtr
<
const
byte
>
(
nullptr
)
{}
inline
Reader
(
const
byte
*
value
,
size_t
size
)
:
ArrayPtr
<
const
byte
>
(
value
,
size
)
{}
inline
Reader
(
const
kj
::
Array
<
const
byte
>&
value
)
:
ArrayPtr
<
const
byte
>
(
value
)
{}
inline
Reader
(
const
ArrayPtr
<
const
byte
>&
value
)
:
ArrayPtr
<
const
byte
>
(
value
)
{}
inline
Reader
(
const
kj
::
Array
<
byte
>&
value
)
:
ArrayPtr
<
const
byte
>
(
value
)
{}
inline
Reader
(
const
ArrayPtr
<
byte
>&
value
)
:
ArrayPtr
<
const
byte
>
(
value
)
{}
};
class
Text
::
Reader
:
public
Data
::
Reade
r
{
class
Text
::
Reader
:
public
kj
::
StringPt
r
{
// Like Data::Reader, but points at NUL-terminated UTF-8 text. The NUL terminator is not counted
// in the size but must be present immediately after the last byte.
//
// Text::Reader's interface contract is that its data MUST be NUL-terminated. The producer of
// the Text::Reader must guarantee this, so that the consumer need not check. The data SHOULD
// also be valid UTF-8, but this is NOT guaranteed -- the consumer must verify if it cares.
//
// Text::Reader can be implicitly converted to and from const char*. Additionally, it can be
// implicitly converted to any type that can be constructed from a (const char*, size) pair, as
// well as from any type which has c_str() and size() methods. Many types follow this pattern,
// such as std::string.
public
:
typedef
Text
Reads
;
inline
Reader
()
:
Data
::
Reader
(
""
,
0
)
{}
inline
Reader
(
const
char
*
text
)
:
Data
::
Reader
(
text
,
strlen
(
text
))
{}
inline
Reader
(
char
*
text
)
:
Data
::
Reader
(
text
,
strlen
(
text
))
{}
inline
Reader
(
const
char
*
text
,
uint
size
)
:
Data
::
Reader
(
text
,
size
)
{
KJ_IREQUIRE
(
text
[
size
]
==
'\0'
,
"Text must be NUL-terminated."
);
}
template
<
typename
T
>
inline
Reader
(
const
T
&
other
)
:
Data
::
Reader
(
other
.
c_str
(),
other
.
size
())
{
// Primarily intended for converting from std::string.
KJ_IREQUIRE
(
data
()[
size
()]
==
'\0'
,
"Text must be NUL-terminated."
);
}
inline
const
char
*
c_str
()
const
{
return
data
();
}
inline
operator
const
char
*
()
const
{
return
data
();
}
Reader
()
=
default
;
inline
Reader
(
decltype
(
nullptr
))
:
StringPtr
(
nullptr
)
{}
inline
Reader
(
const
char
*
value
)
:
StringPtr
(
value
)
{}
inline
Reader
(
const
char
*
value
,
size_t
size
)
:
StringPtr
(
value
,
size
)
{}
inline
Reader
(
const
kj
::
String
&
value
)
:
StringPtr
(
value
)
{}
inline
Reader
(
const
StringPtr
&
value
)
:
StringPtr
(
value
)
{}
};
inline
kj
::
StringPtr
KJ_STRINGIFY
(
Text
::
Reader
reader
)
{
// TODO(soon): Use size().
return
reader
.
c_str
();
}
class
Data
::
Builder
{
// Like Data::Reader except the pointers aren't const, and it can't be implicitly constructed from
// other types.
class
Data
::
Builder
:
public
kj
::
ArrayPtr
<
byte
>
{
// Like Data::Reader except the pointers aren't const.
public
:
typedef
Data
Builds
;
inline
Builder
()
:
bytes
(
nullptr
),
size_
(
0
)
{}
inline
Builder
(
char
*
bytes
,
uint
size
)
:
bytes
(
bytes
),
size_
(
size
)
{}
template
<
typename
T
>
inline
operator
T
()
const
{
return
T
(
bytes
,
size_
);
}
// Primarily intended for converting to std::string.
Builder
()
=
default
;
inline
Builder
(
decltype
(
nullptr
))
:
ArrayPtr
<
byte
>
(
nullptr
)
{}
inline
Builder
(
byte
*
value
,
size_t
size
)
:
ArrayPtr
<
byte
>
(
value
,
size
)
{}
inline
Builder
(
kj
::
Array
<
byte
>&
value
)
:
ArrayPtr
<
byte
>
(
value
)
{}
inline
Builder
(
const
ArrayPtr
<
byte
>&
value
)
:
ArrayPtr
<
byte
>
(
value
)
{}
inline
operator
Data
::
Reader
()
const
{
return
Data
::
Reader
(
bytes
,
size_
);
}
template
<
typename
T
>
inline
T
as
()
const
{
return
T
(
bytes
,
size_
);
}
// Explicitly converts to the desired type, which must have a (char*, size) constructor.
inline
Data
::
Reader
asReader
()
const
{
return
Data
::
Reader
(
*
this
);
}
};
inline
char
*
data
()
const
{
return
bytes
;
}
inline
uint
size
()
const
{
return
size_
;
}
inline
char
&
operator
[](
uint
index
)
const
{
return
bytes
[
index
];
}
class
Text
::
Builder
{
// Basically identical to kj::StringPtr, except that the contents are non-const.
inline
Builder
slice
(
uint
start
,
uint
end
)
const
{
KJ_IREQUIRE
(
start
<=
end
&&
end
<=
size_
,
"Out-of-bounds slice."
);
return
Builder
(
bytes
+
start
,
end
-
start
);
public
:
inline
Builder
()
:
content
(
nulstr
,
1
)
{}
inline
Builder
(
decltype
(
nullptr
))
:
content
(
nulstr
,
1
)
{}
inline
Builder
(
char
*
value
)
:
content
(
value
,
strlen
(
value
)
+
1
)
{}
inline
Builder
(
char
*
value
,
size_t
size
)
:
content
(
value
,
size
+
1
)
{
KJ_IREQUIRE
(
value
[
size
]
==
'\0'
,
"StringPtr must be NUL-terminated."
);
}
inline
bool
operator
==
(
const
Builder
&
other
)
const
{
return
size_
==
other
.
size_
&&
memcmp
(
bytes
,
other
.
bytes
,
size_
)
==
0
;
}
inline
bool
operator
<=
(
const
Builder
&
other
)
const
{
bool
shorter
=
size_
<=
other
.
size_
;
int
cmp
=
memcmp
(
bytes
,
other
.
bytes
,
shorter
?
size_
:
other
.
size_
);
return
cmp
<
0
?
true
:
cmp
>
0
?
false
:
size_
<=
other
.
size_
;
}
inline
bool
operator
!=
(
const
Builder
&
other
)
const
{
return
!
(
*
this
==
other
);
}
inline
bool
operator
>=
(
const
Builder
&
other
)
const
{
return
other
<=
*
this
;
}
inline
bool
operator
<
(
const
Builder
&
other
)
const
{
return
!
(
other
<=
*
this
);
}
inline
bool
operator
>
(
const
Builder
&
other
)
const
{
return
!
(
*
this
<=
other
);
}
template
<
typename
T
>
inline
void
copyFrom
(
const
T
&
other
)
const
{
KJ_IREQUIRE
(
size
()
==
other
.
size
(),
"Sizes must match to copy."
);
memcpy
(
bytes
,
other
.
data
(),
other
.
size
());
}
inline
void
copyFrom
(
const
void
*
other
)
const
{
memcpy
(
bytes
,
other
,
size_
);
}
inline
Reader
asReader
()
const
{
return
Reader
(
content
.
begin
(),
content
.
size
());
}
inline
char
*
begin
()
const
{
return
bytes
;
}
inline
char
*
end
()
const
{
return
bytes
+
size_
;
}
inline
operator
kj
::
ArrayPtr
<
char
>
()
const
;
inline
kj
::
ArrayPtr
<
char
>
asArray
()
const
;
// Result does not include NUL terminator.
inline
Data
::
Reader
asReader
()
{
return
Data
::
Reader
(
bytes
,
size_
);
}
inline
operator
kj
::
StringPtr
()
const
;
inline
kj
::
StringPtr
asString
()
const
;
private
:
char
*
bytes
;
uint
size_
;
};
inline
const
char
*
cStr
()
const
{
return
content
.
begin
();
}
// Returns NUL-terminated string.
class
Text
::
Builder
:
public
Data
::
Builder
{
// Like Text::Reader except the pointers aren't const, and it can't be implicitly constructed from
// other types. The Text::Builder automatically initializes the NUL terminator at construction,
// so it is never necessary for the caller to do so.
inline
size_t
size
()
const
{
return
content
.
size
()
-
1
;
}
// Result does not include NUL terminator.
public
:
typedef
Text
Builds
;
inline
char
operator
[](
size_t
index
)
const
{
return
content
[
index
];
}
inline
char
*
begin
()
const
{
return
content
.
begin
();
}
inline
char
*
end
()
const
{
return
content
.
end
()
-
1
;
}
inline
Builder
()
:
Data
::
Builder
(
nulstr
,
0
)
{
}
inline
Builder
(
char
*
text
,
uint
size
)
:
Data
::
Builder
(
text
,
size
)
{
text
[
size
]
=
'\0'
;
}
inline
bool
operator
==
(
decltype
(
nullptr
))
const
{
return
content
.
size
()
<=
1
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
const
{
return
content
.
size
()
>
1
;
}
inline
char
*
c_str
()
const
{
return
data
();
}
inline
operator
char
*
()
const
{
return
data
();
}
inline
operator
const
char
*
()
const
{
return
data
();
}
inline
bool
operator
==
(
Builder
other
)
const
{
return
asString
()
==
other
.
asString
();
}
inline
bool
operator
!=
(
Builder
other
)
const
{
return
asString
()
==
other
.
asString
();
}
inline
bool
operator
<
(
Builder
other
)
const
{
return
asString
()
<
other
.
asString
();
}
inline
bool
operator
>
(
Builder
other
)
const
{
return
asString
()
>
other
.
asString
();
}
inline
bool
operator
<=
(
Builder
other
)
const
{
return
asString
()
<=
other
.
asString
();
}
inline
bool
operator
>=
(
Builder
other
)
const
{
return
asString
()
>=
other
.
asString
();
}
inline
Text
::
Reader
asReader
()
{
return
Text
::
Reader
(
begin
(),
size
());
}
inline
Builder
slice
(
size_t
start
)
const
;
inline
kj
::
ArrayPtr
<
char
>
slice
(
size_t
start
,
size_t
end
)
const
;
// A string slice is only NUL-terminated if it is a suffix, so slice() has a one-parameter
// version that assumes end = size().
private
:
inline
explicit
Builder
(
kj
::
ArrayPtr
<
char
>
content
)
:
content
(
content
)
{}
kj
::
ArrayPtr
<
char
>
content
;
static
char
nulstr
[
1
];
};
inline
kj
::
StringPtr
KJ_STRINGIFY
(
Text
::
Builder
builder
)
{
// TODO(soon): Use size().
return
builder
.
c_str
();
return
builder
.
asString
();
}
inline
bool
operator
==
(
const
char
*
a
,
Data
::
Reader
b
)
{
return
Data
::
Reader
(
a
)
==
b
;
}
inline
bool
operator
==
(
const
char
*
a
,
Data
::
Builder
b
)
{
return
Data
::
Reader
(
a
)
==
(
Data
::
Reader
)
b
;
}
inline
bool
operator
==
(
Data
::
Reader
a
,
Data
::
Builder
b
)
{
return
a
==
(
Data
::
Reader
)
b
;
}
inline
bool
operator
==
(
Data
::
Builder
a
,
Data
::
Reader
b
)
{
return
(
Data
::
Reader
)
a
==
b
;
}
template
<
typename
T
>
T
&
operator
<<
(
T
&
os
,
Data
::
Reader
value
)
{
return
os
.
write
(
value
.
data
(),
value
.
size
());
}
template
<
typename
T
>
T
&
operator
<<
(
T
&
os
,
Data
::
Builder
value
)
{
return
os
.
write
(
value
.
data
(),
value
.
size
());
}
template
<
typename
T
>
T
&
operator
<<
(
T
&
os
,
Text
::
Reader
value
)
{
return
os
.
write
(
value
.
data
(),
value
.
size
());
}
template
<
typename
T
>
T
&
operator
<<
(
T
&
os
,
Text
::
Builder
value
)
{
return
os
.
write
(
value
.
data
(),
value
.
size
());
}
inline
bool
operator
==
(
const
char
*
a
,
const
Text
::
Builder
&
b
)
{
return
a
==
b
.
asString
();
}
inline
bool
operator
!=
(
const
char
*
a
,
const
Text
::
Builder
&
b
)
{
return
a
!=
b
.
asString
();
}
inline
Text
::
Builder
::
operator
kj
::
StringPtr
()
const
{
return
kj
::
StringPtr
(
content
.
begin
(),
content
.
size
()
-
1
);
}
inline
kj
::
StringPtr
Text
::
Builder
::
asString
()
const
{
return
kj
::
StringPtr
(
content
.
begin
(),
content
.
size
()
-
1
);
}
inline
Text
::
Builder
::
operator
kj
::
ArrayPtr
<
char
>
()
const
{
return
content
.
slice
(
0
,
content
.
size
()
-
1
);
}
inline
kj
::
ArrayPtr
<
char
>
Text
::
Builder
::
asArray
()
const
{
return
content
.
slice
(
0
,
content
.
size
()
-
1
);
}
inline
Text
::
Builder
Text
::
Builder
::
slice
(
size_t
start
)
const
{
return
Text
::
Builder
(
content
.
slice
(
start
,
content
.
size
()));
}
inline
kj
::
ArrayPtr
<
char
>
Text
::
Builder
::
slice
(
size_t
start
,
size_t
end
)
const
{
return
content
.
slice
(
start
,
end
);
}
}
// namespace capnproto
...
...
c++/src/capnproto/dynamic.c++
View file @
b4953e9d
...
...
@@ -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
getObjectAs
Data
Impl
(
builder
,
member
);
return
getObjectAs
Text
Impl
(
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
initFieldAs
Data
Impl
(
builder
,
member
,
size
);
return
initFieldAs
Text
Impl
(
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
getObjectAs
Text
(
schema
.
getMemberByName
(
name
));
return
getObjectAs
Data
(
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
initObjectAs
Text
(
schema
.
getMemberByName
(
name
),
size
);
return
initObjectAs
Data
(
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()."
)
{
...
...
c++/src/capnproto/dynamic.h
View file @
b4953e9d
...
...
@@ -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).
//
...
...
c++/src/capnproto/encoding-test.c++
View file @
b4953e9d
...
...
@@ -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
});
...
...
c++/src/capnproto/layout.c++
View file @
b4953e9d
...
...
@@ -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
{
...
...
c++/src/capnproto/layout.h
View file @
b4953e9d
...
...
@@ -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
>
...
...
c++/src/capnproto/schema-loader-test.c++
View file @
b4953e9d
...
...
@@ -170,8 +170,8 @@ TEST(SchemaLoader, Upgrade) {
loadUnderAlternateTypeId
<
test
::
TestNewVersion
>
(
loader
,
typeId
<
test
::
TestOldVersion
>
());
// The new version replaced the old.
EXPECT_
STR
EQ
(
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_
STR
EQ
(
Schema
::
from
<
test
::
TestNewVersion
>
().
getProto
().
getDisplayName
(),
schema
.
getProto
().
getDisplayName
());
EXPECT_EQ
(
Schema
::
from
<
test
::
TestNewVersion
>
().
getProto
().
getDisplayName
(),
schema
.
getProto
().
getDisplayName
());
schema
.
requireUsableAs
<
test
::
TestNewVersion
>
();
}
...
...
c++/src/capnproto/serialize-packed-test.c++
View file @
b4953e9d
...
...
@@ -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.
...
...
c++/src/capnproto/stringify.c++
View file @
b4953e9d
...
...
@@ -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
_s
tr
();
os
<<
enumerant
->
getProto
().
getName
().
c
S
tr
();
}
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
_s
tr
()
<<
" = "
;
os
<<
member
.
getProto
().
getName
().
c
S
tr
()
<<
" = "
;
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
<<
")"
;
...
...
c++/src/capnproto/test-util.c++
View file @
b4953e9d
...
...
@@ -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.5
f
,
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-10
f
,
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.0
f
,
1234567.0
f
,
1e37
f
,
-
1e37
f
,
1e-37
f
,
-
1e-37
f
});
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.5
f
,
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-10
f
,
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.0
f
,
1234567.0
f
,
1e37
f
,
-
1e37
f
,
1e-37
f
,
-
1e-37
f
});
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
>
());
...
...
c++/src/capnproto/test-util.h
View file @
b4953e9d
...
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment