[fidl][go] Support unknown data for tables (1.5/4)
Between step 2 and step 3, createMarshaler must be able
to handle tables that may or may not have an I_unknownData
field.
This also defines the fidl.UnknownData type which is
referenced in codegen added in step 2.
Step 1: Ib6f9dce7cea743ce50f61fc5cba8b5e6c4c49242
Step 2: I3e839ceb761820299238f19c3bebdcd95fd1eb2f
Step 3: Ifd7ebe3db2544f4a07add78600d008a072c1d1a2
Test: fx test -v go-fidl-tests
Change-Id: I98b63518ad640d56029d9cbc1b07cd773a37015e
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/go/+/439059
Commit-Queue: Felix Zhu <fcz@google.com>
Reviewed-by: Pascal Perez <pascallouis@google.com>
diff --git a/api/fuchsia.txt b/api/fuchsia.txt
index 66f6a34..882578d 100644
--- a/api/fuchsia.txt
+++ b/api/fuchsia.txt
@@ -1093,6 +1093,9 @@
pkg syscall/zx/fidl, type ServiceRequest interface, ToChannel() zx.Channel
pkg syscall/zx/fidl, type Stub interface { Dispatch }
pkg syscall/zx/fidl, type Stub interface, Dispatch(DispatchArgs) (Message, bool, error)
+pkg syscall/zx/fidl, type UnknownData struct
+pkg syscall/zx/fidl, type UnknownData struct, Bytes []uint8
+pkg syscall/zx/fidl, type UnknownData struct, Handles []zx.HandleInfo
pkg syscall/zx/fidl, type ValidationError interface { Code, Error }
pkg syscall/zx/fidl, type ValidationError interface, Code() ErrorCode
pkg syscall/zx/fidl, type ValidationError interface, Error() string
diff --git a/src/syscall/zx/fidl/encoding_new.go b/src/syscall/zx/fidl/encoding_new.go
index c7f9c6f..ae4782e 100644
--- a/src/syscall/zx/fidl/encoding_new.go
+++ b/src/syscall/zx/fidl/encoding_new.go
@@ -307,10 +307,20 @@
presenceOffsets []uintptr
)
+ // If a table has an I_unknownData field, then all presence fields must be
+ // odd-numbered. If there is no I_unknownData field, then all presence
+ // fields must be even numbered
+ presenceFieldOddness := 1
+
// - structs, unions, and xunions have fields one after the other;
// - tables have a field, followed by a bool presence indicator, etc.
for index, field := range dataFields(typ) {
- if kind == tableTag && index%2 == 1 {
+ if (kind == xunionTag || kind == tableTag) && isUnknownDataField(field.Name) {
+ presenceFieldOddness = 0
+ continue
+ }
+
+ if kind == tableTag && index%2 == presenceFieldOddness {
// Presence field
if field.Type.Kind() != reflect.Bool {
return nil, errors.New("incorrect presence field on " + nicefmt(typ))
@@ -319,10 +329,6 @@
continue
}
- if (kind == xunionTag || kind == tableTag) && isUnknownDataField(field.Name) {
- continue
- }
-
fieldBounds := readBoundsTag(field)
handleRights, handleSubtype, err := readHandleRightsAndSubtype(field)
if err != nil {
diff --git a/src/syscall/zx/fidl/types.go b/src/syscall/zx/fidl/types.go
index ea78174..1bacc86 100644
--- a/src/syscall/zx/fidl/types.go
+++ b/src/syscall/zx/fidl/types.go
@@ -4,6 +4,8 @@
package fidl
+import "syscall/zx"
+
// Enum is implemented by any value that is a FIDL enum.
//
// During code generation, `fidlgen_go` ensures that all domain types generated
@@ -34,3 +36,9 @@
// GetUnknownBits returns a uint64 containing only the unknown bits
GetUnknownBits() uint64
}
+
+// UnknownData represents the raw bytes and handles of an unknown payload
+type UnknownData struct {
+ Bytes []byte
+ Handles []zx.HandleInfo
+}