| // Copyright 2018 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package fidl |
| |
| import ( |
| "sync" |
| |
| "syscall/zx" |
| ) |
| |
| // messageBytesPool is a pool of buffers that can fit the data part of any |
| // FIDL message. |
| var messageBytesPool = sync.Pool{ |
| New: func() interface{} { |
| return make([]byte, zx.ChannelMaxMessageBytes) |
| }, |
| } |
| |
| // messageHandleInfosPool is a pool of buffers that can fit the handle infos |
| // for a FIDL message. |
| var messageHandleInfosPool = sync.Pool{ |
| New: func() interface{} { |
| return make([]zx.HandleInfo, zx.ChannelMaxMessageHandles) |
| }, |
| } |
| |
| // messageHandlesPool is a pool of buffers that can fit the handle dispositions |
| // for a FIDL message. |
| var messageHandleDispositionsPool = sync.Pool{ |
| New: func() interface{} { |
| return make([]zx.HandleDisposition, zx.ChannelMaxMessageHandles) |
| }, |
| } |
| |
| // MarshalHeaderThenMessage marshals a transactional message |
| // (see https://fuchsia.googlesource.com/fuchsia/+/master/docs/development/languages/fidl/reference/wire-format/README.md#messages-for-transactions). |
| // It marshals a `MessageHeader`, optionally followed by a `Message` (body). |
| func MarshalHeaderThenMessage(header *MessageHeader, body Message, data []byte, handleDispositions []zx.HandleDisposition) (int, int, error) { |
| ctx := header.NewCtx() |
| hnb, _, err := Marshal(ctx, header, data, nil) |
| if err != nil { |
| return 0, 0, err |
| } |
| if body == nil { |
| return hnb, 0, nil |
| } |
| nb, nh, err := Marshal(ctx, body, data[hnb:], handleDispositions) |
| if err != nil { |
| return 0, 0, err |
| } |
| return hnb + nb, nh, nil |
| } |
| |
| // UnmarshalHeaderThenMessage unmarshals a transactional message |
| // (see https://fuchsia.googlesource.com/fuchsia/+/master/docs/development/languages/fidl/reference/wire-format/README.md#messages-for-transactions). |
| // It unmarshals a `MessageHeader`, optionally followed by a `Message` (body). |
| func UnmarshalHeaderThenMessage(data []byte, handleInfos []zx.HandleInfo, header *MessageHeader, body Message) error { |
| ctx := header.NewCtx() |
| if err := Unmarshal(ctx, data[:MessageHeaderSize], nil, header); err != nil { |
| return err |
| } |
| if body == nil { |
| return nil |
| } |
| return Unmarshal(ctx, data[MessageHeaderSize:], handleInfos, body) |
| } |