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
648d267d
Commit
648d267d
authored
Mar 03, 2013
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finish rewriting WireFormat.
parent
36a60467
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
180 additions
and
102 deletions
+180
-102
descriptor-test.c++
c++/src/capnproto/descriptor-test.c++
+9
-16
type-safety.h
c++/src/capnproto/type-safety.h
+28
-58
wire-format-test.c++
c++/src/capnproto/wire-format-test.c++
+93
-0
wire-format.c++
c++/src/capnproto/wire-format.c++
+0
-0
wire-format.h
c++/src/capnproto/wire-format.h
+50
-28
No files found.
c++/src/capnproto/descriptor-test.c++
View file @
648d267d
...
...
@@ -31,28 +31,23 @@ namespace {
const
int
READONLY_SEGMENT_START
=
123
;
const
FieldDescriptor
TEST_FIELDS
[
2
]
=
{
{
1
*
WORDS
,
0
,
0
,
FieldSize
::
FOUR_BYTES
,
1
,
0
,
0
,
0
},
{
1
*
WORDS
,
1
,
0
,
FieldSize
::
REFERENCE
,
1
,
0
,
0
,
0
}
{
1
*
WORDS
,
0
*
REFERENCES
,
FieldSize
::
FOUR_BYTES
,
0
*
ELEMENTS
,
0
*
BYTES
,
1
,
0
,
0
*
BYTES
,
0
*
BITS
,
nullptr
,
nullptr
},
{
1
*
WORDS
,
1
*
REFERENCES
,
FieldSize
::
REFERENCE
,
0
*
ELEMENTS
,
0
*
BYTES
,
1
,
0
,
0
*
BYTES
,
0
*
BITS
,
nullptr
,
nullptr
}
};
extern
const
StructDescriptor
TEST_STRUCT
;
extern
const
Descriptor
*
const
TEST_STRUCT_DEFAULT_REFS
[
1
]
=
{
&
TEST_STRUCT
.
base
};
const
AlignedData
<
1
>
TEST_STRUCT_DEFAULT_DATA
=
{
const
AlignedData
<
1
>
TEST_STRUCT_DEFAULT_VALUE
=
{
{
0x12
,
0x34
,
0x56
,
0x78
,
0x9a
,
0xbc
,
0xde
,
0xf0
}
};
const
StructDescriptor
TEST_STRUCT
=
{
{
Descriptor
::
Kind
::
STRUCT
},
2
,
WordCount8
(
1
*
WORDS
)
,
1
,
FieldNumber
(
2
)
,
1
*
WORDS
,
1
*
REFERENCES
,
TEST_FIELDS
,
TEST_STRUCT_DEFAULT_DATA
.
bytes
,
TEST_STRUCT_DEFAULT_REFS
TEST_STRUCT_DEFAULT_VALUE
.
words
};
const
int
READONLY_SEGMENT_END
=
321
;
...
...
@@ -66,10 +61,8 @@ TEST(Descriptors, InReadOnlySegment) {
EXPECT_LE
((
const
void
*
)
&
READONLY_SEGMENT_START
,
(
const
void
*
)
&
TEST_FIELDS
);
EXPECT_GE
((
const
void
*
)
&
READONLY_SEGMENT_END
,
(
const
void
*
)
&
TEST_FIELDS
);
EXPECT_LE
((
const
void
*
)
&
READONLY_SEGMENT_START
,
(
const
void
*
)
&
TEST_STRUCT_DEFAULT_DATA
);
EXPECT_GE
((
const
void
*
)
&
READONLY_SEGMENT_END
,
(
const
void
*
)
&
TEST_STRUCT_DEFAULT_DATA
);
EXPECT_LE
((
const
void
*
)
&
READONLY_SEGMENT_START
,
(
const
void
*
)
&
TEST_STRUCT_DEFAULT_REFS
);
EXPECT_GE
((
const
void
*
)
&
READONLY_SEGMENT_END
,
(
const
void
*
)
&
TEST_STRUCT_DEFAULT_REFS
);
EXPECT_LE
((
const
void
*
)
&
READONLY_SEGMENT_START
,
(
const
void
*
)
&
TEST_STRUCT_DEFAULT_VALUE
);
EXPECT_GE
((
const
void
*
)
&
READONLY_SEGMENT_END
,
(
const
void
*
)
&
TEST_STRUCT_DEFAULT_VALUE
);
EXPECT_LE
((
const
void
*
)
&
READONLY_SEGMENT_START
,
(
const
void
*
)
&
TEST_STRUCT
);
EXPECT_GE
((
const
void
*
)
&
READONLY_SEGMENT_END
,
(
const
void
*
)
&
TEST_STRUCT
);
}
...
...
c++/src/capnproto/type-safety.h
View file @
648d267d
...
...
@@ -90,6 +90,10 @@ public:
// This constructor was intended to be private, but GCC complains about it being private in a
// bunch of places that don't appear to even call it, so I made it public. Oh well.
template
<
typename
OtherNumber
>
inline
constexpr
UnitRatio
(
const
UnitRatio
<
OtherNumber
,
Unit1
,
Unit2
>&
other
)
:
unit1PerUnit2
(
other
.
unit1PerUnit2
)
{}
template
<
typename
OtherNumber
,
typename
Unit3
>
inline
constexpr
UnitRatio
<
decltype
(
Number
(
1
)
*
OtherNumber
(
1
)),
Unit3
,
Unit2
>
operator
*
(
UnitRatio
<
OtherNumber
,
Unit3
,
Unit1
>
other
)
{
...
...
@@ -422,72 +426,38 @@ inline constexpr decltype(BYTES / ELEMENTS) bytesPerElement() {
#ifndef __CDT_PARSER__
template
<
typename
T
>
inline
constexpr
byte
*
operator
+
(
byte
*
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
+
offset
/
BYTES
;
}
template
<
typename
T
>
inline
constexpr
const
byte
*
operator
+
(
const
byte
*
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
+
offset
/
BYTES
;
}
template
<
typename
T
>
inline
constexpr
byte
*
operator
+=
(
byte
*&
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
=
ptr
+
offset
/
BYTES
;
}
template
<
typename
T
>
inline
constexpr
const
byte
*
operator
+=
(
const
byte
*
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
=
ptr
+
offset
/
BYTES
;
}
template
<
typename
T
>
inline
constexpr
word
*
operator
+
(
word
*
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
+
offset
/
WORDS
;
}
template
<
typename
T
>
inline
constexpr
const
word
*
operator
+
(
const
word
*
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
+
offset
/
WORDS
;
}
template
<
typename
T
>
inline
constexpr
word
*
operator
+=
(
word
*&
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
=
ptr
+
offset
/
WORDS
;
}
template
<
typename
T
>
inline
constexpr
const
word
*
operator
+=
(
const
word
*&
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
=
ptr
+
offset
/
WORDS
;
}
template
<
typename
T
>
inline
constexpr
byte
*
operator
-
(
byte
*
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
-
offset
/
BYTES
;
template
<
typename
T
,
typename
U
>
inline
constexpr
U
*
operator
+
(
U
*
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
+
offset
/
unit
<
Quantity
<
T
,
U
>>
();
}
template
<
typename
T
>
inline
constexpr
const
byte
*
operator
-
(
const
byte
*
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
-
offset
/
BYTES
;
template
<
typename
T
,
typename
U
>
inline
constexpr
const
U
*
operator
+
(
const
U
*
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
+
offset
/
unit
<
Quantity
<
T
,
U
>>
()
;
}
template
<
typename
T
>
inline
constexpr
byte
*
operator
-=
(
byte
*&
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
=
ptr
-
offset
/
BYTES
;
template
<
typename
T
,
typename
U
>
inline
constexpr
U
*
operator
+=
(
U
*&
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
=
ptr
+
offset
/
unit
<
Quantity
<
T
,
U
>>
()
;
}
template
<
typename
T
>
inline
constexpr
const
byte
*
operator
-=
(
const
byte
*
ptr
,
Quantity
<
T
,
byte
>
offset
)
{
return
ptr
=
ptr
-
offset
/
BYTES
;
template
<
typename
T
,
typename
U
>
inline
constexpr
const
U
*
operator
+=
(
const
U
*&
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
=
ptr
+
offset
/
unit
<
Quantity
<
T
,
U
>>
()
;
}
template
<
typename
T
>
inline
constexpr
word
*
operator
-
(
word
*
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
-
offset
/
WORDS
;
template
<
typename
T
,
typename
U
>
inline
constexpr
U
*
operator
-
(
U
*
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
-
offset
/
unit
<
Quantity
<
T
,
U
>>
()
;
}
template
<
typename
T
>
inline
constexpr
const
word
*
operator
-
(
const
word
*
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
-
offset
/
WORDS
;
template
<
typename
T
,
typename
U
>
inline
constexpr
const
U
*
operator
-
(
const
U
*
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
-
offset
/
unit
<
Quantity
<
T
,
U
>>
()
;
}
template
<
typename
T
>
inline
constexpr
word
*
operator
-=
(
word
*&
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
=
ptr
-
offset
/
WORDS
;
template
<
typename
T
,
typename
U
>
inline
constexpr
U
*
operator
-=
(
U
*&
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
=
ptr
-
offset
/
unit
<
Quantity
<
T
,
U
>>
()
;
}
template
<
typename
T
>
inline
constexpr
const
word
*
operator
-=
(
const
word
*&
ptr
,
Quantity
<
T
,
word
>
offset
)
{
return
ptr
=
ptr
-
offset
/
WORDS
;
template
<
typename
T
,
typename
U
>
inline
constexpr
const
U
*
operator
-=
(
const
U
*&
ptr
,
Quantity
<
T
,
U
>
offset
)
{
return
ptr
=
ptr
-
offset
/
unit
<
Quantity
<
T
,
U
>>
()
;
}
#endif
...
...
c++/src/capnproto/wire-format-test.c++
0 → 100644
View file @
648d267d
// 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 "wire-format.h"
#include "descriptor.h"
#include <gtest/gtest.h>
namespace
capnproto
{
namespace
internal
{
namespace
{
TEST
(
StructReader
,
RawData
)
{
AlignedData
<
2
>
data
=
{
{
// Struct ref, offset = 1, fieldCount = 1, dataSize = 1, referenceCount = 0
0x08
,
0x00
,
0x00
,
0x00
,
0x01
,
0x01
,
0x00
,
0x00
,
// Content for the data segment.
0x01
,
0x23
,
0x45
,
0x67
,
0x89
,
0xab
,
0xcd
,
0xef
}
};
StructReader
reader
=
StructReader
::
readRootTrusted
(
data
.
words
,
data
.
words
);
EXPECT_EQ
(
0xefcdab8967452301ull
,
reader
.
getDataField
<
uint64_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint64_t
>
(
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0x67452301u
,
reader
.
getDataField
<
uint32_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0xefcdab89u
,
reader
.
getDataField
<
uint32_t
>
(
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint32_t
>
(
2
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0x2301u
,
reader
.
getDataField
<
uint16_t
>
(
0
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0x6745u
,
reader
.
getDataField
<
uint16_t
>
(
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0xab89u
,
reader
.
getDataField
<
uint16_t
>
(
2
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
0xefcdu
,
reader
.
getDataField
<
uint16_t
>
(
3
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataField
<
uint16_t
>
(
4
*
ELEMENTS
,
321u
));
// Bits
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
0
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
1
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
2
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
3
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
4
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
5
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
6
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
7
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
8
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
9
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
10
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
11
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
12
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
13
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
14
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
15
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataField
<
bool
>
(
64
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataField
<
bool
>
(
64
*
ELEMENTS
,
true
));
// Field number guards.
EXPECT_EQ
(
0xefcdab89u
,
reader
.
getDataFieldCheckingNumber
<
uint32_t
>
(
FieldNumber
(
0
),
1
*
ELEMENTS
,
321u
));
EXPECT_EQ
(
321u
,
reader
.
getDataFieldCheckingNumber
<
uint32_t
>
(
FieldNumber
(
1
),
1
*
ELEMENTS
,
321u
));
EXPECT_TRUE
(
reader
.
getDataFieldCheckingNumber
<
bool
>
(
FieldNumber
(
0
),
0
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataFieldCheckingNumber
<
bool
>
(
FieldNumber
(
0
),
0
*
ELEMENTS
,
true
));
EXPECT_FALSE
(
reader
.
getDataFieldCheckingNumber
<
bool
>
(
FieldNumber
(
0
),
1
*
ELEMENTS
,
false
));
EXPECT_FALSE
(
reader
.
getDataFieldCheckingNumber
<
bool
>
(
FieldNumber
(
0
),
1
*
ELEMENTS
,
true
));
EXPECT_FALSE
(
reader
.
getDataFieldCheckingNumber
<
bool
>
(
FieldNumber
(
1
),
0
*
ELEMENTS
,
false
));
EXPECT_TRUE
(
reader
.
getDataFieldCheckingNumber
<
bool
>
(
FieldNumber
(
1
),
0
*
ELEMENTS
,
true
));
}
}
// namespace
}
// namespace internal
}
// namespace capnproto
c++/src/capnproto/wire-format.c++
View file @
648d267d
This diff is collapsed.
Click to expand it.
c++/src/capnproto/wire-format.h
View file @
648d267d
...
...
@@ -81,9 +81,10 @@ private:
class
StructBuilder
{
public
:
inline
StructBuilder
()
:
segment
(
nullptr
),
ptr
(
nullptr
)
{}
inline
StructBuilder
()
:
segment
(
nullptr
),
data
(
nullptr
),
references
(
nullptr
)
{}
static
StructBuilder
initRoot
(
SegmentBuilder
*
segment
,
word
*
location
);
static
StructBuilder
initRoot
(
SegmentBuilder
*
segment
,
word
*
location
,
FieldNumber
fieldCount
,
WordCount
dataSize
,
WireReferenceCount
referenceCount
);
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
T
getDataField
(
ElementCount
offset
)
const
);
...
...
@@ -95,16 +96,21 @@ public:
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
// Set the data field value at the given offset.
inline
StructBuilder
getStructField
(
WireReferenceCount
refIndex
)
const
;
StructBuilder
getStructField
(
WireReferenceCount
refIndex
,
FieldNumber
fieldCount
,
WordCount
dataSize
,
WireReferenceCount
referenceCount
)
const
;
// Get the struct field at the given index in the reference segment. Allocates space for the
// struct if necessary.
inline
ListBuilder
initListField
(
WireReferenceCount
refIndex
,
FieldSize
field
Size
,
ListBuilder
initListField
(
WireReferenceCount
refIndex
,
FieldSize
element
Size
,
ElementCount
elementCount
)
const
;
ListBuilder
initStructListField
(
WireReferenceCount
refIndex
,
ElementCount
elementCount
,
FieldNumber
fieldCount
,
WordCount
dataSize
,
WireReferenceCount
referenceCount
)
const
;
// Allocate a new list of the given size for the field at the given index in the reference
// segment, and return a pointer to it.
inline
ListBuilder
getListField
(
WireReferenceCount
refIndex
)
const
;
ListBuilder
getListField
(
WireReferenceCount
refIndex
,
FieldSize
elementSize
)
const
;
// Get the already-allocated list field for the given reference index. Returns an empty list --
// NOT necessarily the default value -- if the field is not initialized.
...
...
@@ -113,10 +119,11 @@ public:
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the struct resides.
word
*
ptr
;
// Pointer to the encoded struct (data followed by references).
word
*
data
;
// Pointer to the encoded data.
WireReference
*
references
;
// Pointer to the encoded references.
inline
StructBuilder
(
SegmentBuilder
*
segment
,
word
*
ptr
)
:
segment
(
segment
),
ptr
(
ptr
)
{}
inline
StructBuilder
(
SegmentBuilder
*
segment
,
word
*
data
,
WireReference
*
references
)
:
segment
(
segment
),
data
(
data
),
references
(
references
)
{}
friend
class
ListBuilder
;
friend
struct
WireHelpers
;
...
...
@@ -128,6 +135,10 @@ public:
:
segment
(
nullptr
),
ptr
(
nullptr
),
fieldCount
(
0
),
dataSize
(
0
),
referenceCount
(
0
),
bit0Offset
(
0
*
BITS
),
recursionLimit
(
0
)
{}
static
StructReader
readRootTrusted
(
const
word
*
location
,
const
word
*
defaultValue
);
static
StructReader
readRoot
(
const
word
*
location
,
const
word
*
defaultValue
,
SegmentReader
*
segment
,
int
recursionLimit
);
template
<
typename
T
>
CAPNPROTO_ALWAYS_INLINE
(
T
getDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
defaultValue
)
const
);
...
...
@@ -143,11 +154,13 @@ public:
// with later numbers, and therefore the offset being in-bounds alone does not prove that the
// struct contains the field.
inline
StructReader
getStructField
(
WireReferenceCount
refIndex
)
const
;
StructReader
getStructField
(
WireReferenceCount
refIndex
,
const
word
*
defaultValue
)
const
;
// Get the struct field at the given index in the reference segment, or the default value if not
// initialized.
// initialized. defaultValue will be interpreted as a trusted message -- it must point at a
// struct reference, which in turn points at the struct value.
inline
ListReader
getListField
(
WireReferenceCount
refIndex
,
FieldSize
expectedElementSize
)
const
;
ListReader
getListField
(
WireReferenceCount
refIndex
,
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
;
// Get the list field at the given index in the reference segment, or the default value if not
// initialized.
...
...
@@ -208,20 +221,27 @@ public:
ElementCount
index
,
typename
NoInfer
<
T
>::
Type
value
)
const
);
// Set the element at the given index.
CAPNPROTO_ALWAYS_INLINE
(
StructBuilder
getStructElement
(
ElementCount
index
,
decltype
(
WORDS
/
ELEMENTS
)
elementSize
)
const
)
;
StructBuilder
getStructElement
(
ElementCount
index
,
decltype
(
WORDS
/
ELEMENTS
)
elementSize
,
WordCount
structDataSize
)
const
;
// Get the struct element at the given index. elementSize is the size, in 64-bit words, of
// each element.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
initListElement
(
WireReferenceCount
index
,
ElementCount
size
)
const
);
ListBuilder
initListElement
(
WireReferenceCount
index
,
FieldSize
elementSize
,
ElementCount
elementCount
)
const
;
ListBuilder
initStructListElement
(
WireReferenceCount
index
,
ElementCount
elementCount
,
FieldNumber
fieldCount
,
WordCount
dataSize
,
WireReferenceCount
referenceCount
)
const
;
// Create a new list element of the given size at the given index.
CAPNPROTO_ALWAYS_INLINE
(
ListBuilder
getListElement
(
WireReferenceCount
index
)
const
)
;
ListBuilder
getListElement
(
WireReferenceCount
index
,
FieldSize
elementSize
)
const
;
// Get the existing list element at the given index.
ListReader
asReader
()
const
;
// Get a ListReader pointing at the same memory.
ListReader
asReader
(
FieldSize
elementSize
)
const
;
// Get a ListReader pointing at the same memory. Use this version only for non-struct lists.
ListReader
asReader
(
FieldNumber
fieldCount
,
WordCount
dataSize
,
WireReferenceCount
referenceCount
)
const
;
// Get a ListReader pointing at the same memory. Use this version only for struct lists.
private
:
SegmentBuilder
*
segment
;
// Memory segment in which the list resides.
...
...
@@ -249,11 +269,11 @@ public:
CAPNPROTO_ALWAYS_INLINE
(
T
getDataElement
(
ElementCount
index
)
const
);
// Get the element of the given type at the given index.
CAPNPROTO_ALWAYS_INLINE
(
StructReader
getStructElement
(
ElementCount
index
)
const
)
;
StructReader
getStructElement
(
ElementCount
index
,
const
word
*
defaultValue
)
const
;
// Get the struct element at the given index.
CAPNPROTO_ALWAYS_INLINE
(
ListReader
getListElement
(
WireReferenceCount
index
,
FieldSize
expectedElementSize
)
const
)
;
ListReader
getListElement
(
WireReferenceCount
index
,
FieldSize
expectedElementSize
,
const
word
*
defaultValue
)
const
;
// Get the list element at the given index.
private
:
...
...
@@ -273,7 +293,9 @@ private:
FieldNumber
structFieldCount
;
WordCount
structDataSize
;
WireReferenceCount
structReferenceCount
;
// If the elements are structs, the properties of the struct.
// If the elements are structs, the properties of the struct. The field and reference counts are
// only used to check for field presence; the data size is also used to compute the reference
// pointer.
int
recursionLimit
;
// Limits the depth of message structures to guard against stack-overflow-based DoS attacks.
...
...
@@ -302,26 +324,26 @@ private:
template
<
typename
T
>
inline
T
StructBuilder
::
getDataField
(
ElementCount
offset
)
const
{
return
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
)[
offset
/
ELEMENTS
].
get
();
return
reinterpret_cast
<
WireValue
<
T
>*>
(
data
)[
offset
/
ELEMENTS
].
get
();
}
template
<>
inline
bool
StructBuilder
::
getDataField
<
bool
>
(
ElementCount
offset
)
const
{
BitCount
boffset
=
offset
*
(
1
*
BITS
/
ELEMENTS
);
byte
*
b
=
reinterpret_cast
<
byte
*>
(
ptr
)
+
boffset
/
BITS_PER_BYTE
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
boffset
/
BITS_PER_BYTE
;
return
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
(
1
<<
(
boffset
%
BITS_PER_BYTE
/
BITS
)))
!=
0
;
}
template
<
typename
T
>
inline
void
StructBuilder
::
setDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
value
)
const
{
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
)[
offset
/
ELEMENTS
].
set
(
value
);
reinterpret_cast
<
WireValue
<
T
>*>
(
data
)[
offset
/
ELEMENTS
].
set
(
value
);
}
template
<>
inline
void
StructBuilder
::
setDataField
<
bool
>
(
ElementCount
offset
,
bool
value
)
const
{
BitCount
boffset
=
offset
*
(
1
*
BITS
/
ELEMENTS
);
byte
*
b
=
reinterpret_cast
<
byte
*>
(
ptr
)
+
boffset
/
BITS_PER_BYTE
;
byte
*
b
=
reinterpret_cast
<
byte
*>
(
data
)
+
boffset
/
BITS_PER_BYTE
;
uint
bitnum
=
boffset
%
BITS_PER_BYTE
/
BITS
;
*
reinterpret_cast
<
uint8_t
*>
(
b
)
=
(
*
reinterpret_cast
<
uint8_t
*>
(
b
)
&
~
(
1
<<
bitnum
))
|
(
static_cast
<
uint8_t
>
(
value
)
<<
bitnum
);
...
...
@@ -332,7 +354,7 @@ inline void StructBuilder::setDataField<bool>(ElementCount offset, bool value) c
template
<
typename
T
>
T
StructReader
::
getDataField
(
ElementCount
offset
,
typename
NoInfer
<
T
>::
Type
defaultValue
)
const
{
if
(
offset
*
bytesPerElement
<
T
>
()
<
dataSize
*
BYTES_PER_WORD
)
{
return
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
)[
offset
/
ELEMENTS
].
get
();
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
ptr
)[
offset
/
ELEMENTS
].
get
();
}
else
{
return
defaultValue
;
}
...
...
@@ -359,7 +381,7 @@ T StructReader::getDataFieldCheckingNumber(
// Intentionally use & rather than && to reduce branches.
if
((
fieldNumber
<
fieldCount
)
&
(
offset
*
bytesPerElement
<
T
>
()
<
dataSize
*
BYTES_PER_WORD
))
{
return
reinterpret_cast
<
WireValue
<
T
>*>
(
ptr
)[
offset
/
ELEMENTS
].
get
();
return
reinterpret_cast
<
const
WireValue
<
T
>*>
(
ptr
)[
offset
/
ELEMENTS
].
get
();
}
else
{
return
defaultValue
;
}
...
...
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