mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 19:29:57 +00:00
TUN-528: Move cloudflared into a separate repo
This commit is contained in:
12
vendor/zombiezen.com/go/capnproto2/.gitignore
generated
vendored
Normal file
12
vendor/zombiezen.com/go/capnproto2/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/capnpc-go/capnpc-go
|
||||
/internal/cmd/mktemplates/mktemplates
|
||||
TAGS
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# Bazel
|
||||
/bazel-bin
|
||||
/bazel-capnproto2
|
||||
/bazel-genfiles
|
||||
/bazel-out
|
||||
/bazel-testlogs
|
9
vendor/zombiezen.com/go/capnproto2/.travis.yml
generated
vendored
Normal file
9
vendor/zombiezen.com/go/capnproto2/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
language: go
|
||||
go_import_path: zombiezen.com/go/capnproto2
|
||||
go:
|
||||
- 1.x
|
||||
install: _travis/install.bash
|
||||
script: _travis/build.bash
|
||||
env:
|
||||
- USE_BAZEL=0
|
||||
- USE_BAZEL=1
|
27
vendor/zombiezen.com/go/capnproto2/AUTHORS
generated
vendored
Normal file
27
vendor/zombiezen.com/go/capnproto2/AUTHORS
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# This is the official list of go-capnproto authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS files.
|
||||
# See the latter for an explanation.
|
||||
|
||||
# Names should be added to this file as one of
|
||||
# Organization's name
|
||||
# Individual's name <submission email address>
|
||||
# Individual's name <submission email address> <email2> <emailN>
|
||||
# See CONTRIBUTORS for the meaning of multiple email addresses.
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
CloudFlare Inc.
|
||||
Daniel Darabos <darabos.daniel@gmail.com>
|
||||
Eran Duchan <pavius@gmail.com>
|
||||
Evan Shaw <edsrzf@gmail.com>
|
||||
Google Inc.
|
||||
Ian Denhardt <ian@zenhack.net>
|
||||
James McKaskill <james@foobar.co.nz>
|
||||
Jason E. Aten <j.e.aten@gmail.com>
|
||||
Johan Hernandez <im@bithavoc.io>
|
||||
Joonsung Lee <joonsung@devsisters.com>
|
||||
Lev Radomislensky <lev.radomislensky@gmail.com>
|
||||
Peter Waldschmidt <peterw@gnoso.com>
|
||||
Tom Thorogood <me+github@tomthorogood.co.uk>
|
||||
TJ Holowaychuk <tj@apex.sh>
|
||||
William Laffin <william.laffin@gmail.com>
|
62
vendor/zombiezen.com/go/capnproto2/BUILD.bazel
generated
vendored
Normal file
62
vendor/zombiezen.com/go/capnproto2/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
# gazelle:prefix zombiezen.com/go/capnproto2
|
||||
gazelle(
|
||||
name = "gazelle",
|
||||
command = "fix",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"address.go",
|
||||
"canonical.go",
|
||||
"capability.go",
|
||||
"capn.go",
|
||||
"doc.go",
|
||||
"go.capnp.go",
|
||||
"list.go",
|
||||
"mem.go",
|
||||
"mem_18.go",
|
||||
"mem_other.go",
|
||||
"pointer.go",
|
||||
"rawpointer.go",
|
||||
"readlimit.go",
|
||||
"strings.go",
|
||||
"struct.go",
|
||||
],
|
||||
importpath = "zombiezen.com/go/capnproto2",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//internal/packed:go_default_library",
|
||||
"//internal/strquote:go_default_library",
|
||||
"//schemas:go_default_library",
|
||||
"@org_golang_x_net//context:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"address_test.go",
|
||||
"canonical_test.go",
|
||||
"capability_test.go",
|
||||
"capn_test.go",
|
||||
"example_test.go",
|
||||
"integration_test.go",
|
||||
"integrationutil_test.go",
|
||||
"list_test.go",
|
||||
"mem_test.go",
|
||||
"rawpointer_test.go",
|
||||
"readlimit_test.go",
|
||||
],
|
||||
data = [
|
||||
"//internal/aircraftlib:schema",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//internal/aircraftlib:go_default_library",
|
||||
"//internal/capnptool:go_default_library",
|
||||
],
|
||||
)
|
194
vendor/zombiezen.com/go/capnproto2/CHANGELOG.md
generated
vendored
Normal file
194
vendor/zombiezen.com/go/capnproto2/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
# Go Cap'n Proto Release Notes
|
||||
|
||||
## 2.17.0
|
||||
|
||||
- Add `capnp.Canonicalize` function that implements the
|
||||
[canonicalization](https://capnproto.org/encoding.html#canonicalization)
|
||||
algorithm. ([#92](https://github.com/capnproto/go-capnproto2/issues/92))
|
||||
- Zero-sized struct pointers are now written with an offset of
|
||||
-1 to distinguish them from a null pointer.
|
||||
([#92](https://github.com/capnproto/go-capnproto2/issues/92))
|
||||
- Better support for alternate `Arena` implementations
|
||||
- [Document `Arena` contract](https://godoc.org/zombiezen.com/go/capnproto2#Arena)
|
||||
in more detail
|
||||
- Permit an `Arena` to have a single empty segment in `NewMessage`
|
||||
- `Arena` allocation optimizations: both `SingleSegment` and
|
||||
`MultiSegment` now gradually ramp up the amount of space allocated in
|
||||
a single allocation as the message grows. This is similar to how
|
||||
built-in Go `append` function works. Workloads with medium to large
|
||||
messages should expect a decrease in number of allocations, while
|
||||
small message workloads should remain about the same. Please file an
|
||||
issue if you encounter any performance regressions.
|
||||
([#96](https://github.com/capnproto/go-capnproto2/issues/96))
|
||||
- Fix double-far pointer logic. ([#97](https://github.com/capnproto/go-capnproto2/issues/97))
|
||||
This is a long-standing bug with reading and writing multi-segment
|
||||
messages. I've added broader test coverage for multi-segment messages
|
||||
and far pointers, so it's unlikely that such a failure will persist in
|
||||
the future.
|
||||
- Accessing a field in a union when that field is not the one set now
|
||||
results in a panic. ([#56](https://github.com/capnproto/go-capnproto2/issues/56))
|
||||
This is intended to help uncover programming mistakes where a union
|
||||
field is accessed without checking `Which()`. Prior to this change,
|
||||
unset union field accessors would silently return garbage.
|
||||
- `Struct.Address()` and `List.Address()` are now deprecated.
|
||||
Especially for `List`, where the address is at the beginning of the
|
||||
data, not the composite literal, the return value is not well-defined
|
||||
and its not clear how to use it. Use `capnp.SamePtr` if you need to
|
||||
check for pointer reference equality. File an issue if you're using
|
||||
`Address()` for something else.
|
||||
|
||||
## 2.16.0
|
||||
|
||||
- Add BUILD.bazel files ([#88](https://github.com/capnproto/go-capnproto2/issues/88))
|
||||
|
||||
## 2.15.0
|
||||
|
||||
- capnpc-go now fails when a file does not include an import annotation.
|
||||
([#41](https://github.com/capnproto/go-capnproto2/issues/41))
|
||||
- Remove rbtree dependency ([#80](https://github.com/capnproto/go-capnproto2/issues/80))
|
||||
- Add option to reduce allocations in `capnp.Decoder`
|
||||
([#79](https://github.com/capnproto/go-capnproto2/issues/79))
|
||||
- Add `String()` methods for lists
|
||||
([#85](https://github.com/capnproto/go-capnproto2/issues/85))
|
||||
- Add `String()` methods to schema.capnp.go
|
||||
([#83](https://github.com/capnproto/go-capnproto2/issues/83))
|
||||
|
||||
## 2.14.1
|
||||
|
||||
- Use [new Go generated code convention](https://golang.org/s/generatedcode) in
|
||||
capnpc-go output ([#78](https://github.com/capnproto/go-capnproto2/issues/78))
|
||||
|
||||
## Retroactive Releases
|
||||
|
||||
go-capnproto2 was originally a "build from HEAD" sort of library, as was
|
||||
convention for most Go libraries at the time. Before 2.14.1, Semantic
|
||||
Versioning tags were retroactively added so that it would be clear what the
|
||||
differences were since original release, since marking it as "2.0.0" would seem
|
||||
awkward.
|
||||
|
||||
The general process was: any significant new feature was given a minor release,
|
||||
and then any bugfixes before the next minor release were given a "2.X.1"
|
||||
release.
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Version</th>
|
||||
<th scope="col">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.14.0">2.14.0</a></th>
|
||||
<td>Add support to <code>pogs</code> for interface types (<a href="https://github.com/capnproto/go-capnproto2/issues/66">#66</a> and <a href="https://github.com/capnproto/go-capnproto2/issues/74">#74</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.13.1">2.13.1</a></th>
|
||||
<td>Fix bug with far far pointers (<a href="https://github.com/capnproto/go-capnproto2/issues/71">#71</a>), use <code>writev</code> system call to encode multi-segment messages efficiently in Go 1.8+ (<a href="https://github.com/capnproto/go-capnproto2/issues/70">#70</a>), and add GitHub-Linguist-compatible code generation comment</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.13.0">2.13.0</a></th>
|
||||
<td>Add <code>Conn.Done</code> and <code>Conn.Err</code> methods</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.12.4">2.12.4</a></th>
|
||||
<td>Fix size of created <code>List(Float32)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.12.3">2.12.3</a></th>
|
||||
<td>Fix bugs from fuzz tests: mismatched element size on list access causing crashes (<a href="https://github.com/capnproto/go-capnproto2/issues/59">#59</a>) and miscellaneous packed reader issues</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.12.2">2.12.2</a></th>
|
||||
<td>Fix another shutdown race condition (<a href="https://github.com/capnproto/go-capnproto2/issues/54">#54</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.12.1">2.12.1</a></th>
|
||||
<td>Fix ownership bug with receiver-hosted capabilities, add discriminant check to <code>HasField</code> (<a href="https://github.com/capnproto/go-capnproto2/issues/55">#55</a>), fix multi-segment bug for data/text lists, and use nulls for setting empty data/text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.12.0">2.12.0</a></th>
|
||||
<td>Add <code>rpc.ConnLog</code> option and fix race conditions and edge cases in RPC implementation</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.11.1">2.11.1</a></th>
|
||||
<td>Fix packed reader behavior on certain readers (<a href="https://github.com/capnproto/go-capnproto2/issues/49">#49</a>), add <code>capnp.UnmarshalPacked</code> function that performs faster, and reduce locking overhead of segment maps</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.11.0">2.11.0</a></th>
|
||||
<td>Fix shutdown deadlock in RPC shutdown (<a href="https://github.com/capnproto/go-capnproto2/issues/45">#45</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.10.1">2.10.1</a></th>
|
||||
<td>Work around lack of support for RPC-level promise capabilities (<a href="https://github.com/capnproto/go-capnproto2/issues/2">#2</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.10.0">2.10.0</a></th>
|
||||
<td>Add <code>pogs</code> package (<a href="https://github.com/capnproto/go-capnproto2/issues/33">#33</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.9.1">2.9.1</a></th>
|
||||
<td>Fix not-found behavior in schemas and add missing group IDs in generated embedded schemas</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.9.0">2.9.0</a></th>
|
||||
<td>Add <code>encoding/text</code> package (<a href="https://github.com/capnproto/go-capnproto2/issues/20">#20</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.8.0">2.8.0</a></th>
|
||||
<td>Reduce generated code size for text fields and correct NUL check</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.7.0">2.7.0</a></th>
|
||||
<td>Insert compressed schema data into generated code</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.6.1">2.6.1</a></th>
|
||||
<td>Strip NUL byte from <code>TextList.BytesAt</code> and fix capnpc-go output for struct groups</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.6.0">2.6.0</a></th>
|
||||
<td>Add packages for predefined Cap'n Proto schemas</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.5.1">2.5.1</a></th>
|
||||
<td>Fix capnpc-go regression (<a href="https://github.com/capnproto/go-capnproto2/issues/29">#29</a>) and strip trailing NUL byte in TextBytes accessor</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.5.0">2.5.0</a></th>
|
||||
<td>Add <code>NewFoo</code> method for list fields in generated structs (<a href="https://github.com/capnproto/go-capnproto2/issues/7">#7</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.4.0">2.4.0</a></th>
|
||||
<td>Add maximum segment limit (<a href="https://github.com/capnproto/go-capnproto2/issues/25">#25</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.3.0">2.3.0</a></th>
|
||||
<td>Add depth and traversal limit security checks</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.2.1">2.2.1</a></th>
|
||||
<td>Fix data race in reading <code>Message</code> from multiple goroutines</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.2.0">2.2.0</a></th>
|
||||
<td>Add <code>HasFoo</code> pointer field methods to generated code (<a href="https://github.com/capnproto/go-capnproto2/issues/24">#24</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.1.0">2.1.0</a></th>
|
||||
<td><a href="https://github.com/capnproto/go-capnproto2/wiki/New-Ptr-Type">Introduce <code>Ptr</code> type</a> and reduce allocations in single-segment cases</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.0.2">2.0.2</a></th>
|
||||
<td>Allow allocation-less string field access via <code>TextList.BytesAt()</code> and <code>StringBytes()</code> (<a href="https://github.com/capnproto/go-capnproto2/issues/17">#17</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.0.1">2.0.1</a></th>
|
||||
<td>Allow nil params in client wrappers (<a href="https://github.com/capnproto/go-capnproto2/issues/9">#9</a>) and fix integer underflow on compare function (<a href="https://github.com/capnproto/go-capnproto2/issues/12">#12</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><a href="https://github.com/capnproto/go-capnproto2/releases/tag/v2.0.0">2.0.0</a></th>
|
||||
<td>First release under <code>zombiezen.com/go/capnproto2</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
22
vendor/zombiezen.com/go/capnproto2/CONTRIBUTING.md
generated
vendored
Normal file
22
vendor/zombiezen.com/go/capnproto2/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# How to contribute
|
||||
|
||||
We'd love to accept your patches and contributions to this project. There are a
|
||||
just a few small guidelines you need to follow.
|
||||
|
||||
## Code contributions
|
||||
|
||||
All submissions, including submissions by project members, require review. We
|
||||
use GitHub pull requests for this purpose. Consult [GitHub Help][] for more
|
||||
information on using pull requests.
|
||||
|
||||
When you make your first submission to this repository, please add your name to
|
||||
the AUTHORS and CONTRIBUTORS file as part of your first pull request.
|
||||
|
||||
As a policy, go-capnproto2 should always build cleanly and pass tests on every
|
||||
commit. We run a [Travis build][] that checks before and after merges to
|
||||
enforce this policy. However, as a courtesy to other contributors, please run
|
||||
`go test ./...` before sending a pull request (this is what the Travis
|
||||
build does).
|
||||
|
||||
[GitHub Help]: https://help.github.com/articles/about-pull-requests/
|
||||
[Travis build]: https://travis-ci.org/capnproto/go-capnproto2
|
33
vendor/zombiezen.com/go/capnproto2/CONTRIBUTORS
generated
vendored
Normal file
33
vendor/zombiezen.com/go/capnproto2/CONTRIBUTORS
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# This is the official list of people who can contribute
|
||||
# (and typically have contributed) code to the go-capnproto repository.
|
||||
# The AUTHORS file lists the copyright holders; this file
|
||||
# lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
#
|
||||
# When adding J Random Contributor's name to this file,
|
||||
# either J's name or J's organization's name should be
|
||||
# added to the AUTHORS file, depending on whether the
|
||||
# copyright belongs to the individual or the corporation.
|
||||
|
||||
# Names should be added to this file like so:
|
||||
# Individual's name <submission email address>
|
||||
# Individual's name <submission email address> <email2> <emailN>
|
||||
|
||||
# Please keep the list sorted.
|
||||
|
||||
Alan Braithwaite <alan@cloudflare.com>
|
||||
Albert Strasheim <albert@cloudflare.com>
|
||||
Daniel Darabos <darabos.daniel@gmail.com>
|
||||
Eran Duchan <pavius@gmail.com>
|
||||
Evan Shaw <edsrzf@gmail.com>
|
||||
Ian Denhardt <ian@zenhack.net>
|
||||
James McKaskill <james@foobar.co.nz>
|
||||
Jason E. Aten <j.e.aten@gmail.com>
|
||||
Johan Hernandez <im@bithavoc.io>
|
||||
Joonsung Lee <joonsung@devsisters.com>
|
||||
Lev Radomislensky <lev.radomislensky@gmail.com>
|
||||
Peter Waldschmidt <peterw@gnoso.com>
|
||||
Ross Light <light@google.com> <ross@zombiezen.com>
|
||||
Tom Thorogood <me+github@tomthorogood.co.uk>
|
||||
TJ Holowaychuk <tj@apex.sh>
|
||||
William Laffin <william.laffin@gmail.com>
|
25
vendor/zombiezen.com/go/capnproto2/LICENSE
generated
vendored
Normal file
25
vendor/zombiezen.com/go/capnproto2/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
go-capnproto is licensed under the terms of the MIT license reproduced below.
|
||||
|
||||
===============================================================================
|
||||
|
||||
Copyright (C) 2014 the go-capnproto authors and contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
===============================================================================
|
68
vendor/zombiezen.com/go/capnproto2/README.md
generated
vendored
Normal file
68
vendor/zombiezen.com/go/capnproto2/README.md
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# Cap'n Proto bindings for Go
|
||||
|
||||
[][godoc]
|
||||
[][travis]
|
||||
|
||||
go-capnproto consists of:
|
||||
- a Go code generator for [Cap'n Proto](https://capnproto.org/)
|
||||
- a Go package that provides runtime support
|
||||
- a Go package that implements Level 1 of the RPC protocol
|
||||
|
||||
[godoc]: https://godoc.org/zombiezen.com/go/capnproto2
|
||||
[travis]: https://travis-ci.org/capnproto/go-capnproto2
|
||||
|
||||
## Getting started
|
||||
|
||||
You will need the `capnp` tool to compile schemas into Go.
|
||||
This package has been tested with Cap'n Proto 0.5.0.
|
||||
|
||||
```
|
||||
$ go get -u -t zombiezen.com/go/capnproto2/...
|
||||
$ go test -v zombiezen.com/go/capnproto2/...
|
||||
```
|
||||
|
||||
This library uses [SemVer tags][] to indicate stable releases.
|
||||
While the goal is that master should always be passing all known tests, tagged releases are vetted more.
|
||||
When possible, use the [latest release tag](https://github.com/capnproto/go-capnproto2/releases).
|
||||
|
||||
```
|
||||
$ cd $GOPATH/src/zombiezen.com/go/capnproto2
|
||||
$ git fetch
|
||||
$ git checkout v2.16.0 # check the releases page for the latest
|
||||
```
|
||||
|
||||
Then read the [Getting Started guide][].
|
||||
|
||||
[SemVer tags]: http://semver.org/
|
||||
[Getting Started guide]: https://github.com/capnproto/go-capnproto2/wiki/Getting-Started
|
||||
|
||||
## API Compatibility
|
||||
|
||||
Consider this package's API as beta software, since the Cap'n Proto spec is not final.
|
||||
In the spirit of the [Go 1 compatibility guarantee][gocompat], I will make every effort to avoid making breaking API changes.
|
||||
The major cases where I reserve the right to make breaking changes are:
|
||||
|
||||
- Security.
|
||||
- Changes in the Cap'n Proto specification.
|
||||
- Bugs.
|
||||
|
||||
The `pogs` package is relatively new and may change over time.
|
||||
However, its functionality has been well-tested and will probably only relax restrictions.
|
||||
|
||||
[gocompat]: https://golang.org/doc/go1compat
|
||||
|
||||
## Documentation
|
||||
|
||||
See the docs on [godoc.org][godoc].
|
||||
|
||||
## What is Cap'n Proto?
|
||||
|
||||
The best cerealization...
|
||||
|
||||
https://capnproto.org/
|
||||
|
||||
## License
|
||||
|
||||
MIT - see [LICENSE][] file
|
||||
|
||||
[LICENSE]: https://github.com/capnproto/go-capnproto2/blob/master/LICENSE
|
45
vendor/zombiezen.com/go/capnproto2/WORKSPACE
generated
vendored
Normal file
45
vendor/zombiezen.com/go/capnproto2/WORKSPACE
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
workspace(name = "com_zombiezen_go_capnproto2")
|
||||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "8b68d0630d63d95dacc0016c3bb4b76154fe34fca93efd65d1c366de3fcb4294",
|
||||
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.12.1/rules_go-0.12.1.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "bazel_gazelle",
|
||||
sha256 = "ddedc7aaeb61f2654d7d7d4fd7940052ea992ccdb031b8f9797ed143ac7e8d43",
|
||||
urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.12.0/bazel-gazelle-0.12.0.tar.gz"],
|
||||
)
|
||||
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_dependencies")
|
||||
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains()
|
||||
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
|
||||
|
||||
gazelle_dependencies()
|
||||
|
||||
go_repository(
|
||||
name = "com_github_kylelemons_godebug",
|
||||
importpath = "github.com/kylelemons/godebug",
|
||||
sha256 = "4415b09bae90e41695bc17e4d00d0708e1f6bbb6e21cc22ce0146a26ddc243a7",
|
||||
strip_prefix = "godebug-a616ab194758ae0a11290d87ca46ee8c440117b0",
|
||||
urls = [
|
||||
"https://github.com/kylelemons/godebug/archive/a616ab194758ae0a11290d87ca46ee8c440117b0.zip",
|
||||
],
|
||||
)
|
||||
|
||||
go_repository(
|
||||
name = "org_golang_x_net",
|
||||
importpath = "golang.org/x/net",
|
||||
sha256 = "880dc04d0af397dce6875ee2349bbb4295fe5a47352f7a4da4270456f726edd4",
|
||||
strip_prefix = "net-f5079bd7f6f74e23c4d65efa0f4ce14cbd6a3c0f",
|
||||
urls = [
|
||||
"https://github.com/golang/net/archive/f5079bd7f6f74e23c4d65efa0f4ce14cbd6a3c0f.zip",
|
||||
],
|
||||
)
|
3
vendor/zombiezen.com/go/capnproto2/_travis/bazelrc
generated
vendored
Normal file
3
vendor/zombiezen.com/go/capnproto2/_travis/bazelrc
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
startup --batch --host_jvm_args=-Xms2500m --host_jvm_args=-Xmx2500m
|
||||
build --noshow_progress --spawn_strategy=standalone --genrule_strategy=standalone --local_resources=1536,1.5,0.5
|
||||
test --noshow_progress --test_output=errors --spawn_strategy=standalone --genrule_strategy=standalone --test_strategy=standalone --local_resources=1536,1.5,0.5
|
19
vendor/zombiezen.com/go/capnproto2/_travis/build.bash
generated
vendored
Executable file
19
vendor/zombiezen.com/go/capnproto2/_travis/build.bash
generated
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
must() {
|
||||
echo "$@" 1>&2
|
||||
"$@" || die "FAIL"
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "$@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ -z "$USE_BAZEL" || "$USE_BAZEL" -eq "0" ]]; then
|
||||
must go test -v ./...
|
||||
else
|
||||
# On Travis, this will use "$HOME/bin/bazel", but don't assume this
|
||||
# for local testing of the CI script.
|
||||
must bazel --bazelrc=_travis/bazelrc test //...
|
||||
fi
|
39
vendor/zombiezen.com/go/capnproto2/_travis/install.bash
generated
vendored
Executable file
39
vendor/zombiezen.com/go/capnproto2/_travis/install.bash
generated
vendored
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
must() {
|
||||
echo "$@" 1>&2
|
||||
"$@" || die "FAIL"
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "$@" 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ -z "$USE_BAZEL" || "$USE_BAZEL" -eq "0" ]]; then
|
||||
must go get -t ./...
|
||||
else
|
||||
BAZEL_VERSION="${BAZEL_VERSION:-0.14.1}"
|
||||
case "$TRAVIS_OS_NAME" in
|
||||
linux)
|
||||
BAZEL_INSTALLER_URL="https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-installer-linux-x86_64.sh"
|
||||
SEDI="sed -i"
|
||||
;;
|
||||
osx)
|
||||
BAZEL_INSTALLER_URL="https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-installer-darwin-x86_64.sh"
|
||||
SEDI="sed -i ''"
|
||||
;;
|
||||
*)
|
||||
die "unknown OS $TRAVIS_OS_NAME"
|
||||
;;
|
||||
esac
|
||||
must curl -fsSLo /tmp/bazel.sh "$BAZEL_INSTALLER_URL"
|
||||
must chmod +x /tmp/bazel.sh
|
||||
must /tmp/bazel.sh --user
|
||||
rm -f /tmp/bazel.sh
|
||||
if [[ ! -z "$TRAVIS_GO_VERSION" ]]; then
|
||||
must $SEDI -e 's/^go_register_toolchains()/go_register_toolchains(go_version="host")/' WORKSPACE
|
||||
fi
|
||||
must "$HOME/bin/bazel" --bazelrc=_travis/bazelrc version
|
||||
must "$HOME/bin/bazel" --bazelrc=_travis/bazelrc fetch //...
|
||||
fi
|
116
vendor/zombiezen.com/go/capnproto2/address.go
generated
vendored
Normal file
116
vendor/zombiezen.com/go/capnproto2/address.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
package capnp
|
||||
|
||||
// An Address is an index inside a segment's data (in bytes).
|
||||
type Address uint32
|
||||
|
||||
// addSize returns the address a+sz.
|
||||
func (a Address) addSize(sz Size) (b Address, ok bool) {
|
||||
x := int64(a) + int64(sz)
|
||||
if x > int64(maxSize) {
|
||||
return 0, false
|
||||
}
|
||||
return Address(x), true
|
||||
}
|
||||
|
||||
// element returns the address a+i*sz.
|
||||
func (a Address) element(i int32, sz Size) (b Address, ok bool) {
|
||||
x := int64(i) * int64(sz)
|
||||
if x > int64(maxSize) {
|
||||
return 0, false
|
||||
}
|
||||
x += int64(a)
|
||||
if x > int64(maxSize) {
|
||||
return 0, false
|
||||
}
|
||||
return Address(x), true
|
||||
}
|
||||
|
||||
// addOffset returns the address a+o.
|
||||
func (a Address) addOffset(o DataOffset) Address {
|
||||
return a + Address(o)
|
||||
}
|
||||
|
||||
// A Size is a size (in bytes).
|
||||
type Size uint32
|
||||
|
||||
// wordSize is the number of bytes in a Cap'n Proto word.
|
||||
const wordSize Size = 8
|
||||
|
||||
// maxSize is the maximum representable size.
|
||||
const maxSize Size = 1<<32 - 1
|
||||
|
||||
// times returns the size sz*n.
|
||||
func (sz Size) times(n int32) (ns Size, ok bool) {
|
||||
x := int64(sz) * int64(n)
|
||||
if x > int64(maxSize) {
|
||||
return 0, false
|
||||
}
|
||||
return Size(x), true
|
||||
}
|
||||
|
||||
// padToWord adds padding to sz to make it divisible by wordSize.
|
||||
func (sz Size) padToWord() Size {
|
||||
n := Size(wordSize - 1)
|
||||
return (sz + n) &^ n
|
||||
}
|
||||
|
||||
// DataOffset is an offset in bytes from the beginning of a struct's data section.
|
||||
type DataOffset uint32
|
||||
|
||||
// ObjectSize records section sizes for a struct or list.
|
||||
type ObjectSize struct {
|
||||
DataSize Size
|
||||
PointerCount uint16
|
||||
}
|
||||
|
||||
// isZero reports whether sz is the zero size.
|
||||
func (sz ObjectSize) isZero() bool {
|
||||
return sz.DataSize == 0 && sz.PointerCount == 0
|
||||
}
|
||||
|
||||
// isOneByte reports whether the object size is one byte (for Text/Data element sizes).
|
||||
func (sz ObjectSize) isOneByte() bool {
|
||||
return sz.DataSize == 1 && sz.PointerCount == 0
|
||||
}
|
||||
|
||||
// isValid reports whether sz's fields are in range.
|
||||
func (sz ObjectSize) isValid() bool {
|
||||
return sz.DataSize <= 0xffff*wordSize
|
||||
}
|
||||
|
||||
// pointerSize returns the number of bytes the pointer section occupies.
|
||||
func (sz ObjectSize) pointerSize() Size {
|
||||
// Guaranteed not to overflow
|
||||
return wordSize * Size(sz.PointerCount)
|
||||
}
|
||||
|
||||
// totalSize returns the number of bytes that the object occupies.
|
||||
func (sz ObjectSize) totalSize() Size {
|
||||
return sz.DataSize + sz.pointerSize()
|
||||
}
|
||||
|
||||
// dataWordCount returns the number of words in the data section.
|
||||
func (sz ObjectSize) dataWordCount() int32 {
|
||||
if sz.DataSize%wordSize != 0 {
|
||||
panic("data size not aligned by word")
|
||||
}
|
||||
return int32(sz.DataSize / wordSize)
|
||||
}
|
||||
|
||||
// totalWordCount returns the number of words that the object occupies.
|
||||
func (sz ObjectSize) totalWordCount() int32 {
|
||||
return sz.dataWordCount() + int32(sz.PointerCount)
|
||||
}
|
||||
|
||||
// BitOffset is an offset in bits from the beginning of a struct's data section.
|
||||
type BitOffset uint32
|
||||
|
||||
// offset returns the equivalent byte offset.
|
||||
func (bit BitOffset) offset() DataOffset {
|
||||
return DataOffset(bit / 8)
|
||||
}
|
||||
|
||||
// mask returns the bitmask for the bit.
|
||||
func (bit BitOffset) mask() byte {
|
||||
return byte(1 << (bit % 8))
|
||||
}
|
31
vendor/zombiezen.com/go/capnproto2/address_test.go
generated
vendored
Normal file
31
vendor/zombiezen.com/go/capnproto2/address_test.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
package capnp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAddressElement(t *testing.T) {
|
||||
tests := []struct {
|
||||
a Address
|
||||
i int32
|
||||
sz Size
|
||||
out Address
|
||||
ok bool
|
||||
}{
|
||||
{0, 0, 0, 0, true},
|
||||
{0, 1, 0, 0, true},
|
||||
{0, 1, 8, 8, true},
|
||||
{0, 2, 8, 16, true},
|
||||
{24, 1, 0, 24, true},
|
||||
{24, 1, 8, 32, true},
|
||||
{24, 2, 8, 40, true},
|
||||
{0, 0x7fffffff, 3, 0, false},
|
||||
{0xffffffff, 0x7fffffff, 0xffffffff, 0, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out, ok := test.a.element(test.i, test.sz)
|
||||
if ok != test.ok || (ok && out != test.out) {
|
||||
t.Errorf("%#v.element(%d, %d) = %#v, %t; want %#v, %t", test.a, test.i, test.sz, out, ok, test.out, test.ok)
|
||||
}
|
||||
}
|
||||
}
|
161
vendor/zombiezen.com/go/capnproto2/canonical.go
generated
vendored
Normal file
161
vendor/zombiezen.com/go/capnproto2/canonical.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
package capnp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Canonicalize encodes a struct into its canonical form: a single-
|
||||
// segment blob without a segment table. The result will be identical
|
||||
// for equivalent structs, even as the schema evolves. The blob is
|
||||
// suitable for hashing or signing.
|
||||
func Canonicalize(s Struct) ([]byte, error) {
|
||||
msg, seg, _ := NewMessage(SingleSegment(nil))
|
||||
if !s.IsValid() {
|
||||
return seg.Data(), nil
|
||||
}
|
||||
root, err := NewRootStruct(seg, canonicalStructSize(s))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("canonicalize: %v", err)
|
||||
}
|
||||
if err := msg.SetRootPtr(root.ToPtr()); err != nil {
|
||||
return nil, fmt.Errorf("canonicalize: %v", err)
|
||||
}
|
||||
if err := fillCanonicalStruct(root, s); err != nil {
|
||||
return nil, fmt.Errorf("canonicalize: %v", err)
|
||||
}
|
||||
return seg.Data(), nil
|
||||
}
|
||||
|
||||
func canonicalPtr(dst *Segment, p Ptr) (Ptr, error) {
|
||||
if !p.IsValid() {
|
||||
return Ptr{}, nil
|
||||
}
|
||||
switch p.flags.ptrType() {
|
||||
case structPtrType:
|
||||
ss, err := NewStruct(dst, canonicalStructSize(p.Struct()))
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
if err := fillCanonicalStruct(ss, p.Struct()); err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
return ss.ToPtr(), nil
|
||||
case listPtrType:
|
||||
ll, err := canonicalList(dst, p.List())
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
return ll.ToPtr(), nil
|
||||
case interfacePtrType:
|
||||
return Ptr{}, errors.New("cannot canonicalize interface")
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
|
||||
func fillCanonicalStruct(dst, s Struct) error {
|
||||
copy(dst.seg.slice(dst.off, dst.size.DataSize), s.seg.slice(s.off, s.size.DataSize))
|
||||
for i := uint16(0); i < dst.size.PointerCount; i++ {
|
||||
p, err := s.Ptr(i)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pointer %d: %v", i, err)
|
||||
}
|
||||
cp, err := canonicalPtr(dst.seg, p)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pointer %d: %v", i, err)
|
||||
}
|
||||
if err := dst.SetPtr(i, cp); err != nil {
|
||||
return fmt.Errorf("pointer %d: %v", i, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func canonicalStructSize(s Struct) ObjectSize {
|
||||
if !s.IsValid() {
|
||||
return ObjectSize{}
|
||||
}
|
||||
var sz ObjectSize
|
||||
// int32 will not overflow because max struct data size is 2^16 words.
|
||||
for off := int32(s.size.DataSize &^ (wordSize - 1)); off >= 0; off -= int32(wordSize) {
|
||||
if s.Uint64(DataOffset(off)) != 0 {
|
||||
sz.DataSize = Size(off) + wordSize
|
||||
break
|
||||
}
|
||||
}
|
||||
for i := int32(s.size.PointerCount) - 1; i >= 0; i-- {
|
||||
if s.seg.readRawPointer(s.pointerAddress(uint16(i))) != 0 {
|
||||
sz.PointerCount = uint16(i + 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
return sz
|
||||
}
|
||||
|
||||
func canonicalList(dst *Segment, l List) (List, error) {
|
||||
if !l.IsValid() {
|
||||
return List{}, nil
|
||||
}
|
||||
if l.size.PointerCount == 0 {
|
||||
// Data only, just copy over.
|
||||
sz := l.allocSize()
|
||||
_, newAddr, err := alloc(dst, sz)
|
||||
if err != nil {
|
||||
return List{}, err
|
||||
}
|
||||
cl := List{
|
||||
seg: dst,
|
||||
off: newAddr,
|
||||
length: l.length,
|
||||
size: l.size,
|
||||
flags: l.flags,
|
||||
depthLimit: maxDepth,
|
||||
}
|
||||
end, _ := l.off.addSize(sz) // list was already validated
|
||||
copy(dst.data[newAddr:], l.seg.data[l.off:end])
|
||||
return cl, nil
|
||||
}
|
||||
if l.flags&isCompositeList == 0 {
|
||||
cl, err := NewPointerList(dst, l.length)
|
||||
if err != nil {
|
||||
return List{}, err
|
||||
}
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
p, err := PointerList{l}.PtrAt(i)
|
||||
if err != nil {
|
||||
return List{}, fmt.Errorf("element %d: %v", i, err)
|
||||
}
|
||||
cp, err := canonicalPtr(dst, p)
|
||||
if err != nil {
|
||||
return List{}, fmt.Errorf("element %d: %v", i, err)
|
||||
}
|
||||
if err := cl.SetPtr(i, cp); err != nil {
|
||||
return List{}, fmt.Errorf("element %d: %v", i, err)
|
||||
}
|
||||
}
|
||||
return cl.List, nil
|
||||
}
|
||||
|
||||
// Struct/composite list
|
||||
var elemSize ObjectSize
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
sz := canonicalStructSize(l.Struct(i))
|
||||
if sz.DataSize > elemSize.DataSize {
|
||||
elemSize.DataSize = sz.DataSize
|
||||
}
|
||||
if sz.PointerCount > elemSize.PointerCount {
|
||||
elemSize.PointerCount = sz.PointerCount
|
||||
}
|
||||
}
|
||||
cl, err := NewCompositeList(dst, elemSize, l.length)
|
||||
if err != nil {
|
||||
return List{}, err
|
||||
}
|
||||
for i := 0; i < cl.Len(); i++ {
|
||||
if err := fillCanonicalStruct(cl.Struct(i), l.Struct(i)); err != nil {
|
||||
return List{}, fmt.Errorf("element %d: %v", i, err)
|
||||
}
|
||||
}
|
||||
return cl, nil
|
||||
}
|
192
vendor/zombiezen.com/go/capnproto2/canonical_test.go
generated
vendored
Normal file
192
vendor/zombiezen.com/go/capnproto2/canonical_test.go
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
package capnp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCanonicalize(t *testing.T) {
|
||||
{
|
||||
// null
|
||||
b, err := Canonicalize(Struct{})
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(Struct{}):", err)
|
||||
}
|
||||
if want := ([]byte{0, 0, 0, 0, 0, 0, 0, 0}); !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(Struct{}) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// empty struct
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{})
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(empty struct):", err)
|
||||
}
|
||||
want := ([]byte{0xfc, 0xff, 0xff, 0xff, 0, 0, 0, 0})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(empty struct) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// zero data, zero pointer struct
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{DataSize: 8, PointerCount: 1})
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(zero data, zero pointer struct):", err)
|
||||
}
|
||||
want := ([]byte{0xfc, 0xff, 0xff, 0xff, 0, 0, 0, 0})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(zero data, zero pointer struct) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// one word data struct
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{DataSize: 8, PointerCount: 1})
|
||||
s.SetUint16(0, 0xbeef)
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(one word data struct):", err)
|
||||
}
|
||||
want := ([]byte{
|
||||
0, 0, 0, 0, 1, 0, 0, 0,
|
||||
0xef, 0xbe, 0, 0, 0, 0, 0, 0,
|
||||
})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(one word data struct) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// two pointers to zero structs
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{PointerCount: 2})
|
||||
e1, _ := NewStruct(seg, ObjectSize{DataSize: 8})
|
||||
e2, _ := NewStruct(seg, ObjectSize{DataSize: 8})
|
||||
s.SetPtr(0, e1.ToPtr())
|
||||
s.SetPtr(1, e2.ToPtr())
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(two pointers to zero structs):", err)
|
||||
}
|
||||
want := ([]byte{
|
||||
0, 0, 0, 0, 0, 0, 2, 0,
|
||||
0xfc, 0xff, 0xff, 0xff, 0, 0, 0, 0,
|
||||
0xfc, 0xff, 0xff, 0xff, 0, 0, 0, 0,
|
||||
})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(two pointers to zero structs) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// int list
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{PointerCount: 1})
|
||||
l, _ := NewInt8List(seg, 5)
|
||||
s.SetPtr(0, l.ToPtr())
|
||||
l.Set(0, 1)
|
||||
l.Set(1, 2)
|
||||
l.Set(2, 3)
|
||||
l.Set(3, 4)
|
||||
l.Set(4, 5)
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(int list):", err)
|
||||
}
|
||||
want := ([]byte{
|
||||
0, 0, 0, 0, 0, 0, 1, 0,
|
||||
0x01, 0, 0, 0, 0x2a, 0, 0, 0,
|
||||
1, 2, 3, 4, 5, 0, 0, 0,
|
||||
})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(int list) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// zero int list
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{PointerCount: 1})
|
||||
l, _ := NewInt8List(seg, 5)
|
||||
s.SetPtr(0, l.ToPtr())
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(zero int list):", err)
|
||||
}
|
||||
want := ([]byte{
|
||||
0, 0, 0, 0, 0, 0, 1, 0,
|
||||
0x01, 0, 0, 0, 0x2a, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(zero int list) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// struct list
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{PointerCount: 1})
|
||||
l, _ := NewCompositeList(seg, ObjectSize{DataSize: 8, PointerCount: 1}, 2)
|
||||
s.SetPtr(0, l.ToPtr())
|
||||
l.Struct(0).SetUint64(0, 0xdeadbeef)
|
||||
txt, _ := NewText(seg, "xyzzy")
|
||||
l.Struct(1).SetPtr(0, txt.ToPtr())
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(struct list):", err)
|
||||
}
|
||||
want := ([]byte{
|
||||
0, 0, 0, 0, 0, 0, 1, 0,
|
||||
0x01, 0, 0, 0, 0x27, 0, 0, 0,
|
||||
0x08, 0, 0, 0, 1, 0, 1, 0,
|
||||
0xef, 0xbe, 0xad, 0xde, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x01, 0, 0, 0, 0x32, 0, 0, 0,
|
||||
'x', 'y', 'z', 'z', 'y', 0, 0, 0,
|
||||
})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(struct list) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// zero struct list
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{PointerCount: 1})
|
||||
l, _ := NewCompositeList(seg, ObjectSize{DataSize: 16, PointerCount: 2}, 3)
|
||||
s.SetPtr(0, l.ToPtr())
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(zero struct list):", err)
|
||||
}
|
||||
want := ([]byte{
|
||||
0, 0, 0, 0, 0, 0, 1, 0,
|
||||
0x01, 0, 0, 0, 0x07, 0, 0, 0,
|
||||
0x0c, 0, 0, 0, 0, 0, 0, 0,
|
||||
})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(zero struct list) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
{
|
||||
// zero-length struct list
|
||||
_, seg, _ := NewMessage(SingleSegment(nil))
|
||||
s, _ := NewStruct(seg, ObjectSize{PointerCount: 1})
|
||||
l, _ := NewCompositeList(seg, ObjectSize{DataSize: 16, PointerCount: 2}, 0)
|
||||
s.SetPtr(0, l.ToPtr())
|
||||
b, err := Canonicalize(s)
|
||||
if err != nil {
|
||||
t.Fatal("Canonicalize(zero-length struct list):", err)
|
||||
}
|
||||
want := ([]byte{
|
||||
0, 0, 0, 0, 0, 0, 1, 0,
|
||||
0x01, 0, 0, 0, 0x07, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
})
|
||||
if !bytes.Equal(b, want) {
|
||||
t.Errorf("Canonicalize(zero-length struct list) =\n%s\n; want\n%s", hex.Dump(b), hex.Dump(want))
|
||||
}
|
||||
}
|
||||
}
|
541
vendor/zombiezen.com/go/capnproto2/capability.go
generated
vendored
Normal file
541
vendor/zombiezen.com/go/capnproto2/capability.go
generated
vendored
Normal file
@@ -0,0 +1,541 @@
|
||||
package capnp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// An Interface is a reference to a client in a message's capability table.
|
||||
type Interface struct {
|
||||
seg *Segment
|
||||
cap CapabilityID
|
||||
}
|
||||
|
||||
// NewInterface creates a new interface pointer. No allocation is
|
||||
// performed; s is only used for Segment()'s return value.
|
||||
func NewInterface(s *Segment, cap CapabilityID) Interface {
|
||||
return Interface{
|
||||
seg: s,
|
||||
cap: cap,
|
||||
}
|
||||
}
|
||||
|
||||
// ToInterface converts p to an Interface.
|
||||
//
|
||||
// Deprecated: Use Ptr.Interface.
|
||||
func ToInterface(p Pointer) Interface {
|
||||
if !IsValid(p) {
|
||||
return Interface{}
|
||||
}
|
||||
i, ok := p.underlying().(Interface)
|
||||
if !ok {
|
||||
return Interface{}
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// ToPtr converts the interface to a generic pointer.
|
||||
func (p Interface) ToPtr() Ptr {
|
||||
return Ptr{
|
||||
seg: p.seg,
|
||||
lenOrCap: uint32(p.cap),
|
||||
flags: interfacePtrFlag,
|
||||
}
|
||||
}
|
||||
|
||||
// Segment returns the segment this pointer came from.
|
||||
func (i Interface) Segment() *Segment {
|
||||
return i.seg
|
||||
}
|
||||
|
||||
// IsValid returns whether the interface is valid.
|
||||
func (i Interface) IsValid() bool {
|
||||
return i.seg != nil
|
||||
}
|
||||
|
||||
// HasData is always true.
|
||||
func (i Interface) HasData() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Capability returns the capability ID of the interface.
|
||||
func (i Interface) Capability() CapabilityID {
|
||||
return i.cap
|
||||
}
|
||||
|
||||
// value returns a raw interface pointer with the capability ID.
|
||||
func (i Interface) value(paddr Address) rawPointer {
|
||||
if i.seg == nil {
|
||||
return 0
|
||||
}
|
||||
return rawInterfacePointer(i.cap)
|
||||
}
|
||||
|
||||
func (i Interface) underlying() Pointer {
|
||||
return i
|
||||
}
|
||||
|
||||
// Client returns the client stored in the message's capability table
|
||||
// or nil if the pointer is invalid.
|
||||
func (i Interface) Client() Client {
|
||||
if i.seg == nil {
|
||||
return nil
|
||||
}
|
||||
tab := i.seg.msg.CapTable
|
||||
if int64(i.cap) >= int64(len(tab)) {
|
||||
return nil
|
||||
}
|
||||
return tab[i.cap]
|
||||
}
|
||||
|
||||
// ErrNullClient is returned from a call made on a null client pointer.
|
||||
var ErrNullClient = errors.New("capnp: call on null client")
|
||||
|
||||
// A CapabilityID is an index into a message's capability table.
|
||||
type CapabilityID uint32
|
||||
|
||||
// A Client represents an Cap'n Proto interface type. It is safe to use
|
||||
// from multiple goroutines.
|
||||
//
|
||||
// Generally, only RPC protocol implementers should provide types that
|
||||
// implement Client: call ordering guarantees, promises, and
|
||||
// synchronization are tricky to get right. Prefer creating a server
|
||||
// that wraps another interface than trying to implement Client.
|
||||
type Client interface {
|
||||
// Call starts executing a method and returns an answer that will hold
|
||||
// the resulting struct. The call's parameters must be placed before
|
||||
// Call() returns.
|
||||
//
|
||||
// Calls are delivered to the capability in the order they are made.
|
||||
// This guarantee is based on the concept of a capability
|
||||
// acknowledging delivery of a call: this is specific to an
|
||||
// implementation of Client. A type that implements Client must
|
||||
// guarantee that if foo() then bar() is called on a client, that
|
||||
// acknowledging foo() happens before acknowledging bar().
|
||||
Call(call *Call) Answer
|
||||
|
||||
// Close releases any resources associated with this client.
|
||||
// No further calls to the client should be made after calling Close.
|
||||
Close() error
|
||||
}
|
||||
|
||||
// The Call type holds the record for an outgoing interface call.
|
||||
type Call struct {
|
||||
// Ctx is the context of the call.
|
||||
Ctx context.Context
|
||||
|
||||
// Method is the interface ID and method ID, along with the optional name,
|
||||
// of the method to call.
|
||||
Method Method
|
||||
|
||||
// Params is a struct containing parameters for the call.
|
||||
// This should be set when the RPC system receives a call for an
|
||||
// exported interface. It is mutually exclusive with ParamsFunc
|
||||
// and ParamsSize.
|
||||
Params Struct
|
||||
// ParamsFunc is a function that populates an allocated struct with
|
||||
// the parameters for the call. ParamsSize determines the size of the
|
||||
// struct to allocate. This is used when application code is using a
|
||||
// client. These settings should be set together; they are mutually
|
||||
// exclusive with Params.
|
||||
ParamsFunc func(Struct) error
|
||||
ParamsSize ObjectSize
|
||||
|
||||
// Options passes RPC-specific options for the call.
|
||||
Options CallOptions
|
||||
}
|
||||
|
||||
// Copy clones a call, ensuring that its Params are placed.
|
||||
// If Call.ParamsFunc is nil, then the same Call will be returned.
|
||||
func (call *Call) Copy(s *Segment) (*Call, error) {
|
||||
if call.ParamsFunc == nil {
|
||||
return call, nil
|
||||
}
|
||||
p, err := call.PlaceParams(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Call{
|
||||
Ctx: call.Ctx,
|
||||
Method: call.Method,
|
||||
Params: p,
|
||||
Options: call.Options,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PlaceParams returns the parameters struct, allocating it inside
|
||||
// segment s as necessary. If s is nil, a new single-segment message
|
||||
// is allocated.
|
||||
func (call *Call) PlaceParams(s *Segment) (Struct, error) {
|
||||
if call.ParamsFunc == nil {
|
||||
return call.Params, nil
|
||||
}
|
||||
if s == nil {
|
||||
var err error
|
||||
_, s, err = NewMessage(SingleSegment(nil))
|
||||
if err != nil {
|
||||
return Struct{}, err
|
||||
}
|
||||
}
|
||||
p, err := NewStruct(s, call.ParamsSize)
|
||||
if err != nil {
|
||||
return Struct{}, nil
|
||||
}
|
||||
err = call.ParamsFunc(p)
|
||||
return p, err
|
||||
}
|
||||
|
||||
// CallOptions holds RPC-specific options for an interface call.
|
||||
// Its usage is similar to the values in context.Context, but is only
|
||||
// used for a single call: its values are not intended to propagate to
|
||||
// other callees. An example of an option would be the
|
||||
// Call.sendResultsTo field in rpc.capnp.
|
||||
type CallOptions struct {
|
||||
m map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// NewCallOptions builds a CallOptions value from a list of individual options.
|
||||
func NewCallOptions(opts []CallOption) CallOptions {
|
||||
co := CallOptions{make(map[interface{}]interface{})}
|
||||
for _, o := range opts {
|
||||
o.f(co)
|
||||
}
|
||||
return co
|
||||
}
|
||||
|
||||
// Value retrieves the value associated with the options for this key,
|
||||
// or nil if no value is associated with this key.
|
||||
func (co CallOptions) Value(key interface{}) interface{} {
|
||||
return co.m[key]
|
||||
}
|
||||
|
||||
// With creates a copy of the CallOptions value with other options applied.
|
||||
func (co CallOptions) With(opts []CallOption) CallOptions {
|
||||
newopts := CallOptions{make(map[interface{}]interface{})}
|
||||
for k, v := range co.m {
|
||||
newopts.m[k] = v
|
||||
}
|
||||
for _, o := range opts {
|
||||
o.f(newopts)
|
||||
}
|
||||
return newopts
|
||||
}
|
||||
|
||||
// A CallOption is a function that modifies options on an interface call.
|
||||
type CallOption struct {
|
||||
f func(CallOptions)
|
||||
}
|
||||
|
||||
// SetOptionValue returns a call option that associates a value to an
|
||||
// option key. This can be retrieved later with CallOptions.Value.
|
||||
func SetOptionValue(key, value interface{}) CallOption {
|
||||
return CallOption{func(co CallOptions) {
|
||||
co.m[key] = value
|
||||
}}
|
||||
}
|
||||
|
||||
// An Answer is the deferred result of a client call, which is usually wrapped by a Pipeline.
|
||||
type Answer interface {
|
||||
// Struct waits until the call is finished and returns the result.
|
||||
Struct() (Struct, error)
|
||||
|
||||
// The following methods are the same as in Client except with
|
||||
// an added transform parameter -- a path to the interface to use.
|
||||
|
||||
PipelineCall(transform []PipelineOp, call *Call) Answer
|
||||
PipelineClose(transform []PipelineOp) error
|
||||
}
|
||||
|
||||
// A Pipeline is a generic wrapper for an answer.
|
||||
type Pipeline struct {
|
||||
answer Answer
|
||||
parent *Pipeline
|
||||
op PipelineOp
|
||||
}
|
||||
|
||||
// NewPipeline returns a new pipeline based on an answer.
|
||||
func NewPipeline(ans Answer) *Pipeline {
|
||||
return &Pipeline{answer: ans}
|
||||
}
|
||||
|
||||
// Answer returns the answer the pipeline is derived from.
|
||||
func (p *Pipeline) Answer() Answer {
|
||||
return p.answer
|
||||
}
|
||||
|
||||
// Transform returns the operations needed to transform the root answer
|
||||
// into the value p represents.
|
||||
func (p *Pipeline) Transform() []PipelineOp {
|
||||
n := 0
|
||||
for q := p; q.parent != nil; q = q.parent {
|
||||
n++
|
||||
}
|
||||
xform := make([]PipelineOp, n)
|
||||
for i, q := n-1, p; q.parent != nil; i, q = i-1, q.parent {
|
||||
xform[i] = q.op
|
||||
}
|
||||
return xform
|
||||
}
|
||||
|
||||
// Struct waits until the answer is resolved and returns the struct
|
||||
// this pipeline represents.
|
||||
func (p *Pipeline) Struct() (Struct, error) {
|
||||
s, err := p.answer.Struct()
|
||||
if err != nil {
|
||||
return Struct{}, err
|
||||
}
|
||||
ptr, err := TransformPtr(s.ToPtr(), p.Transform())
|
||||
if err != nil {
|
||||
return Struct{}, err
|
||||
}
|
||||
return ptr.Struct(), nil
|
||||
}
|
||||
|
||||
// Client returns the client version of p.
|
||||
func (p *Pipeline) Client() *PipelineClient {
|
||||
return (*PipelineClient)(p)
|
||||
}
|
||||
|
||||
// GetPipeline returns a derived pipeline which yields the pointer field given.
|
||||
func (p *Pipeline) GetPipeline(off uint16) *Pipeline {
|
||||
return p.GetPipelineDefault(off, nil)
|
||||
}
|
||||
|
||||
// GetPipelineDefault returns a derived pipeline which yields the pointer field given,
|
||||
// defaulting to the value given.
|
||||
func (p *Pipeline) GetPipelineDefault(off uint16, def []byte) *Pipeline {
|
||||
return &Pipeline{
|
||||
answer: p.answer,
|
||||
parent: p,
|
||||
op: PipelineOp{
|
||||
Field: off,
|
||||
DefaultValue: def,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// PipelineClient implements Client by calling to the pipeline's answer.
|
||||
type PipelineClient Pipeline
|
||||
|
||||
func (pc *PipelineClient) transform() []PipelineOp {
|
||||
return (*Pipeline)(pc).Transform()
|
||||
}
|
||||
|
||||
// Call calls Answer.PipelineCall with the pipeline's transform.
|
||||
func (pc *PipelineClient) Call(call *Call) Answer {
|
||||
return pc.answer.PipelineCall(pc.transform(), call)
|
||||
}
|
||||
|
||||
// Close calls Answer.PipelineClose with the pipeline's transform.
|
||||
func (pc *PipelineClient) Close() error {
|
||||
return pc.answer.PipelineClose(pc.transform())
|
||||
}
|
||||
|
||||
// A PipelineOp describes a step in transforming a pipeline.
|
||||
// It maps closely with the PromisedAnswer.Op struct in rpc.capnp.
|
||||
type PipelineOp struct {
|
||||
Field uint16
|
||||
DefaultValue []byte
|
||||
}
|
||||
|
||||
// String returns a human-readable description of op.
|
||||
func (op PipelineOp) String() string {
|
||||
s := make([]byte, 0, 32)
|
||||
s = append(s, "get field "...)
|
||||
s = strconv.AppendInt(s, int64(op.Field), 10)
|
||||
if op.DefaultValue == nil {
|
||||
return string(s)
|
||||
}
|
||||
s = append(s, " with default"...)
|
||||
return string(s)
|
||||
}
|
||||
|
||||
// A Method identifies a method along with an optional human-readable
|
||||
// description of the method.
|
||||
type Method struct {
|
||||
InterfaceID uint64
|
||||
MethodID uint16
|
||||
|
||||
// Canonical name of the interface. May be empty.
|
||||
InterfaceName string
|
||||
// Method name as it appears in the schema. May be empty.
|
||||
MethodName string
|
||||
}
|
||||
|
||||
// String returns a formatted string containing the interface name or
|
||||
// the method name if present, otherwise it uses the raw IDs.
|
||||
// This is suitable for use in error messages and logs.
|
||||
func (m *Method) String() string {
|
||||
buf := make([]byte, 0, 128)
|
||||
if m.InterfaceName == "" {
|
||||
buf = append(buf, '@', '0', 'x')
|
||||
buf = strconv.AppendUint(buf, m.InterfaceID, 16)
|
||||
} else {
|
||||
buf = append(buf, m.InterfaceName...)
|
||||
}
|
||||
buf = append(buf, '.')
|
||||
if m.MethodName == "" {
|
||||
buf = append(buf, '@')
|
||||
buf = strconv.AppendUint(buf, uint64(m.MethodID), 10)
|
||||
} else {
|
||||
buf = append(buf, m.MethodName...)
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
// Transform applies a sequence of pipeline operations to a pointer
|
||||
// and returns the result.
|
||||
//
|
||||
// Deprecated: Use TransformPtr.
|
||||
func Transform(p Pointer, transform []PipelineOp) (Pointer, error) {
|
||||
pp, err := TransformPtr(toPtr(p), transform)
|
||||
return pp.toPointer(), err
|
||||
}
|
||||
|
||||
// TransformPtr applies a sequence of pipeline operations to a pointer
|
||||
// and returns the result.
|
||||
func TransformPtr(p Ptr, transform []PipelineOp) (Ptr, error) {
|
||||
n := len(transform)
|
||||
if n == 0 {
|
||||
return p, nil
|
||||
}
|
||||
s := p.Struct()
|
||||
for _, op := range transform[:n-1] {
|
||||
field, err := s.Ptr(op.Field)
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
s, err = field.StructDefault(op.DefaultValue)
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
}
|
||||
op := transform[n-1]
|
||||
p, err := s.Ptr(op.Field)
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
if op.DefaultValue != nil {
|
||||
p, err = p.Default(op.DefaultValue)
|
||||
}
|
||||
return p, err
|
||||
}
|
||||
|
||||
type immediateAnswer struct {
|
||||
s Struct
|
||||
}
|
||||
|
||||
// ImmediateAnswer returns an Answer that accesses s.
|
||||
func ImmediateAnswer(s Struct) Answer {
|
||||
return immediateAnswer{s}
|
||||
}
|
||||
|
||||
func (ans immediateAnswer) Struct() (Struct, error) {
|
||||
return ans.s, nil
|
||||
}
|
||||
|
||||
func (ans immediateAnswer) findClient(transform []PipelineOp) Client {
|
||||
p, err := TransformPtr(ans.s.ToPtr(), transform)
|
||||
if err != nil {
|
||||
return ErrorClient(err)
|
||||
}
|
||||
return p.Interface().Client()
|
||||
}
|
||||
|
||||
func (ans immediateAnswer) PipelineCall(transform []PipelineOp, call *Call) Answer {
|
||||
c := ans.findClient(transform)
|
||||
if c == nil {
|
||||
return ErrorAnswer(ErrNullClient)
|
||||
}
|
||||
return c.Call(call)
|
||||
}
|
||||
|
||||
func (ans immediateAnswer) PipelineClose(transform []PipelineOp) error {
|
||||
c := ans.findClient(transform)
|
||||
if c == nil {
|
||||
return ErrNullClient
|
||||
}
|
||||
return c.Close()
|
||||
}
|
||||
|
||||
type errorAnswer struct {
|
||||
e error
|
||||
}
|
||||
|
||||
// ErrorAnswer returns a Answer that always returns error e.
|
||||
func ErrorAnswer(e error) Answer {
|
||||
return errorAnswer{e}
|
||||
}
|
||||
|
||||
func (ans errorAnswer) Struct() (Struct, error) {
|
||||
return Struct{}, ans.e
|
||||
}
|
||||
|
||||
func (ans errorAnswer) PipelineCall([]PipelineOp, *Call) Answer {
|
||||
return ans
|
||||
}
|
||||
|
||||
func (ans errorAnswer) PipelineClose([]PipelineOp) error {
|
||||
return ans.e
|
||||
}
|
||||
|
||||
// IsFixedAnswer reports whether an answer was created by
|
||||
// ImmediateAnswer or ErrorAnswer.
|
||||
func IsFixedAnswer(ans Answer) bool {
|
||||
switch ans.(type) {
|
||||
case immediateAnswer:
|
||||
return true
|
||||
case errorAnswer:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type errorClient struct {
|
||||
e error
|
||||
}
|
||||
|
||||
// ErrorClient returns a Client that always returns error e.
|
||||
func ErrorClient(e error) Client {
|
||||
return errorClient{e}
|
||||
}
|
||||
|
||||
func (ec errorClient) Call(*Call) Answer {
|
||||
return ErrorAnswer(ec.e)
|
||||
}
|
||||
|
||||
func (ec errorClient) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsErrorClient reports whether c was created with ErrorClient.
|
||||
func IsErrorClient(c Client) bool {
|
||||
_, ok := c.(errorClient)
|
||||
return ok
|
||||
}
|
||||
|
||||
// MethodError is an error on an associated method.
|
||||
type MethodError struct {
|
||||
Method *Method
|
||||
Err error
|
||||
}
|
||||
|
||||
// Error returns the method name concatenated with the error string.
|
||||
func (e *MethodError) Error() string {
|
||||
return e.Method.String() + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
// ErrUnimplemented is the error returned when a method is called on
|
||||
// a server that does not implement the method.
|
||||
var ErrUnimplemented = errors.New("capnp: method not implemented")
|
||||
|
||||
// IsUnimplemented reports whether e indicates an unimplemented method error.
|
||||
func IsUnimplemented(e error) bool {
|
||||
if me, ok := e.(*MethodError); ok {
|
||||
e = me.Err
|
||||
}
|
||||
return e == ErrUnimplemented
|
||||
}
|
280
vendor/zombiezen.com/go/capnproto2/capability_test.go
generated
vendored
Normal file
280
vendor/zombiezen.com/go/capnproto2/capability_test.go
generated
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
package capnp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestToInterface(t *testing.T) {
|
||||
_, seg, err := NewMessage(SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tests := []struct {
|
||||
ptr Pointer
|
||||
in Interface
|
||||
}{
|
||||
{nil, Interface{}},
|
||||
{Struct{}, Interface{}},
|
||||
{Struct{seg: seg, off: 0, depthLimit: maxDepth}, Interface{}},
|
||||
{Interface{}, Interface{}},
|
||||
{Interface{seg, 42}, Interface{seg, 42}},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if in := ToInterface(test.ptr); in != test.in {
|
||||
t.Errorf("ToInterface(%#v) = %#v; want %#v", test.ptr, in, test.in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterface_value(t *testing.T) {
|
||||
_, seg, err := NewMessage(SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tests := []struct {
|
||||
in Interface
|
||||
val rawPointer
|
||||
}{
|
||||
{Interface{}, 0},
|
||||
{NewInterface(seg, 0), 0x0000000000000003},
|
||||
{NewInterface(seg, 0xdeadbeef), 0xdeadbeef00000003},
|
||||
}
|
||||
for _, test := range tests {
|
||||
for paddr := Address(0); paddr < 16; paddr++ {
|
||||
if val := test.in.value(paddr); val != test.val {
|
||||
t.Errorf("Interface{seg: %p, cap: %d}.value(%v) = %v; want %v", test.in.seg, test.in.cap, paddr, val, test.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransform(t *testing.T) {
|
||||
_, s, err := NewMessage(SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := NewStruct(s, ObjectSize{PointerCount: 2})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
a, err := NewStruct(s, ObjectSize{DataSize: 8, PointerCount: 1})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root.SetPointer(1, a)
|
||||
a.SetUint64(0, 1)
|
||||
b, err := NewStruct(s, ObjectSize{DataSize: 8})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b.SetUint64(0, 2)
|
||||
a.SetPointer(0, b)
|
||||
|
||||
dmsg, d, err := NewMessage(SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
da, err := NewStruct(d, ObjectSize{DataSize: 8, PointerCount: 1})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := dmsg.SetRoot(da); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
da.SetUint64(0, 56)
|
||||
db, err := NewStruct(d, ObjectSize{DataSize: 8})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
db.SetUint64(0, 78)
|
||||
da.SetPointer(0, db)
|
||||
|
||||
tests := []struct {
|
||||
p Pointer
|
||||
transform []PipelineOp
|
||||
out Pointer
|
||||
}{
|
||||
{
|
||||
root,
|
||||
nil,
|
||||
root,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{},
|
||||
root,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 0},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 0, DefaultValue: mustMarshal(t, dmsg)},
|
||||
},
|
||||
da,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 1},
|
||||
},
|
||||
a,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 1, DefaultValue: mustMarshal(t, dmsg)},
|
||||
},
|
||||
a,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 1},
|
||||
{Field: 0},
|
||||
},
|
||||
b,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 0},
|
||||
{Field: 0},
|
||||
},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 0, DefaultValue: mustMarshal(t, dmsg)},
|
||||
{Field: 0},
|
||||
},
|
||||
db,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 0},
|
||||
{Field: 0, DefaultValue: mustMarshal(t, dmsg)},
|
||||
},
|
||||
da,
|
||||
},
|
||||
{
|
||||
root,
|
||||
[]PipelineOp{
|
||||
{Field: 0, DefaultValue: mustMarshal(t, dmsg)},
|
||||
{Field: 1, DefaultValue: mustMarshal(t, dmsg)},
|
||||
},
|
||||
da,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
out, err := Transform(test.p, test.transform)
|
||||
if !deepPointerEqual(out, test.out) {
|
||||
t.Errorf("Transform(%+v, %v) = %+v; want %+v", test.p, test.transform, out, test.out)
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("Transform(%+v, %v) error: %v", test.p, test.transform, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethodString(t *testing.T) {
|
||||
tests := []struct {
|
||||
m *Method
|
||||
s string
|
||||
}{
|
||||
{
|
||||
&Method{
|
||||
InterfaceID: 0x8e5322c1e9282534,
|
||||
MethodID: 1,
|
||||
},
|
||||
"@0x8e5322c1e9282534.@1",
|
||||
},
|
||||
{
|
||||
&Method{
|
||||
InterfaceID: 0x8e5322c1e9282534,
|
||||
MethodID: 1,
|
||||
InterfaceName: "aircraftlib:Echo",
|
||||
MethodName: "foo",
|
||||
},
|
||||
"aircraftlib:Echo.foo",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if s := test.m.String(); s != test.s {
|
||||
t.Errorf("%#v.String() = %q; want %q", test.m, s, test.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipelineOpString(t *testing.T) {
|
||||
tests := []struct {
|
||||
op PipelineOp
|
||||
s string
|
||||
}{
|
||||
{
|
||||
PipelineOp{Field: 4},
|
||||
"get field 4",
|
||||
},
|
||||
{
|
||||
PipelineOp{Field: 4, DefaultValue: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
"get field 4 with default",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if s := test.op.String(); s != test.s {
|
||||
t.Errorf("%#v.String() = %q; want %q", test.op, s, test.s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsUnimplemented(t *testing.T) {
|
||||
tests := []struct {
|
||||
e error
|
||||
ok bool
|
||||
}{
|
||||
{nil, false},
|
||||
{ErrUnimplemented, true},
|
||||
{errors.New("foo"), false},
|
||||
{&MethodError{Method: new(Method), Err: ErrUnimplemented}, true},
|
||||
{&MethodError{Method: new(Method), Err: errors.New("foo")}, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if ok := IsUnimplemented(test.e); ok != test.ok {
|
||||
t.Errorf("IsUnimplemented(%#v) = %t; want %t", test.e, ok, test.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mustMarshal(t *testing.T, msg *Message) []byte {
|
||||
data, err := msg.Marshal()
|
||||
if err != nil {
|
||||
t.Fatal("Marshal:", err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func deepPointerEqual(a, b Pointer) bool {
|
||||
if a == nil && b == nil {
|
||||
return true
|
||||
}
|
||||
if a == nil || b == nil {
|
||||
return false
|
||||
}
|
||||
msgA, _, _ := NewMessage(SingleSegment(nil))
|
||||
msgA.SetRoot(a)
|
||||
abytes, _ := msgA.Marshal()
|
||||
msgB, _, _ := NewMessage(SingleSegment(nil))
|
||||
msgB.SetRoot(b)
|
||||
bbytes, _ := msgB.Marshal()
|
||||
return bytes.Equal(abytes, bbytes)
|
||||
}
|
427
vendor/zombiezen.com/go/capnproto2/capn.go
generated
vendored
Normal file
427
vendor/zombiezen.com/go/capnproto2/capn.go
generated
vendored
Normal file
@@ -0,0 +1,427 @@
|
||||
package capnp
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// A SegmentID is a numeric identifier for a Segment.
|
||||
type SegmentID uint32
|
||||
|
||||
// A Segment is an allocation arena for Cap'n Proto objects.
|
||||
// It is part of a Message, which can contain other segments that
|
||||
// reference each other.
|
||||
type Segment struct {
|
||||
msg *Message
|
||||
id SegmentID
|
||||
data []byte
|
||||
}
|
||||
|
||||
// Message returns the message that contains s.
|
||||
func (s *Segment) Message() *Message {
|
||||
return s.msg
|
||||
}
|
||||
|
||||
// ID returns the segment's ID.
|
||||
func (s *Segment) ID() SegmentID {
|
||||
return s.id
|
||||
}
|
||||
|
||||
// Data returns the raw byte slice for the segment.
|
||||
func (s *Segment) Data() []byte {
|
||||
return s.data
|
||||
}
|
||||
|
||||
func (s *Segment) inBounds(addr Address) bool {
|
||||
return addr < Address(len(s.data))
|
||||
}
|
||||
|
||||
func (s *Segment) regionInBounds(base Address, sz Size) bool {
|
||||
end, ok := base.addSize(sz)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return end <= Address(len(s.data))
|
||||
}
|
||||
|
||||
// slice returns the segment of data from base to base+sz.
|
||||
func (s *Segment) slice(base Address, sz Size) []byte {
|
||||
// Bounds check should have happened before calling slice.
|
||||
return s.data[base : base+Address(sz)]
|
||||
}
|
||||
|
||||
func (s *Segment) readUint8(addr Address) uint8 {
|
||||
return s.slice(addr, 1)[0]
|
||||
}
|
||||
|
||||
func (s *Segment) readUint16(addr Address) uint16 {
|
||||
return binary.LittleEndian.Uint16(s.slice(addr, 2))
|
||||
}
|
||||
|
||||
func (s *Segment) readUint32(addr Address) uint32 {
|
||||
return binary.LittleEndian.Uint32(s.slice(addr, 4))
|
||||
}
|
||||
|
||||
func (s *Segment) readUint64(addr Address) uint64 {
|
||||
return binary.LittleEndian.Uint64(s.slice(addr, 8))
|
||||
}
|
||||
|
||||
func (s *Segment) readRawPointer(addr Address) rawPointer {
|
||||
return rawPointer(s.readUint64(addr))
|
||||
}
|
||||
|
||||
func (s *Segment) writeUint8(addr Address, val uint8) {
|
||||
s.slice(addr, 1)[0] = val
|
||||
}
|
||||
|
||||
func (s *Segment) writeUint16(addr Address, val uint16) {
|
||||
binary.LittleEndian.PutUint16(s.slice(addr, 2), val)
|
||||
}
|
||||
|
||||
func (s *Segment) writeUint32(addr Address, val uint32) {
|
||||
binary.LittleEndian.PutUint32(s.slice(addr, 4), val)
|
||||
}
|
||||
|
||||
func (s *Segment) writeUint64(addr Address, val uint64) {
|
||||
binary.LittleEndian.PutUint64(s.slice(addr, 8), val)
|
||||
}
|
||||
|
||||
func (s *Segment) writeRawPointer(addr Address, val rawPointer) {
|
||||
s.writeUint64(addr, uint64(val))
|
||||
}
|
||||
|
||||
// root returns a 1-element pointer list that references the first word
|
||||
// in the segment. This only makes sense to call on the first segment
|
||||
// in a message.
|
||||
func (s *Segment) root() PointerList {
|
||||
sz := ObjectSize{PointerCount: 1}
|
||||
if !s.regionInBounds(0, sz.totalSize()) {
|
||||
return PointerList{}
|
||||
}
|
||||
return PointerList{List{
|
||||
seg: s,
|
||||
length: 1,
|
||||
size: sz,
|
||||
depthLimit: s.msg.depthLimit(),
|
||||
}}
|
||||
}
|
||||
|
||||
func (s *Segment) lookupSegment(id SegmentID) (*Segment, error) {
|
||||
if s.id == id {
|
||||
return s, nil
|
||||
}
|
||||
return s.msg.Segment(id)
|
||||
}
|
||||
|
||||
func (s *Segment) readPtr(paddr Address, depthLimit uint) (ptr Ptr, err error) {
|
||||
s, base, val, err := s.resolveFarPointer(paddr)
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
if val == 0 {
|
||||
return Ptr{}, nil
|
||||
}
|
||||
if depthLimit == 0 {
|
||||
return Ptr{}, errDepthLimit
|
||||
}
|
||||
switch val.pointerType() {
|
||||
case structPointer:
|
||||
sp, err := s.readStructPtr(base, val)
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
if !s.msg.ReadLimiter().canRead(sp.readSize()) {
|
||||
return Ptr{}, errReadLimit
|
||||
}
|
||||
sp.depthLimit = depthLimit - 1
|
||||
return sp.ToPtr(), nil
|
||||
case listPointer:
|
||||
lp, err := s.readListPtr(base, val)
|
||||
if err != nil {
|
||||
return Ptr{}, err
|
||||
}
|
||||
if !s.msg.ReadLimiter().canRead(lp.readSize()) {
|
||||
return Ptr{}, errReadLimit
|
||||
}
|
||||
lp.depthLimit = depthLimit - 1
|
||||
return lp.ToPtr(), nil
|
||||
case otherPointer:
|
||||
if val.otherPointerType() != 0 {
|
||||
return Ptr{}, errOtherPointer
|
||||
}
|
||||
return Interface{
|
||||
seg: s,
|
||||
cap: val.capabilityIndex(),
|
||||
}.ToPtr(), nil
|
||||
default:
|
||||
// Only other types are far pointers.
|
||||
return Ptr{}, errBadLandingPad
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Segment) readStructPtr(base Address, val rawPointer) (Struct, error) {
|
||||
addr, ok := val.offset().resolve(base)
|
||||
if !ok {
|
||||
return Struct{}, errPointerAddress
|
||||
}
|
||||
sz := val.structSize()
|
||||
if !s.regionInBounds(addr, sz.totalSize()) {
|
||||
return Struct{}, errPointerAddress
|
||||
}
|
||||
return Struct{
|
||||
seg: s,
|
||||
off: addr,
|
||||
size: sz,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Segment) readListPtr(base Address, val rawPointer) (List, error) {
|
||||
addr, ok := val.offset().resolve(base)
|
||||
if !ok {
|
||||
return List{}, errPointerAddress
|
||||
}
|
||||
lsize, ok := val.totalListSize()
|
||||
if !ok {
|
||||
return List{}, errOverflow
|
||||
}
|
||||
if !s.regionInBounds(addr, lsize) {
|
||||
return List{}, errPointerAddress
|
||||
}
|
||||
lt := val.listType()
|
||||
if lt == compositeList {
|
||||
hdr := s.readRawPointer(addr)
|
||||
var ok bool
|
||||
addr, ok = addr.addSize(wordSize)
|
||||
if !ok {
|
||||
return List{}, errOverflow
|
||||
}
|
||||
if hdr.pointerType() != structPointer {
|
||||
return List{}, errBadTag
|
||||
}
|
||||
sz := hdr.structSize()
|
||||
n := int32(hdr.offset())
|
||||
// TODO(light): check that this has the same end address
|
||||
if tsize, ok := sz.totalSize().times(n); !ok {
|
||||
return List{}, errOverflow
|
||||
} else if !s.regionInBounds(addr, tsize) {
|
||||
return List{}, errPointerAddress
|
||||
}
|
||||
return List{
|
||||
seg: s,
|
||||
size: sz,
|
||||
off: addr,
|
||||
length: n,
|
||||
flags: isCompositeList,
|
||||
}, nil
|
||||
}
|
||||
if lt == bit1List {
|
||||
return List{
|
||||
seg: s,
|
||||
off: addr,
|
||||
length: val.numListElements(),
|
||||
flags: isBitList,
|
||||
}, nil
|
||||
}
|
||||
return List{
|
||||
seg: s,
|
||||
size: val.elementSize(),
|
||||
off: addr,
|
||||
length: val.numListElements(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Segment) resolveFarPointer(paddr Address) (dst *Segment, base Address, resolved rawPointer, err error) {
|
||||
// Encoding details at https://capnproto.org/encoding.html#inter-segment-pointers
|
||||
|
||||
val := s.readRawPointer(paddr)
|
||||
switch val.pointerType() {
|
||||
case doubleFarPointer:
|
||||
padSeg, err := s.lookupSegment(val.farSegment())
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
padAddr := val.farAddress()
|
||||
if !padSeg.regionInBounds(padAddr, wordSize*2) {
|
||||
return nil, 0, 0, errPointerAddress
|
||||
}
|
||||
far := padSeg.readRawPointer(padAddr)
|
||||
if far.pointerType() != farPointer {
|
||||
return nil, 0, 0, errBadLandingPad
|
||||
}
|
||||
tagAddr, ok := padAddr.addSize(wordSize)
|
||||
if !ok {
|
||||
return nil, 0, 0, errOverflow
|
||||
}
|
||||
tag := padSeg.readRawPointer(tagAddr)
|
||||
if pt := tag.pointerType(); (pt != structPointer && pt != listPointer) || tag.offset() != 0 {
|
||||
return nil, 0, 0, errBadLandingPad
|
||||
}
|
||||
if dst, err = s.lookupSegment(far.farSegment()); err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
return dst, 0, landingPadNearPointer(far, tag), nil
|
||||
case farPointer:
|
||||
var err error
|
||||
dst, err = s.lookupSegment(val.farSegment())
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
padAddr := val.farAddress()
|
||||
if !dst.regionInBounds(padAddr, wordSize) {
|
||||
return nil, 0, 0, errPointerAddress
|
||||
}
|
||||
var ok bool
|
||||
base, ok = padAddr.addSize(wordSize)
|
||||
if !ok {
|
||||
return nil, 0, 0, errOverflow
|
||||
}
|
||||
return dst, base, dst.readRawPointer(padAddr), nil
|
||||
default:
|
||||
var ok bool
|
||||
base, ok = paddr.addSize(wordSize)
|
||||
if !ok {
|
||||
return nil, 0, 0, errOverflow
|
||||
}
|
||||
return s, base, val, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Segment) writePtr(off Address, src Ptr, forceCopy bool) error {
|
||||
if !src.IsValid() {
|
||||
s.writeRawPointer(off, 0)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Copy src, if needed, and process pointers where placement is
|
||||
// irrelevant (capabilities and zero-sized structs).
|
||||
var srcAddr Address
|
||||
var srcRaw rawPointer
|
||||
switch src.flags.ptrType() {
|
||||
case structPtrType:
|
||||
st := src.Struct()
|
||||
if st.size.isZero() {
|
||||
// Zero-sized structs should always be encoded with offset -1 in
|
||||
// order to avoid conflating with null. No allocation needed.
|
||||
s.writeRawPointer(off, rawStructPointer(-1, ObjectSize{}))
|
||||
return nil
|
||||
}
|
||||
if forceCopy || src.seg.msg != s.msg || st.flags&isListMember != 0 {
|
||||
newSeg, newAddr, err := alloc(s, st.size.totalSize())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dst := Struct{
|
||||
seg: newSeg,
|
||||
off: newAddr,
|
||||
size: st.size,
|
||||
depthLimit: maxDepth,
|
||||
// clear flags
|
||||
}
|
||||
if err := copyStruct(dst, st); err != nil {
|
||||
return err
|
||||
}
|
||||
st = dst
|
||||
src = dst.ToPtr()
|
||||
}
|
||||
srcAddr = st.off
|
||||
srcRaw = rawStructPointer(0, st.size)
|
||||
case listPtrType:
|
||||
l := src.List()
|
||||
if forceCopy || src.seg.msg != s.msg {
|
||||
sz := l.allocSize()
|
||||
newSeg, newAddr, err := alloc(s, sz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dst := List{
|
||||
seg: newSeg,
|
||||
off: newAddr,
|
||||
length: l.length,
|
||||
size: l.size,
|
||||
flags: l.flags,
|
||||
depthLimit: maxDepth,
|
||||
}
|
||||
if dst.flags&isCompositeList != 0 {
|
||||
// Copy tag word
|
||||
newSeg.writeRawPointer(newAddr, l.seg.readRawPointer(l.off-Address(wordSize)))
|
||||
var ok bool
|
||||
dst.off, ok = dst.off.addSize(wordSize)
|
||||
if !ok {
|
||||
return errOverflow
|
||||
}
|
||||
sz -= wordSize
|
||||
}
|
||||
if dst.flags&isBitList != 0 || dst.size.PointerCount == 0 {
|
||||
end, _ := l.off.addSize(sz) // list was already validated
|
||||
copy(newSeg.data[dst.off:], l.seg.data[l.off:end])
|
||||
} else {
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
err := copyStruct(dst.Struct(i), l.Struct(i))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
l = dst
|
||||
src = dst.ToPtr()
|
||||
}
|
||||
srcAddr = l.off
|
||||
if l.flags&isCompositeList != 0 {
|
||||
srcAddr -= Address(wordSize)
|
||||
}
|
||||
srcRaw = l.raw()
|
||||
case interfacePtrType:
|
||||
i := src.Interface()
|
||||
if src.seg.msg != s.msg {
|
||||
c := s.msg.AddCap(i.Client())
|
||||
i = NewInterface(s, c)
|
||||
}
|
||||
s.writeRawPointer(off, i.value(off))
|
||||
return nil
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
switch {
|
||||
case src.seg == s:
|
||||
// Common case: src is in same segment as pointer.
|
||||
// Use a near pointer.
|
||||
s.writeRawPointer(off, srcRaw.withOffset(nearPointerOffset(off, srcAddr)))
|
||||
return nil
|
||||
case hasCapacity(src.seg.data, wordSize):
|
||||
// Enough room adjacent to src to write a far pointer landing pad.
|
||||
_, padAddr, _ := alloc(src.seg, wordSize)
|
||||
src.seg.writeRawPointer(padAddr, srcRaw.withOffset(nearPointerOffset(padAddr, srcAddr)))
|
||||
s.writeRawPointer(off, rawFarPointer(src.seg.id, padAddr))
|
||||
return nil
|
||||
default:
|
||||
// Not enough room for a landing pad, need to use a double-far pointer.
|
||||
padSeg, padAddr, err := alloc(s, wordSize*2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
padSeg.writeRawPointer(padAddr, rawFarPointer(src.seg.id, srcAddr))
|
||||
padSeg.writeRawPointer(padAddr+Address(wordSize), srcRaw)
|
||||
s.writeRawPointer(off, rawDoubleFarPointer(padSeg.id, padAddr))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
errPointerAddress = errors.New("capnp: invalid pointer address")
|
||||
errBadLandingPad = errors.New("capnp: invalid far pointer landing pad")
|
||||
errBadTag = errors.New("capnp: invalid tag word")
|
||||
errOtherPointer = errors.New("capnp: unknown pointer type")
|
||||
errObjectSize = errors.New("capnp: invalid object size")
|
||||
errElementSize = errors.New("capnp: mismatched list element size")
|
||||
errReadLimit = errors.New("capnp: read traversal limit reached")
|
||||
errDepthLimit = errors.New("capnp: depth limit reached")
|
||||
)
|
||||
|
||||
var (
|
||||
errOverflow = errors.New("capnp: address or size overflow")
|
||||
errOutOfBounds = errors.New("capnp: address out of bounds")
|
||||
errCopyDepth = errors.New("capnp: copy depth too large")
|
||||
errOverlap = errors.New("capnp: overlapping data on copy")
|
||||
errListSize = errors.New("capnp: invalid list size")
|
||||
)
|
742
vendor/zombiezen.com/go/capnproto2/capn_test.go
generated
vendored
Normal file
742
vendor/zombiezen.com/go/capnproto2/capn_test.go
generated
vendored
Normal file
@@ -0,0 +1,742 @@
|
||||
package capnp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSegmentInBounds(t *testing.T) {
|
||||
tests := []struct {
|
||||
n int
|
||||
addr Address
|
||||
ok bool
|
||||
}{
|
||||
{0, 0, false},
|
||||
{0, 1, false},
|
||||
{0, 2, false},
|
||||
{1, 0, true},
|
||||
{1, 1, false},
|
||||
{1, 2, false},
|
||||
{2, 0, true},
|
||||
{2, 1, true},
|
||||
{2, 2, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
seg := &Segment{data: make([]byte, test.n)}
|
||||
if ok := seg.inBounds(test.addr); ok != test.ok {
|
||||
t.Errorf("&Segment{data: make([]byte, %d)}.inBounds(%#v) = %t; want %t", test.n, test.addr, ok, test.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentRegionInBounds(t *testing.T) {
|
||||
tests := []struct {
|
||||
n int
|
||||
addr Address
|
||||
sz Size
|
||||
ok bool
|
||||
}{
|
||||
{0, 0, 0, true}, // zero-sized region <= len is okay
|
||||
{0, 0, 1, false},
|
||||
{0, 1, 0, false},
|
||||
{0, 1, 1, false},
|
||||
{1, 0, 0, true},
|
||||
{1, 0, 1, true},
|
||||
{1, 1, 0, true},
|
||||
{1, 1, 1, false},
|
||||
{2, 0, 0, true},
|
||||
{2, 0, 1, true},
|
||||
{2, 0, 2, true},
|
||||
{2, 0, 3, false},
|
||||
{2, 1, 0, true},
|
||||
{2, 1, 1, true},
|
||||
{2, 1, 2, false},
|
||||
{2, 1, 3, false},
|
||||
{2, 2, 0, true},
|
||||
{2, 2, 1, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
seg := &Segment{data: make([]byte, test.n)}
|
||||
if ok := seg.regionInBounds(test.addr, test.sz); ok != test.ok {
|
||||
t.Errorf("&Segment{data: make([]byte, %d)}.regionInBounds(%#v, %#v) = %t; want %t", test.n, test.addr, test.sz, ok, test.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentReadUint8(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint8
|
||||
panics bool
|
||||
}{
|
||||
{data: []byte{}, addr: 0, panics: true},
|
||||
{data: []byte{42}, addr: 0, val: 42},
|
||||
{data: []byte{42}, addr: 1, panics: true},
|
||||
{data: []byte{1, 42, 2}, addr: 0, val: 1},
|
||||
{data: []byte{1, 42, 2}, addr: 1, val: 42},
|
||||
{data: []byte{1, 42, 2}, addr: 2, val: 2},
|
||||
{data: []byte{1, 42, 2}, addr: 3, panics: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
seg := &Segment{data: test.data}
|
||||
var val uint8
|
||||
err := catchPanic(func() {
|
||||
val = seg.readUint8(test.addr)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint8(%v) unexpected panic: %v", test.data, test.addr, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint8(%v) did not panic as expected", test.data, test.addr)
|
||||
continue
|
||||
}
|
||||
if val != test.val {
|
||||
t.Errorf("&Segment{data: % x}.readUint8(%v) = %#x; want %#x", test.data, test.addr, val, test.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentReadUint16(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint16
|
||||
panics bool
|
||||
}{
|
||||
{data: []byte{}, addr: 0, panics: true},
|
||||
{data: []byte{0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00}, addr: 0, val: 0},
|
||||
{data: []byte{0x01, 0x00}, addr: 0, val: 1},
|
||||
{data: []byte{0x34, 0x12}, addr: 0, val: 0x1234},
|
||||
{data: []byte{0x34, 0x12, 0x56}, addr: 0, val: 0x1234},
|
||||
{data: []byte{0x34, 0x12, 0x56}, addr: 1, val: 0x5612},
|
||||
{data: []byte{0x34, 0x12, 0x56}, addr: 2, panics: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
seg := &Segment{data: test.data}
|
||||
var val uint16
|
||||
err := catchPanic(func() {
|
||||
val = seg.readUint16(test.addr)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint16(%v) unexpected panic: %v", test.data, test.addr, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint16(%v) did not panic as expected", test.data, test.addr)
|
||||
continue
|
||||
}
|
||||
if val != test.val {
|
||||
t.Errorf("&Segment{data: % x}.readUint16(%v) = %#x; want %#x", test.data, test.addr, val, test.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentReadUint32(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint32
|
||||
panics bool
|
||||
}{
|
||||
{data: []byte{}, addr: 0, panics: true},
|
||||
{data: []byte{0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00, 0x00}, addr: 0, val: 0},
|
||||
{data: []byte{0x78, 0x56, 0x34, 0x12}, addr: 0, val: 0x12345678},
|
||||
{data: []byte{0xff, 0x78, 0x56, 0x34, 0x12, 0xff}, addr: 1, val: 0x12345678},
|
||||
{data: []byte{0xff, 0x78, 0x56, 0x34, 0x12, 0xff}, addr: 2, val: 0xff123456},
|
||||
{data: []byte{0xff, 0x78, 0x56, 0x34, 0x12, 0xff}, addr: 3, panics: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
seg := &Segment{data: test.data}
|
||||
var val uint32
|
||||
err := catchPanic(func() {
|
||||
val = seg.readUint32(test.addr)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint32(%v) unexpected panic: %v", test.data, test.addr, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint32(%v) did not panic as expected", test.data, test.addr)
|
||||
continue
|
||||
}
|
||||
if val != test.val {
|
||||
t.Errorf("&Segment{data: % x}.readUint32(%v) = %#x; want %#x", test.data, test.addr, val, test.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentReadUint64(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint64
|
||||
panics bool
|
||||
}{
|
||||
{data: []byte{}, addr: 0, panics: true},
|
||||
{data: []byte{0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00, 0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, addr: 0, panics: true},
|
||||
{data: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, addr: 0, val: 0},
|
||||
{data: []byte{0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01}, addr: 0, val: 0x0123456789abcdef},
|
||||
{data: []byte{0xff, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff}, addr: 0, val: 0x23456789abcdefff},
|
||||
{data: []byte{0xff, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff}, addr: 1, val: 0x0123456789abcdef},
|
||||
{data: []byte{0xff, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff}, addr: 2, val: 0xff0123456789abcd},
|
||||
{data: []byte{0xff, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 0xff}, addr: 3, panics: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
seg := &Segment{data: test.data}
|
||||
var val uint64
|
||||
err := catchPanic(func() {
|
||||
val = seg.readUint64(test.addr)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint64(%v) unexpected panic: %v", test.data, test.addr, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.readUint64(%v) did not panic as expected", test.data, test.addr)
|
||||
continue
|
||||
}
|
||||
if val != test.val {
|
||||
t.Errorf("&Segment{data: % x}.readUint64(%v) = %#x; want %#x", test.data, test.addr, val, test.val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentWriteUint8(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint8
|
||||
out []byte
|
||||
panics bool
|
||||
}{
|
||||
{
|
||||
data: []byte{},
|
||||
addr: 0,
|
||||
val: 0,
|
||||
panics: true,
|
||||
},
|
||||
{
|
||||
data: []byte{1},
|
||||
addr: 0,
|
||||
val: 42,
|
||||
out: []byte{42},
|
||||
},
|
||||
{
|
||||
data: []byte{42},
|
||||
addr: 1,
|
||||
val: 1,
|
||||
panics: true,
|
||||
},
|
||||
{
|
||||
data: []byte{1, 2, 3},
|
||||
addr: 0,
|
||||
val: 0xff,
|
||||
out: []byte{0xff, 2, 3},
|
||||
},
|
||||
{
|
||||
data: []byte{1, 2, 3},
|
||||
addr: 1,
|
||||
val: 0xff,
|
||||
out: []byte{1, 0xff, 3},
|
||||
},
|
||||
{
|
||||
data: []byte{1, 2, 3},
|
||||
addr: 2,
|
||||
val: 0xff,
|
||||
out: []byte{1, 2, 0xff},
|
||||
},
|
||||
{
|
||||
data: []byte{1, 2, 3},
|
||||
addr: 3,
|
||||
val: 0xff,
|
||||
panics: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out := make([]byte, len(test.data))
|
||||
copy(out, test.data)
|
||||
seg := &Segment{data: out}
|
||||
err := catchPanic(func() {
|
||||
seg.writeUint8(test.addr, test.val)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint8(%v, %#x) unexpected panic: %v", test.data, test.addr, test.val, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint8(%v, %#x) did not panic as expected", test.data, test.addr, test.val)
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(out, test.out) {
|
||||
t.Errorf("data after &Segment{data: % x}.writeUint8(%v, %#x) = % x; want % x", test.data, test.addr, test.val, out, test.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentWriteUint16(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint16
|
||||
out []byte
|
||||
panics bool
|
||||
}{
|
||||
{
|
||||
data: []byte{},
|
||||
addr: 0,
|
||||
val: 0,
|
||||
panics: true,
|
||||
},
|
||||
{
|
||||
data: []byte{1, 2, 3, 4},
|
||||
addr: 1,
|
||||
val: 0x1234,
|
||||
out: []byte{1, 0x34, 0x12, 4},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out := make([]byte, len(test.data))
|
||||
copy(out, test.data)
|
||||
seg := &Segment{data: out}
|
||||
err := catchPanic(func() {
|
||||
seg.writeUint16(test.addr, test.val)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint16(%v, %#x) unexpected panic: %v", test.data, test.addr, test.val, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint16(%v, %#x) did not panic as expected", test.data, test.addr, test.val)
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(out, test.out) {
|
||||
t.Errorf("data after &Segment{data: % x}.writeUint16(%v, %#x) = % x; want % x", test.data, test.addr, test.val, out, test.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentWriteUint32(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint32
|
||||
out []byte
|
||||
panics bool
|
||||
}{
|
||||
{
|
||||
data: []byte{},
|
||||
addr: 0,
|
||||
val: 0,
|
||||
panics: true,
|
||||
},
|
||||
{
|
||||
data: []byte{1, 2, 3, 4, 5, 6},
|
||||
addr: 1,
|
||||
val: 0x01234567,
|
||||
out: []byte{1, 0x67, 0x45, 0x23, 0x01, 6},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out := make([]byte, len(test.data))
|
||||
copy(out, test.data)
|
||||
seg := &Segment{data: out}
|
||||
err := catchPanic(func() {
|
||||
seg.writeUint32(test.addr, test.val)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint32(%v, %#x) unexpected panic: %v", test.data, test.addr, test.val, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint32(%v, %#x) did not panic as expected", test.data, test.addr, test.val)
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(out, test.out) {
|
||||
t.Errorf("data after &Segment{data: % x}.writeUint32(%v, %#x) = % x; want % x", test.data, test.addr, test.val, out, test.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSegmentWriteUint64(t *testing.T) {
|
||||
tests := []struct {
|
||||
data []byte
|
||||
addr Address
|
||||
val uint64
|
||||
out []byte
|
||||
panics bool
|
||||
}{
|
||||
{
|
||||
data: []byte{},
|
||||
addr: 0,
|
||||
val: 0,
|
||||
panics: true,
|
||||
},
|
||||
{
|
||||
data: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
addr: 1,
|
||||
val: 0x0123456789abcdef,
|
||||
out: []byte{1, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01, 10},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out := make([]byte, len(test.data))
|
||||
copy(out, test.data)
|
||||
seg := &Segment{data: out}
|
||||
err := catchPanic(func() {
|
||||
seg.writeUint64(test.addr, test.val)
|
||||
})
|
||||
if err != nil {
|
||||
if !test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint64(%v, %#x) unexpected panic: %v", test.data, test.addr, test.val, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.panics {
|
||||
t.Errorf("&Segment{data: % x}.writeUint64(%v, %#x) did not panic as expected", test.data, test.addr, test.val)
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(out, test.out) {
|
||||
t.Errorf("data after &Segment{data: % x}.writeUint64(%v, %#x) = % x; want % x", test.data, test.addr, test.val, out, test.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetPtrCopyListMember(t *testing.T) {
|
||||
_, seg, err := NewMessage(SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal("NewMessage:", err)
|
||||
}
|
||||
root, err := NewRootStruct(seg, ObjectSize{PointerCount: 2})
|
||||
if err != nil {
|
||||
t.Fatal("NewRootStruct:", err)
|
||||
}
|
||||
plist, err := NewCompositeList(seg, ObjectSize{PointerCount: 1}, 1)
|
||||
if err != nil {
|
||||
t.Fatal("NewCompositeList:", err)
|
||||
}
|
||||
if err := root.SetPtr(0, plist.ToPtr()); err != nil {
|
||||
t.Fatal("root.SetPtr(0, plist):", err)
|
||||
}
|
||||
sub, err := NewStruct(seg, ObjectSize{DataSize: 8})
|
||||
if err != nil {
|
||||
t.Fatal("NewStruct:", err)
|
||||
}
|
||||
sub.SetUint64(0, 42)
|
||||
pl0 := plist.Struct(0)
|
||||
if err := pl0.SetPtr(0, sub.ToPtr()); err != nil {
|
||||
t.Fatal("pl0.SetPtr(0, sub.ToPtr()):", err)
|
||||
}
|
||||
|
||||
if err := root.SetPtr(1, pl0.ToPtr()); err != nil {
|
||||
t.Error("root.SetPtr(1, pl0):", err)
|
||||
}
|
||||
|
||||
p1, err := root.Ptr(1)
|
||||
if err != nil {
|
||||
t.Error("root.Ptr(1):", err)
|
||||
}
|
||||
s1 := p1.Struct()
|
||||
if !s1.IsValid() {
|
||||
t.Error("root.Ptr(1) is not a valid struct")
|
||||
}
|
||||
if SamePtr(s1.ToPtr(), pl0.ToPtr()) {
|
||||
t.Error("list member not copied; points to same object")
|
||||
}
|
||||
s1p0, err := s1.Ptr(0)
|
||||
if err != nil {
|
||||
t.Error("root.Ptr(1).Struct().Ptr(0):", err)
|
||||
}
|
||||
s1s0 := s1p0.Struct()
|
||||
if !s1s0.IsValid() {
|
||||
t.Error("root.Ptr(1).Struct().Ptr(0) is not a valid struct")
|
||||
}
|
||||
if SamePtr(s1s0.ToPtr(), sub.ToPtr()) {
|
||||
t.Error("sub-object not copied; points to same object")
|
||||
}
|
||||
if got := s1s0.Uint64(0); got != 42 {
|
||||
t.Errorf("sub-object data = %d; want 42", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetPtrToZeroSizeStruct(t *testing.T) {
|
||||
_, seg, err := NewMessage(SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal("NewMessage:", err)
|
||||
}
|
||||
root, err := NewRootStruct(seg, ObjectSize{PointerCount: 1})
|
||||
if err != nil {
|
||||
t.Fatal("NewRootStruct:", err)
|
||||
}
|
||||
sub, err := NewStruct(seg, ObjectSize{})
|
||||
if err != nil {
|
||||
t.Fatal("NewStruct:", err)
|
||||
}
|
||||
if err := root.SetPtr(0, sub.ToPtr()); err != nil {
|
||||
t.Fatal("root.SetPtr(0, sub.ToPtr()):", err)
|
||||
}
|
||||
ptrSlice := seg.Data()[root.off : root.off+8]
|
||||
want := []byte{0xfc, 0xff, 0xff, 0xff, 0, 0, 0, 0}
|
||||
if !bytes.Equal(ptrSlice, want) {
|
||||
t.Errorf("SetPtr wrote % 02x; want % 02x", ptrSlice, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadFarPointers(t *testing.T) {
|
||||
msg := &Message{
|
||||
// an rpc.capnp Message
|
||||
Arena: MultiSegment([][]byte{
|
||||
// Segment 0
|
||||
{
|
||||
// Double-far pointer: segment 2, offset 0
|
||||
0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
},
|
||||
// Segment 1
|
||||
{
|
||||
// (Root) Struct data section
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Struct pointer section
|
||||
// Double-far pointer: segment 4, offset 0
|
||||
0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
},
|
||||
// Segment 2
|
||||
{
|
||||
// Far pointer landing pad: segment 1, offset 0
|
||||
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
// Far pointer landing pad tag word: struct with 1 word data and 1 pointer
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
},
|
||||
// Segment 3
|
||||
{
|
||||
// (Root>0) Struct data section
|
||||
0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
|
||||
0xaa, 0x70, 0x65, 0x21, 0xd7, 0x7b, 0x31, 0xa7,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Struct pointer section
|
||||
// Far pointer: segment 4, offset 4
|
||||
0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
// Far pointer: segment 4, offset 7
|
||||
0x3a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
// Null
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
// Segment 4
|
||||
{
|
||||
// Far pointer landing pad: segment 3, offset 0
|
||||
0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
// Far pointer landing pad tag word: struct with 3 word data and 3 pointer
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
// (Root>0>0) Struct data section
|
||||
0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Struct pointer section
|
||||
// Null
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Far pointer landing pad: struct pointer: offset -3, 1 word data, 1 pointer
|
||||
0xf4, 0xff, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00,
|
||||
// (Root>0>1) Struct pointer section
|
||||
// Struct pointer: offset 2, 1 word data
|
||||
0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
// Null
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Far pointer landing pad: struct pointer: offset -3, 2 pointers
|
||||
0xf4, 0xff, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00,
|
||||
// (Root>0>1>0) Struct data section
|
||||
0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
}),
|
||||
}
|
||||
rootp, err := msg.RootPtr()
|
||||
if err != nil {
|
||||
t.Error("RootPtr:", err)
|
||||
}
|
||||
root := rootp.Struct()
|
||||
if root.Uint16(0) != 2 {
|
||||
t.Errorf("root.Uint16(0) = %d; want 2", root.Uint16(0))
|
||||
}
|
||||
callp, err := root.Ptr(0)
|
||||
if err != nil {
|
||||
t.Error("root.Ptr(0):", err)
|
||||
}
|
||||
call := callp.Struct()
|
||||
targetp, err := call.Ptr(0)
|
||||
if err != nil {
|
||||
t.Error("root.Ptr(0).Ptr(0):", err)
|
||||
}
|
||||
if got := targetp.Struct().Uint32(0); got != 84 {
|
||||
t.Errorf("root.Ptr(0).Ptr(0).Uint32(0) = %d; want 84", got)
|
||||
}
|
||||
paramsp, err := call.Ptr(1)
|
||||
if err != nil {
|
||||
t.Error("root.Ptr(0).Ptr(1):", err)
|
||||
}
|
||||
contentp, err := paramsp.Struct().Ptr(0)
|
||||
if err != nil {
|
||||
t.Error("root.Ptr(0).Ptr(1).Ptr(0):", err)
|
||||
}
|
||||
if got := contentp.Struct().Uint64(0); got != 42 {
|
||||
t.Errorf("root.Ptr(0).Ptr(1).Ptr(0).Uint64(0) = %d; want 42", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteFarPointer(t *testing.T) {
|
||||
// TODO(someday): run same test with a two-word list
|
||||
|
||||
msg := &Message{
|
||||
Arena: MultiSegment([][]byte{
|
||||
make([]byte, 8),
|
||||
make([]byte, 0, 24),
|
||||
}),
|
||||
}
|
||||
seg1, err := msg.Segment(1)
|
||||
if err != nil {
|
||||
t.Fatal("msg.Segment(1):", err)
|
||||
}
|
||||
s, err := NewStruct(seg1, ObjectSize{DataSize: 8, PointerCount: 1})
|
||||
if err != nil {
|
||||
t.Fatal("NewStruct(msg.Segment(1), ObjectSize{8, 1}):", err)
|
||||
}
|
||||
if s.Segment() != seg1 {
|
||||
t.Fatalf("struct allocated in segment %d", s.Segment().ID())
|
||||
}
|
||||
if err := msg.SetRootPtr(s.ToPtr()); err != nil {
|
||||
t.Error("msg.SetRootPtr(...):", err)
|
||||
}
|
||||
seg0, err := msg.Segment(0)
|
||||
if err != nil {
|
||||
t.Fatal("msg.Segment(0):", err)
|
||||
}
|
||||
|
||||
root := rawPointer(binary.LittleEndian.Uint64(seg0.Data()))
|
||||
if root.pointerType() != farPointer {
|
||||
t.Fatalf("root (%#016x) type = %v; want %v (farPointer)", root, root.pointerType(), farPointer)
|
||||
}
|
||||
if root.farSegment() != 1 {
|
||||
t.Fatalf("root points to segment %d; want 1", root.farSegment())
|
||||
}
|
||||
padAddr := root.farAddress()
|
||||
if padAddr > Address(len(seg1.Data())-8) {
|
||||
t.Fatalf("root points to out of bounds address %v; size of segment is %d", padAddr, len(seg1.Data()))
|
||||
}
|
||||
|
||||
pad := rawPointer(binary.LittleEndian.Uint64(seg1.Data()[padAddr:]))
|
||||
if pad.pointerType() != structPointer {
|
||||
t.Errorf("landing pad (%#016x) type = %v; want %v (structPointer)", pad, pad.pointerType(), structPointer)
|
||||
}
|
||||
if got, ok := pad.offset().resolve(padAddr + 8); !ok || got != s.off {
|
||||
t.Errorf("landing pad (%#016x @ %v) resolved address = %v, %t; want %v, true", pad, padAddr, got, ok, s.off)
|
||||
}
|
||||
if got, want := pad.structSize(), (ObjectSize{DataSize: 8, PointerCount: 1}); got != want {
|
||||
t.Errorf("landing pad (%#016x) struct size = %v; want %v", pad, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteDoubleFarPointer(t *testing.T) {
|
||||
// TODO(someday): run same test with a two-word list
|
||||
|
||||
msg := &Message{
|
||||
Arena: MultiSegment([][]byte{
|
||||
make([]byte, 8),
|
||||
make([]byte, 0, 16),
|
||||
}),
|
||||
}
|
||||
seg1, err := msg.Segment(1)
|
||||
if err != nil {
|
||||
t.Fatal("msg.Segment(1):", err)
|
||||
}
|
||||
s, err := NewStruct(seg1, ObjectSize{DataSize: 8, PointerCount: 1})
|
||||
if err != nil {
|
||||
t.Fatal("NewStruct(msg.Segment(1), ObjectSize{8, 1}):", err)
|
||||
}
|
||||
if s.Segment() != seg1 {
|
||||
t.Fatalf("struct allocated in segment %d", s.Segment().ID())
|
||||
}
|
||||
if err := msg.SetRootPtr(s.ToPtr()); err != nil {
|
||||
t.Error("msg.SetRootPtr(...):", err)
|
||||
}
|
||||
seg0, err := msg.Segment(0)
|
||||
if err != nil {
|
||||
t.Fatal("msg.Segment(0):", err)
|
||||
}
|
||||
|
||||
root := rawPointer(binary.LittleEndian.Uint64(seg0.Data()))
|
||||
if root.pointerType() != doubleFarPointer {
|
||||
t.Fatalf("root (%#016x) type = %v; want %v (doubleFarPointer)", root, root.pointerType(), doubleFarPointer)
|
||||
}
|
||||
if root.farSegment() == 0 || root.farSegment() == 1 {
|
||||
t.Fatalf("root points to segment %d; want !=0,1", root.farSegment())
|
||||
}
|
||||
padSeg, err := msg.Segment(root.farSegment())
|
||||
if err != nil {
|
||||
t.Fatalf("msg.Segment(%d): %v", root.farSegment(), err)
|
||||
}
|
||||
padAddr := root.farAddress()
|
||||
if padAddr > Address(len(padSeg.Data())-16) {
|
||||
t.Fatalf("root points to out of bounds address %v; size of segment is %d", padAddr, len(padSeg.Data()))
|
||||
}
|
||||
|
||||
pad1 := rawPointer(binary.LittleEndian.Uint64(padSeg.Data()[padAddr:]))
|
||||
if pad1.pointerType() != farPointer {
|
||||
t.Errorf("landing pad pointer 1 (%#016x) type = %v; want %v (farPointer)", pad1, pad1.pointerType(), farPointer)
|
||||
}
|
||||
if pad1.farSegment() != 1 {
|
||||
t.Fatalf("landing pad pointer 1 (%#016x) points to segment %d; want 1", pad1, pad1.farSegment())
|
||||
}
|
||||
if pad1.farAddress() != s.off {
|
||||
t.Fatalf("landing pad pointer 1 (%#016x) points to address %v; want %v", pad1, pad1.farAddress(), s.off)
|
||||
}
|
||||
|
||||
pad2 := rawPointer(binary.LittleEndian.Uint64(padSeg.Data()[padAddr+8:]))
|
||||
if pad2.pointerType() != structPointer {
|
||||
t.Errorf("landing pad pointer 2 (%#016x) type = %v; want %v (structPointer)", pad2, pad2.pointerType(), structPointer)
|
||||
}
|
||||
if pad2.offset() != 0 {
|
||||
t.Errorf("landing pad pointer 2 (%#016x) offset = %d; want 0", pad2, pad2.offset())
|
||||
}
|
||||
if got, want := pad2.structSize(), (ObjectSize{DataSize: 8, PointerCount: 1}); got != want {
|
||||
t.Errorf("landing pad pointer 2 (%#016x) struct size = %v; want %v", pad2, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func catchPanic(f func()) (err error) {
|
||||
defer func() {
|
||||
pval := recover()
|
||||
if pval == nil {
|
||||
return
|
||||
}
|
||||
e, ok := pval.(error)
|
||||
if !ok {
|
||||
err = fmt.Errorf("non-error panic: %#v", pval)
|
||||
return
|
||||
}
|
||||
err = e
|
||||
}()
|
||||
f()
|
||||
return nil
|
||||
}
|
1
vendor/zombiezen.com/go/capnproto2/capnpc-go/.gitignore
generated
vendored
Normal file
1
vendor/zombiezen.com/go/capnproto2/capnpc-go/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/capnpc-go
|
36
vendor/zombiezen.com/go/capnproto2/capnpc-go/BUILD.bazel
generated
vendored
Normal file
36
vendor/zombiezen.com/go/capnproto2/capnpc-go/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"capnpc-go.go",
|
||||
"fileparts.go",
|
||||
"nodes.go",
|
||||
"templateparams.go",
|
||||
"templates.go",
|
||||
],
|
||||
importpath = "zombiezen.com/go/capnproto2/capnpc-go",
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//:go_default_library",
|
||||
"//internal/schema:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_binary(
|
||||
name = "capnpc-go",
|
||||
embed = [":go_default_library"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["capnpc-go_test.go"],
|
||||
data = glob(["testdata/**"]),
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//:go_default_library",
|
||||
"//encoding/text:go_default_library",
|
||||
"//internal/schema:go_default_library",
|
||||
],
|
||||
)
|
1208
vendor/zombiezen.com/go/capnproto2/capnpc-go/capnpc-go.go
generated
vendored
Normal file
1208
vendor/zombiezen.com/go/capnproto2/capnpc-go/capnpc-go.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
471
vendor/zombiezen.com/go/capnproto2/capnpc-go/capnpc-go_test.go
generated
vendored
Normal file
471
vendor/zombiezen.com/go/capnproto2/capnpc-go/capnpc-go_test.go
generated
vendored
Normal file
@@ -0,0 +1,471 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/encoding/text"
|
||||
"zombiezen.com/go/capnproto2/internal/schema"
|
||||
)
|
||||
|
||||
func readTestFile(name string) ([]byte, error) {
|
||||
path := filepath.Join("testdata", name)
|
||||
return ioutil.ReadFile(path)
|
||||
}
|
||||
|
||||
func mustReadTestFile(t *testing.T, name string) []byte {
|
||||
data, err := readTestFile(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func mustReadGeneratorRequest(t *testing.T, name string) schema.CodeGeneratorRequest {
|
||||
data := mustReadTestFile(t, name)
|
||||
msg, err := capnp.Unmarshal(data)
|
||||
if err != nil {
|
||||
t.Fatalf("Unmarshaling %s: %v", name, err)
|
||||
}
|
||||
req, err := schema.ReadRootCodeGeneratorRequest(msg)
|
||||
if err != nil {
|
||||
t.Fatalf("Reading code generator request %s: %v", name, err)
|
||||
}
|
||||
return req
|
||||
}
|
||||
|
||||
func TestBuildNodeMap(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fileID uint64
|
||||
fileNodes []uint64
|
||||
}{
|
||||
{
|
||||
name: "go.capnp.out",
|
||||
fileID: 0xd12a1c51fedd6c88,
|
||||
fileNodes: []uint64{
|
||||
0xbea97f1023792be0,
|
||||
0xe130b601260e44b5,
|
||||
0xc58ad6bd519f935e,
|
||||
0xa574b41924caefc7,
|
||||
0xc8768679ec52e012,
|
||||
0xfa10659ae02f2093,
|
||||
0xc2b96012172f8df1,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "group.capnp.out",
|
||||
fileID: 0x83c2b5818e83ab19,
|
||||
fileNodes: []uint64{
|
||||
0xd119fd352d8ea888, // the struct
|
||||
0x822357857e5925d4, // the group
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
data, err := readTestFile(test.name)
|
||||
if err != nil {
|
||||
t.Errorf("readTestFile(%q): %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
msg, err := capnp.Unmarshal(data)
|
||||
if err != nil {
|
||||
t.Errorf("Unmarshaling %s: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
req, err := schema.ReadRootCodeGeneratorRequest(msg)
|
||||
if err != nil {
|
||||
t.Errorf("Reading code generator request %s: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
nodes, err := buildNodeMap(req)
|
||||
if err != nil {
|
||||
t.Errorf("%s: buildNodeMap: %v", test.name, err)
|
||||
}
|
||||
f := nodes[test.fileID]
|
||||
if f == nil {
|
||||
t.Errorf("%s: node map is missing file node @%#x", test.name, test.fileID)
|
||||
continue
|
||||
}
|
||||
if f.Id() != test.fileID {
|
||||
t.Errorf("%s: node map has ID @%#x for lookup of @%#x", test.name, f.Id(), test.fileID)
|
||||
}
|
||||
|
||||
// Test node.nodes collection
|
||||
for _, id := range test.fileNodes {
|
||||
found := false
|
||||
for _, fn := range f.nodes {
|
||||
if fn.Id() == id {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("%s: missing @%#x from file nodes", test.name, id)
|
||||
}
|
||||
}
|
||||
// Test map lookup
|
||||
for _, k := range test.fileNodes {
|
||||
n := nodes[k]
|
||||
if n == nil {
|
||||
t.Errorf("%s: missing @%#x from node map", test.name, k)
|
||||
}
|
||||
if n.Id() != k {
|
||||
t.Errorf("%s: node map has ID @%#x for lookup of @%#x", test.name, n.Id(), k)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteScope(t *testing.T) {
|
||||
type scopeTest struct {
|
||||
name string
|
||||
constID uint64
|
||||
initImports []importSpec
|
||||
|
||||
remoteName string
|
||||
remoteNew string
|
||||
imports []importSpec
|
||||
}
|
||||
tests := []scopeTest{
|
||||
{
|
||||
name: "same-file struct",
|
||||
constID: 0x84efedc75e99768d, // scopes.fooVar
|
||||
remoteName: "Foo",
|
||||
remoteNew: "NewFoo",
|
||||
},
|
||||
{
|
||||
name: "different file struct",
|
||||
constID: 0x836faf1834d91729, // scopes.otherFooVar
|
||||
remoteName: "otherscopes.Foo",
|
||||
remoteNew: "otherscopes.NewFoo",
|
||||
imports: []importSpec{
|
||||
{name: "otherscopes", path: "zombiezen.com/go/capnproto2/capnpc-go/testdata/otherscopes"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "same-file struct list",
|
||||
constID: 0xcda2680ec5c921e0, // scopes.fooListVar
|
||||
remoteName: "Foo_List",
|
||||
remoteNew: "NewFoo_List",
|
||||
},
|
||||
{
|
||||
name: "different file struct list",
|
||||
constID: 0x83e7e1b3cd1be338, // scopes.otherFooListVar
|
||||
remoteName: "otherscopes.Foo_List",
|
||||
remoteNew: "otherscopes.NewFoo_List",
|
||||
imports: []importSpec{
|
||||
{name: "otherscopes", path: "zombiezen.com/go/capnproto2/capnpc-go/testdata/otherscopes"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "built-in Int32 list",
|
||||
constID: 0xacf3d9917d0bb0f0, // scopes.intList
|
||||
remoteName: "capnp.Int32List",
|
||||
remoteNew: "capnp.NewInt32List",
|
||||
imports: []importSpec{
|
||||
{name: "capnp", path: "zombiezen.com/go/capnproto2"},
|
||||
},
|
||||
},
|
||||
}
|
||||
req := mustReadGeneratorRequest(t, "scopes.capnp.out")
|
||||
nodes, err := buildNodeMap(req)
|
||||
if err != nil {
|
||||
t.Fatal("buildNodeMap:", err)
|
||||
}
|
||||
collect := func(test scopeTest) (g *generator, typ schema.Type, from *node, ok bool) {
|
||||
g = newGenerator(0xd68755941d99d05e, nodes, genoptions{})
|
||||
v := nodes[test.constID]
|
||||
if v == nil {
|
||||
t.Errorf("Can't find const @%#x for %s test", test.constID, test.name)
|
||||
return nil, schema.Type{}, nil, false
|
||||
}
|
||||
if v.Which() != schema.Node_Which_const {
|
||||
t.Errorf("Type of node @%#x in %s test is a %v node; want const. Check the test.", test.constID, test.name, v.Which())
|
||||
return nil, schema.Type{}, nil, false
|
||||
}
|
||||
constType, _ := v.Const().Type()
|
||||
for _, i := range test.initImports {
|
||||
g.imports.add(i)
|
||||
}
|
||||
return g, constType, v, true
|
||||
}
|
||||
for _, test := range tests {
|
||||
g, typ, from, ok := collect(test)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rn, err := g.RemoteTypeName(typ, from)
|
||||
if err != nil {
|
||||
t.Errorf("%s: g.RemoteTypeName(nodes[%#x].Const().Type(), nodes[%#x]) error: %v", test.name, test.constID, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if rn != test.remoteName {
|
||||
t.Errorf("%s: g.RemoteTypeName(nodes[%#x].Const().Type(), nodes[%#x]) = %q; want %q", test.name, test.constID, test.constID, rn, test.remoteName)
|
||||
continue
|
||||
}
|
||||
if !hasExactImports(test.imports, g.imports) {
|
||||
t.Errorf("%s: g.RemoteTypeName(nodes[%#x].Const().Type(), nodes[%#x]); g.imports = %s; want %s", test.name, test.constID, test.constID, formatImportSpecs(g.imports.usedImports()), formatImportSpecs(test.imports))
|
||||
continue
|
||||
}
|
||||
}
|
||||
for _, test := range tests {
|
||||
g, typ, from, ok := collect(test)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
rn, err := g.RemoteTypeNew(typ, from)
|
||||
if err != nil {
|
||||
t.Errorf("%s: g.RemoteTypeNew(nodes[%#x].Const().Type(), nodes[%#x]) error: %v", test.name, test.constID, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if rn != test.remoteNew {
|
||||
t.Errorf("%s: g.RemoteTypeNew(nodes[%#x].Const().Type(), nodes[%#x]) = %q; want %q", test.name, test.constID, test.constID, rn, test.remoteNew)
|
||||
continue
|
||||
}
|
||||
if !hasExactImports(test.imports, g.imports) {
|
||||
t.Errorf("%s: g.RemoteTypeNew(nodes[%#x].Const().Type(), nodes[%#x]); g.imports = %s; want %s", test.name, test.constID, test.constID, formatImportSpecs(g.imports.usedImports()), formatImportSpecs(test.imports))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func hasExactImports(specs []importSpec, imp imports) bool {
|
||||
used := imp.usedImports()
|
||||
if len(used) != len(specs) {
|
||||
return false
|
||||
}
|
||||
outer:
|
||||
for i := range specs {
|
||||
for j := range used {
|
||||
if specs[i] == used[j] {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func formatImportSpecs(specs []importSpec) string {
|
||||
var buf bytes.Buffer
|
||||
for i, s := range specs {
|
||||
if i > 0 {
|
||||
buf.WriteString("; ")
|
||||
}
|
||||
buf.WriteString(s.String())
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func TestDefineConstNodes(t *testing.T) {
|
||||
req := mustReadGeneratorRequest(t, "const.capnp.out")
|
||||
nodes, err := buildNodeMap(req)
|
||||
if err != nil {
|
||||
t.Fatal("buildNodeMap:", err)
|
||||
}
|
||||
g := newGenerator(0xc260cb50ae622e10, nodes, genoptions{})
|
||||
getCalls := traceGenerator(g)
|
||||
err = g.defineConstNodes(nodes[0xc260cb50ae622e10].nodes)
|
||||
if err != nil {
|
||||
t.Fatal("defineConstNodes:", err)
|
||||
}
|
||||
calls := getCalls()
|
||||
if len(calls) != 1 {
|
||||
t.Fatalf("defineConstNodes called %d templates; want 1", len(calls))
|
||||
}
|
||||
p, ok := calls[0].params.(constantsParams)
|
||||
if calls[0].name != "constants" || !ok {
|
||||
t.Fatalf("defineConstNodes rendered %v; want render of constants template", calls[0])
|
||||
}
|
||||
if !containsExactlyIDs(p.Consts, 0xda96e2255811b258) {
|
||||
t.Errorf("defineConstNodes rendered Consts %s", nodeListString(p.Consts))
|
||||
}
|
||||
if !containsExactlyIDs(p.Vars, 0xe0a385c7be1fea4d) {
|
||||
t.Errorf("defineConstNodes rendered Vars %s", nodeListString(p.Vars))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefineFile(t *testing.T) {
|
||||
// Sanity check to make sure codegen produces parseable Go.
|
||||
|
||||
const iterations = 3
|
||||
|
||||
defaultOptions := genoptions{
|
||||
promises: true,
|
||||
schemas: true,
|
||||
structStrings: true,
|
||||
}
|
||||
tests := []struct {
|
||||
fileID uint64
|
||||
fname string
|
||||
opts genoptions
|
||||
}{
|
||||
{0x832bcc6686a26d56, "aircraft.capnp.out", defaultOptions},
|
||||
{0x832bcc6686a26d56, "aircraft.capnp.out", genoptions{
|
||||
promises: false,
|
||||
schemas: false,
|
||||
structStrings: false,
|
||||
}},
|
||||
{0x832bcc6686a26d56, "aircraft.capnp.out", genoptions{
|
||||
promises: true,
|
||||
schemas: false,
|
||||
structStrings: false,
|
||||
}},
|
||||
{0x832bcc6686a26d56, "aircraft.capnp.out", genoptions{
|
||||
promises: false,
|
||||
schemas: true,
|
||||
structStrings: false,
|
||||
}},
|
||||
{0x832bcc6686a26d56, "aircraft.capnp.out", genoptions{
|
||||
promises: true,
|
||||
schemas: true,
|
||||
structStrings: false,
|
||||
}},
|
||||
{0x832bcc6686a26d56, "aircraft.capnp.out", genoptions{
|
||||
promises: false,
|
||||
schemas: true,
|
||||
structStrings: true,
|
||||
}},
|
||||
{0x83c2b5818e83ab19, "group.capnp.out", defaultOptions},
|
||||
{0xb312981b2552a250, "rpc.capnp.out", defaultOptions},
|
||||
{0xd68755941d99d05e, "scopes.capnp.out", defaultOptions},
|
||||
{0xecd50d792c3d9992, "util.capnp.out", defaultOptions},
|
||||
}
|
||||
for _, test := range tests {
|
||||
data, err := readTestFile(test.fname)
|
||||
if err != nil {
|
||||
t.Errorf("reading %s: %v", test.fname, err)
|
||||
continue
|
||||
}
|
||||
msg, err := capnp.Unmarshal(data)
|
||||
if err != nil {
|
||||
t.Errorf("Unmarshaling %s: %v", test.fname, err)
|
||||
continue
|
||||
}
|
||||
req, err := schema.ReadRootCodeGeneratorRequest(msg)
|
||||
if err != nil {
|
||||
t.Errorf("Reading code generator request %s: %v", test.fname, err)
|
||||
continue
|
||||
}
|
||||
nodes, err := buildNodeMap(req)
|
||||
if err != nil {
|
||||
t.Errorf("buildNodeMap %s: %v", test.fname, err)
|
||||
continue
|
||||
}
|
||||
g := newGenerator(test.fileID, nodes, test.opts)
|
||||
if err := g.defineFile(); err != nil {
|
||||
t.Errorf("defineFile %s %+v: %v", test.fname, test.opts, err)
|
||||
continue
|
||||
}
|
||||
src := g.generate()
|
||||
if _, err := parser.ParseFile(token.NewFileSet(), test.fname+".go", src, 0); err != nil {
|
||||
// TODO(light): log src
|
||||
t.Errorf("generate %s %+v failed to parse: %v", test.fname, test.opts, err)
|
||||
}
|
||||
|
||||
// Generation should be deterministic between runs.
|
||||
for i := 0; i < iterations-1; i++ {
|
||||
g := newGenerator(test.fileID, nodes, test.opts)
|
||||
if err := g.defineFile(); err != nil {
|
||||
t.Errorf("defineFile %s %+v [iteration %d]: %v", test.fname, test.opts, i+2, err)
|
||||
continue
|
||||
}
|
||||
src2 := g.generate()
|
||||
if !bytes.Equal(src, src2) {
|
||||
t.Errorf("defineFile %s %+v [iteration %d] did not match iteration 1: non-deterministic", test.fname, test.opts, i+2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSchemaVarLiteral(t *testing.T) {
|
||||
tests := []string{
|
||||
"",
|
||||
"foo",
|
||||
"deadbeefdeadbeef",
|
||||
"deadbeefdeadbeefdeadbeef",
|
||||
"\x00\x00",
|
||||
"\xff\xff",
|
||||
"\n",
|
||||
" ~\"\\",
|
||||
"\xff\xff\x27\xa1\xe3\xf1",
|
||||
}
|
||||
for _, test := range tests {
|
||||
got := schemaVarParams{schema: []byte(test)}.SchemaLiteral()
|
||||
u, err := strconv.Unquote(strings.Replace(got, "\" +\n\t\"", "", -1))
|
||||
if err != nil {
|
||||
t.Errorf("schema literal of %q does not parse: %v\n\tproduced: %s", test, err, got)
|
||||
} else if u != test {
|
||||
t.Errorf("schema literal of %q != %s", test, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type traceRenderer struct {
|
||||
renderer
|
||||
calls []renderCall
|
||||
}
|
||||
|
||||
func traceGenerator(g *generator) (getCalls func() []renderCall) {
|
||||
tr := &traceRenderer{renderer: g.r}
|
||||
g.r = tr
|
||||
return func() []renderCall { return tr.calls }
|
||||
}
|
||||
|
||||
func (tr *traceRenderer) Render(name string, params interface{}) error {
|
||||
tr.calls = append(tr.calls, renderCall{name, params})
|
||||
return tr.renderer.Render(name, params)
|
||||
}
|
||||
|
||||
type renderCall struct {
|
||||
name string
|
||||
params interface{}
|
||||
}
|
||||
|
||||
func (rc renderCall) String() string {
|
||||
return fmt.Sprintf("{%q %#v}", rc.name, rc.params)
|
||||
}
|
||||
|
||||
func containsExactlyIDs(nodes []*node, ids ...uint64) bool {
|
||||
if len(nodes) != len(ids) {
|
||||
return false
|
||||
}
|
||||
sorted := make([]uint64, len(ids))
|
||||
copy(sorted, ids)
|
||||
sort.Sort(uint64Slice(sorted))
|
||||
actual := make([]uint64, len(nodes))
|
||||
for i := range nodes {
|
||||
actual[i] = nodes[i].Id()
|
||||
}
|
||||
sort.Sort(uint64Slice(actual))
|
||||
for i := range sorted {
|
||||
if actual[i] != sorted[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func nodeListString(n []*node) string {
|
||||
b := new(bytes.Buffer)
|
||||
e := text.NewEncoder(b)
|
||||
b.WriteByte('[')
|
||||
for i, nn := range n {
|
||||
if i > 0 {
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
e.Encode(0xe682ab4cf923a417, nn.Struct)
|
||||
}
|
||||
b.WriteByte(']')
|
||||
return b.String()
|
||||
}
|
194
vendor/zombiezen.com/go/capnproto2/capnpc-go/fileparts.go
generated
vendored
Normal file
194
vendor/zombiezen.com/go/capnproto2/capnpc-go/fileparts.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
)
|
||||
|
||||
type staticData struct {
|
||||
name string
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func (sd *staticData) init(fileID uint64) {
|
||||
sd.name = fmt.Sprintf("x_%x", fileID)
|
||||
sd.buf = make([]byte, 0, 4096)
|
||||
}
|
||||
|
||||
func (sd *staticData) copyData(obj capnp.Ptr) (staticDataRef, error) {
|
||||
m, _, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
if err != nil {
|
||||
return staticDataRef{}, err
|
||||
}
|
||||
err = m.SetRootPtr(obj)
|
||||
if err != nil {
|
||||
return staticDataRef{}, err
|
||||
}
|
||||
data, err := m.Marshal()
|
||||
if err != nil {
|
||||
return staticDataRef{}, err
|
||||
}
|
||||
ref := staticDataRef{data: sd}
|
||||
ref.Start = len(sd.buf)
|
||||
sd.buf = append(sd.buf, data...)
|
||||
ref.End = len(sd.buf)
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
type staticDataRef struct {
|
||||
data *staticData
|
||||
Start, End int
|
||||
}
|
||||
|
||||
func (ref staticDataRef) IsValid() bool {
|
||||
return ref.Start < ref.End
|
||||
}
|
||||
|
||||
func (ref staticDataRef) String() string {
|
||||
return fmt.Sprintf("%s[%d:%d]", ref.data.name, ref.Start, ref.End)
|
||||
}
|
||||
|
||||
type imports struct {
|
||||
specs []importSpec
|
||||
used map[string]bool // keyed on import path
|
||||
}
|
||||
|
||||
var capnpImportSpec = importSpec{path: capnpImport, name: "capnp"}
|
||||
|
||||
func (i *imports) init() {
|
||||
i.specs = nil
|
||||
i.used = make(map[string]bool)
|
||||
|
||||
i.reserve(capnpImportSpec)
|
||||
i.reserve(importSpec{path: schemasImport, name: "schemas"})
|
||||
i.reserve(importSpec{path: serverImport, name: "server"})
|
||||
i.reserve(importSpec{path: textImport, name: "text"})
|
||||
i.reserve(importSpec{path: contextImport, name: "context"})
|
||||
|
||||
i.reserve(importSpec{path: "math", name: "math"})
|
||||
i.reserve(importSpec{path: "strconv", name: "strconv"})
|
||||
}
|
||||
|
||||
func (i *imports) Capnp() string {
|
||||
return i.add(importSpec{path: capnpImport, name: "capnp"})
|
||||
}
|
||||
|
||||
func (i *imports) Schemas() string {
|
||||
return i.add(importSpec{path: schemasImport, name: "schemas"})
|
||||
}
|
||||
|
||||
func (i *imports) Server() string {
|
||||
return i.add(importSpec{path: serverImport, name: "server"})
|
||||
}
|
||||
|
||||
func (i *imports) Text() string {
|
||||
return i.add(importSpec{path: textImport, name: "text"})
|
||||
}
|
||||
|
||||
func (i *imports) Context() string {
|
||||
return i.add(importSpec{path: contextImport, name: "context"})
|
||||
}
|
||||
|
||||
func (i *imports) Math() string {
|
||||
return i.add(importSpec{path: "math", name: "math"})
|
||||
}
|
||||
|
||||
func (i *imports) Strconv() string {
|
||||
return i.add(importSpec{path: "strconv", name: "strconv"})
|
||||
}
|
||||
|
||||
func (i *imports) usedImports() []importSpec {
|
||||
specs := make([]importSpec, 0, len(i.specs))
|
||||
for _, s := range i.specs {
|
||||
if i.used[s.path] {
|
||||
specs = append(specs, s)
|
||||
}
|
||||
}
|
||||
return specs
|
||||
}
|
||||
|
||||
func (i *imports) byPath(path string) (spec importSpec, ok bool) {
|
||||
for _, spec = range i.specs {
|
||||
if spec.path == path {
|
||||
return spec, true
|
||||
}
|
||||
}
|
||||
return importSpec{}, false
|
||||
}
|
||||
|
||||
func (i *imports) byName(name string) (spec importSpec, ok bool) {
|
||||
for _, spec = range i.specs {
|
||||
if spec.name == name {
|
||||
return spec, true
|
||||
}
|
||||
}
|
||||
return importSpec{}, false
|
||||
}
|
||||
|
||||
func (i *imports) add(spec importSpec) (name string) {
|
||||
name = i.reserve(spec)
|
||||
i.used[spec.path] = true
|
||||
return name
|
||||
}
|
||||
|
||||
// reserve adds an import spec without marking it as used.
|
||||
func (i *imports) reserve(spec importSpec) (name string) {
|
||||
if ispec, ok := i.byPath(spec.path); ok {
|
||||
return ispec.name
|
||||
}
|
||||
if spec.name == "" {
|
||||
spec.name = pkgFromImport(spec.path)
|
||||
}
|
||||
if _, found := i.byName(spec.name); found {
|
||||
for base, n := spec.name, uint64(2); ; n++ {
|
||||
spec.name = base + strconv.FormatUint(n, 10)
|
||||
if _, found = i.byName(spec.name); !found {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
i.specs = append(i.specs, spec)
|
||||
return spec.name
|
||||
}
|
||||
|
||||
func pkgFromImport(path string) string {
|
||||
if i := strings.LastIndex(path, "/"); i != -1 {
|
||||
path = path[i+1:]
|
||||
}
|
||||
p := []rune(path)
|
||||
n := 0
|
||||
for _, r := range p {
|
||||
if isIdent(r) {
|
||||
p[n] = r
|
||||
n++
|
||||
}
|
||||
}
|
||||
if n == 0 || !isLower(p[0]) {
|
||||
return "pkg" + string(p[:n])
|
||||
}
|
||||
return string(p[:n])
|
||||
}
|
||||
|
||||
func isLower(r rune) bool {
|
||||
return 'a' <= r && r <= 'z' || r == '_'
|
||||
}
|
||||
|
||||
func isIdent(r rune) bool {
|
||||
return isLower(r) || 'A' <= r && r <= 'Z' || r >= 0x80 && unicode.IsLetter(r)
|
||||
}
|
||||
|
||||
type importSpec struct {
|
||||
path string
|
||||
name string
|
||||
}
|
||||
|
||||
func (spec importSpec) String() string {
|
||||
if spec.name == "" {
|
||||
return strconv.Quote(spec.path)
|
||||
}
|
||||
return spec.name + " " + strconv.Quote(spec.path)
|
||||
}
|
336
vendor/zombiezen.com/go/capnproto2/capnpc-go/nodes.go
generated
vendored
Normal file
336
vendor/zombiezen.com/go/capnproto2/capnpc-go/nodes.go
generated
vendored
Normal file
@@ -0,0 +1,336 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/internal/schema"
|
||||
)
|
||||
|
||||
type node struct {
|
||||
schema.Node
|
||||
pkg string
|
||||
imp string
|
||||
nodes []*node // only for file nodes
|
||||
Name string
|
||||
}
|
||||
|
||||
func (n *node) codeOrderFields() []field {
|
||||
fields, _ := n.StructNode().Fields()
|
||||
numFields := fields.Len()
|
||||
mbrs := make([]field, numFields)
|
||||
for i := 0; i < numFields; i++ {
|
||||
f := fields.At(i)
|
||||
fann, _ := f.Annotations()
|
||||
fname, _ := f.Name()
|
||||
fname = parseAnnotations(fann).Rename(fname)
|
||||
mbrs[f.CodeOrder()] = field{Field: f, Name: fname}
|
||||
}
|
||||
return mbrs
|
||||
}
|
||||
|
||||
// DiscriminantOffset returns the byte offset of the struct union discriminant.
|
||||
func (n *node) DiscriminantOffset() (uint32, error) {
|
||||
if n == nil {
|
||||
return 0, errors.New("discriminant offset called on nil node")
|
||||
}
|
||||
if n.Which() != schema.Node_Which_structNode {
|
||||
return 0, fmt.Errorf("discriminant offset called on %v node", n.Which())
|
||||
}
|
||||
return n.StructNode().DiscriminantOffset() * 2, nil
|
||||
}
|
||||
|
||||
func (n *node) shortDisplayName() string {
|
||||
dn, _ := n.DisplayName()
|
||||
return dn[n.DisplayNamePrefixLength():]
|
||||
}
|
||||
|
||||
// String returns the node's display name.
|
||||
func (n *node) String() string {
|
||||
return displayName(n)
|
||||
}
|
||||
|
||||
func displayName(n interface {
|
||||
DisplayName() (string, error)
|
||||
}) string {
|
||||
dn, _ := n.DisplayName()
|
||||
return dn
|
||||
}
|
||||
|
||||
type field struct {
|
||||
schema.Field
|
||||
Name string
|
||||
}
|
||||
|
||||
// HasDiscriminant reports whether the field is in a union.
|
||||
func (f field) HasDiscriminant() bool {
|
||||
return f.DiscriminantValue() != schema.Field_noDiscriminant
|
||||
}
|
||||
|
||||
type enumval struct {
|
||||
schema.Enumerant
|
||||
Name string
|
||||
Val int
|
||||
Tag string
|
||||
parent *node
|
||||
}
|
||||
|
||||
func makeEnumval(enum *node, i int, e schema.Enumerant) enumval {
|
||||
eann, _ := e.Annotations()
|
||||
ann := parseAnnotations(eann)
|
||||
name, _ := e.Name()
|
||||
name = ann.Rename(name)
|
||||
t := ann.Tag(name)
|
||||
return enumval{e, name, i, t, enum}
|
||||
}
|
||||
|
||||
func (e *enumval) FullName() string {
|
||||
return e.parent.Name + "_" + e.Name
|
||||
}
|
||||
|
||||
type interfaceMethod struct {
|
||||
schema.Method
|
||||
Interface *node
|
||||
ID int
|
||||
Name string
|
||||
OriginalName string
|
||||
Params *node
|
||||
Results *node
|
||||
}
|
||||
|
||||
func methodSet(methods []interfaceMethod, n *node, nodes nodeMap) ([]interfaceMethod, error) {
|
||||
ms, _ := n.Interface().Methods()
|
||||
for i := 0; i < ms.Len(); i++ {
|
||||
m := ms.At(i)
|
||||
mname, _ := m.Name()
|
||||
mann, _ := m.Annotations()
|
||||
pn, err := nodes.mustFind(m.ParamStructType())
|
||||
if err != nil {
|
||||
return methods, fmt.Errorf("could not find param type for %s.%s", n.shortDisplayName(), mname)
|
||||
}
|
||||
rn, err := nodes.mustFind(m.ResultStructType())
|
||||
if err != nil {
|
||||
return methods, fmt.Errorf("could not find result type for %s.%s", n.shortDisplayName(), mname)
|
||||
}
|
||||
methods = append(methods, interfaceMethod{
|
||||
Method: m,
|
||||
Interface: n,
|
||||
ID: i,
|
||||
OriginalName: mname,
|
||||
Name: parseAnnotations(mann).Rename(mname),
|
||||
Params: pn,
|
||||
Results: rn,
|
||||
})
|
||||
}
|
||||
// TODO(light): sort added methods by code order
|
||||
|
||||
supers, _ := n.Interface().Superclasses()
|
||||
for i := 0; i < supers.Len(); i++ {
|
||||
s := supers.At(i)
|
||||
sn, err := nodes.mustFind(s.Id())
|
||||
if err != nil {
|
||||
return methods, fmt.Errorf("could not find superclass %#x of %s", s.Id(), n)
|
||||
}
|
||||
methods, err = methodSet(methods, sn, nodes)
|
||||
if err != nil {
|
||||
return methods, err
|
||||
}
|
||||
}
|
||||
return methods, nil
|
||||
}
|
||||
|
||||
// Tag types
|
||||
const (
|
||||
defaultTag = iota
|
||||
noTag
|
||||
customTag
|
||||
)
|
||||
|
||||
type annotations struct {
|
||||
Doc string
|
||||
Package string
|
||||
Import string
|
||||
TagType int
|
||||
CustomTag string
|
||||
Name string
|
||||
}
|
||||
|
||||
func parseAnnotations(list schema.Annotation_List) *annotations {
|
||||
ann := new(annotations)
|
||||
for i, n := 0, list.Len(); i < n; i++ {
|
||||
a := list.At(i)
|
||||
val, _ := a.Value()
|
||||
text, _ := val.Text()
|
||||
switch a.Id() {
|
||||
case capnp.Doc:
|
||||
ann.Doc = text
|
||||
case capnp.Package:
|
||||
ann.Package = text
|
||||
case capnp.Import:
|
||||
ann.Import = text
|
||||
case capnp.Tag:
|
||||
ann.TagType = customTag
|
||||
ann.CustomTag = text
|
||||
case capnp.Notag:
|
||||
ann.TagType = noTag
|
||||
case capnp.Name:
|
||||
ann.Name = text
|
||||
}
|
||||
}
|
||||
return ann
|
||||
}
|
||||
|
||||
// Tag returns the string value that an enumerant value called name should have.
|
||||
// An empty string indicates that this enumerant value has no tag.
|
||||
func (ann *annotations) Tag(name string) string {
|
||||
switch ann.TagType {
|
||||
case noTag:
|
||||
return ""
|
||||
case customTag:
|
||||
return ann.CustomTag
|
||||
case defaultTag:
|
||||
fallthrough
|
||||
default:
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
// Rename returns the overridden name from the annotations or the given name
|
||||
// if no annotation was found.
|
||||
func (ann *annotations) Rename(given string) string {
|
||||
if ann.Name == "" {
|
||||
return given
|
||||
}
|
||||
return ann.Name
|
||||
}
|
||||
|
||||
type nodeMap map[uint64]*node
|
||||
|
||||
func buildNodeMap(req schema.CodeGeneratorRequest) (nodeMap, error) {
|
||||
rnodes, err := req.Nodes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nodes := make(nodeMap, rnodes.Len())
|
||||
var allfiles []*node
|
||||
for i := 0; i < rnodes.Len(); i++ {
|
||||
ni := rnodes.At(i)
|
||||
n := &node{Node: ni}
|
||||
nodes[n.Id()] = n
|
||||
if n.Which() == schema.Node_Which_file {
|
||||
allfiles = append(allfiles, n)
|
||||
}
|
||||
}
|
||||
for _, f := range allfiles {
|
||||
fann, err := f.Annotations()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading annotations for %v: %v", f, err)
|
||||
}
|
||||
ann := parseAnnotations(fann)
|
||||
f.pkg = ann.Package
|
||||
f.imp = ann.Import
|
||||
nnodes, _ := f.NestedNodes()
|
||||
for i := 0; i < nnodes.Len(); i++ {
|
||||
nn := nnodes.At(i)
|
||||
if ni := nodes[nn.Id()]; ni != nil {
|
||||
nname, _ := nn.Name()
|
||||
if err := resolveName(nodes, ni, "", nname, f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// resolveName is called as part of building up a node map to populate the name field of n.
|
||||
func resolveName(nodes nodeMap, n *node, base, name string, file *node) error {
|
||||
na, err := n.Annotations()
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading annotations for %s: %v", n, err)
|
||||
}
|
||||
name = parseAnnotations(na).Rename(name)
|
||||
if base == "" {
|
||||
n.Name = strings.Title(name)
|
||||
} else {
|
||||
n.Name = base + "_" + name
|
||||
}
|
||||
n.pkg = file.pkg
|
||||
n.imp = file.imp
|
||||
file.nodes = append(file.nodes, n)
|
||||
|
||||
nnodes, err := n.NestedNodes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("listing nested nodes for %s: %v", n, err)
|
||||
}
|
||||
for i := 0; i < nnodes.Len(); i++ {
|
||||
nn := nnodes.At(i)
|
||||
ni := nodes[nn.Id()]
|
||||
if ni == nil {
|
||||
continue
|
||||
}
|
||||
nname, err := nn.Name()
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading name of nested node %d in %s: %v", i+1, n, err)
|
||||
}
|
||||
if err := resolveName(nodes, ni, n.Name, nname, file); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
switch n.Which() {
|
||||
case schema.Node_Which_structNode:
|
||||
fields, _ := n.StructNode().Fields()
|
||||
for i := 0; i < fields.Len(); i++ {
|
||||
f := fields.At(i)
|
||||
if f.Which() != schema.Field_Which_group {
|
||||
continue
|
||||
}
|
||||
fa, _ := f.Annotations()
|
||||
fname, _ := f.Name()
|
||||
grp := nodes[f.Group().TypeId()]
|
||||
if grp == nil {
|
||||
return fmt.Errorf("could not find type information for group %s in %s", fname, n)
|
||||
}
|
||||
fname = parseAnnotations(fa).Rename(fname)
|
||||
if err := resolveName(nodes, grp, n.Name, fname, file); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
case schema.Node_Which_interface:
|
||||
m, _ := n.Interface().Methods()
|
||||
methodResolve := func(id uint64, mname string, base string, name string) error {
|
||||
x := nodes[id]
|
||||
if x == nil {
|
||||
return fmt.Errorf("could not find type %#x for %s.%s", id, n, mname)
|
||||
}
|
||||
if x.ScopeId() != 0 {
|
||||
return nil
|
||||
}
|
||||
return resolveName(nodes, x, base, name, file)
|
||||
}
|
||||
for i := 0; i < m.Len(); i++ {
|
||||
mm := m.At(i)
|
||||
mname, _ := mm.Name()
|
||||
mann, _ := mm.Annotations()
|
||||
base := n.Name + "_" + parseAnnotations(mann).Rename(mname)
|
||||
if err := methodResolve(mm.ParamStructType(), mname, base, "Params"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := methodResolve(mm.ResultStructType(), mname, base, "Results"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nm nodeMap) mustFind(id uint64) (*node, error) {
|
||||
n := nm[id]
|
||||
if n == nil {
|
||||
return nil, fmt.Errorf("could not find node %#x in schema", id)
|
||||
}
|
||||
return n, nil
|
||||
}
|
236
vendor/zombiezen.com/go/capnproto2/capnpc-go/templateparams.go
generated
vendored
Normal file
236
vendor/zombiezen.com/go/capnproto2/capnpc-go/templateparams.go
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type annotationParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
}
|
||||
|
||||
type constantsParams struct {
|
||||
G *generator
|
||||
Consts []*node
|
||||
Vars []*node
|
||||
}
|
||||
|
||||
type enumParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Annotations *annotations
|
||||
EnumValues []enumval
|
||||
}
|
||||
|
||||
type structTypesParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Annotations *annotations
|
||||
BaseNode *node
|
||||
}
|
||||
|
||||
func (p structTypesParams) IsBase() bool {
|
||||
return p.Node == p.BaseNode
|
||||
}
|
||||
|
||||
type baseStructFuncsParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
StringMethod bool
|
||||
}
|
||||
|
||||
type structFuncsParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
}
|
||||
|
||||
type structGroupParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Group *node
|
||||
Field field
|
||||
}
|
||||
|
||||
type structFieldParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Field field
|
||||
Annotations *annotations
|
||||
FieldType string
|
||||
}
|
||||
|
||||
type (
|
||||
structFloatFieldParams structUintFieldParams
|
||||
structInterfaceFieldParams structFieldParams
|
||||
structVoidFieldParams structFieldParams
|
||||
structListFieldParams structObjectFieldParams
|
||||
structPointerFieldParams structObjectFieldParams
|
||||
structStructFieldParams structObjectFieldParams
|
||||
)
|
||||
|
||||
type structBoolFieldParams struct {
|
||||
structFieldParams
|
||||
Default bool
|
||||
}
|
||||
|
||||
type structUintFieldParams struct {
|
||||
structFieldParams
|
||||
Bits uint
|
||||
Default uint64
|
||||
}
|
||||
|
||||
func (p structUintFieldParams) Offset() uint32 {
|
||||
return p.Field.Slot().Offset() * uint32(p.Bits/8)
|
||||
}
|
||||
|
||||
func (p structFloatFieldParams) Offset() uint32 {
|
||||
return structUintFieldParams(p).Offset()
|
||||
}
|
||||
|
||||
type structIntFieldParams struct {
|
||||
structUintFieldParams
|
||||
EnumName string
|
||||
}
|
||||
|
||||
func (p structIntFieldParams) ReturnType() string {
|
||||
if p.EnumName != "" {
|
||||
return p.EnumName
|
||||
}
|
||||
return fmt.Sprintf("int%d", p.Bits)
|
||||
}
|
||||
|
||||
type structTextFieldParams struct {
|
||||
structFieldParams
|
||||
Default string
|
||||
}
|
||||
|
||||
type structDataFieldParams struct {
|
||||
structFieldParams
|
||||
Default []byte
|
||||
}
|
||||
|
||||
type structObjectFieldParams struct {
|
||||
structFieldParams
|
||||
TypeNode *node
|
||||
Default staticDataRef
|
||||
}
|
||||
|
||||
type structListParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
StringMethod bool
|
||||
}
|
||||
|
||||
type structEnumsParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Fields []field
|
||||
EnumString enumString
|
||||
}
|
||||
|
||||
type promiseParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Fields []field
|
||||
}
|
||||
|
||||
type promiseGroupParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Field field
|
||||
Group *node
|
||||
}
|
||||
|
||||
type promiseFieldStructParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Field field
|
||||
Struct *node
|
||||
Default staticDataRef
|
||||
}
|
||||
|
||||
type promiseFieldAnyPointerParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Field field
|
||||
}
|
||||
|
||||
type promiseFieldInterfaceParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Field field
|
||||
Interface *node
|
||||
}
|
||||
|
||||
type interfaceClientParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Annotations *annotations
|
||||
Methods []interfaceMethod
|
||||
}
|
||||
|
||||
type interfaceServerParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Annotations *annotations
|
||||
Methods []interfaceMethod
|
||||
}
|
||||
|
||||
type structValueParams struct {
|
||||
G *generator
|
||||
Node *node
|
||||
Typ *node
|
||||
Value staticDataRef
|
||||
}
|
||||
|
||||
type pointerValueParams struct {
|
||||
G *generator
|
||||
Value staticDataRef
|
||||
}
|
||||
|
||||
type listValueParams struct {
|
||||
G *generator
|
||||
Typ string
|
||||
Value staticDataRef
|
||||
}
|
||||
|
||||
type schemaVarParams struct {
|
||||
G *generator
|
||||
FileID uint64
|
||||
NodeIDs []uint64
|
||||
schema []byte
|
||||
}
|
||||
|
||||
func (p schemaVarParams) SchemaLiteral() string {
|
||||
const width = 16
|
||||
var out bytes.Buffer
|
||||
out.WriteByte('"')
|
||||
for i, b := range p.schema {
|
||||
if i > 0 && i%width == 0 {
|
||||
out.WriteString("\" +\n\t\"")
|
||||
}
|
||||
switch {
|
||||
case b < ' ' || b > '~':
|
||||
// unprintable
|
||||
out.WriteString("\\x")
|
||||
out.WriteByte(hexdigit(b >> 4))
|
||||
out.WriteByte(hexdigit(b & 0xf))
|
||||
case b == '"':
|
||||
out.WriteString("\\\"")
|
||||
case b == '\\':
|
||||
out.WriteString("\\\\")
|
||||
default:
|
||||
out.WriteByte(b)
|
||||
}
|
||||
}
|
||||
out.WriteByte('"')
|
||||
return out.String()
|
||||
}
|
||||
|
||||
func hexdigit(b byte) byte {
|
||||
if b < 10 {
|
||||
return b + '0'
|
||||
}
|
||||
return (b - 10) + 'a'
|
||||
}
|
109
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates.go
generated
vendored
Normal file
109
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates.go
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
5
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_checktag
generated
vendored
Normal file
5
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_checktag
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{{if .Field.HasDiscriminant -}}
|
||||
if s.Struct.Uint16({{.Node.DiscriminantOffset}}) != {{.Field.DiscriminantValue}} {
|
||||
panic({{printf "Which() != %s" .Field.Name | printf "%q"}})
|
||||
}
|
||||
{{end -}}
|
9
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_hasfield
generated
vendored
Normal file
9
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_hasfield
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
func (s {{.Node.Name}}) Has{{.Field.Name|title}}() bool {
|
||||
{{if .Field.HasDiscriminant -}}
|
||||
if s.Struct.Uint16({{.Node.DiscriminantOffset}}) != {{.Field.DiscriminantValue}} {
|
||||
return false
|
||||
}
|
||||
{{end -}}
|
||||
p, err := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
return p.IsValid() || err != nil
|
||||
}
|
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_interfaceMethod
generated
vendored
Normal file
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_interfaceMethod
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
InterfaceID: {{.Interface.Id|printf "%#x"}},
|
||||
MethodID: {{.ID}},
|
||||
InterfaceName: {{.Interface.DisplayName|printf "%q"}},
|
||||
MethodName: {{.OriginalName|printf "%q"}},
|
3
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_settag
generated
vendored
Normal file
3
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_settag
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{{if .Field.HasDiscriminant -}}
|
||||
s.Struct.SetUint16({{.Node.DiscriminantOffset}}, {{.Field.DiscriminantValue}})
|
||||
{{end -}}
|
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_typeid
generated
vendored
Normal file
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/_typeid
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
// {{.Name}}_TypeID is the unique identifier for the type {{.Name}}.
|
||||
const {{.Name}}_TypeID = {{.Id|printf "%#x"}}
|
1
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/annotation
generated
vendored
Normal file
1
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/annotation
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
const {{.Node.Name}} = uint64({{.Node.Id|printf "%#x"}})
|
23
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/baseStructFuncs
generated
vendored
Normal file
23
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/baseStructFuncs
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
{{ template "_typeid" .Node }}
|
||||
|
||||
func New{{.Node.Name}}(s *{{.G.Capnp}}.Segment) ({{.Node.Name}}, error) {
|
||||
st, err := {{$.G.Capnp}}.NewStruct(s, {{.G.ObjectSize .Node}})
|
||||
return {{.Node.Name}}{st}, err
|
||||
}
|
||||
|
||||
func NewRoot{{.Node.Name}}(s *{{.G.Capnp}}.Segment) ({{.Node.Name}}, error) {
|
||||
st, err := {{.G.Capnp}}.NewRootStruct(s, {{.G.ObjectSize .Node}})
|
||||
return {{.Node.Name}}{st}, err
|
||||
}
|
||||
|
||||
func ReadRoot{{.Node.Name}}(msg *{{.G.Capnp}}.Message) ({{.Node.Name}}, error) {
|
||||
root, err := msg.RootPtr()
|
||||
return {{.Node.Name}}{root.Struct()}, err
|
||||
}
|
||||
{{if .StringMethod}}
|
||||
func (s {{.Node.Name}}) String() string {
|
||||
str, _ := {{.G.Imports.Text}}.Marshal({{.Node.Id|printf "%#x"}}, s.Struct)
|
||||
return str
|
||||
}
|
||||
{{end}}
|
||||
|
14
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/constants
generated
vendored
Normal file
14
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/constants
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{{with .Consts -}}
|
||||
// Constants defined in {{$.G.Basename}}.
|
||||
const (
|
||||
{{range .}} {{.Name}} = {{$.G.Value . .Const.Type .Const.Value}}
|
||||
{{end}}
|
||||
)
|
||||
{{end}}
|
||||
{{with .Vars -}}
|
||||
// Constants defined in {{$.G.Basename}}.
|
||||
var (
|
||||
{{range .}} {{.Name}} = {{$.G.Value . .Const.Type .Const.Value}}
|
||||
{{end}}
|
||||
)
|
||||
{{end}}
|
55
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/enum
generated
vendored
Normal file
55
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/enum
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
{{with .Annotations.Doc -}}
|
||||
// {{.}}
|
||||
{{end -}}
|
||||
type {{.Node.Name}} uint16
|
||||
|
||||
{{ template "_typeid" .Node }}
|
||||
|
||||
{{with .EnumValues -}}
|
||||
// Values of {{$.Node.Name}}.
|
||||
const (
|
||||
{{range . -}}
|
||||
{{.FullName}} {{$.Node.Name}} = {{.Val}}
|
||||
{{end}}
|
||||
)
|
||||
|
||||
// String returns the enum's constant name.
|
||||
func (c {{$.Node.Name}}) String() string {
|
||||
switch c {
|
||||
{{range . -}}
|
||||
{{if .Tag}}case {{.FullName}}: return {{printf "%q" .Tag}}
|
||||
{{end}}
|
||||
{{- end}}
|
||||
default: return ""
|
||||
}
|
||||
}
|
||||
|
||||
// {{$.Node.Name}}FromString returns the enum value with a name,
|
||||
// or the zero value if there's no such value.
|
||||
func {{$.Node.Name}}FromString(c string) {{$.Node.Name}} {
|
||||
switch c {
|
||||
{{range . -}}
|
||||
{{if .Tag}}case {{printf "%q" .Tag}}: return {{.FullName}}
|
||||
{{end}}
|
||||
{{- end}}
|
||||
default: return 0
|
||||
}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
type {{.Node.Name}}_List struct { {{$.G.Capnp}}.List }
|
||||
|
||||
func New{{.Node.Name}}_List(s *{{$.G.Capnp}}.Segment, sz int32) ({{.Node.Name}}_List, error) {
|
||||
l, err := {{.G.Capnp}}.NewUInt16List(s, sz)
|
||||
return {{.Node.Name}}_List{l.List}, err
|
||||
}
|
||||
|
||||
func (l {{.Node.Name}}_List) At(i int) {{.Node.Name}} {
|
||||
ul := {{.G.Capnp}}.UInt16List{List: l.List}
|
||||
return {{.Node.Name}}(ul.At(i))
|
||||
}
|
||||
|
||||
func (l {{.Node.Name}}_List) Set(i int, v {{.Node.Name}}) {
|
||||
ul := {{.G.Capnp}}.UInt16List{List: l.List}
|
||||
ul.Set(i, uint16(v))
|
||||
}
|
26
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/interfaceClient
generated
vendored
Normal file
26
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/interfaceClient
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
{{with .Annotations.Doc -}}
|
||||
// {{.}}
|
||||
{{end -}}
|
||||
type {{.Node.Name}} struct { Client {{.G.Capnp}}.Client }
|
||||
|
||||
{{ template "_typeid" .Node }}
|
||||
|
||||
{{range .Methods -}}
|
||||
func (c {{$.Node.Name}}) {{.Name|title}}(ctx {{$.G.Imports.Context}}.Context, params func({{$.G.RemoteNodeName .Params $.Node}}) error, opts ...{{$.G.Capnp}}.CallOption) {{$.G.RemoteNodeName .Results $.Node}}_Promise {
|
||||
if c.Client == nil {
|
||||
return {{$.G.RemoteNodeName .Results $.Node}}_Promise{Pipeline: {{$.G.Capnp}}.NewPipeline({{$.G.Capnp}}.ErrorAnswer({{$.G.Capnp}}.ErrNullClient))}
|
||||
}
|
||||
call := &{{$.G.Capnp}}.Call{
|
||||
Ctx: ctx,
|
||||
Method: {{$.G.Capnp}}.Method{
|
||||
{{template "_interfaceMethod" .}}
|
||||
},
|
||||
Options: {{$.G.Capnp}}.NewCallOptions(opts),
|
||||
}
|
||||
if params != nil {
|
||||
call.ParamsSize = {{$.G.ObjectSize .Params}}
|
||||
call.ParamsFunc = func(s {{$.G.Capnp}}.Struct) error { return params({{$.G.RemoteNodeName .Params $.Node}}{Struct: s}) }
|
||||
}
|
||||
return {{$.G.RemoteNodeName .Results $.Node}}_Promise{Pipeline: {{$.G.Capnp}}.NewPipeline(c.Client.Call(call))}
|
||||
}
|
||||
{{end}}
|
40
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/interfaceServer
generated
vendored
Normal file
40
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/interfaceServer
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
type {{.Node.Name}}_Server interface {
|
||||
{{range .Methods}}
|
||||
{{.Name|title}}({{$.G.RemoteNodeName .Interface $.Node}}_{{.Name}}) error
|
||||
{{end}}
|
||||
}
|
||||
|
||||
func {{.Node.Name}}_ServerToClient(s {{.Node.Name}}_Server) {{.Node.Name}} {
|
||||
c, _ := s.({{.G.Imports.Server}}.Closer)
|
||||
return {{.Node.Name}}{Client: {{.G.Imports.Server}}.New({{.Node.Name}}_Methods(nil, s), c)}
|
||||
}
|
||||
|
||||
func {{.Node.Name}}_Methods(methods []{{.G.Imports.Server}}.Method, s {{.Node.Name}}_Server) []{{.G.Imports.Server}}.Method {
|
||||
if cap(methods) == 0 {
|
||||
methods = make([]{{.G.Imports.Server}}.Method, 0, {{len .Methods}})
|
||||
}
|
||||
{{range .Methods}}
|
||||
methods = append(methods, {{$.G.Imports.Server}}.Method{
|
||||
Method: {{$.G.Capnp}}.Method{
|
||||
{{template "_interfaceMethod" .}}
|
||||
},
|
||||
Impl: func(c {{$.G.Imports.Context}}.Context, opts {{$.G.Capnp}}.CallOptions, p, r {{$.G.Capnp}}.Struct) error {
|
||||
call := {{$.G.RemoteNodeName .Interface $.Node}}_{{.Name}}{c, opts, {{$.G.RemoteNodeName .Params $.Node}}{Struct: p}, {{$.G.RemoteNodeName .Results $.Node}}{Struct: r} }
|
||||
return s.{{.Name|title}}(call)
|
||||
},
|
||||
ResultsSize: {{$.G.ObjectSize .Results}},
|
||||
})
|
||||
{{end}}
|
||||
return methods
|
||||
}
|
||||
{{range .Methods -}}
|
||||
{{if eq .Interface.Id $.Node.Id}}
|
||||
// {{$.Node.Name}}_{{.Name}} holds the arguments for a server call to {{$.Node.Name}}.{{.Name}}.
|
||||
type {{$.Node.Name}}_{{.Name}} struct {
|
||||
Ctx {{$.G.Imports.Context}}.Context
|
||||
Options {{$.G.Capnp}}.CallOptions
|
||||
Params {{$.G.RemoteNodeName .Params $.Node}}
|
||||
Results {{$.G.RemoteNodeName .Results $.Node}}
|
||||
}
|
||||
{{end}}
|
||||
{{- end}}
|
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/listValue
generated
vendored
Normal file
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/listValue
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
{{.Typ}}{List: {{.G.Capnp}}.MustUnmarshalRootPtr({{.Value}}).List()}
|
||||
{{- /* no EOL */ -}}
|
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/pointerValue
generated
vendored
Normal file
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/pointerValue
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
{{.G.Capnp}}.MustUnmarshalRootPtr({{.Value}})
|
||||
{{- /* no EOL */ -}}
|
8
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promise
generated
vendored
Normal file
8
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promise
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// {{.Node.Name}}_Promise is a wrapper for a {{.Node.Name}} promised by a client call.
|
||||
type {{.Node.Name}}_Promise struct { *{{.G.Capnp}}.Pipeline }
|
||||
|
||||
func (p {{.Node.Name}}_Promise) Struct() ({{.Node.Name}}, error) {
|
||||
s, err := p.Pipeline.Struct()
|
||||
return {{.Node.Name}}{s}, err
|
||||
}
|
||||
|
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseFieldAnyPointer
generated
vendored
Normal file
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseFieldAnyPointer
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
func (p {{.Node.Name}}_Promise) {{.Field.Name|title}}() *{{.G.Capnp}}.Pipeline {
|
||||
return p.Pipeline.GetPipeline({{.Field.Slot.Offset}})
|
||||
}
|
||||
|
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseFieldInterface
generated
vendored
Normal file
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseFieldInterface
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
func (p {{.Node.Name}}_Promise) {{.Field.Name|title}}() {{.G.RemoteNodeName .Interface .Node}} {
|
||||
return {{.G.RemoteNodeName .Interface .Node}}{Client: p.Pipeline.GetPipeline({{.Field.Slot.Offset}}).Client()}
|
||||
}
|
||||
|
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseFieldStruct
generated
vendored
Normal file
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseFieldStruct
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
func (p {{.Node.Name}}_Promise) {{.Field.Name|title}}() {{.G.RemoteNodeName .Struct .Node}}_Promise {
|
||||
return {{.G.RemoteNodeName .Struct .Node}}_Promise{Pipeline: p.Pipeline.{{if .Default.IsValid}}GetPipelineDefault({{.Field.Slot.Offset}}, {{.Default}}){{else}}GetPipeline({{.Field.Slot.Offset}}){{end}} }
|
||||
}
|
||||
|
1
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseGroup
generated
vendored
Normal file
1
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/promiseGroup
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
func (p {{.Node.Name}}_Promise) {{.Field.Name|title}}() {{.Group.Name}}_Promise { return {{.Group.Name}}_Promise{p.Pipeline} }
|
8
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/schemaVar
generated
vendored
Normal file
8
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/schemaVar
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const schema_{{.FileID|printf "%x"}} = {{.SchemaLiteral}}
|
||||
|
||||
func init() {
|
||||
{{.G.Imports.Schemas}}.Register(schema_{{.FileID|printf "%x"}},
|
||||
{{- range .NodeIDs}}
|
||||
{{.|printf "%#x"}},
|
||||
{{- end}})
|
||||
}
|
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structBoolField
generated
vendored
Normal file
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structBoolField
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() bool {
|
||||
{{template "_checktag" . -}}
|
||||
return {{if .Default}}!{{end}}s.Struct.Bit({{.Field.Slot.Offset}})
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v bool) {
|
||||
{{template "_settag" . -}}
|
||||
s.Struct.SetBit({{.Field.Slot.Offset}}, {{if .Default}}!{{end}}v)
|
||||
}
|
||||
|
22
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structDataField
generated
vendored
Normal file
22
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structDataField
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() ({{.FieldType}}, error) {
|
||||
{{template "_checktag" . -}}
|
||||
p, err := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
{{with .Default -}}
|
||||
return {{$.FieldType}}(p.DataDefault({{printf "%#v" .}})), err
|
||||
{{- else -}}
|
||||
return {{.FieldType}}(p.Data()), err
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
{{template "_hasfield" .}}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v {{.FieldType}}) error {
|
||||
{{template "_settag" . -}}
|
||||
{{if .Default -}}
|
||||
if v == nil {
|
||||
v = []byte{}
|
||||
}
|
||||
{{end -}}
|
||||
return s.Struct.SetData({{.Field.Slot.Offset}}, v)
|
||||
}
|
||||
|
17
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structEnums
generated
vendored
Normal file
17
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structEnums
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
type {{.Node.Name}}_Which uint16
|
||||
|
||||
const (
|
||||
{{range .Fields}} {{$.Node.Name}}_Which_{{.Name}} {{$.Node.Name}}_Which = {{.DiscriminantValue}}
|
||||
{{end}}
|
||||
)
|
||||
|
||||
func (w {{.Node.Name}}_Which) String() string {
|
||||
const s = {{.EnumString.ValueString|printf "%q"}}
|
||||
switch w {
|
||||
{{range $i, $f := .Fields}}case {{$.Node.Name}}_Which_{{.Name}}:
|
||||
return s{{$.EnumString.SliceFor $i}}
|
||||
{{end}}
|
||||
}
|
||||
return "{{.Node.Name}}_Which(" + {{.G.Imports.Strconv}}.FormatUint(uint64(w), 10) + ")"
|
||||
}
|
||||
|
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structFloatField
generated
vendored
Normal file
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structFloatField
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() float{{.Bits}} {
|
||||
{{template "_checktag" . -}}
|
||||
return {{.G.Imports.Math}}.Float{{.Bits}}frombits(s.Struct.Uint{{.Bits}}({{.Offset}}){{with .Default}} ^ {{printf "%#x" .}}{{end}})
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v float{{.Bits}}) {
|
||||
{{template "_settag" . -}}
|
||||
s.Struct.SetUint{{.Bits}}({{.Offset}}, {{.G.Imports.Math}}.Float{{.Bits}}bits(v){{with .Default}}^{{printf "%#x" .}}{{end}})
|
||||
}
|
||||
|
5
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structFuncs
generated
vendored
Normal file
5
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structFuncs
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{{if gt .Node.StructNode.DiscriminantCount 0}}
|
||||
func (s {{.Node.Name}}) Which() {{.Node.Name}}_Which {
|
||||
return {{.Node.Name}}_Which(s.Struct.Uint16({{.Node.DiscriminantOffset}}))
|
||||
}
|
||||
{{end -}}
|
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structGroup
generated
vendored
Normal file
4
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structGroup
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() {{.Group.Name}} { return {{.Group.Name}}(s) }
|
||||
{{if .Field.HasDiscriminant}}
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}() { {{template "_settag" .}} }
|
||||
{{end}}
|
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structIntField
generated
vendored
Normal file
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structIntField
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() {{.ReturnType}} {
|
||||
{{template "_checktag" . -}}
|
||||
return {{.ReturnType}}(s.Struct.Uint{{.Bits}}({{.Offset}}){{with .Default}} ^ {{.}}{{end}})
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v {{.ReturnType}}) {
|
||||
{{template "_settag" . -}}
|
||||
s.Struct.SetUint{{.Bits}}({{.Offset}}, uint{{.Bits}}(v){{with .Default}}^{{.}}{{end}})
|
||||
}
|
||||
|
18
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structInterfaceField
generated
vendored
Normal file
18
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structInterfaceField
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() {{.FieldType}} {
|
||||
{{template "_checktag" . -}}
|
||||
p, _ := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
return {{.FieldType}}{Client: p.Interface().Client()}
|
||||
}
|
||||
|
||||
{{template "_hasfield" .}}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v {{.FieldType}}) error {
|
||||
{{template "_settag" . -}}
|
||||
if v.Client == nil {
|
||||
return s.Struct.SetPtr({{.Field.Slot.Offset}}, capnp.Ptr{})
|
||||
}
|
||||
seg := s.Segment()
|
||||
in := {{.G.Capnp}}.NewInterface(seg, seg.Message().AddCap(v.Client))
|
||||
return s.Struct.SetPtr({{.Field.Slot.Offset}}, in.ToPtr())
|
||||
}
|
||||
|
19
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structList
generated
vendored
Normal file
19
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structList
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// {{.Node.Name}}_List is a list of {{.Node.Name}}.
|
||||
type {{.Node.Name}}_List struct{ {{.G.Capnp}}.List }
|
||||
|
||||
// New{{.Node.Name}} creates a new list of {{.Node.Name}}.
|
||||
func New{{.Node.Name}}_List(s *{{.G.Capnp}}.Segment, sz int32) ({{.Node.Name}}_List, error) {
|
||||
l, err := {{.G.Capnp}}.NewCompositeList(s, {{.G.ObjectSize .Node}}, sz)
|
||||
return {{.Node.Name}}_List{l}, err
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}_List) At(i int) {{.Node.Name}} { return {{.Node.Name}}{ s.List.Struct(i) } }
|
||||
|
||||
func (s {{.Node.Name}}_List) Set(i int, v {{.Node.Name}}) error { return s.List.SetStruct(i, v.Struct) }
|
||||
{{if .StringMethod}}
|
||||
func (s {{.Node.Name}}_List) String() string {
|
||||
str, _ := {{.G.Imports.Text}}.MarshalList({{.Node.Id|printf "%#x"}}, s.List)
|
||||
return str
|
||||
}
|
||||
{{end}}
|
||||
|
33
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structListField
generated
vendored
Normal file
33
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structListField
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() ({{.FieldType}}, error) {
|
||||
{{template "_checktag" . -}}
|
||||
p, err := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
{{if .Default.IsValid -}}
|
||||
if err != nil {
|
||||
return {{.FieldType}}{}, err
|
||||
}
|
||||
l, err := p.ListDefault({{.Default}})
|
||||
return {{.FieldType}}{List: l}, err
|
||||
{{- else -}}
|
||||
return {{.FieldType}}{List: p.List()}, err
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
{{template "_hasfield" .}}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v {{.FieldType}}) error {
|
||||
{{template "_settag" . -}}
|
||||
return s.Struct.SetPtr({{.Field.Slot.Offset}}, v.List.ToPtr())
|
||||
}
|
||||
|
||||
// New{{.Field.Name|title}} sets the {{.Field.Name}} field to a newly
|
||||
// allocated {{.FieldType}}, preferring placement in s's segment.
|
||||
func (s {{.Node.Name}}) New{{.Field.Name|title}}(n int32) ({{.FieldType}}, error) {
|
||||
{{template "_settag" . -}}
|
||||
l, err := {{.G.RemoteTypeNew .Field.Slot.Type .Node}}(s.Struct.Segment(), n)
|
||||
if err != nil {
|
||||
return {{.FieldType}}{}, err
|
||||
}
|
||||
err = s.Struct.SetPtr({{.Field.Slot.Offset}}, l.List.ToPtr())
|
||||
return l, err
|
||||
}
|
||||
|
37
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structPointerField
generated
vendored
Normal file
37
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structPointerField
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() ({{.G.Capnp}}.Pointer, error) {
|
||||
{{template "_checktag" . -}}
|
||||
{{if .Default.IsValid -}}
|
||||
p, err := s.Struct.Pointer({{.Field.Slot.Offset}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return {{.G.Capnp}}.PointerDefault(p, {{.Default}})
|
||||
{{- else -}}
|
||||
return s.Struct.Pointer({{.Field.Slot.Offset}})
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
{{template "_hasfield" .}}
|
||||
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}Ptr() ({{.G.Capnp}}.Ptr, error) {
|
||||
{{if .Default.IsValid -}}
|
||||
p, err := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.Default({{.Default}})
|
||||
{{- else -}}
|
||||
return s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v {{.G.Capnp}}.Pointer) error {
|
||||
{{template "_settag" . -}}
|
||||
return s.Struct.SetPointer({{.Field.Slot.Offset}}, v)
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}Ptr(v {{.G.Capnp}}.Ptr) error {
|
||||
{{template "_settag" . -}}
|
||||
return s.Struct.SetPtr({{.Field.Slot.Offset}}, v)
|
||||
}
|
||||
|
33
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structStructField
generated
vendored
Normal file
33
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structStructField
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() ({{.FieldType}}, error) {
|
||||
{{template "_checktag" . -}}
|
||||
p, err := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
{{if .Default.IsValid -}}
|
||||
if err != nil {
|
||||
return {{.FieldType}}{}, err
|
||||
}
|
||||
ss, err := p.StructDefault({{.Default}})
|
||||
return {{.FieldType}}{Struct: ss}, err
|
||||
{{- else -}}
|
||||
return {{.FieldType}}{Struct: p.Struct()}, err
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
{{template "_hasfield" .}}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v {{.FieldType}}) error {
|
||||
{{template "_settag" . -}}
|
||||
return s.Struct.SetPtr({{.Field.Slot.Offset}}, v.Struct.ToPtr())
|
||||
}
|
||||
|
||||
// New{{.Field.Name|title}} sets the {{.Field.Name}} field to a newly
|
||||
// allocated {{.FieldType}} struct, preferring placement in s's segment.
|
||||
func (s {{.Node.Name}}) New{{.Field.Name|title}}() ({{.FieldType}}, error) {
|
||||
{{template "_settag" . -}}
|
||||
ss, err := {{.G.RemoteNodeNew .TypeNode .Node}}(s.Struct.Segment())
|
||||
if err != nil {
|
||||
return {{.FieldType}}{}, err
|
||||
}
|
||||
err = s.Struct.SetPtr({{.Field.Slot.Offset}}, ss.Struct.ToPtr())
|
||||
return ss, err
|
||||
}
|
||||
|
30
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structTextField
generated
vendored
Normal file
30
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structTextField
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() (string, error) {
|
||||
{{template "_checktag" . -}}
|
||||
p, err := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
{{with .Default -}}
|
||||
return p.TextDefault({{printf "%q" .}}), err
|
||||
{{- else -}}
|
||||
return p.Text(), err
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
{{template "_hasfield" .}}
|
||||
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}Bytes() ([]byte, error) {
|
||||
p, err := s.Struct.Ptr({{.Field.Slot.Offset}})
|
||||
{{with .Default -}}
|
||||
return p.TextBytesDefault({{printf "%q" .}}), err
|
||||
{{- else -}}
|
||||
return p.TextBytes(), err
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v string) error {
|
||||
{{template "_settag" . -}}
|
||||
{{if .Default -}}
|
||||
return s.Struct.SetNewText({{.Field.Slot.Offset}}, v)
|
||||
{{- else -}}
|
||||
return s.Struct.SetText({{.Field.Slot.Offset}}, v)
|
||||
{{- end}}
|
||||
}
|
||||
|
8
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structTypes
generated
vendored
Normal file
8
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structTypes
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{{with .Annotations.Doc -}}
|
||||
// {{.}}
|
||||
{{end -}}
|
||||
type {{.Node.Name}} {{if .IsBase -}}
|
||||
struct{ {{.G.Capnp}}.Struct }
|
||||
{{- else -}}
|
||||
{{.BaseNode.Name}}
|
||||
{{- end}}
|
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structUintField
generated
vendored
Normal file
10
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structUintField
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
func (s {{.Node.Name}}) {{.Field.Name|title}}() uint{{.Bits}} {
|
||||
{{template "_checktag" . -}}
|
||||
return s.Struct.Uint{{.Bits}}({{.Offset}}){{with .Default}} ^ {{.}}{{end}}
|
||||
}
|
||||
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}(v uint{{.Bits}}) {
|
||||
{{template "_settag" . -}}
|
||||
s.Struct.SetUint{{.Bits}}({{.Offset}}, v{{with .Default}}^{{.}}{{end}})
|
||||
}
|
||||
|
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structValue
generated
vendored
Normal file
2
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structValue
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
{{.G.RemoteNodeName .Typ .Node}}{Struct: {{.G.Capnp}}.MustUnmarshalRootPtr({{.Value}}).Struct()}
|
||||
{{- /* no EOL */ -}}
|
6
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structVoidField
generated
vendored
Normal file
6
vendor/zombiezen.com/go/capnproto2/capnpc-go/templates/structVoidField
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{{if .Field.HasDiscriminant -}}
|
||||
func (s {{.Node.Name}}) Set{{.Field.Name|title}}() {
|
||||
{{template "_settag" .}}
|
||||
}
|
||||
|
||||
{{end -}}
|
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/aircraft.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/aircraft.capnp.out
generated
vendored
Normal file
Binary file not shown.
13
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/const.capnp
generated
vendored
Normal file
13
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/const.capnp
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Generate scopes.capnp.out with:
|
||||
# capnp compile -o- scopes.capnp > scopes.capnp.out
|
||||
# Must run inside this directory to preserve paths.
|
||||
|
||||
using Go = import "go.capnp";
|
||||
|
||||
@0xc260cb50ae622e10;
|
||||
|
||||
$Go.package("const");
|
||||
$Go.import("zombiezen.com/go/capnproto2/capnpc-go/testdata/const");
|
||||
|
||||
const answer @0xda96e2255811b258 :Int64 = 42;
|
||||
const blob @0xe0a385c7be1fea4d :Data = "\x01\x02\x03";
|
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/const.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/const.capnp.out
generated
vendored
Normal file
Binary file not shown.
15
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/go.capnp
generated
vendored
Normal file
15
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/go.capnp
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Generate go.capnp.out with:
|
||||
# capnp compile -o- go.capnp > go.capnp.out
|
||||
# Must run inside this directory to preserve paths.
|
||||
|
||||
@0xd12a1c51fedd6c88;
|
||||
|
||||
annotation package(file) :Text;
|
||||
annotation import(file) :Text;
|
||||
annotation doc(struct, field, enum) :Text;
|
||||
annotation tag(enumerant) :Text;
|
||||
annotation notag(enumerant) :Void;
|
||||
annotation customtype(field) :Text;
|
||||
annotation name(struct, field, union, enum, enumerant, interface, method, param, annotation, const, group) :Text;
|
||||
|
||||
$package("capnp");
|
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/go.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/go.capnp.out
generated
vendored
Normal file
Binary file not shown.
11
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/group.capnp
generated
vendored
Normal file
11
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/group.capnp
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
using Go = import "go.capnp";
|
||||
@0x83c2b5818e83ab19;
|
||||
|
||||
$Go.package("template_fix");
|
||||
$Go.import("zombiezen.com/go/capnproto2/capnpc-go/testdata/group");
|
||||
|
||||
struct SomeMisguidedStruct {
|
||||
someGroup :group {
|
||||
someGroupField @0 :UInt64;
|
||||
}
|
||||
}
|
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/group.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/group.capnp.out
generated
vendored
Normal file
Binary file not shown.
11
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/otherscopes.capnp
generated
vendored
Normal file
11
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/otherscopes.capnp
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# File to be imported from scopes.capnp.
|
||||
|
||||
using Go = import "go.capnp";
|
||||
|
||||
@0x9c339b0568fe60ba;
|
||||
|
||||
$Go.package("otherscopes");
|
||||
$Go.import("zombiezen.com/go/capnproto2/capnpc-go/testdata/otherscopes");
|
||||
|
||||
struct Foo @0xd127518fcfe6191d {
|
||||
}
|
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/rpc.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/rpc.capnp.out
generated
vendored
Normal file
Binary file not shown.
20
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/scopes.capnp
generated
vendored
Normal file
20
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/scopes.capnp
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generate scopes.capnp.out with:
|
||||
# capnp compile -o- scopes.capnp > scopes.capnp.out
|
||||
# Must run inside this directory to preserve paths.
|
||||
|
||||
using Go = import "go.capnp";
|
||||
using Other = import "otherscopes.capnp";
|
||||
|
||||
@0xd68755941d99d05e;
|
||||
|
||||
$Go.package("scopes");
|
||||
$Go.import("zombiezen.com/go/capnproto2/capnpc-go/testdata/scopes");
|
||||
|
||||
struct Foo @0xc8d7b3b4e07f8bd9 {
|
||||
}
|
||||
|
||||
const fooVar @0x84efedc75e99768d :Foo = ();
|
||||
const otherFooVar @0x836faf1834d91729 :Other.Foo = ();
|
||||
const fooListVar @0xcda2680ec5c921e0 :List(Foo) = [];
|
||||
const otherFooListVar @0x83e7e1b3cd1be338 :List(Other.Foo) = [];
|
||||
const intList @0xacf3d9917d0bb0f0 :List(Int32) = [];
|
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/scopes.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/scopes.capnp.out
generated
vendored
Normal file
Binary file not shown.
173
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/util.capnp
generated
vendored
Normal file
173
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/util.capnp
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
# Sandstorm - Personal Cloud Sandbox
|
||||
# Copyright (c) 2014 Sandstorm Development Group, Inc. and contributors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Derived from sandstorm at 08fafe55995edfe188777eb00b5a2d1826032c59.
|
||||
# Using Go annotations.
|
||||
|
||||
@0xecd50d792c3d9992;
|
||||
|
||||
using Go = import "go.capnp";
|
||||
$Go.package("util");
|
||||
$Go.import("zombiezen.com/go/capnproto2/capnpc-go/testdata/util");
|
||||
|
||||
using DateInNs = Int64;
|
||||
using DurationInNs = UInt64;
|
||||
|
||||
struct KeyValue {
|
||||
key @0 :Text;
|
||||
value @1 :Text;
|
||||
}
|
||||
|
||||
struct LocalizedText {
|
||||
# Text intended to be displayed to a user. May be localized to multiple languages.
|
||||
#
|
||||
# TODO(soon): Maybe instead of packing all translations in here, we should have a message code
|
||||
# and parameter substitutions, with the (message code, locale) -> text map stored elsewhere?
|
||||
|
||||
defaultText @0 :Text;
|
||||
# What to display if no localization matching the user's preferences is available.
|
||||
|
||||
localizations @1 :List(Localization);
|
||||
# Localized versions of the text.
|
||||
|
||||
struct Localization {
|
||||
locale @0 :Text; # IETF BCP 47 locale, e.g. "en" or "en-US".
|
||||
text @1 :Text; # Localized text.
|
||||
}
|
||||
}
|
||||
|
||||
interface Handle {
|
||||
# Arbitrary handle to some resource provided by the platform. May or may not be persistent,
|
||||
# depending on the use case.
|
||||
#
|
||||
# To "drop" a handle means to discard any references. The purpose of a handle is to detect when
|
||||
# it has been dropped and to free the underlying resource and cancel any ongoing operation at
|
||||
# that time.
|
||||
#
|
||||
# A handle can be persistent. Once you have called `save()` on it to obtain a SturdyRef, dropping
|
||||
# the live reference will not cancel the operation. You must drop all live references *and*
|
||||
# explicitly drop any SturdyRef. Every interface which supports restoring SturdyRefs also
|
||||
# has a corresponding `drop()` method for this purpose.
|
||||
#
|
||||
# Unfortunately, there is no way to ensure that a SturdyRef will eventually be deleted. A grain
|
||||
# could, for example, call `save()` and then simply fail to store the SturdyRef anywhere, causing
|
||||
# it to be "leaked" until such a time as the grain itself is destroyed. Or worse, a whole server
|
||||
# could be destroyed in a fire, leaking all SturdyRefs stored therein forever. Apps implementing
|
||||
# persistent handles must be designed to account for this, probably by giving the owning user
|
||||
# a way to inspect incoming references and remove them manually. Sandstorm automatically provides
|
||||
# such an interface for all apps it hosts.
|
||||
}
|
||||
|
||||
interface ByteStream {
|
||||
# Represents a destination for a stream of bytes. The bytes are ordered, but boundaries between
|
||||
# messages are not semantically important.
|
||||
#
|
||||
# Streams are push-oriented (traditionally, "output streams") rather than pull-oriented ("input
|
||||
# streams") because this most easily allows multiple packets to be in-flight at once while
|
||||
# allowing flow control at either end. If we tried to design a pull-oriented stream, it would
|
||||
# suffer from problems:
|
||||
# * If we used a naive read() method that returns a simple data blob, you would need to make
|
||||
# multiple simultaneous calls to deal with network latency. However, those calls could
|
||||
# potentially return in the wrong order. Although you could restore order by keeping track of
|
||||
# the order in which the calls were made, this would be a lot of work, and most callers would
|
||||
# probably fail to do it.
|
||||
# * We could instead have a read() method that returns a blob as well as a capability to read the
|
||||
# next blob. You would then make multiple calls using pipelining. Even in this case, though,
|
||||
# an unpredictable event loop could schedule a pipelined call's return before the parent call.
|
||||
# Moreover, the interface would be awkward to use and implement. E.g. what happens if you call
|
||||
# read() twice on the same capability?
|
||||
|
||||
write @0 (data :Data);
|
||||
# Add bytes.
|
||||
#
|
||||
# It's safe to make overlapping calls to `write()`, since Cap'n Proto enforces E-Order and so
|
||||
# the calls will be delivered in order. However, it is a good idea to limit how much data is
|
||||
# in-flight at a time, so that it doesn't fill up buffers and block other traffic. On the other
|
||||
# hand, having only one `write()` in flight at a time will not fully utilize the available
|
||||
# bandwidth if the connection has any significant latency, so parallelizing a few `write()`s is
|
||||
# a good idea.
|
||||
#
|
||||
# Similarly, the implementation of `ByteStream` can delay returning from `write()` as a way to
|
||||
# hint to the caller that it should hold off on further writes.
|
||||
|
||||
done @1 ();
|
||||
# Call after the last write to indicate that there is no more data. If the `ByteStream` is
|
||||
# discarded without a call to `done()`, the callee must assume that an error occurred and that
|
||||
# the data is incomplete.
|
||||
#
|
||||
# This will not return until all bytes are successfully written to their final destination.
|
||||
# It will throw an exception if any error occurs, including if the total number of bytes written
|
||||
# did not match `expectSize()`.
|
||||
|
||||
expectSize @2 (size :UInt64);
|
||||
# Optionally called to let the receiver know exactly how much data will be written. This should
|
||||
# normally be called before the first write(), but if called later, `size` indicates how many
|
||||
# more bytes to expect _after_ the call. It is an error by the caller if more or fewer bytes are
|
||||
# actually written before `done()`; this also implies that all calls to `expectSize()` must be
|
||||
# consistent. The caller will ignore any exceptions thrown from this method, therefore it
|
||||
# is not necessary for the callee to actually implement it.
|
||||
}
|
||||
|
||||
interface Blob @0xe53527a75d90198f {
|
||||
# Represents a large byte blob.
|
||||
|
||||
getSize @0 () -> (size :UInt64);
|
||||
# Get the total size of the blob. May block if the blob is still being uploaded and the size is
|
||||
# not yet known.
|
||||
|
||||
writeTo @1 (stream :ByteStream, startAtOffset :UInt64 = 0) -> (handle :Handle);
|
||||
# Write the contents of the blob to `stream`.
|
||||
|
||||
getSlice @2 (offset :UInt64, size :UInt32) -> (data :Data);
|
||||
# Read a slice of the blob starting at the given offset. `size` cannot be greater than Cap'n
|
||||
# Proto's limit of 2^29-1, and reasonable servers will likely impose far lower limits. If the
|
||||
# slice would cross past the end of the blob, it is truncated. Otherwise, `data` is always
|
||||
# exactly `size` bytes (though the caller should check for security purposes).
|
||||
#
|
||||
# One technique that makes a lot of sense is to start off by calling e.g. `getSlice(0, 65536)`.
|
||||
# If the returned data is less than 65536 bytes then you know you got the whole blob, otherwise
|
||||
# you may want to switch to `writeTo`.
|
||||
}
|
||||
|
||||
interface Assignable(T) {
|
||||
# An "assignable" -- a mutable memory cell. Supports subscribing to updates.
|
||||
|
||||
get @0 () -> (value :T, setter :Setter);
|
||||
# The returned setter functions the same as you'd get from `asSetter()` except that it will
|
||||
# become disconnected the next time the Assignable is set by someone else. Thus, you may use this
|
||||
# to implement optimistic concurrency control.
|
||||
|
||||
asGetter @1 () -> (getter :Getter);
|
||||
# Return a read-only capability for this assignable, co-hosted with the assignable itself for
|
||||
# performance. If the assignable is persistent, the getter is as well.
|
||||
|
||||
asSetter @2 () -> (setter :Setter);
|
||||
# Return a write-only capability for this assignable, co-hosted with the assignable itself for
|
||||
# performance. If the assignable is persistent, the setter is as well.
|
||||
|
||||
interface Getter {
|
||||
get @0 () -> (value :T);
|
||||
|
||||
subscribe @1 (setter :Setter) -> (handle :Handle);
|
||||
# Subscribe to updates. Calls the given setter any time the assignable's value changes. Drop
|
||||
# the returned handle to stop receiving updates. If `setter` is persistent, `handle` will also
|
||||
# be persistent.
|
||||
}
|
||||
|
||||
interface Setter {
|
||||
set @0 (value :T) -> ();
|
||||
}
|
||||
}
|
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/util.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/capnpc-go/testdata/util.capnp.out
generated
vendored
Normal file
Binary file not shown.
384
vendor/zombiezen.com/go/capnproto2/doc.go
generated
vendored
Normal file
384
vendor/zombiezen.com/go/capnproto2/doc.go
generated
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
Package capnp is a Cap'n Proto library for Go.
|
||||
https://capnproto.org/
|
||||
|
||||
Read the Getting Started guide for a tutorial on how to use this
|
||||
package. https://github.com/capnproto/go-capnproto2/wiki/Getting-Started
|
||||
|
||||
Generating code
|
||||
|
||||
capnpc-go provides the compiler backend for capnp.
|
||||
|
||||
# First, install capnpc-go to $PATH.
|
||||
go install zombiezen.com/go/capnproto2/capnpc-go
|
||||
# Then, generate Go files.
|
||||
capnp compile -I$GOPATH/src/zombiezen.com/go/capnproto2/std -ogo *.capnp
|
||||
|
||||
capnpc-go requires two annotations for all files: package and import.
|
||||
package is needed to know what package to place at the head of the
|
||||
generated file and what identifier to use when referring to the type
|
||||
from another package. import should be the fully qualified import path
|
||||
and is used to generate import statement from other packages and to
|
||||
detect when two types are in the same package. For example:
|
||||
|
||||
using Go = import "/go.capnp";
|
||||
$Go.package("main");
|
||||
$Go.import("zombiezen.com/go/capnproto2/example");
|
||||
|
||||
For adding documentation comments to the generated code, there's the doc
|
||||
annotation. This annotation adds the comment to a struct, enum or field so
|
||||
that godoc will pick it up. For example:
|
||||
|
||||
struct Zdate $Go.doc("Zdate represents a calendar date") {
|
||||
year @0 :Int16;
|
||||
month @1 :UInt8;
|
||||
day @2 :UInt8 ;
|
||||
}
|
||||
|
||||
Messages and Segments
|
||||
|
||||
In Cap'n Proto, the unit of communication is a message. A message
|
||||
consists of one or more segments -- contiguous blocks of memory. This
|
||||
allows large messages to be split up and loaded independently or lazily.
|
||||
Typically you will use one segment per message. Logically, a message is
|
||||
organized in a tree of objects, with the root always being a struct (as
|
||||
opposed to a list or primitive). Messages can be read from and written
|
||||
to a stream.
|
||||
|
||||
The Message and Segment types are the main types that application code
|
||||
will use from this package. The Message type has methods for marshaling
|
||||
and unmarshaling its segments to the wire format. If the application
|
||||
needs to read or write from a stream, it should use the Encoder and
|
||||
Decoder types.
|
||||
|
||||
Pointers
|
||||
|
||||
The type for a generic reference to a Cap'n Proto object is Ptr. A Ptr
|
||||
can refer to a struct, a list, or an interface. Ptr, Struct, List, and
|
||||
Interface (the pointer types) have value semantics and refer to data in
|
||||
a single segment. All of the pointer types have a notion of "valid".
|
||||
An invalid pointer will return the default value from any accessor and
|
||||
panic when any setter is called.
|
||||
|
||||
In previous versions of this package, the Pointer interface was used
|
||||
instead of the Ptr struct. This interface and functions that use it are
|
||||
now deprecated. See https://github.com/capnproto/go-capnproto2/wiki/New-Ptr-Type
|
||||
for details about this API change.
|
||||
|
||||
Data accessors and setters (i.e. struct primitive fields and list
|
||||
elements) do not return errors, but pointer accessors and setters do.
|
||||
There are a few reasons that a read or write of a pointer can fail, but
|
||||
the most common are bad pointers or allocation failures. For accessors,
|
||||
an invalid object will be returned in case of an error.
|
||||
|
||||
Since Go doesn't have generics, wrapper types provide type safety on
|
||||
lists. This package provides lists of basic types, and capnpc-go
|
||||
generates list wrappers for named types. However, if you need to use
|
||||
deeper nesting of lists (e.g. List(List(UInt8))), you will need to use a
|
||||
PointerList and wrap the elements.
|
||||
|
||||
Structs
|
||||
|
||||
For the following schema:
|
||||
|
||||
struct Foo @0x8423424e9b01c0af {
|
||||
num @0 :UInt32;
|
||||
bar @1 :Foo;
|
||||
}
|
||||
|
||||
capnpc-go will generate:
|
||||
|
||||
// Foo is a pointer to a Foo struct in a segment.
|
||||
// Member functions are provided to get/set members in the
|
||||
// struct.
|
||||
type Foo struct{ capnp.Struct }
|
||||
|
||||
// Foo_TypeID is the unique identifier for the type Foo.
|
||||
// It remains the same across languages and schema changes.
|
||||
const Foo_TypeID = 0x8423424e9b01c0af
|
||||
|
||||
// NewFoo creates a new orphaned Foo struct, preferring placement in
|
||||
// s. If there isn't enough space, then another segment in the
|
||||
// message will be used or allocated. You can set a field of type Foo
|
||||
// to this new message, but usually you will want to use the
|
||||
// NewBar()-style method shown below.
|
||||
func NewFoo(s *capnp.Segment) (Foo, error)
|
||||
|
||||
// NewRootFoo creates a new Foo struct and sets the message's root to
|
||||
// it.
|
||||
func NewRootFoo(s *capnp.Segment) (Foo, error)
|
||||
|
||||
// ReadRootFoo reads the message's root pointer and converts it to a
|
||||
// Foo struct.
|
||||
func ReadRootFoo(msg *capnp.Message) (Foo, error)
|
||||
|
||||
// Num returns the value of the num field.
|
||||
func (s Foo) Num() uint32
|
||||
|
||||
// SetNum sets the value of the num field to v.
|
||||
func (s Foo) SetNum(v uint32)
|
||||
|
||||
// Bar returns the value of the bar field. This can return an error
|
||||
// if the pointer goes beyond the segment's range, the segment fails
|
||||
// to load, or the pointer recursion limit has been reached.
|
||||
func (s Foo) Bar() (Foo, error)
|
||||
|
||||
// HasBar reports whether the bar field was initialized (non-null).
|
||||
func (s Foo) HasBar() bool
|
||||
|
||||
// SetBar sets the value of the bar field to v.
|
||||
func (s Foo) SetBar(v Foo) error
|
||||
|
||||
// NewBar sets the bar field to a newly allocated Foo struct,
|
||||
// preferring placement in s's segment.
|
||||
func (s Foo) NewBar() (Foo, error)
|
||||
|
||||
// Foo_List is a value with pointer semantics. It is created for all
|
||||
// structs, and is used for List(Foo) in the capnp file.
|
||||
type Foo_List struct{ capnp.List }
|
||||
|
||||
// NewFoo_List creates a new orphaned List(Foo), preferring placement
|
||||
// in s. This can then be added to a message by using a Set function
|
||||
// which takes a Foo_List. sz specifies the number of elements in the
|
||||
// list. The list's size cannot be changed after creation.
|
||||
func NewFoo_List(s *capnp.Segment, sz int32) Foo_List
|
||||
|
||||
// Len returns the number of elements in the list.
|
||||
func (s Foo_List) Len() int
|
||||
|
||||
// At returns a pointer to the i'th element. If i is an invalid index,
|
||||
// this will return an invalid Foo (all getters will return default
|
||||
// values, setters will fail).
|
||||
func (s Foo_List) At(i int) Foo
|
||||
|
||||
// Foo_Promise is a promise for a Foo. Methods are provided to get
|
||||
// promises of struct and interface fields.
|
||||
type Foo_Promise struct{ *capnp.Pipeline }
|
||||
|
||||
// Get waits until the promise is resolved and returns the result.
|
||||
func (p Foo_Promise) Get() (Foo, error)
|
||||
|
||||
// Bar returns a promise for that bar field.
|
||||
func (p Foo_Promise) Bar() Foo_Promise
|
||||
|
||||
|
||||
Groups
|
||||
|
||||
For each group a typedef is created with a different method set for just the
|
||||
groups fields:
|
||||
|
||||
struct Foo {
|
||||
group :Group {
|
||||
field @0 :Bool;
|
||||
}
|
||||
}
|
||||
|
||||
generates the following:
|
||||
|
||||
type Foo struct{ capnp.Struct }
|
||||
type Foo_group Foo
|
||||
|
||||
func (s Foo) Group() Foo_group
|
||||
func (s Foo_group) Field() bool
|
||||
|
||||
That way the following may be used to access a field in a group:
|
||||
|
||||
var f Foo
|
||||
value := f.Group().Field()
|
||||
|
||||
Note that group accessors just convert the type and so have no overhead.
|
||||
|
||||
Unions
|
||||
|
||||
Named unions are treated as a group with an inner unnamed union. Unnamed
|
||||
unions generate an enum Type_Which and a corresponding Which() function:
|
||||
|
||||
struct Foo {
|
||||
union {
|
||||
a @0 :Bool;
|
||||
b @1 :Bool;
|
||||
}
|
||||
}
|
||||
|
||||
generates the following:
|
||||
|
||||
type Foo_Which uint16
|
||||
|
||||
const (
|
||||
Foo_Which_a Foo_Which = 0
|
||||
Foo_Which_b Foo_Which = 1
|
||||
)
|
||||
|
||||
func (s Foo) A() bool
|
||||
func (s Foo) B() bool
|
||||
func (s Foo) SetA(v bool)
|
||||
func (s Foo) SetB(v bool)
|
||||
func (s Foo) Which() Foo_Which
|
||||
|
||||
Which() should be checked before using the getters, and the default case must
|
||||
always be handled.
|
||||
|
||||
Setters for single values will set the union discriminator as well as set the
|
||||
value.
|
||||
|
||||
For voids in unions, there is a void setter that just sets the discriminator.
|
||||
For example:
|
||||
|
||||
struct Foo {
|
||||
union {
|
||||
a @0 :Void;
|
||||
b @1 :Void;
|
||||
}
|
||||
}
|
||||
|
||||
generates the following:
|
||||
|
||||
func (s Foo) SetA() // Set that we are using A
|
||||
func (s Foo) SetB() // Set that we are using B
|
||||
|
||||
Similarly, for groups in unions, there is a group setter that just sets
|
||||
the discriminator. This must be called before the group getter can be
|
||||
used to set values. For example:
|
||||
|
||||
struct Foo {
|
||||
union {
|
||||
a :group {
|
||||
v :Bool
|
||||
}
|
||||
b :group {
|
||||
v :Bool
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
and in usage:
|
||||
|
||||
f.SetA() // Set that we are using group A
|
||||
f.A().SetV(true) // then we can use the group A getter to set the inner values
|
||||
|
||||
Enums
|
||||
|
||||
capnpc-go generates enum values as constants. For example in the capnp file:
|
||||
|
||||
enum ElementSize {
|
||||
empty @0;
|
||||
bit @1;
|
||||
byte @2;
|
||||
twoBytes @3;
|
||||
fourBytes @4;
|
||||
eightBytes @5;
|
||||
pointer @6;
|
||||
inlineComposite @7;
|
||||
}
|
||||
|
||||
In the generated capnp.go file:
|
||||
|
||||
type ElementSize uint16
|
||||
|
||||
const (
|
||||
ElementSize_empty ElementSize = 0
|
||||
ElementSize_bit ElementSize = 1
|
||||
ElementSize_byte ElementSize = 2
|
||||
ElementSize_twoBytes ElementSize = 3
|
||||
ElementSize_fourBytes ElementSize = 4
|
||||
ElementSize_eightBytes ElementSize = 5
|
||||
ElementSize_pointer ElementSize = 6
|
||||
ElementSize_inlineComposite ElementSize = 7
|
||||
)
|
||||
|
||||
In addition an enum.String() function is generated that will convert the constants to a string
|
||||
for debugging or logging purposes. By default, the enum name is used as the tag value,
|
||||
but the tags can be customized with a $Go.tag or $Go.notag annotation.
|
||||
|
||||
For example:
|
||||
|
||||
enum ElementSize {
|
||||
empty @0 $Go.tag("void");
|
||||
bit @1 $Go.tag("1 bit");
|
||||
byte @2 $Go.tag("8 bits");
|
||||
inlineComposite @7 $Go.notag;
|
||||
}
|
||||
|
||||
In the generated go file:
|
||||
|
||||
func (c ElementSize) String() string {
|
||||
switch c {
|
||||
case ElementSize_empty:
|
||||
return "void"
|
||||
case ElementSize_bit:
|
||||
return "1 bit"
|
||||
case ElementSize_byte:
|
||||
return "8 bits"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
Interfaces
|
||||
|
||||
capnpc-go generates type-safe Client wrappers for interfaces. For parameter
|
||||
lists and result lists, structs are generated as described above with the names
|
||||
Interface_method_Params and Interface_method_Results, unless a single struct
|
||||
type is used. For example, for this interface:
|
||||
|
||||
interface Calculator {
|
||||
evaluate @0 (expression :Expression) -> (value :Value);
|
||||
}
|
||||
|
||||
capnpc-go generates the following Go code (along with the structs
|
||||
Calculator_evaluate_Params and Calculator_evaluate_Results):
|
||||
|
||||
// Calculator is a client to a Calculator interface.
|
||||
type Calculator struct{ Client capnp.Client }
|
||||
|
||||
// Evaluate calls `evaluate` on the client. params is called on a newly
|
||||
// allocated Calculator_evaluate_Params struct to fill in the parameters.
|
||||
func (c Calculator) Evaluate(
|
||||
ctx context.Context,
|
||||
params func(Calculator_evaluate_Params) error,
|
||||
opts ...capnp.CallOption) *Calculator_evaluate_Results_Promise
|
||||
|
||||
capnpc-go also generates code to implement the interface:
|
||||
|
||||
// A Calculator_Server implements the Calculator interface.
|
||||
type Calculator_Server interface {
|
||||
Evaluate(Calculator_evaluate_Call) error
|
||||
}
|
||||
|
||||
// Calculator_evaluate_Call holds the arguments for a Calculator.evaluate server call.
|
||||
type Calculator_evaluate_Call struct {
|
||||
Ctx context.Context
|
||||
Options capnp.CallOptions
|
||||
Params Calculator_evaluate_Params
|
||||
Results Calculator_evaluate_Results
|
||||
}
|
||||
|
||||
// Calculator_ServerToClient is equivalent to calling:
|
||||
// NewCalculator(capnp.NewServer(Calculator_Methods(nil, s), s))
|
||||
// If s does not implement the Close method, then nil is used.
|
||||
func Calculator_ServerToClient(s Calculator_Server) Calculator
|
||||
|
||||
// Calculator_Methods appends methods from Calculator that call to server and
|
||||
// returns the methods. If methods is nil or the capacity of the underlying
|
||||
// slice is too small, a new slice is returned.
|
||||
func Calculator_Methods(methods []server.Method, s Calculator_Server) []server.Method
|
||||
|
||||
Since a single capability may want to implement many interfaces, you can
|
||||
use multiple *_Methods functions to build a single slice to send to
|
||||
NewServer.
|
||||
|
||||
An example of combining the client/server code to communicate with a locally
|
||||
implemented Calculator:
|
||||
|
||||
var srv Calculator_Server
|
||||
calc := Calculator_ServerToClient(srv)
|
||||
result := calc.Evaluate(ctx, func(params Calculator_evaluate_Params) {
|
||||
params.SetExpression(expr)
|
||||
})
|
||||
val := result.Value().Get()
|
||||
|
||||
A note about message ordering: when implementing a server method, you
|
||||
are responsible for acknowledging delivery of a method call. Failure to
|
||||
do so can cause deadlocks. See the server.Ack function for more details.
|
||||
*/
|
||||
package capnp // import "zombiezen.com/go/capnproto2"
|
27
vendor/zombiezen.com/go/capnproto2/encoding/text/BUILD.bazel
generated
vendored
Normal file
27
vendor/zombiezen.com/go/capnproto2/encoding/text/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["marshal.go"],
|
||||
importpath = "zombiezen.com/go/capnproto2/encoding/text",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//:go_default_library",
|
||||
"//internal/nodemap:go_default_library",
|
||||
"//internal/schema:go_default_library",
|
||||
"//internal/strquote:go_default_library",
|
||||
"//schemas:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["marshal_test.go"],
|
||||
data = glob(["testdata/**"]),
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//:go_default_library",
|
||||
"//internal/schema:go_default_library",
|
||||
"//schemas:go_default_library",
|
||||
],
|
||||
)
|
455
vendor/zombiezen.com/go/capnproto2/encoding/text/marshal.go
generated
vendored
Normal file
455
vendor/zombiezen.com/go/capnproto2/encoding/text/marshal.go
generated
vendored
Normal file
@@ -0,0 +1,455 @@
|
||||
// Package text supports marshaling Cap'n Proto messages as text based on a schema.
|
||||
package text
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/internal/nodemap"
|
||||
"zombiezen.com/go/capnproto2/internal/schema"
|
||||
"zombiezen.com/go/capnproto2/internal/strquote"
|
||||
"zombiezen.com/go/capnproto2/schemas"
|
||||
)
|
||||
|
||||
// Marker strings.
|
||||
const (
|
||||
voidMarker = "void"
|
||||
interfaceMarker = "<external capability>"
|
||||
anyPointerMarker = "<opaque pointer>"
|
||||
)
|
||||
|
||||
// Marshal returns the text representation of a struct.
|
||||
func Marshal(typeID uint64, s capnp.Struct) (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := NewEncoder(buf).Encode(typeID, s); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// MarshalList returns the text representation of a struct list.
|
||||
func MarshalList(typeID uint64, l capnp.List) (string, error) {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := NewEncoder(buf).EncodeList(typeID, l); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// An Encoder writes the text format of Cap'n Proto messages to an output stream.
|
||||
type Encoder struct {
|
||||
w errWriter
|
||||
tmp []byte
|
||||
nodes nodemap.Map
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return &Encoder{w: errWriter{w: w}}
|
||||
}
|
||||
|
||||
// UseRegistry changes the registry that the encoder consults for
|
||||
// schemas from the default registry.
|
||||
func (enc *Encoder) UseRegistry(reg *schemas.Registry) {
|
||||
enc.nodes.UseRegistry(reg)
|
||||
}
|
||||
|
||||
// Encode writes the text representation of s to the stream.
|
||||
func (enc *Encoder) Encode(typeID uint64, s capnp.Struct) error {
|
||||
if enc.w.err != nil {
|
||||
return enc.w.err
|
||||
}
|
||||
err := enc.marshalStruct(typeID, s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return enc.w.err
|
||||
}
|
||||
|
||||
// EncodeList writes the text representation of struct list l to the stream.
|
||||
func (enc *Encoder) EncodeList(typeID uint64, l capnp.List) error {
|
||||
_, seg, _ := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
typ, _ := schema.NewRootType(seg)
|
||||
typ.SetStructType()
|
||||
typ.StructType().SetTypeId(typeID)
|
||||
return enc.marshalList(typ, l)
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalBool(v bool) {
|
||||
if v {
|
||||
enc.w.WriteString("true")
|
||||
} else {
|
||||
enc.w.WriteString("false")
|
||||
}
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalInt(i int64) {
|
||||
enc.tmp = strconv.AppendInt(enc.tmp[:0], i, 10)
|
||||
enc.w.Write(enc.tmp)
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalUint(i uint64) {
|
||||
enc.tmp = strconv.AppendUint(enc.tmp[:0], i, 10)
|
||||
enc.w.Write(enc.tmp)
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalFloat32(f float32) {
|
||||
enc.tmp = strconv.AppendFloat(enc.tmp[:0], float64(f), 'g', -1, 32)
|
||||
enc.w.Write(enc.tmp)
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalFloat64(f float64) {
|
||||
enc.tmp = strconv.AppendFloat(enc.tmp[:0], f, 'g', -1, 64)
|
||||
enc.w.Write(enc.tmp)
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalText(t []byte) {
|
||||
enc.tmp = strquote.Append(enc.tmp[:0], t)
|
||||
enc.w.Write(enc.tmp)
|
||||
}
|
||||
|
||||
func needsEscape(b byte) bool {
|
||||
return b < 0x20 || b >= 0x7f
|
||||
}
|
||||
|
||||
func hexDigit(b byte) byte {
|
||||
const digits = "0123456789abcdef"
|
||||
return digits[b]
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalStruct(typeID uint64, s capnp.Struct) error {
|
||||
n, err := enc.nodes.Find(typeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !n.IsValid() || n.Which() != schema.Node_Which_structNode {
|
||||
return fmt.Errorf("cannot find struct type %#x", typeID)
|
||||
}
|
||||
var discriminant uint16
|
||||
if n.StructNode().DiscriminantCount() > 0 {
|
||||
discriminant = s.Uint16(capnp.DataOffset(n.StructNode().DiscriminantOffset() * 2))
|
||||
}
|
||||
enc.w.WriteByte('(')
|
||||
fields := codeOrderFields(n.StructNode())
|
||||
first := true
|
||||
for _, f := range fields {
|
||||
if !(f.Which() == schema.Field_Which_slot || f.Which() == schema.Field_Which_group) {
|
||||
continue
|
||||
}
|
||||
if dv := f.DiscriminantValue(); !(dv == schema.Field_noDiscriminant || dv == discriminant) {
|
||||
continue
|
||||
}
|
||||
if !first {
|
||||
enc.w.WriteString(", ")
|
||||
}
|
||||
first = false
|
||||
name, err := f.NameBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enc.w.Write(name)
|
||||
enc.w.WriteString(" = ")
|
||||
switch f.Which() {
|
||||
case schema.Field_Which_slot:
|
||||
if err := enc.marshalFieldValue(s, f); err != nil {
|
||||
return err
|
||||
}
|
||||
case schema.Field_Which_group:
|
||||
if err := enc.marshalStruct(f.Group().TypeId(), s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
enc.w.WriteByte(')')
|
||||
return nil
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalFieldValue(s capnp.Struct, f schema.Field) error {
|
||||
typ, err := f.Slot().Type()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dv, err := f.Slot().DefaultValue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dv.IsValid() && int(typ.Which()) != int(dv.Which()) {
|
||||
name, _ := f.Name()
|
||||
return fmt.Errorf("marshal field %s: default value is a %v, want %v", name, dv.Which(), typ.Which())
|
||||
}
|
||||
switch typ.Which() {
|
||||
case schema.Type_Which_void:
|
||||
enc.w.WriteString(voidMarker)
|
||||
case schema.Type_Which_bool:
|
||||
v := s.Bit(capnp.BitOffset(f.Slot().Offset()))
|
||||
d := dv.Bool()
|
||||
enc.marshalBool(!d && v || d && !v)
|
||||
case schema.Type_Which_int8:
|
||||
v := s.Uint8(capnp.DataOffset(f.Slot().Offset()))
|
||||
d := uint8(dv.Int8())
|
||||
enc.marshalInt(int64(int8(v ^ d)))
|
||||
case schema.Type_Which_int16:
|
||||
v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2))
|
||||
d := uint16(dv.Int16())
|
||||
enc.marshalInt(int64(int16(v ^ d)))
|
||||
case schema.Type_Which_int32:
|
||||
v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4))
|
||||
d := uint32(dv.Int32())
|
||||
enc.marshalInt(int64(int32(v ^ d)))
|
||||
case schema.Type_Which_int64:
|
||||
v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8))
|
||||
d := uint64(dv.Int64())
|
||||
enc.marshalInt(int64(v ^ d))
|
||||
case schema.Type_Which_uint8:
|
||||
v := s.Uint8(capnp.DataOffset(f.Slot().Offset()))
|
||||
d := dv.Uint8()
|
||||
enc.marshalUint(uint64(v ^ d))
|
||||
case schema.Type_Which_uint16:
|
||||
v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2))
|
||||
d := dv.Uint16()
|
||||
enc.marshalUint(uint64(v ^ d))
|
||||
case schema.Type_Which_uint32:
|
||||
v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4))
|
||||
d := dv.Uint32()
|
||||
enc.marshalUint(uint64(v ^ d))
|
||||
case schema.Type_Which_uint64:
|
||||
v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8))
|
||||
d := dv.Uint64()
|
||||
enc.marshalUint(v ^ d)
|
||||
case schema.Type_Which_float32:
|
||||
v := s.Uint32(capnp.DataOffset(f.Slot().Offset() * 4))
|
||||
d := math.Float32bits(dv.Float32())
|
||||
enc.marshalFloat32(math.Float32frombits(v ^ d))
|
||||
case schema.Type_Which_float64:
|
||||
v := s.Uint64(capnp.DataOffset(f.Slot().Offset() * 8))
|
||||
d := math.Float64bits(dv.Float64())
|
||||
enc.marshalFloat64(math.Float64frombits(v ^ d))
|
||||
case schema.Type_Which_structType:
|
||||
p, err := s.Ptr(uint16(f.Slot().Offset()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !p.IsValid() {
|
||||
p, _ = dv.StructValuePtr()
|
||||
}
|
||||
return enc.marshalStruct(typ.StructType().TypeId(), p.Struct())
|
||||
case schema.Type_Which_data:
|
||||
p, err := s.Ptr(uint16(f.Slot().Offset()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !p.IsValid() {
|
||||
b, _ := dv.Data()
|
||||
enc.marshalText(b)
|
||||
return nil
|
||||
}
|
||||
enc.marshalText(p.Data())
|
||||
case schema.Type_Which_text:
|
||||
p, err := s.Ptr(uint16(f.Slot().Offset()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !p.IsValid() {
|
||||
b, _ := dv.TextBytes()
|
||||
enc.marshalText(b)
|
||||
return nil
|
||||
}
|
||||
enc.marshalText(p.TextBytes())
|
||||
case schema.Type_Which_list:
|
||||
elem, err := typ.List().ElementType()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p, err := s.Ptr(uint16(f.Slot().Offset()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !p.IsValid() {
|
||||
p, _ = dv.ListPtr()
|
||||
}
|
||||
return enc.marshalList(elem, p.List())
|
||||
case schema.Type_Which_enum:
|
||||
v := s.Uint16(capnp.DataOffset(f.Slot().Offset() * 2))
|
||||
d := dv.Uint16()
|
||||
return enc.marshalEnum(typ.Enum().TypeId(), v^d)
|
||||
case schema.Type_Which_interface:
|
||||
enc.w.WriteString(interfaceMarker)
|
||||
case schema.Type_Which_anyPointer:
|
||||
enc.w.WriteString(anyPointerMarker)
|
||||
default:
|
||||
return fmt.Errorf("unknown field type %v", typ.Which())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func codeOrderFields(s schema.Node_structNode) []schema.Field {
|
||||
list, _ := s.Fields()
|
||||
n := list.Len()
|
||||
fields := make([]schema.Field, n)
|
||||
for i := 0; i < n; i++ {
|
||||
f := list.At(i)
|
||||
fields[f.CodeOrder()] = f
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalList(elem schema.Type, l capnp.List) error {
|
||||
switch elem.Which() {
|
||||
case schema.Type_Which_void:
|
||||
enc.w.WriteString(capnp.VoidList{List: l}.String())
|
||||
case schema.Type_Which_bool:
|
||||
enc.w.WriteString(capnp.BitList{List: l}.String())
|
||||
case schema.Type_Which_int8:
|
||||
enc.w.WriteString(capnp.Int8List{List: l}.String())
|
||||
case schema.Type_Which_int16:
|
||||
enc.w.WriteString(capnp.Int16List{List: l}.String())
|
||||
case schema.Type_Which_int32:
|
||||
enc.w.WriteString(capnp.Int32List{List: l}.String())
|
||||
case schema.Type_Which_int64:
|
||||
enc.w.WriteString(capnp.Int64List{List: l}.String())
|
||||
case schema.Type_Which_uint8:
|
||||
enc.w.WriteString(capnp.UInt8List{List: l}.String())
|
||||
case schema.Type_Which_uint16:
|
||||
enc.w.WriteString(capnp.UInt16List{List: l}.String())
|
||||
case schema.Type_Which_uint32:
|
||||
enc.w.WriteString(capnp.UInt32List{List: l}.String())
|
||||
case schema.Type_Which_uint64:
|
||||
enc.w.WriteString(capnp.UInt64List{List: l}.String())
|
||||
case schema.Type_Which_float32:
|
||||
enc.w.WriteString(capnp.Float32List{List: l}.String())
|
||||
case schema.Type_Which_float64:
|
||||
enc.w.WriteString(capnp.Float64List{List: l}.String())
|
||||
case schema.Type_Which_data:
|
||||
enc.w.WriteString(capnp.DataList{List: l}.String())
|
||||
case schema.Type_Which_text:
|
||||
enc.w.WriteString(capnp.TextList{List: l}.String())
|
||||
case schema.Type_Which_structType:
|
||||
enc.w.WriteByte('[')
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
if i > 0 {
|
||||
enc.w.WriteString(", ")
|
||||
}
|
||||
err := enc.marshalStruct(elem.StructType().TypeId(), l.Struct(i))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
enc.w.WriteByte(']')
|
||||
case schema.Type_Which_list:
|
||||
enc.w.WriteByte('[')
|
||||
ee, err := elem.List().ElementType()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
if i > 0 {
|
||||
enc.w.WriteString(", ")
|
||||
}
|
||||
p, err := capnp.PointerList{List: l}.PtrAt(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = enc.marshalList(ee, p.List())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
enc.w.WriteByte(']')
|
||||
case schema.Type_Which_enum:
|
||||
enc.w.WriteByte('[')
|
||||
il := capnp.UInt16List{List: l}
|
||||
typ := elem.Enum().TypeId()
|
||||
// TODO(light): only search for node once
|
||||
for i := 0; i < il.Len(); i++ {
|
||||
if i > 0 {
|
||||
enc.w.WriteString(", ")
|
||||
}
|
||||
enc.marshalEnum(typ, il.At(i))
|
||||
}
|
||||
enc.w.WriteByte(']')
|
||||
case schema.Type_Which_interface:
|
||||
enc.w.WriteByte('[')
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
if i > 0 {
|
||||
enc.w.WriteString(", ")
|
||||
}
|
||||
enc.w.WriteString(interfaceMarker)
|
||||
}
|
||||
enc.w.WriteByte(']')
|
||||
case schema.Type_Which_anyPointer:
|
||||
enc.w.WriteByte('[')
|
||||
for i := 0; i < l.Len(); i++ {
|
||||
if i > 0 {
|
||||
enc.w.WriteString(", ")
|
||||
}
|
||||
enc.w.WriteString(anyPointerMarker)
|
||||
}
|
||||
enc.w.WriteByte(']')
|
||||
default:
|
||||
return fmt.Errorf("unknown list type %v", elem.Which())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (enc *Encoder) marshalEnum(typ uint64, val uint16) error {
|
||||
n, err := enc.nodes.Find(typ)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n.Which() != schema.Node_Which_enum {
|
||||
return fmt.Errorf("marshaling enum of type @%#x: type is not an enum", typ)
|
||||
}
|
||||
enums, err := n.Enum().Enumerants()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if int(val) >= enums.Len() {
|
||||
enc.marshalUint(uint64(val))
|
||||
return nil
|
||||
}
|
||||
name, err := enums.At(int(val)).NameBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
enc.w.Write(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
type errWriter struct {
|
||||
w io.Writer
|
||||
err error
|
||||
}
|
||||
|
||||
func (ew *errWriter) Write(p []byte) (int, error) {
|
||||
if ew.err != nil {
|
||||
return 0, ew.err
|
||||
}
|
||||
var n int
|
||||
n, ew.err = ew.w.Write(p)
|
||||
return n, ew.err
|
||||
}
|
||||
|
||||
func (ew *errWriter) WriteString(s string) (int, error) {
|
||||
if ew.err != nil {
|
||||
return 0, ew.err
|
||||
}
|
||||
var n int
|
||||
n, ew.err = io.WriteString(ew.w, s)
|
||||
return n, ew.err
|
||||
}
|
||||
|
||||
func (ew *errWriter) WriteByte(b byte) error {
|
||||
if ew.err != nil {
|
||||
return ew.err
|
||||
}
|
||||
if bw, ok := ew.w.(io.ByteWriter); ok {
|
||||
ew.err = bw.WriteByte(b)
|
||||
} else {
|
||||
_, ew.err = ew.w.Write([]byte{b})
|
||||
}
|
||||
return ew.err
|
||||
}
|
229
vendor/zombiezen.com/go/capnproto2/encoding/text/marshal_test.go
generated
vendored
Normal file
229
vendor/zombiezen.com/go/capnproto2/encoding/text/marshal_test.go
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
package text
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/internal/schema"
|
||||
"zombiezen.com/go/capnproto2/schemas"
|
||||
)
|
||||
|
||||
func readTestFile(name string) ([]byte, error) {
|
||||
path := filepath.Join("testdata", name)
|
||||
return ioutil.ReadFile(path)
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
tests := []struct {
|
||||
constID uint64
|
||||
text string
|
||||
}{
|
||||
{0xc0b634e19e5a9a4e, `(key = "42", value = (int32 = -123))`},
|
||||
{0x967c8fe21790b0fb, `(key = "float", value = (float64 = 3.14))`},
|
||||
{0xdf35cb2e1f5ea087, `(key = "bool", value = (bool = false))`},
|
||||
{0xb167974479102805, `(map = [(key = "foo", value = (void = void)), (key = "bar", value = (void = void))])`},
|
||||
{0x81fdbfdc91779421, `(map = [])`},
|
||||
{0x8e85252144f61858, `(data = "Hi\xde\xad\xbe\xef\xca\xfe")`},
|
||||
{0xc21398a8474837ba, `(voidList = [void, void])`},
|
||||
{0xde82c2eeb3a4b07c, `(boolList = [true, false, true, false])`},
|
||||
{0xf9e3ffc179272aa2, `(int8List = [1, -2, 3])`},
|
||||
{0xfc421b96ec6ad2b6, `(int64List = [1, -2, 3])`},
|
||||
{0xb3034b89d02775a5, `(uint8List = [255, 0, 1])`},
|
||||
{0x9246c307e46ad03b, `(uint64List = [1, 2, 3])`},
|
||||
{0xd012128a1a9cb7fc, `(float32List = [0.5, 3.14, -2])`},
|
||||
{0xf16c386c66d492e2, `(textList = ["foo", "bar", "baz"])`},
|
||||
{0xe14f4d42aa55de8c, `(dataList = ["\xde\xad\xbe\xef", "\xca\xfe"])`},
|
||||
{0xe88c91698f7f0b73, `(cheese = gouda)`},
|
||||
{0x9c51b843b337490b, `(cheeseList = [gouda, cheddar])`},
|
||||
{0x81e2aadb8bfb237b, `(matrix = [[1, 2, 3], [4, 5, 6]])`},
|
||||
}
|
||||
|
||||
data, err := readTestFile("txt.capnp.out")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reg := new(schemas.Registry)
|
||||
err = reg.Register(&schemas.Schema{
|
||||
Bytes: data,
|
||||
Nodes: []uint64{
|
||||
0x8df8bc5abdc060a6,
|
||||
0xd3602730c572a43b,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Adding to registry: %v", err)
|
||||
}
|
||||
msg, err := capnp.Unmarshal(data)
|
||||
if err != nil {
|
||||
t.Fatal("Unmarshaling txt.capnp.out:", err)
|
||||
}
|
||||
req, err := schema.ReadRootCodeGeneratorRequest(msg)
|
||||
if err != nil {
|
||||
t.Fatal("Reading code generator request txt.capnp.out:", err)
|
||||
}
|
||||
nodes, err := req.Nodes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
nodeMap := make(map[uint64]schema.Node, nodes.Len())
|
||||
for i := 0; i < nodes.Len(); i++ {
|
||||
n := nodes.At(i)
|
||||
nodeMap[n.Id()] = n
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
c := nodeMap[test.constID]
|
||||
if !c.IsValid() {
|
||||
t.Errorf("Can't find node %#x; skipping", test.constID)
|
||||
continue
|
||||
}
|
||||
dn, _ := c.DisplayName()
|
||||
if c.Which() != schema.Node_Which_const {
|
||||
t.Errorf("%s @%#x is a %v, not const; skipping", dn, test.constID, c.Which())
|
||||
continue
|
||||
}
|
||||
|
||||
typ, err := c.Const().Type()
|
||||
if err != nil {
|
||||
t.Errorf("(%s @%#x).const.type: %v", dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if typ.Which() != schema.Type_Which_structType {
|
||||
t.Errorf("(%s @%#x).const.type is a %v; want struct", dn, test.constID, typ.Which())
|
||||
continue
|
||||
}
|
||||
tid := typ.StructType().TypeId()
|
||||
|
||||
v, err := c.Const().Value()
|
||||
if err != nil {
|
||||
t.Errorf("(%s @%#x).const.value: %v", dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if v.Which() != schema.Value_Which_structValue {
|
||||
t.Errorf("(%s @%#x).const.value is a %v; want struct", dn, test.constID, v.Which())
|
||||
continue
|
||||
}
|
||||
sv, err := v.StructValuePtr()
|
||||
if err != nil {
|
||||
t.Errorf("(%s @%#x).const.value.struct: %v", dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
enc := NewEncoder(buf)
|
||||
enc.UseRegistry(reg)
|
||||
if err := enc.Encode(tid, sv.Struct()); err != nil {
|
||||
t.Errorf("Encode(%#x, (%s @%#x).const.value.struct): %v", tid, dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if text := buf.String(); text != test.text {
|
||||
t.Errorf("Encode(%#x, (%s @%#x).const.value.struct) = %q; want %q", tid, dn, test.constID, text, test.text)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeList(t *testing.T) {
|
||||
tests := []struct {
|
||||
constID uint64
|
||||
text string
|
||||
}{
|
||||
{0x90c9e81e6418df8e, `[(key = "foo", value = (void = void)), (key = "bar", value = (void = void))]`},
|
||||
}
|
||||
|
||||
data, err := readTestFile("txt.capnp.out")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reg := new(schemas.Registry)
|
||||
err = reg.Register(&schemas.Schema{
|
||||
Bytes: data,
|
||||
Nodes: []uint64{
|
||||
0x8df8bc5abdc060a6,
|
||||
0xd3602730c572a43b,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Adding to registry: %v", err)
|
||||
}
|
||||
msg, err := capnp.Unmarshal(data)
|
||||
if err != nil {
|
||||
t.Fatal("Unmarshaling txt.capnp.out:", err)
|
||||
}
|
||||
req, err := schema.ReadRootCodeGeneratorRequest(msg)
|
||||
if err != nil {
|
||||
t.Fatal("Reading code generator request txt.capnp.out:", err)
|
||||
}
|
||||
nodes, err := req.Nodes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
nodeMap := make(map[uint64]schema.Node, nodes.Len())
|
||||
for i := 0; i < nodes.Len(); i++ {
|
||||
n := nodes.At(i)
|
||||
nodeMap[n.Id()] = n
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
c := nodeMap[test.constID]
|
||||
if !c.IsValid() {
|
||||
t.Errorf("Can't find node %#x; skipping", test.constID)
|
||||
continue
|
||||
}
|
||||
dn, _ := c.DisplayName()
|
||||
if c.Which() != schema.Node_Which_const {
|
||||
t.Errorf("%s @%#x is a %v, not const; skipping", dn, test.constID, c.Which())
|
||||
continue
|
||||
}
|
||||
|
||||
typ, err := c.Const().Type()
|
||||
if err != nil {
|
||||
t.Errorf("(%s @%#x).const.type: %v", dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if typ.Which() != schema.Type_Which_list {
|
||||
t.Errorf("(%s @%#x).const.type is a %v; want list", dn, test.constID, typ.Which())
|
||||
continue
|
||||
}
|
||||
etyp, err := typ.List().ElementType()
|
||||
if err != nil {
|
||||
t.Errorf("(%s @%#x).const.type.list.element_type: %v", dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if etyp.Which() != schema.Type_Which_structType {
|
||||
t.Errorf("(%s @%#x).const.type is a %v; want struct", dn, test.constID, etyp.Which())
|
||||
continue
|
||||
}
|
||||
tid := etyp.StructType().TypeId()
|
||||
|
||||
v, err := c.Const().Value()
|
||||
if err != nil {
|
||||
t.Errorf("(%s @%#x).const.value: %v", dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if v.Which() != schema.Value_Which_list {
|
||||
t.Errorf("(%s @%#x).const.value is a %v; want list", dn, test.constID, v.Which())
|
||||
continue
|
||||
}
|
||||
lv, err := v.ListPtr()
|
||||
if err != nil {
|
||||
t.Errorf("(%s @%#x).const.value.list: %v", dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
enc := NewEncoder(buf)
|
||||
enc.UseRegistry(reg)
|
||||
if err := enc.EncodeList(tid, lv.List()); err != nil {
|
||||
t.Errorf("Encode(%#x, (%s @%#x).const.value.list): %v", tid, dn, test.constID, err)
|
||||
continue
|
||||
}
|
||||
if text := buf.String(); text != test.text {
|
||||
t.Errorf("Encode(%#x, (%s @%#x).const.value.list) = %q; want %q", tid, dn, test.constID, text, test.text)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
76
vendor/zombiezen.com/go/capnproto2/encoding/text/testdata/txt.capnp
generated
vendored
Normal file
76
vendor/zombiezen.com/go/capnproto2/encoding/text/testdata/txt.capnp
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
@0x8ae03d633330d781;
|
||||
|
||||
struct KeyValue @0x8df8bc5abdc060a6 {
|
||||
key @0 :Text;
|
||||
value @1 :Value;
|
||||
}
|
||||
|
||||
struct Value @0xd3602730c572a43b {
|
||||
union {
|
||||
void @0 :Void;
|
||||
bool @1 :Bool;
|
||||
int8 @2 :Int8;
|
||||
int16 @3 :Int16;
|
||||
int32 @4 :Int32;
|
||||
int64 @5 :Int64;
|
||||
uint8 @6 :UInt8;
|
||||
uint16 @7 :UInt16;
|
||||
uint32 @8 :UInt32;
|
||||
uint64 @9 :UInt64;
|
||||
float32 @10 :Float32;
|
||||
float64 @11 :Float64;
|
||||
text @12 :Text;
|
||||
data @13 :Data;
|
||||
cheese @29 :Cheese;
|
||||
|
||||
map @14 :List(KeyValue);
|
||||
voidList @15 :List(Void);
|
||||
boolList @16 :List(Bool);
|
||||
int8List @17 :List(Int8);
|
||||
int16List @18 :List(Int16);
|
||||
int32List @19 :List(Int32);
|
||||
int64List @20 :List(Int64);
|
||||
uint8List @21 :List(UInt8);
|
||||
uint16List @22 :List(UInt16);
|
||||
uint32List @23 :List(UInt32);
|
||||
uint64List @24 :List(UInt64);
|
||||
float32List @25 :List(Float32);
|
||||
float64List @26 :List(Float64);
|
||||
textList @27 :List(Text);
|
||||
dataList @28 :List(Data);
|
||||
cheeseList @30 :List(Cheese);
|
||||
matrix @31 :List(List(Int32));
|
||||
}
|
||||
}
|
||||
|
||||
enum Cheese {
|
||||
cheddar @0;
|
||||
gouda @1;
|
||||
}
|
||||
|
||||
const kv @0xc0b634e19e5a9a4e :KeyValue = (key = "42", value = (int32 = -123));
|
||||
const floatKv @0x967c8fe21790b0fb :KeyValue = (key = "float", value = (float64 = 3.14));
|
||||
const boolKv @0xdf35cb2e1f5ea087 :KeyValue = (key = "bool", value = (bool = false));
|
||||
const mapVal @0xb167974479102805 :Value = (map = [
|
||||
(key = "foo", value = (void = void)),
|
||||
(key = "bar", value = (void = void)),
|
||||
]);
|
||||
const data @0x8e85252144f61858 :Value = (data = 0x"4869 dead beef cafe");
|
||||
const emptyMap @0x81fdbfdc91779421 :Value = (map = []);
|
||||
const voidList @0xc21398a8474837ba :Value = (voidList = [void, void]);
|
||||
const boolList @0xde82c2eeb3a4b07c :Value = (boolList = [true, false, true, false]);
|
||||
const int8List @0xf9e3ffc179272aa2 :Value = (int8List = [1, -2, 3]);
|
||||
const int64List @0xfc421b96ec6ad2b6 :Value = (int64List = [1, -2, 3]);
|
||||
const uint8List @0xb3034b89d02775a5 :Value = (uint8List = [255, 0, 1]);
|
||||
const uint64List @0x9246c307e46ad03b :Value = (uint64List = [1, 2, 3]);
|
||||
const floatList @0xd012128a1a9cb7fc :Value = (float32List = [0.5, 3.14, -2.0]);
|
||||
const textList @0xf16c386c66d492e2 :Value = (textList = ["foo", "bar", "baz"]);
|
||||
const dataList @0xe14f4d42aa55de8c :Value = (dataList = [0x"deadbeef", 0x"cafe"]);
|
||||
const cheese @0xe88c91698f7f0b73 :Value = (cheese = gouda);
|
||||
const cheeseList @0x9c51b843b337490b :Value = (cheeseList = [gouda, cheddar]);
|
||||
const matrix @0x81e2aadb8bfb237b :Value = (matrix = [[1, 2, 3], [4, 5, 6]]);
|
||||
|
||||
const kvList @0x90c9e81e6418df8e :List(KeyValue) = [
|
||||
(key = "foo", value = (void = void)),
|
||||
(key = "bar", value = (void = void)),
|
||||
];
|
BIN
vendor/zombiezen.com/go/capnproto2/encoding/text/testdata/txt.capnp.out
generated
vendored
Normal file
BIN
vendor/zombiezen.com/go/capnproto2/encoding/text/testdata/txt.capnp.out
generated
vendored
Normal file
Binary file not shown.
121
vendor/zombiezen.com/go/capnproto2/example_test.go
generated
vendored
Normal file
121
vendor/zombiezen.com/go/capnproto2/example_test.go
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
package capnp_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
air "zombiezen.com/go/capnproto2/internal/aircraftlib"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
// Make a brand new empty message.
|
||||
msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
|
||||
// If you want runtime-type identification, this is easily obtained. Just
|
||||
// wrap everything in a struct that contains a single anoymous union (e.g. struct Z).
|
||||
// Then always set a Z as the root object in you message/first segment.
|
||||
// The cost of the extra word of storage is usually worth it, as
|
||||
// then human readable output is easily obtained via a shell command such as
|
||||
//
|
||||
// $ cat binary.cpz | capnp decode aircraft.capnp Z
|
||||
//
|
||||
// If you need to conserve space, and know your content in advance, it
|
||||
// isn't necessary to use an anonymous union. Just supply the type name
|
||||
// in place of 'Z' in the decode command above.
|
||||
|
||||
// There can only be one root. Subsequent NewRoot* calls will set the root
|
||||
// pointer and orphan the previous root.
|
||||
z, err := air.NewRootZ(seg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// then non-root objects:
|
||||
aircraft, err := z.NewAircraft()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
b737, err := aircraft.NewB737()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
planebase, err := b737.NewBase()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Set primitive fields
|
||||
planebase.SetCanFly(true)
|
||||
planebase.SetName("Henrietta")
|
||||
planebase.SetRating(100)
|
||||
planebase.SetMaxSpeed(876) // km/hr
|
||||
// if we don't set capacity, it will get the default value, in this case 0.
|
||||
//planebase.SetCapacity(26020) // Liters fuel
|
||||
|
||||
// Creating a list
|
||||
homes, err := planebase.NewHomes(2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
homes.Set(0, air.Airport_jfk)
|
||||
homes.Set(1, air.Airport_lax)
|
||||
|
||||
// Ready to write!
|
||||
|
||||
// You can write to memory...
|
||||
buf, err := msg.Marshal()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_ = buf
|
||||
|
||||
// ... or write to an io.Writer.
|
||||
file, err := ioutil.TempFile("", "go-capnproto")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
defer os.Remove(file.Name())
|
||||
err = capnp.NewEncoder(file).Encode(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleUnmarshal() {
|
||||
msg, s, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
if err != nil {
|
||||
fmt.Printf("allocation error %v\n", err)
|
||||
return
|
||||
}
|
||||
d, err := air.NewRootZdate(s)
|
||||
if err != nil {
|
||||
fmt.Printf("root error %v\n", err)
|
||||
return
|
||||
}
|
||||
d.SetYear(2004)
|
||||
d.SetMonth(12)
|
||||
d.SetDay(7)
|
||||
data, err := msg.Marshal()
|
||||
if err != nil {
|
||||
fmt.Printf("marshal error %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Read
|
||||
msg, err = capnp.Unmarshal(data)
|
||||
if err != nil {
|
||||
fmt.Printf("unmarshal error %v\n", err)
|
||||
return
|
||||
}
|
||||
d, err = air.ReadRootZdate(msg)
|
||||
if err != nil {
|
||||
fmt.Printf("read root error %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("year %d, month %d, day %d\n", d.Year(), d.Month(), d.Day())
|
||||
// Output:
|
||||
// year 2004, month 12, day 7
|
||||
}
|
45
vendor/zombiezen.com/go/capnproto2/go.capnp.go
generated
vendored
Normal file
45
vendor/zombiezen.com/go/capnproto2/go.capnp.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Code generated by capnpc-go. DO NOT EDIT.
|
||||
|
||||
package capnp
|
||||
|
||||
import (
|
||||
schemas "zombiezen.com/go/capnproto2/schemas"
|
||||
)
|
||||
|
||||
const Package = uint64(0xbea97f1023792be0)
|
||||
const Import = uint64(0xe130b601260e44b5)
|
||||
const Doc = uint64(0xc58ad6bd519f935e)
|
||||
const Tag = uint64(0xa574b41924caefc7)
|
||||
const Notag = uint64(0xc8768679ec52e012)
|
||||
const Customtype = uint64(0xfa10659ae02f2093)
|
||||
const Name = uint64(0xc2b96012172f8df1)
|
||||
const schema_d12a1c51fedd6c88 = "x\xda\x12\x98\xe2\xc0d\xc8z\x9c\x89\x81!P\x81\x95" +
|
||||
"\xed\xff\xf1\xf7\xa7T$\xb7\x94,e\x08\xe4e\xe5\xf8" +
|
||||
"\xdf\x91s\xf7_\xa0\x8c\xd6E\x06\x06FaO\xc6." +
|
||||
"\xe1@Fv\x06\x86`\x1fFfF\x06\xc6\xff\x0f\xb4" +
|
||||
"+\x95\x05\xeaW\xee\x03)eDQj\xcb\xb8J\xd8" +
|
||||
"\x15\xac\xd4\x01\xa2\xf4c\xaf\xbe\xb8P\xc2\xceC\x0c\x17" +
|
||||
"yY\xff\xf1\xa3\xa85d\x9c$l\x09Vk\x02Q" +
|
||||
"\x1b7y~\xe0\xdek]GA\xc6\x9a\xa0(Ue" +
|
||||
"\xec\x12\xd6\x05+\xd5\x80(\x15z\x10\xf4\xa6\xb2\xad\xec" +
|
||||
"\x04\xa6c%\x19g\x09+\x82\x95\xca@\x94nu\xe1" +
|
||||
"Sc\xdcf\xf0\x10\xd3\xb1\xbc\x8c\x8b\x84E\xc1J\x05" +
|
||||
" J'+\xe8?\x98\x95*\xf0\x0b\xa4T\x01E)" +
|
||||
"#\xe3!aN\xb0R\x16\x90R\x9e\xff\xc5%)\xfa" +
|
||||
"\xe9\xf9z\xc9\x8c\x89\x05y\x05V%\x89\xe9\x0c\x0c\x01" +
|
||||
"\x8c\x8c\x8c<\x0cLhR\x05\x89\xc9\xfc\xd9\x89\xe9\xa9" +
|
||||
"\xd8e\xf3\x12s\x19qH\xa5\xe4'\xe323/\xbf" +
|
||||
"\x8491=\x80\x91\x91\x81\x19M&3\xb7\x80=\xbf" +
|
||||
"\xa8\x04]\x1b\x13X2\xb9\xb4\xb8$?\xb7\xa4\xb2 " +
|
||||
"\x15f. \x00\x00\xff\xff\x89\xff\x94\xdf"
|
||||
|
||||
func init() {
|
||||
schemas.Register(schema_d12a1c51fedd6c88,
|
||||
0xa574b41924caefc7,
|
||||
0xbea97f1023792be0,
|
||||
0xc2b96012172f8df1,
|
||||
0xc58ad6bd519f935e,
|
||||
0xc8768679ec52e012,
|
||||
0xe130b601260e44b5,
|
||||
0xfa10659ae02f2093)
|
||||
}
|
6
vendor/zombiezen.com/go/capnproto2/go.mod
generated
vendored
Normal file
6
vendor/zombiezen.com/go/capnproto2/go.mod
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
module "zombiezen.com/go/capnproto2"
|
||||
|
||||
require (
|
||||
"github.com/kylelemons/godebug" v0.0.0-20170820004349-d65d576e9348
|
||||
"golang.org/x/net" v0.0.0-20180218175443-cbe0f9307d01
|
||||
)
|
2396
vendor/zombiezen.com/go/capnproto2/integration_test.go
generated
vendored
Normal file
2396
vendor/zombiezen.com/go/capnproto2/integration_test.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
110
vendor/zombiezen.com/go/capnproto2/integrationutil_test.go
generated
vendored
Normal file
110
vendor/zombiezen.com/go/capnproto2/integrationutil_test.go
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
package capnp_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
air "zombiezen.com/go/capnproto2/internal/aircraftlib"
|
||||
"zombiezen.com/go/capnproto2/internal/capnptool"
|
||||
)
|
||||
|
||||
const schemaPath = "internal/aircraftlib/aircraft.capnp"
|
||||
|
||||
func initNester(t *testing.T, n air.Nester1Capn, strs ...string) {
|
||||
tl, err := n.NewStrs(int32(len(strs)))
|
||||
if err != nil {
|
||||
t.Fatalf("initNester(..., %q): NewStrs: %v", strs, err)
|
||||
}
|
||||
for i, s := range strs {
|
||||
if err := tl.Set(i, s); err != nil {
|
||||
t.Fatalf("initNester(..., %q): set strs[%d]: %v", strs, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func zdateFilledMessage(t testing.TB, n int32) *capnp.Message {
|
||||
msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
z, err := air.NewRootZ(seg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
list, err := z.NewZdatevec(n)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for i := 0; i < int(n); i++ {
|
||||
d, err := air.NewZdate(seg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d.SetMonth(12)
|
||||
d.SetDay(7)
|
||||
d.SetYear(int16(2004 + i))
|
||||
list.Set(i, d)
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
func zdataFilledMessage(t testing.TB, n int) *capnp.Message {
|
||||
msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
z, err := air.NewRootZ(seg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d, err := air.NewZdata(seg)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := make([]byte, n)
|
||||
for i := 0; i < len(b); i++ {
|
||||
b[i] = byte(i)
|
||||
}
|
||||
d.SetData(b)
|
||||
z.SetZdata(d)
|
||||
return msg
|
||||
}
|
||||
|
||||
// encodeTestMessage encodes the textual Cap'n Proto message to unpacked
|
||||
// binary using the capnp tool, or returns the fallback if the tool fails.
|
||||
func encodeTestMessage(typ string, text string, fallback []byte) ([]byte, error) {
|
||||
tool, err := capnptool.Find()
|
||||
if err != nil {
|
||||
// TODO(light): log tool missing
|
||||
return fallback, nil
|
||||
}
|
||||
b, err := tool.Encode(capnptool.Type{SchemaPath: schemaPath, Name: typ}, text)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s value %q encode failed: %v", typ, text, err)
|
||||
}
|
||||
if !bytes.Equal(b, fallback) {
|
||||
return nil, fmt.Errorf("%s value %q =\n%s; fallback is\n%s\nFallback out of date?", typ, text, hex.Dump(b), hex.Dump(fallback))
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// mustEncodeTestMessage encodes the textual Cap'n Proto message to unpacked
|
||||
// binary using the capnp tool, or returns the fallback if the tool fails.
|
||||
func mustEncodeTestMessage(t testing.TB, typ string, text string, fallback []byte) []byte {
|
||||
b, err := encodeTestMessage(typ, text, fallback)
|
||||
if err != nil {
|
||||
if _, fname, line, ok := runtime.Caller(1); ok {
|
||||
t.Fatalf("%s:%d: %v", filepath.Base(fname), line, err)
|
||||
} else {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
24
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/BUILD.bazel
generated
vendored
Normal file
24
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"aircraft.capnp.go",
|
||||
"generate.go",
|
||||
],
|
||||
importpath = "zombiezen.com/go/capnproto2/internal/aircraftlib",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//:go_default_library",
|
||||
"//encoding/text:go_default_library",
|
||||
"//schemas:go_default_library",
|
||||
"//server:go_default_library",
|
||||
"@org_golang_x_net//context:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "schema",
|
||||
srcs = ["aircraft.capnp"],
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
353
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/aircraft.capnp
generated
vendored
Normal file
353
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/aircraft.capnp
generated
vendored
Normal file
@@ -0,0 +1,353 @@
|
||||
using Go = import "/go.capnp";
|
||||
|
||||
$Go.package("aircraftlib");
|
||||
$Go.import("zombiezen.com/go/capnproto2/internal/aircraftlib");
|
||||
|
||||
@0x832bcc6686a26d56;
|
||||
|
||||
const constDate :Zdate = (year = 2015, month = 8, day = 27);
|
||||
const constList :List(Zdate) = [(year = 2015, month = 8, day = 27), (year = 2015, month = 8, day = 28)];
|
||||
const constEnum :Airport = jfk;
|
||||
|
||||
struct Zdate {
|
||||
year @0 :Int16;
|
||||
month @1 :UInt8;
|
||||
day @2 :UInt8;
|
||||
}
|
||||
|
||||
struct Zdata {
|
||||
data @0 :Data;
|
||||
}
|
||||
|
||||
|
||||
enum Airport {
|
||||
none @0;
|
||||
jfk @1;
|
||||
lax @2;
|
||||
sfo @3;
|
||||
luv @4;
|
||||
dfw @5;
|
||||
test @6;
|
||||
# test must be last because we use it to count
|
||||
# the number of elements in the Airport enum.
|
||||
}
|
||||
|
||||
struct PlaneBase {
|
||||
name @0: Text;
|
||||
homes @1: List(Airport);
|
||||
rating @2: Int64;
|
||||
canFly @3: Bool;
|
||||
capacity @4: Int64;
|
||||
maxSpeed @5: Float64;
|
||||
}
|
||||
|
||||
struct B737 {
|
||||
base @0: PlaneBase;
|
||||
}
|
||||
|
||||
struct A320 {
|
||||
base @0: PlaneBase;
|
||||
}
|
||||
|
||||
struct F16 {
|
||||
base @0: PlaneBase;
|
||||
}
|
||||
|
||||
|
||||
# need a struct with at least two pointers to catch certain bugs
|
||||
struct Regression {
|
||||
base @0: PlaneBase;
|
||||
b0 @1: Float64; # intercept
|
||||
beta @2: List(Float64);
|
||||
planes @3: List(Aircraft);
|
||||
ymu @4: Float64; # y-mean in original space
|
||||
ysd @5: Float64; # y-standard deviation in original space
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct Aircraft {
|
||||
# so we can restrict
|
||||
# and specify a Plane is required in
|
||||
# certain places.
|
||||
|
||||
union {
|
||||
void @0: Void; # @0 will be the default, so always make @0 a Void.
|
||||
b737 @1: B737;
|
||||
a320 @2: A320;
|
||||
f16 @3: F16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct Z {
|
||||
# Z must contain all types, as this is our
|
||||
# runtime type identification. It is a thin shim.
|
||||
|
||||
union {
|
||||
void @0: Void; # always first in any union.
|
||||
zz @1: Z; # any. fyi, this can't be 'z' alone.
|
||||
|
||||
f64 @2: Float64;
|
||||
f32 @3: Float32;
|
||||
|
||||
i64 @4: Int64;
|
||||
i32 @5: Int32;
|
||||
i16 @6: Int16;
|
||||
i8 @7: Int8;
|
||||
|
||||
u64 @8: UInt64;
|
||||
u32 @9: UInt32;
|
||||
u16 @10: UInt16;
|
||||
u8 @11: UInt8;
|
||||
|
||||
bool @12: Bool;
|
||||
text @13: Text;
|
||||
blob @14: Data;
|
||||
|
||||
f64vec @15: List(Float64);
|
||||
f32vec @16: List(Float32);
|
||||
|
||||
i64vec @17: List(Int64);
|
||||
i32vec @18: List(Int32);
|
||||
i16vec @19: List(Int16);
|
||||
i8vec @20: List(Int8);
|
||||
|
||||
u64vec @21: List(UInt64);
|
||||
u32vec @22: List(UInt32);
|
||||
u16vec @23: List(UInt16);
|
||||
u8vec @24: List(UInt8);
|
||||
|
||||
boolvec @39: List(Bool);
|
||||
datavec @40: List(Data);
|
||||
textvec @41: List(Text);
|
||||
|
||||
zvec @25: List(Z);
|
||||
zvecvec @26: List(List(Z));
|
||||
|
||||
zdate @27: Zdate;
|
||||
zdata @28: Zdata;
|
||||
|
||||
aircraftvec @29: List(Aircraft);
|
||||
aircraft @30: Aircraft;
|
||||
regression @31: Regression;
|
||||
planebase @32: PlaneBase;
|
||||
airport @33: Airport;
|
||||
b737 @34: B737;
|
||||
a320 @35: A320;
|
||||
f16 @36: F16;
|
||||
zdatevec @37: List(Zdate);
|
||||
zdatavec @38: List(Zdata);
|
||||
|
||||
grp :group {
|
||||
first @42 :UInt64;
|
||||
second @43 :UInt64;
|
||||
}
|
||||
|
||||
echo @44 :Echo;
|
||||
echoBases @45 :EchoBases;
|
||||
}
|
||||
}
|
||||
|
||||
# tests for Text/List(Text) recusion handling
|
||||
|
||||
struct Counter {
|
||||
size @0: Int64;
|
||||
words @1: Text;
|
||||
wordlist @2: List(Text);
|
||||
bitlist @3: List(Bool);
|
||||
}
|
||||
|
||||
struct Bag {
|
||||
counter @0: Counter;
|
||||
}
|
||||
|
||||
struct Zserver {
|
||||
waitingjobs @0: List(Zjob);
|
||||
}
|
||||
|
||||
struct Zjob {
|
||||
cmd @0: Text;
|
||||
args @1: List(Text);
|
||||
}
|
||||
|
||||
# versioning test structs
|
||||
|
||||
struct VerEmpty {
|
||||
}
|
||||
|
||||
struct VerOneData {
|
||||
val @0: Int16;
|
||||
}
|
||||
|
||||
struct VerTwoData {
|
||||
val @0: Int16;
|
||||
duo @1: Int64;
|
||||
}
|
||||
|
||||
struct VerOnePtr {
|
||||
ptr @0: VerOneData;
|
||||
}
|
||||
|
||||
struct VerTwoPtr {
|
||||
ptr1 @0: VerOneData;
|
||||
ptr2 @1: VerOneData;
|
||||
}
|
||||
|
||||
struct VerTwoDataTwoPtr {
|
||||
val @0: Int16;
|
||||
duo @1: Int64;
|
||||
ptr1 @2: VerOneData;
|
||||
ptr2 @3: VerOneData;
|
||||
}
|
||||
|
||||
struct HoldsVerEmptyList {
|
||||
mylist @0: List(VerEmpty);
|
||||
}
|
||||
|
||||
struct HoldsVerOneDataList {
|
||||
mylist @0: List(VerOneData);
|
||||
}
|
||||
|
||||
struct HoldsVerTwoDataList {
|
||||
mylist @0: List(VerTwoData);
|
||||
}
|
||||
|
||||
struct HoldsVerOnePtrList {
|
||||
mylist @0: List(VerOnePtr);
|
||||
}
|
||||
|
||||
struct HoldsVerTwoPtrList {
|
||||
mylist @0: List(VerTwoPtr);
|
||||
}
|
||||
|
||||
struct HoldsVerTwoTwoList {
|
||||
mylist @0: List(VerTwoDataTwoPtr);
|
||||
}
|
||||
|
||||
struct HoldsVerTwoTwoPlus {
|
||||
mylist @0: List(VerTwoTwoPlus);
|
||||
}
|
||||
|
||||
struct VerTwoTwoPlus {
|
||||
val @0: Int16;
|
||||
duo @1: Int64;
|
||||
ptr1 @2: VerTwoDataTwoPtr;
|
||||
ptr2 @3: VerTwoDataTwoPtr;
|
||||
tre @4: Int64;
|
||||
lst3 @5: List(Int64);
|
||||
}
|
||||
|
||||
# text handling
|
||||
|
||||
struct HoldsText {
|
||||
txt @0: Text;
|
||||
lst @1: List(Text);
|
||||
lstlst @2: List(List(Text));
|
||||
}
|
||||
|
||||
# test that we avoid unnecessary truncation
|
||||
|
||||
struct WrapEmpty {
|
||||
mightNotBeReallyEmpty @0: VerEmpty;
|
||||
}
|
||||
|
||||
struct Wrap2x2 {
|
||||
mightNotBeReallyEmpty @0: VerTwoDataTwoPtr;
|
||||
}
|
||||
|
||||
struct Wrap2x2plus {
|
||||
mightNotBeReallyEmpty @0: VerTwoTwoPlus;
|
||||
}
|
||||
|
||||
# test voids in a union
|
||||
|
||||
struct VoidUnion {
|
||||
union {
|
||||
a @0 :Void;
|
||||
b @1 :Void;
|
||||
}
|
||||
}
|
||||
|
||||
# test List(List(Struct(List)))
|
||||
|
||||
struct Nester1Capn {
|
||||
strs @0: List(Text);
|
||||
}
|
||||
|
||||
struct RWTestCapn {
|
||||
nestMatrix @0: List(List(Nester1Capn));
|
||||
}
|
||||
|
||||
struct ListStructCapn {
|
||||
vec @0: List(Nester1Capn);
|
||||
}
|
||||
|
||||
# test interfaces
|
||||
|
||||
interface Echo {
|
||||
echo @0 (in :Text) -> (out :Text);
|
||||
}
|
||||
|
||||
struct Hoth {
|
||||
base @0 :EchoBase;
|
||||
}
|
||||
|
||||
struct EchoBase {
|
||||
echo @0 :Echo;
|
||||
}
|
||||
|
||||
# test List(Struct(Interface))
|
||||
|
||||
struct EchoBases {
|
||||
bases @0 :List(EchoBase);
|
||||
}
|
||||
|
||||
# test transforms
|
||||
|
||||
struct StackingRoot {
|
||||
a @1 :StackingA;
|
||||
aWithDefault @0 :StackingA = (num = 42);
|
||||
}
|
||||
|
||||
struct StackingA {
|
||||
num @0 :Int32;
|
||||
b @1 :StackingB;
|
||||
}
|
||||
|
||||
struct StackingB {
|
||||
num @0 :Int32;
|
||||
}
|
||||
|
||||
interface CallSequence {
|
||||
getNumber @0 () -> (n :UInt32);
|
||||
}
|
||||
|
||||
# test defaults
|
||||
|
||||
struct Defaults {
|
||||
text @0 :Text = "foo";
|
||||
data @1 :Data = "bar";
|
||||
float @2 :Float32 = 3.14;
|
||||
int @3 :Int32 = -123;
|
||||
uint @4 :UInt32 = 42;
|
||||
}
|
||||
|
||||
# benchmarks
|
||||
|
||||
struct BenchmarkA {
|
||||
name @0 :Text;
|
||||
birthDay @1 :Int64;
|
||||
phone @2 :Text;
|
||||
siblings @3 :Int32;
|
||||
spouse @4 :Bool;
|
||||
money @5 :Float64;
|
||||
}
|
||||
|
||||
struct AllocBenchmark {
|
||||
fields @0 :List(Field);
|
||||
|
||||
struct Field {
|
||||
stringValue @0 :Text;
|
||||
}
|
||||
}
|
6270
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/aircraft.capnp.go
generated
vendored
Normal file
6270
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/aircraft.capnp.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/generate.go
generated
vendored
Normal file
3
vendor/zombiezen.com/go/capnproto2/internal/aircraftlib/generate.go
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
package aircraftlib
|
||||
|
||||
//go:generate capnp compile -I ../../std -ogo aircraft.capnp
|
8
vendor/zombiezen.com/go/capnproto2/internal/capnptool/BUILD.bazel
generated
vendored
Normal file
8
vendor/zombiezen.com/go/capnproto2/internal/capnptool/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["capnptool.go"],
|
||||
importpath = "zombiezen.com/go/capnproto2/internal/capnptool",
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
76
vendor/zombiezen.com/go/capnproto2/internal/capnptool/capnptool.go
generated
vendored
Normal file
76
vendor/zombiezen.com/go/capnproto2/internal/capnptool/capnptool.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Package capnptool provides an API for calling the capnp tool in tests.
|
||||
package capnptool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Tool is the path to the capnp command-line tool.
|
||||
// It can be used from multiple goroutines.
|
||||
type Tool string
|
||||
|
||||
var cache struct {
|
||||
init sync.Once
|
||||
tool Tool
|
||||
err error
|
||||
}
|
||||
|
||||
// Find searches PATH for the capnp tool.
|
||||
func Find() (Tool, error) {
|
||||
cache.init.Do(func() {
|
||||
path, err := exec.LookPath("capnp")
|
||||
if err != nil {
|
||||
cache.err = err
|
||||
return
|
||||
}
|
||||
cache.tool = Tool(path)
|
||||
})
|
||||
return cache.tool, cache.err
|
||||
}
|
||||
|
||||
// Run executes the tool with the given stdin and arguments returns the stdout.
|
||||
func (tool Tool) Run(stdin io.Reader, args ...string) ([]byte, error) {
|
||||
c := exec.Command(string(tool), args...)
|
||||
c.Stdin = stdin
|
||||
stderr := new(bytes.Buffer)
|
||||
c.Stderr = stderr
|
||||
out, err := c.Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("run `%s`: %v; stderr:\n%s", strings.Join(c.Args, " "), err, stderr)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Encode encodes Cap'n Proto text into the binary representation.
|
||||
func (tool Tool) Encode(typ Type, text string) ([]byte, error) {
|
||||
return tool.Run(strings.NewReader(text), "encode", typ.SchemaPath, typ.Name)
|
||||
}
|
||||
|
||||
// Decode decodes a Cap'n Proto message into text.
|
||||
func (tool Tool) Decode(typ Type, r io.Reader) (string, error) {
|
||||
out, err := tool.Run(r, "decode", "--short", typ.SchemaPath, typ.Name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
// DecodePacked decodes a packed Cap'n Proto message into text.
|
||||
func (tool Tool) DecodePacked(typ Type, r io.Reader) (string, error) {
|
||||
out, err := tool.Run(r, "decode", "--short", "--packed", typ.SchemaPath, typ.Name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
// Type is a reference to a Cap'n Proto type in a schema.
|
||||
type Type struct {
|
||||
SchemaPath string
|
||||
Name string
|
||||
}
|
193
vendor/zombiezen.com/go/capnproto2/internal/cmd/mktemplates/mktemplates.go
generated
vendored
Normal file
193
vendor/zombiezen.com/go/capnproto2/internal/cmd/mktemplates/mktemplates.go
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
// +build mktemplates
|
||||
// Build tag so that users who run `go get zombiezen.com/go/capnproto2/...` don't install this command.
|
||||
// cd internal/cmd/mktemplates && go build -tags=mktemplates
|
||||
|
||||
// mktemplates is a command to regenerate capnpc-go/templates.go.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template/parse"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Fprintln(os.Stderr, "usage: mktemplates OUT DIR")
|
||||
os.Exit(64)
|
||||
}
|
||||
dir := os.Args[2]
|
||||
names, err := listdir(dir)
|
||||
if err != nil {
|
||||
fatalln(err)
|
||||
}
|
||||
ts := make([]template, len(names))
|
||||
for i, name := range names {
|
||||
src, err := ioutil.ReadFile(filepath.Join(dir, name))
|
||||
if err != nil {
|
||||
fatalf("reading template %s: %v", name, err)
|
||||
}
|
||||
compiled, err := compileTemplate(name, string(src))
|
||||
if err != nil {
|
||||
fatalf("compiling template %s: %v", name, err)
|
||||
}
|
||||
ts[i] = template{
|
||||
name: name,
|
||||
content: compiled,
|
||||
}
|
||||
}
|
||||
genbuf := new(bytes.Buffer)
|
||||
err = generateGo(genbuf, os.Args, ts)
|
||||
if err != nil {
|
||||
fatalln("generating code:", err)
|
||||
}
|
||||
code, err := format.Source(genbuf.Bytes())
|
||||
if err != nil {
|
||||
fatalln("formatting code:", err)
|
||||
}
|
||||
outname := os.Args[1]
|
||||
out, err := os.Create(outname)
|
||||
if err != nil {
|
||||
fatalf("opening destination %s: %v", outname, err)
|
||||
}
|
||||
_, err = out.Write(code)
|
||||
cerr := out.Close()
|
||||
if err != nil {
|
||||
fatalf("write to %s: %v", outname, err)
|
||||
}
|
||||
if cerr != nil {
|
||||
fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func compileTemplate(name, src string) (string, error) {
|
||||
tset, err := parse.Parse(name, src, "{{", "}}", funcStubs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tset[name].Root.String(), nil
|
||||
}
|
||||
|
||||
func generateGo(w io.Writer, args []string, ts []template) error {
|
||||
src := new(bytes.Buffer)
|
||||
for _, t := range ts {
|
||||
fmt.Fprintf(src, "{{define %q}}", t.name)
|
||||
src.WriteString(t.content)
|
||||
src.WriteString("{{end}}")
|
||||
}
|
||||
|
||||
// TODO(light): collect errors
|
||||
fmt.Fprintln(w, "// Code generated from templates directory. DO NOT EDIT.")
|
||||
fmt.Fprintln(w)
|
||||
fmt.Fprintln(w, "//go:generate", strings.Join(args, " "))
|
||||
fmt.Fprintln(w)
|
||||
fmt.Fprintln(w, "package main")
|
||||
fmt.Fprintln(w, "import (")
|
||||
fmt.Fprintln(w, "\t\"strings\"")
|
||||
fmt.Fprintln(w, "\t\"text/template\"")
|
||||
fmt.Fprintln(w, ")")
|
||||
fmt.Fprintln(w, "var templates = template.Must(template.New(\"\").Funcs(template.FuncMap{")
|
||||
fmt.Fprintln(w, "\t\"title\": strings.Title,")
|
||||
fmt.Fprintf(w, "}).Parse(\n\t%q))\n", src.Bytes())
|
||||
for _, t := range ts {
|
||||
if strings.HasPrefix(t.name, "_") {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(w, "func render%s(r renderer, p %sParams) error {\n\treturn r.Render(%[2]q, p)\n}\n", strings.Title(t.name), t.name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type template struct {
|
||||
name string
|
||||
content string
|
||||
}
|
||||
|
||||
func listdir(name string) ([]string, error) {
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
names, err := f.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n := 0
|
||||
for _, name := range names {
|
||||
if !strings.HasPrefix(name, ".") {
|
||||
names[n] = name
|
||||
n++
|
||||
}
|
||||
}
|
||||
names = names[:n]
|
||||
sort.Strings(names)
|
||||
return names, nil
|
||||
}
|
||||
|
||||
func fatalln(args ...interface{}) {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("mktemplates: ")
|
||||
fmt.Fprintln(&buf, args...)
|
||||
os.Stderr.Write(buf.Bytes())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func fatalf(format string, args ...interface{}) {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString("mktemplates: ")
|
||||
fmt.Fprintf(&buf, format, args...)
|
||||
if !bytes.HasSuffix(buf.Bytes(), []byte{'\n'}) {
|
||||
buf.Write([]byte{'\n'})
|
||||
}
|
||||
os.Stderr.Write(buf.Bytes())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var funcStubs = map[string]interface{}{
|
||||
// Built-ins
|
||||
"and": variadicBoolStub,
|
||||
"call": func(interface{}, ...interface{}) (interface{}, error) { return nil, nil },
|
||||
"eq": func(arg0 interface{}, args ...interface{}) (bool, error) { return false, nil },
|
||||
"ge": cmpStub,
|
||||
"gt": cmpStub,
|
||||
"html": escaperStub,
|
||||
"index": func(interface{}, ...interface{}) (interface{}, error) { return nil, nil },
|
||||
"js": escaperStub,
|
||||
"le": cmpStub,
|
||||
"len": func(interface{}) (int, error) { return 0, nil },
|
||||
"lt": cmpStub,
|
||||
"ne": cmpStub,
|
||||
"not": func(interface{}) bool { return false },
|
||||
"or": variadicBoolStub,
|
||||
"print": fmt.Sprint,
|
||||
"printf": fmt.Sprintf,
|
||||
"println": fmt.Sprintln,
|
||||
"urlquery": escaperStub,
|
||||
|
||||
// App-specific
|
||||
"title": strings.Title,
|
||||
}
|
||||
|
||||
func variadicBoolStub(arg0 interface{}, args ...interface{}) interface{} {
|
||||
return arg0
|
||||
}
|
||||
|
||||
func cmpStub(interface{}, interface{}) (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func escaperStub(...interface{}) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func importStub() string {
|
||||
return ""
|
||||
}
|
24
vendor/zombiezen.com/go/capnproto2/internal/demo/BUILD.bazel
generated
vendored
Normal file
24
vendor/zombiezen.com/go/capnproto2/internal/demo/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["doc.go"],
|
||||
importpath = "zombiezen.com/go/capnproto2/internal/demo",
|
||||
visibility = ["//:__subpackages__"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"book_test.go",
|
||||
"hash_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//:go_default_library",
|
||||
"//internal/demo/books:go_default_library",
|
||||
"//internal/demo/hashes:go_default_library",
|
||||
"//rpc:go_default_library",
|
||||
"@org_golang_x_net//context:go_default_library",
|
||||
],
|
||||
)
|
61
vendor/zombiezen.com/go/capnproto2/internal/demo/book_test.go
generated
vendored
Normal file
61
vendor/zombiezen.com/go/capnproto2/internal/demo/book_test.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
package demo_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"zombiezen.com/go/capnproto2"
|
||||
"zombiezen.com/go/capnproto2/internal/demo/books"
|
||||
)
|
||||
|
||||
func Example_book() {
|
||||
r, w := io.Pipe()
|
||||
go writer(w)
|
||||
reader(r)
|
||||
// Output:
|
||||
// "War and Peace" has 1440 pages
|
||||
}
|
||||
|
||||
func writer(out io.Writer) {
|
||||
// Make a brand new empty message. A Message allocates Cap'n Proto structs.
|
||||
msg, seg, err := capnp.NewMessage(capnp.SingleSegment(nil))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create a new Book struct. Every message must have a root struct.
|
||||
book, err := books.NewRootBook(seg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
book.SetTitle("War and Peace")
|
||||
book.SetPageCount(1440)
|
||||
|
||||
// Write the message to stdout.
|
||||
err = capnp.NewEncoder(out).Encode(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func reader(in io.Reader) {
|
||||
// Read the message from stdin.
|
||||
msg, err := capnp.NewDecoder(in).Decode()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Extract the root struct from the message.
|
||||
book, err := books.ReadRootBook(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Access fields from the struct.
|
||||
title, err := book.Title()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
pageCount := book.PageCount()
|
||||
fmt.Printf("%q has %d pages\n", title, pageCount)
|
||||
}
|
16
vendor/zombiezen.com/go/capnproto2/internal/demo/books/BUILD.bazel
generated
vendored
Normal file
16
vendor/zombiezen.com/go/capnproto2/internal/demo/books/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"books.capnp.go",
|
||||
"gen.go",
|
||||
],
|
||||
importpath = "zombiezen.com/go/capnproto2/internal/demo/books",
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//:go_default_library",
|
||||
"//encoding/text:go_default_library",
|
||||
"//schemas:go_default_library",
|
||||
],
|
||||
)
|
12
vendor/zombiezen.com/go/capnproto2/internal/demo/books/books.capnp
generated
vendored
Normal file
12
vendor/zombiezen.com/go/capnproto2/internal/demo/books/books.capnp
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
using Go = import "/go.capnp";
|
||||
@0x85d3acc39d94e0f8;
|
||||
$Go.package("books");
|
||||
$Go.import("zombiezen.com/go/capnproto2/internal/demo/books");
|
||||
|
||||
struct Book {
|
||||
title @0 :Text;
|
||||
# Title of the book.
|
||||
|
||||
pageCount @1 :Int32;
|
||||
# Number of pages in the book.
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user