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
b4f80598
Commit
b4f80598
authored
Mar 13, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Text and data blobs.
parent
8b7e9096
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
526 additions
and
24 deletions
+526
-24
blob-test.c++
c++/src/capnproto/blob-test.c++
+89
-0
blob.c++
c++/src/capnproto/blob.c++
+30
-0
blob.h
c++/src/capnproto/blob.h
+202
-0
encoding-test.c++
c++/src/capnproto/encoding-test.c++
+3
-0
list.h
c++/src/capnproto/list.h
+99
-15
wire-format.c++
c++/src/capnproto/wire-format.c++
+0
-0
wire-format.h
c++/src/capnproto/wire-format.h
+46
-0
CxxGenerator.hs
compiler/src/CxxGenerator.hs
+21
-7
c++-header.mustache
compiler/src/c++-header.mustache
+36
-2
No files found.
c++/src/capnproto/blob-test.c++
0 → 100644
View file @
b4f80598
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "blob.h"
#include <gtest/gtest.h>
#include <iostream>
#include <string>
namespace
capnproto
{
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Data
::
Reader
&
value
)
{
return
os
.
write
(
value
.
data
(),
value
.
size
());
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Data
::
Builder
&
value
)
{
return
os
.
write
(
value
.
data
(),
value
.
size
());
}
namespace
{
TEST
(
Blob
,
Text
)
{
std
::
string
str
=
"foo"
;
Text
::
Reader
text
=
str
;
EXPECT_STREQ
(
"foo"
,
text
);
EXPECT_STREQ
(
"foo"
,
text
.
c_str
());
EXPECT_STREQ
(
"foo"
,
text
.
data
());
EXPECT_EQ
(
3u
,
text
.
size
());
std
::
string
str2
=
text
;
EXPECT_EQ
(
"foo"
,
str2
);
Text
::
Reader
text2
=
"bar"
;
EXPECT_STREQ
(
"bar"
,
text2
);
char
c
[
4
]
=
"baz"
;
Text
::
Reader
text3
(
c
);
EXPECT_STREQ
(
"baz"
,
text3
);
Text
::
Builder
builder
(
c
,
3
);
EXPECT_STREQ
(
"baz"
,
builder
);
EXPECT_EQ
(
Data
::
Reader
(
"az"
),
builder
.
slice
(
1
,
3
));
}
TEST
(
Blob
,
Data
)
{
std
::
string
str
=
"foo"
;
Data
::
Reader
data
=
str
;
EXPECT_EQ
(
3u
,
data
.
size
());
std
::
string
str2
=
data
;
EXPECT_EQ
(
"foo"
,
str2
);
Data
::
Reader
data2
=
"bar"
;
EXPECT_EQ
(
"bar"
,
data2
.
as
<
std
::
string
>
());
char
c
[
4
]
=
"baz"
;
Data
::
Reader
data3
(
c
);
EXPECT_EQ
(
"baz"
,
data3
.
as
<
std
::
string
>
());
Data
::
Builder
builder
(
c
,
3
);
EXPECT_EQ
(
"baz"
,
builder
.
as
<
std
::
string
>
());
EXPECT_EQ
(
Data
::
Reader
(
"az"
),
builder
.
slice
(
1
,
3
));
}
}
// namespace
}
// namespace capnproto
c++/src/capnproto/blob.c++
0 → 100644
View file @
b4f80598
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "blob.h"
namespace
capnproto
{
char
Text
::
Builder
::
nulstr
[
1
]
=
""
;
}
// namespace capnproto
c++/src/capnproto/blob.h
0 → 100644
View file @
b4f80598
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CAPNPROTO_BLOB_H_
#define CAPNPROTO_BLOB_H_
#include "macros.h"
#include "type-safety.h"
#include <string.h>
namespace
capnproto
{
struct
Data
{
class
Reader
;
class
Builder
;
};
struct
Text
{
class
Reader
;
class
Builder
;
};
class
Data
::
Reader
{
// 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
:
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
operator
T
()
const
{
return
T
(
bytes
,
size_
);
}
// Primarily intended for converting to 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
{
CAPNPROTO_DEBUG_ASSERT
(
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
);
}
private
:
const
char
*
bytes
;
uint
size_
;
};
class
Text
::
Reader
:
public
Data
::
Reader
{
// 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.
//
// TextReader 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
:
inline
Reader
()
:
Data
::
Reader
(
""
,
0
)
{}
inline
Reader
(
const
char
*
text
)
:
Data
::
Reader
(
text
,
strlen
(
text
))
{
CAPNPROTO_DEBUG_ASSERT
(
text
[
size
()]
==
'\0'
,
"Text must be NUL-terminated."
);
}
inline
Reader
(
char
*
text
)
:
Data
::
Reader
(
text
,
strlen
(
text
))
{
CAPNPROTO_DEBUG_ASSERT
(
text
[
size
()]
==
'\0'
,
"Text must be NUL-terminated."
);
}
inline
Reader
(
const
char
*
text
,
uint
size
)
:
Data
::
Reader
(
text
,
size
)
{
CAPNPROTO_DEBUG_ASSERT
(
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.
CAPNPROTO_DEBUG_ASSERT
(
data
()[
size
()]
==
'\0'
,
"Text must be NUL-terminated."
);
}
inline
const
char
*
c_str
()
const
{
return
data
();
}
inline
operator
const
char
*
()
const
{
return
data
();
}
};
class
Data
::
Builder
{
// Like Data::Reader except the pointers aren't const, and it can't be implicitly constructed from
// other types.
public
:
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.
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
char
*
data
()
const
{
return
bytes
;
}
inline
uint
size
()
const
{
return
size_
;
}
inline
char
&
operator
[](
uint
index
)
const
{
return
bytes
[
index
];
}
inline
Builder
slice
(
uint
start
,
uint
end
)
const
{
CAPNPROTO_DEBUG_ASSERT
(
start
<=
end
&&
end
<=
size_
,
"Out-of-bounds slice."
);
return
Builder
(
bytes
+
start
,
end
-
start
);
}
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
{
CAPNPROTO_DEBUG_ASSERT
(
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_
);
}
private
:
char
*
bytes
;
uint
size_
;
};
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.
public
:
inline
Builder
()
:
Data
::
Builder
(
nulstr
,
0
)
{}
inline
Builder
(
char
*
text
,
uint
size
)
:
Data
::
Builder
(
text
,
size
)
{
text
[
size
]
=
'\0'
;
}
inline
char
*
c_str
()
const
{
return
data
();
}
inline
operator
char
*
()
const
{
return
data
();
}
inline
operator
const
char
*
()
const
{
return
data
();
}
private
:
static
char
nulstr
[
1
];
};
}
// namespace capnproto
#endif // CAPNPROTO_BLOB_H_
c++/src/capnproto/encoding-test.c++
View file @
b4f80598
...
...
@@ -45,6 +45,7 @@ TEST(Encoding, Simple) {
builder
.
setB
(
45
);
builder
.
setC
(
67
);
builder
.
initD
().
setX
(
55.25
);
builder
.
setTx
(
"foo"
);
{
List
<
int32_t
>::
Builder
listBuilder
=
builder
.
initNums
(
5
);
...
...
@@ -146,6 +147,7 @@ TEST(Encoding, Simple) {
EXPECT_EQ
(
45
,
builder
.
getB
());
EXPECT_EQ
(
67
,
builder
.
getC
());
EXPECT_EQ
(
55.25
,
builder
.
getD
().
getX
());
EXPECT_STREQ
(
"foo"
,
builder
.
getTx
());
Foo
::
Reader
reader
(
StructReader
::
readRoot
(
segment
->
getStartPtr
(),
Foo
::
DEFAULT
.
words
,
segment
,
4
));
...
...
@@ -154,6 +156,7 @@ TEST(Encoding, Simple) {
EXPECT_EQ
(
45
,
reader
.
getB
());
EXPECT_EQ
(
67
,
reader
.
getC
());
EXPECT_EQ
(
55.25
,
reader
.
getD
().
getX
());
EXPECT_STREQ
(
"foo"
,
reader
.
getTx
());
{
List
<
int32_t
>::
Reader
listReader
=
reader
.
getNums
();
...
...
c++/src/capnproto/list.h
View file @
b4f80598
...
...
@@ -98,24 +98,24 @@ class IndexingIterator {
public
:
IndexingIterator
()
=
default
;
inline
Element
operator
*
()
{
return
(
*
container
)[
index
];
}
inline
TemporaryPointer
<
Element
>
operator
->
()
{
inline
Element
operator
*
()
const
{
return
(
*
container
)[
index
];
}
inline
TemporaryPointer
<
Element
>
operator
->
()
const
{
return
TemporaryPointer
<
Element
>
((
*
container
)[
index
]);
}
inline
Element
operator
[](
int
off
)
{
return
(
*
container
)[
index
];
}
inline
Element
operator
[](
uint
off
)
{
return
(
*
container
)[
index
];
}
inline
Element
operator
[](
int
off
)
const
{
return
(
*
container
)[
index
];
}
inline
Element
operator
[](
uint
off
)
const
{
return
(
*
container
)[
index
];
}
inline
IndexingIterator
&
operator
++
()
{
++
index
;
return
*
this
;
}
inline
IndexingIterator
operator
++
(
int
)
{
IndexingIterator
other
=
*
this
;
++
index
;
return
other
;
}
inline
IndexingIterator
&
operator
--
()
{
--
index
;
return
*
this
;
}
inline
IndexingIterator
operator
--
(
int
)
{
IndexingIterator
other
=
*
this
;
--
index
;
return
other
;
}
inline
IndexingIterator
operator
+
(
uint
amount
)
{
return
IndexingIterator
(
container
,
index
+
amount
);
}
inline
IndexingIterator
operator
-
(
uint
amount
)
{
return
IndexingIterator
(
container
,
index
-
amount
);
}
inline
IndexingIterator
operator
+
(
int
amount
)
{
return
IndexingIterator
(
container
,
index
+
amount
);
}
inline
IndexingIterator
operator
-
(
int
amount
)
{
return
IndexingIterator
(
container
,
index
-
amount
);
}
inline
IndexingIterator
operator
+
(
uint
amount
)
const
{
return
IndexingIterator
(
container
,
index
+
amount
);
}
inline
IndexingIterator
operator
-
(
uint
amount
)
const
{
return
IndexingIterator
(
container
,
index
-
amount
);
}
inline
IndexingIterator
operator
+
(
int
amount
)
const
{
return
IndexingIterator
(
container
,
index
+
amount
);
}
inline
IndexingIterator
operator
-
(
int
amount
)
const
{
return
IndexingIterator
(
container
,
index
-
amount
);
}
inline
int
operator
-
(
const
IndexingIterator
&
other
)
{
return
index
-
other
.
index
;
}
inline
int
operator
-
(
const
IndexingIterator
&
other
)
const
{
return
index
-
other
.
index
;
}
inline
IndexingIterator
&
operator
+=
(
uint
amount
)
{
index
+=
amount
;
return
*
this
;
}
inline
IndexingIterator
&
operator
-=
(
uint
amount
)
{
index
-=
amount
;
return
*
this
;
}
...
...
@@ -124,12 +124,12 @@ public:
// STL says comparing iterators of different containers is not allowed, so we only compare
// indices here.
inline
bool
operator
==
(
const
IndexingIterator
&
other
)
{
return
index
==
other
.
index
;
}
inline
bool
operator
!=
(
const
IndexingIterator
&
other
)
{
return
index
!=
other
.
index
;
}
inline
bool
operator
<=
(
const
IndexingIterator
&
other
)
{
return
index
<=
other
.
index
;
}
inline
bool
operator
>=
(
const
IndexingIterator
&
other
)
{
return
index
>=
other
.
index
;
}
inline
bool
operator
<
(
const
IndexingIterator
&
other
)
{
return
index
<
other
.
index
;
}
inline
bool
operator
>
(
const
IndexingIterator
&
other
)
{
return
index
>
other
.
index
;
}
inline
bool
operator
==
(
const
IndexingIterator
&
other
)
const
{
return
index
==
other
.
index
;
}
inline
bool
operator
!=
(
const
IndexingIterator
&
other
)
const
{
return
index
!=
other
.
index
;
}
inline
bool
operator
<=
(
const
IndexingIterator
&
other
)
const
{
return
index
<=
other
.
index
;
}
inline
bool
operator
>=
(
const
IndexingIterator
&
other
)
const
{
return
index
>=
other
.
index
;
}
inline
bool
operator
<
(
const
IndexingIterator
&
other
)
const
{
return
index
<
other
.
index
;
}
inline
bool
operator
>
(
const
IndexingIterator
&
other
)
const
{
return
index
>
other
.
index
;
}
private
:
Container
*
container
;
...
...
@@ -316,6 +316,90 @@ struct List<List<T>, false> {
};
};
template
<>
struct
List
<
Data
,
false
>
{
class
Reader
{
public
:
Reader
()
=
default
;
inline
explicit
Reader
(
internal
::
ListReader
reader
)
:
reader
(
reader
)
{}
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
Data
::
Reader
operator
[](
uint
index
)
{
return
reader
.
getDataElement
(
index
*
REFERENCES
);
}
typedef
internal
::
IndexingIterator
<
Reader
,
Data
::
Reader
>
iterator
;
inline
iterator
begin
()
{
return
iterator
(
this
,
0
);
}
inline
iterator
end
()
{
return
iterator
(
this
,
size
());
}
private
:
internal
::
ListReader
reader
;
};
class
Builder
{
public
:
Builder
()
=
default
;
inline
explicit
Builder
(
internal
::
ListBuilder
builder
)
:
builder
(
builder
)
{}
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
Data
::
Builder
operator
[](
uint
index
)
{
return
builder
.
getDataElement
(
index
*
REFERENCES
);
}
inline
Data
::
Builder
init
(
uint
index
,
uint
size
)
{
return
builder
.
initDataElement
(
index
*
REFERENCES
,
size
*
BYTES
);
}
typedef
internal
::
IndexingIterator
<
Builder
,
Data
::
Builder
>
iterator
;
inline
iterator
begin
()
{
return
iterator
(
this
,
0
);
}
inline
iterator
end
()
{
return
iterator
(
this
,
size
());
}
private
:
internal
::
ListBuilder
builder
;
};
};
template
<>
struct
List
<
Text
,
false
>
{
class
Reader
{
public
:
Reader
()
=
default
;
inline
explicit
Reader
(
internal
::
ListReader
reader
)
:
reader
(
reader
)
{}
inline
uint
size
()
{
return
reader
.
size
()
/
ELEMENTS
;
}
inline
Text
::
Reader
operator
[](
uint
index
)
{
return
reader
.
getTextElement
(
index
*
REFERENCES
);
}
typedef
internal
::
IndexingIterator
<
Reader
,
Text
::
Reader
>
iterator
;
inline
iterator
begin
()
{
return
iterator
(
this
,
0
);
}
inline
iterator
end
()
{
return
iterator
(
this
,
size
());
}
private
:
internal
::
ListReader
reader
;
};
class
Builder
{
public
:
Builder
()
=
default
;
inline
explicit
Builder
(
internal
::
ListBuilder
builder
)
:
builder
(
builder
)
{}
inline
uint
size
()
{
return
builder
.
size
()
/
ELEMENTS
;
}
inline
Text
::
Builder
operator
[](
uint
index
)
{
return
builder
.
getTextElement
(
index
*
REFERENCES
);
}
inline
Text
::
Builder
init
(
uint
index
,
uint
size
)
{
return
builder
.
initTextElement
(
index
*
REFERENCES
,
size
*
BYTES
);
}
typedef
internal
::
IndexingIterator
<
Builder
,
Text
::
Builder
>
iterator
;
inline
iterator
begin
()
{
return
iterator
(
this
,
0
);
}
inline
iterator
end
()
{
return
iterator
(
this
,
size
());
}
private
:
internal
::
ListBuilder
builder
;
};
};
}
// namespace capnproto
#endif // CAPNPROTO_LIST_H_
c++/src/capnproto/wire-format.c++
View file @
b4f80598
This diff is collapsed.
Click to expand it.
c++/src/capnproto/wire-format.h
View file @
b4f80598
...
...
@@ -32,6 +32,7 @@
#include "macros.h"
#include "type-safety.h"
#include "blob.h"
namespace
capnproto
{
class
SegmentReader
;
...
...
@@ -124,6 +125,23 @@ public:
// already allocated, it is allocated as a deep copy of the given default value (a trusted
// message). If the default value is null, an empty list is used.
Text
::
Builder
initTextField
(
WireReferenceCount
refIndex
,
ByteCount
size
)
const
;
// Initialize the text field to the given size in bytes (not including NUL terminator) and return
// a Text::Builder which can be used to fill in the content.
void
setTextField
(
WireReferenceCount
refIndex
,
Text
::
Reader
value
)
const
;
// Set the text field to a copy of the given text.
Text
::
Builder
getTextField
(
WireReferenceCount
refIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Get the text field. If it is not initialized, initialize it to a copy of the given default.
Data
::
Builder
initDataField
(
WireReferenceCount
refIndex
,
ByteCount
size
)
const
;
void
setDataField
(
WireReferenceCount
refIndex
,
Data
::
Reader
value
)
const
;
Data
::
Builder
getDataField
(
WireReferenceCount
refIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Same as *Text*, but for data blobs.
StructReader
asReader
()
const
;
// Gets a StructReader pointing at the same memory.
...
...
@@ -174,6 +192,14 @@ public:
// Get the list field at the given index in the reference segment, or the default value if not
// initialized. The default value is allowed to be null, in which case an empty list is used.
Text
::
Reader
getTextField
(
WireReferenceCount
refIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Gets the text field, or the given default value if not initialized.
Data
::
Reader
getDataField
(
WireReferenceCount
refIndex
,
const
void
*
defaultValue
,
ByteCount
defaultSize
)
const
;
// Gets the data field, or the given default value if not initialized.
private
:
SegmentReader
*
segment
;
// Memory segment in which the struct resides.
...
...
@@ -244,6 +270,20 @@ public:
// Get the existing list element at the given index. Returns an empty list if the element is
// not initialized.
Text
::
Builder
initTextElement
(
WireReferenceCount
index
,
ByteCount
size
)
const
;
// Initialize the text element to the given size in bytes (not including NUL terminator) and
// return a Text::Builder which can be used to fill in the content.
void
setTextElement
(
WireReferenceCount
index
,
Text
::
Reader
value
)
const
;
// Set the text element to a copy of the given text.
Text
::
Builder
getTextElement
(
WireReferenceCount
index
)
const
;
// Get the text element. If it is not initialized, returns an empty Text::Builder.
Data
::
Builder
initDataElement
(
WireReferenceCount
index
,
ByteCount
size
)
const
;
void
setDataElement
(
WireReferenceCount
index
,
Data
::
Reader
value
)
const
;
Data
::
Builder
getDataElement
(
WireReferenceCount
index
)
const
;
ListReader
asReader
(
FieldSize
elementSize
)
const
;
// Get a ListReader pointing at the same memory. Use this version only for non-struct lists.
...
...
@@ -283,6 +323,12 @@ public:
ListReader
getListElement
(
WireReferenceCount
index
,
FieldSize
expectedElementSize
)
const
;
// Get the list element at the given index.
Text
::
Reader
getTextElement
(
WireReferenceCount
index
)
const
;
// Get the text element. If it is not initialized, returns an empty Text::Reader.
Data
::
Reader
getDataElement
(
WireReferenceCount
index
)
const
;
// Get the data element. If it is not initialized, returns an empty Data::Reader.
private
:
SegmentReader
*
segment
;
// Memory segment in which the list resides.
...
...
compiler/src/CxxGenerator.hs
View file @
b4f80598
...
...
@@ -49,12 +49,16 @@ hashString str =
MD5
.
hash
$
UTF8
.
encode
str
isPrimitive
(
BuiltinType
_
)
=
True
isPrimitive
t
@
(
BuiltinType
_
)
=
not
$
isBlob
t
isPrimitive
(
EnumType
_
)
=
True
isPrimitive
(
StructType
_
)
=
False
isPrimitive
(
InterfaceType
_
)
=
False
isPrimitive
(
ListType
_
)
=
False
isBlob
(
BuiltinType
BuiltinText
)
=
True
isBlob
(
BuiltinType
BuiltinData
)
=
True
isBlob
_
=
False
isStruct
(
StructType
_
)
=
True
isStruct
_
=
False
...
...
@@ -67,6 +71,10 @@ isNonStructList _ = False
isStructList
(
ListType
t
)
=
isStruct
t
isStructList
_
=
False
blobTypeString
(
BuiltinType
BuiltinText
)
=
"Text"
blobTypeString
(
BuiltinType
BuiltinData
)
=
"Data"
blobTypeString
_
=
error
"Not a blob."
cxxTypeString
(
BuiltinType
BuiltinVoid
)
=
"void"
cxxTypeString
(
BuiltinType
BuiltinBool
)
=
"bool"
cxxTypeString
(
BuiltinType
BuiltinInt8
)
=
" ::int8_t"
...
...
@@ -79,8 +87,8 @@ cxxTypeString (BuiltinType BuiltinUInt32) = " ::uint32_t"
cxxTypeString
(
BuiltinType
BuiltinUInt64
)
=
" ::uint64_t"
cxxTypeString
(
BuiltinType
BuiltinFloat32
)
=
"float"
cxxTypeString
(
BuiltinType
BuiltinFloat64
)
=
"double"
cxxTypeString
(
BuiltinType
BuiltinText
)
=
"
TODO
"
cxxTypeString
(
BuiltinType
BuiltinData
)
=
"
TODO
"
cxxTypeString
(
BuiltinType
BuiltinText
)
=
"
::capnproto::Text
"
cxxTypeString
(
BuiltinType
BuiltinData
)
=
"
::capnproto::Data
"
cxxTypeString
(
EnumType
desc
)
=
enumName
desc
-- TODO: full name
cxxTypeString
(
StructType
desc
)
=
structName
desc
-- TODO: full name
cxxTypeString
(
InterfaceType
desc
)
=
interfaceName
desc
-- TODO: full name
...
...
@@ -146,11 +154,15 @@ elementType _ = error "Called elementType on non-list."
repeatedlyTake
_
[]
=
[]
repeatedlyTake
n
l
=
take
n
l
:
repeatedlyTake
n
(
drop
n
l
)
defaultBytesContext
::
Monad
m
=>
(
String
->
MuType
m
)
->
[
Word8
]
->
MuContext
m
defaultBytesContext
parent
bytes
=
mkStrContext
context
where
defaultBytesContext
::
Monad
m
=>
(
String
->
MuType
m
)
->
TypeDesc
->
[
Word8
]
->
MuContext
m
defaultBytesContext
parent
t
bytes
=
mkStrContext
context
where
codeLines
=
map
(
delimit
", "
)
$
repeatedlyTake
8
$
map
(
printf
"%3d"
)
bytes
context
"defaultByteList"
=
MuVariable
$
delimit
",
\n
"
codeLines
context
"defaultWordCount"
=
MuVariable
$
div
(
length
bytes
+
7
)
8
context
"defaultBlobSize"
=
case
t
of
BuiltinType
BuiltinText
->
MuVariable
(
length
bytes
-
1
)
-- Don't include NUL terminator.
BuiltinType
BuiltinData
->
MuVariable
(
length
bytes
)
_
->
error
"defaultBlobSize used on non-blob."
context
s
=
parent
s
fieldContext
parent
desc
=
mkStrContext
context
where
...
...
@@ -159,15 +171,17 @@ fieldContext parent desc = mkStrContext context where
context
"fieldTitleCase"
=
MuVariable
$
toTitleCase
$
fieldName
desc
context
"fieldUpperCase"
=
MuVariable
$
toUpperCaseWithUnderscores
$
fieldName
desc
context
"fieldIsPrimitive"
=
MuBool
$
isPrimitive
$
fieldType
desc
context
"fieldIsBlob"
=
MuBool
$
isBlob
$
fieldType
desc
context
"fieldIsStruct"
=
MuBool
$
isStruct
$
fieldType
desc
context
"fieldIsList"
=
MuBool
$
isList
$
fieldType
desc
context
"fieldIsNonStructList"
=
MuBool
$
isNonStructList
$
fieldType
desc
context
"fieldIsStructList"
=
MuBool
$
isStructList
$
fieldType
desc
context
"fieldDefaultBytes"
=
case
fieldDefaultValue
desc
>>=
defaultValueBytes
(
fieldType
desc
)
of
Just
v
->
MuList
[
defaultBytesContext
context
v
]
Just
v
->
MuList
[
defaultBytesContext
context
(
fieldType
desc
)
v
]
Nothing
->
muNull
context
"fieldType"
=
MuVariable
$
cxxTypeString
$
fieldType
desc
context
"fieldBlobType"
=
MuVariable
$
blobTypeString
$
fieldType
desc
context
"fieldOffset"
=
MuVariable
$
fieldOffset
desc
context
"fieldDefaultValue"
=
case
fieldDefaultValue
desc
of
Just
v
->
MuVariable
$
cxxValueString
v
...
...
@@ -184,7 +198,7 @@ structContext parent desc = mkStrContext context where
context
"structDataSize"
=
MuVariable
$
packingDataSize
$
structPacking
desc
context
"structReferenceCount"
=
MuVariable
$
packingReferenceCount
$
structPacking
desc
context
"structChildren"
=
MuList
[]
-- TODO
context
"structDefault"
=
MuList
[
defaultBytesContext
context
context
"structDefault"
=
MuList
[
defaultBytesContext
context
(
StructType
desc
)
(
encodeMessage
(
StructType
desc
)
(
StructValueDesc
[]
))]
context
s
=
parent
s
...
...
compiler/src/c++-header.mustache
View file @
b4f80598
...
...
@@ -66,6 +66,9 @@ public:
{{#
fieldIsPrimitive
}}
inline
{{
fieldType
}}
get
{{
fieldTitleCase
}}
();
{{/
fieldIsPrimitive
}}
{{#
fieldIsBlob
}}
inline
{{
fieldType
}}
::Reader get
{{
fieldTitleCase
}}
();
{{/
fieldIsBlob
}}
{{#
fieldIsStruct
}}
inline
{{
fieldType
}}
::Reader get
{{
fieldTitleCase
}}
();
{{/
fieldIsStruct
}}
...
...
@@ -90,6 +93,11 @@ public:
inline
{{
fieldType
}}
get
{{
fieldTitleCase
}}
();
inline void set
{{
fieldTitleCase
}}
(
{{
fieldType
}}
value);
{{/
fieldIsPrimitive
}}
{{#
fieldIsBlob
}}
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
inline void set
{{
fieldTitleCase
}}
(
{{
fieldType
}}
::Reader value);
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
(unsigned int size);
{{/
fieldIsBlob
}}
{{#
fieldIsStruct
}}
inline
{{
fieldType
}}
::Builder init
{{
fieldTitleCase
}}
();
inline
{{
fieldType
}}
::Builder get
{{
fieldTitleCase
}}
();
...
...
@@ -117,12 +125,22 @@ inline {{fieldType}} {{structName}}::Reader::get{{fieldTitleCase}}() {
{{
fieldOffset
}}
* ::capnproto::ELEMENTS,
{{
fieldDefaultValue
}}
);
}
{{/
fieldIsPrimitive
}}
{{#
fieldIsBlob
}}
inline
{{
fieldType
}}
::Reader
{{
structName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
return _reader.get
{{
fieldBlobType
}}
Field(
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words,
{{
defaultBlobSize
}}
* ::capnproto::BYTES
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
nullptr, 0 * ::capnproto::BYTES
{{/
fieldDefaultBytes
}}
);
}
{{/
fieldIsBlob
}}
{{#
fieldIsStruct
}}
inline
{{
fieldType
}}
::Reader
{{
structName
}}
::Reader::get
{{
fieldTitleCase
}}
() {
{{! TODO: Support per-field default values. }}
return
{{
fieldType
}}
::Reader(_reader.getStructField(
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}{{/
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}{{
fieldType
}}
::DEFAULT.words
{{/
fieldDefaultBytes
}}
));
}
{{/
fieldIsStruct
}}
...
...
@@ -150,6 +168,22 @@ inline void {{structName}}::Builder::set{{fieldTitleCase}}({{fieldType}} value)
{{
fieldOffset
}}
* ::capnproto::ELEMENTS, value);
}
{{/
fieldIsPrimitive
}}
{{#
fieldIsBlob
}}
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::get
{{
fieldTitleCase
}}
() {
return _builder.get
{{
fieldBlobType
}}
Field(
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words,
{{
defaultBlobSize
}}
* ::capnproto::BYTES
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}
nullptr, 0 * ::capnproto::BYTES
{{/
fieldDefaultBytes
}}
);
}
inline void
{{
structName
}}
::Builder::set
{{
fieldTitleCase
}}
(
{{
fieldType
}}
::Reader value) {
_builder.set
{{
fieldBlobType
}}
Field(
{{
fieldOffset
}}
* ::capnproto::REFERENCES, value);
}
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::init
{{
fieldTitleCase
}}
(unsigned int size) {
return _builder.init
{{
fieldBlobType
}}
Field(
{{
fieldOffset
}}
* ::capnproto::REFERENCES, size * ::capnproto::BYTES);
}
{{/
fieldIsBlob
}}
{{#
fieldIsStruct
}}
inline
{{
fieldType
}}
::Builder
{{
structName
}}
::Builder::init
{{
fieldTitleCase
}}
() {
return
{{
fieldType
}}
::Builder(_builder.initStructField(
...
...
@@ -159,7 +193,7 @@ inline {{fieldType}}::Builder {{structName}}::Builder::get{{fieldTitleCase}}() {
{{! TODO: Support per-field default values. }}
return
{{
fieldType
}}
::Builder(_builder.getStructField(
{{
fieldOffset
}}
* ::capnproto::REFERENCES,
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}{{/
fieldDefaultBytes
}}
{{#
fieldDefaultBytes
}}
DEFAULT_
{{
fieldUpperCase
}}
.words
{{/
fieldDefaultBytes
}}
{{^
fieldDefaultBytes
}}{{
fieldType
}}
::DEFAULT.words
{{/
fieldDefaultBytes
}}
));
}
{{/
fieldIsStruct
}}
...
...
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