blob: 37b13695782921d3fdd23c0bcd98bcdcdeb9e7f9 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_LEDGER_LIB_ENCODING_ENCODING_H_
#define SRC_LEDGER_LIB_ENCODING_ENCODING_H_
#include <lib/fidl/cpp/encoder.h>
#include <string>
#include <vector>
#include "src/ledger/lib/logging/logging.h"
#include "src/ledger/lib/vmo/vector.h"
namespace ledger {
// Serializes T in a buffer. In our use case, we do not rely on FIDL encoding
// being stable: the buffer is simply a way to extend the maximum message size,
// and we expect the buffer to be immediately deserialized.
// Caveats: see https://fuchsia-review.googlesource.com/c/fuchsia/+/262309
// TODO(ambre): rewrite this using a more-supported API when available.
template <typename T>
bool EncodeToBuffer(T* data, fuchsia::mem::Buffer* buffer) {
LEDGER_DCHECK(data);
LEDGER_DCHECK(buffer);
fidl::Encoder encoder(fidl::Encoder::NO_HEADER);
// We need to preallocate the size of the structure in the encoder, the rest
// is allocated when the vector is encoded.
encoder.Alloc(fidl::EncodingInlineSize<T, fidl::Encoder>(&encoder));
fidl::Encode(&encoder, data, 0);
return VmoFromVector(encoder.TakeBytes(), buffer);
}
// Deserialization of T from a buffer. See the comment in EncodeToBuffer for
// details/caveats.
// TODO(ambre): rewrite this using a supported API when available.
template <typename T>
bool DecodeFromBuffer(const fuchsia::mem::Buffer& buffer, T* data) {
LEDGER_DCHECK(data);
std::vector<uint8_t> bytes;
if (!VectorFromVmo(buffer, &bytes)) {
return false;
}
if (!bytes.data()) {
// Message::Decode cannot handle a nullptr input and has an assertion checking for this case.
return false;
}
fidl::Message message(fidl::BytePart(bytes.data(), bytes.size(), bytes.size()),
fidl::HandlePart());
const char* error_msg;
zx_status_t status = message.Decode(T::FidlType, &error_msg);
if (status != ZX_OK) {
return false;
}
fidl::Decoder decoder(std::move(message));
T::Decode(&decoder, data, 0);
return true;
}
} // namespace ledger
#endif // SRC_LEDGER_LIB_ENCODING_ENCODING_H_