Revert "Add protobuf encoding/decoding logic."

This reverts commit 7208083bd3944948e3c512b1b66fd712faa3e351.

Change-Id: If719379558661c8cd7d8f4b413d16b5528d5b515
diff --git a/Android.mk b/Android.mk
index fec35c3..68dc90b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -20,8 +20,7 @@
 LOCAL_MODULE := libnvram
 LOCAL_SRC_FILES := \
 	blob.cpp \
-	io.cpp \
-	message_codec.cpp
+	io.cpp
 LOCAL_STATIC_LIBRARIES := libbase
 LOCAL_CFLAGS := -Wall -Werror -Wextra -fvisibility=hidden
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
diff --git a/include/nvram/compiler.h b/include/nvram/compiler.h
index efcba79..8d6ad05 100644
--- a/include/nvram/compiler.h
+++ b/include/nvram/compiler.h
@@ -30,9 +30,6 @@
 // Check a condition, abort if it doesn't hold.
 #define NVRAM_CHECK(cond) if (!(cond)) abort()
 
-// The noinline attribute is understood both by clang and GCC.
-#define NVRAM_NOINLINE __attribute__((noinline))
-
 // The visibility attribute works both with clang and GCC.
 #define NVRAM_EXPORT __attribute__((visibility("default")))
 
diff --git a/include/nvram/io.h b/include/nvram/io.h
index 87a716e..c61ac12 100644
--- a/include/nvram/io.h
+++ b/include/nvram/io.h
@@ -28,18 +28,16 @@
 namespace nvram {
 
 // Abstraction used by the protobuf decoder to read data. The idea here is that
-// |InputStreamBuffer| maintains a window of the data to be read. Access to the
-// contents of the current window is direct, i.e. doesn't need to go through
-// virtual dispatch to subclasses. Whenever the window is exhausted, the next
-// window must be set up. This latter operation is left for implementation of
-// the virtual |Advance()| member function in subclasses, which is entirely free
-// to pull its data from anywhere.
+// |InputStreamBuffer| maintains a window of the data to be read. Whenever the
+// window is exhausted, the next window must be set up. This latter operation is
+// left for implementation in subclasses, which is entirely free to pull its
+// data from anywhere.
 class NVRAM_EXPORT InputStreamBuffer {
  public:
-  InputStreamBuffer() = default;
+  InputStreamBuffer();
   InputStreamBuffer(const void* data, size_t size);
   InputStreamBuffer(const void* start, const void* end);
-  virtual ~InputStreamBuffer() = default;
+  virtual ~InputStreamBuffer();
 
   // Checks whether the stream is exhausted;
   bool Done();
@@ -83,7 +81,7 @@
   // |delegate|. Note that |delegate| must remain valid throughout the life time
   // of this |NestedInputStreamBuffer|.
   NestedInputStreamBuffer(InputStreamBuffer* delegate, size_t size);
-  ~NestedInputStreamBuffer() override = default;
+  ~NestedInputStreamBuffer() override;
 
  private:
   // InputStreamBuffer:
@@ -93,20 +91,13 @@
   size_t remaining_;
 };
 
-// Abstraction used by the protobuf decoder to output data. This class maintains
-// a current window of memory to write output to. Access to the current window's
-// bytes is direct and doesn't require virtual dispatch. Once the capacity of
-// the current window is exhausted, the virtual |Advance()| member function is
-// invoked to set up a new window. Subclasses are entirely free to implement
-// this operation as appropriate for their I/O mechanism, for example a
-// socket-based implementations might flush the buffer to the socket and reset
-// the window pointers to accept more output.
+// Abstraction used by the protobuf decoder to output data.
 class NVRAM_EXPORT OutputStreamBuffer {
  public:
-  OutputStreamBuffer() = default;
+  OutputStreamBuffer();
   OutputStreamBuffer(void* data, size_t size);
   OutputStreamBuffer(void* data, void* end);
-  virtual ~OutputStreamBuffer() = default;
+  virtual ~OutputStreamBuffer();
 
   // Checks whether the stream is exhausted.
   bool Done();
@@ -142,7 +133,7 @@
 class NVRAM_EXPORT CountingOutputStreamBuffer : public OutputStreamBuffer {
  public:
   CountingOutputStreamBuffer();
-  ~CountingOutputStreamBuffer() override = default;
+  ~CountingOutputStreamBuffer() override;
 
   size_t bytes_written() const {
     return bytes_written_ + (pos_ - scratch_space_);
@@ -156,13 +147,7 @@
   // We share a single scratch buffer that all |CountingOutputStreamBuffer|
   // instances use as the destination for writes. Its contents are pretty much
   // unpredictable.
-  //
-  // TODO(mnissler): This adds a static 256 bytes memory allocation to each
-  // process linking to this code. If that becomes a problem, we might want to
-  // be smarter here and dynamically allocate a chunk of memory only when it's
-  // needed, or maybe even map some address space that's not even backed by
-  // actual memory (not sure that's possible).
-  static constexpr size_t kScratchSpaceSize = 256;
+  static constexpr size_t kScratchSpaceSize = 1024;
   static uint8_t scratch_space_[kScratchSpaceSize];
 
   // Number of bytes that had been written when the last |Advance()| call
@@ -178,14 +163,14 @@
   // |blob|, which will get resized as necessary. Note that |blob| must remain
   // valid for the life time of the |BlobOutputStreamBuffer| object.
   BlobOutputStreamBuffer(Blob* blob);
-  ~BlobOutputStreamBuffer() override = default;
+  virtual ~BlobOutputStreamBuffer();
 
   // Truncate the blob to match the current output size.
   bool Truncate();
 
  protected:
   // OutputStreamBuffer:
-  bool Advance() override;
+  virtual bool Advance() override;
 
  private:
   Blob* blob_;
diff --git a/include/nvram/message_codec.h b/include/nvram/message_codec.h
deleted file mode 100644
index 63359d9..0000000
--- a/include/nvram/message_codec.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef NVRAM_MESSAGE_CODEC_H_
-#define NVRAM_MESSAGE_CODEC_H_
-
-extern "C" {
-#include <stddef.h>
-#include <stdint.h>
-}
-
-#include <nvram/compiler.h>
-#include <nvram/io.h>
-
-namespace nvram {
-namespace proto {
-
-// |FieldDescriptor| describes a single proto field in a struct. We compile a
-// table of field descriptors for each struct that needs to be encoded or
-// decoded into the binary. See proto.hpp for the code that initializes the
-// static tables.
-struct FieldDescriptor {
-  // A function to encode a struct field in protobuf wire format. |object| is a
-  // pointer to the struct to read the value from, |writer| receives the output.
-  using EncodeFunction = bool(const void* object, ProtoWriter* writer);
-
-  // A function to encode a protobuf struct field from |reader|. The decoded
-  // data is stored in the struct instance pointed at by |object|.
-  using DecodeFunction = bool(void* object, ProtoReader* reader);
-
-  constexpr FieldDescriptor(uint32_t field_number,
-                            WireType wire_type,
-                            EncodeFunction* encode_function,
-                            DecodeFunction* decode_function)
-      : field_number(field_number),
-        wire_type(wire_type),
-        encode_function(encode_function),
-        decode_function(decode_function) {}
-
-  uint32_t field_number;
-  WireType wire_type;
-  EncodeFunction* encode_function;
-  DecodeFunction* decode_function;
-};
-
-// A table-driven protobuf message encoder. Takes a pointer to a C++ object to
-// encode and a corresponding table of field descriptors. Provides functions to
-// encode the message data in protobuf wire format.
-class NVRAM_EXPORT MessageEncoderBase {
- public:
-  // Initialize the encoder to encode |object|, using the descriptor table
-  // passed in |descriptors|.
-  MessageEncoderBase(const void* object,
-                     const FieldDescriptor* descriptors,
-                     size_t num_descriptors);
-
-  // Convenience helper that constructs an encoder instance and invokes
-  // |Encode()|.
-  static bool Encode(const void* object,
-                     ProtoWriter* writer,
-                     const FieldDescriptor* descriptors,
-                     size_t num_descriptors);
-
-  // Returns the encoded size of the object.
-  size_t GetSize();
-
-  // Encodes the object as a sequence of protobuf fields, wrapped in a
-  // length-delimited container.
-  bool Encode(ProtoWriter* writer);
-
-  // Encodes the object as a sequence of protobuf fields without any wrapping.
-  bool EncodeData(ProtoWriter* writer);
-
- private:
-  // The pointer to the object to encode. This is a void pointer, so the encoder
-  // logic can be generic and doesn't need to be instantiated for every struct
-  // type. The encode function provided by the field descriptor will cast back
-  // to the correct type.
-  const void* object_;
-
-  // Field descriptor table.
-  const FieldDescriptor* descriptors_;
-  size_t num_descriptors_;
-};
-
-// A protobuf message decoder, driven by a table of field descriptors. Consumes
-// data from a |ProtoReader|, decodes fields per the descriptor table and stores
-// it to a C++ object.
-class NVRAM_EXPORT MessageDecoderBase {
- public:
-  // Initialize a decoder to store field data according to the |descriptors|
-  // table in |object|.
-  MessageDecoderBase(void* object,
-                     const FieldDescriptor* descriptors,
-                     size_t num_descriptors);
-
-  // Convenience helper that constructs a decoder and invokes |Decode()|.
-  static bool Decode(void* object,
-                     ProtoReader* reader,
-                     const FieldDescriptor* descriptors,
-                     size_t num_descriptors);
-
-  // Decode a nested protobuf message wrapped in a length-delimited protobuf
-  // field.
-  bool Decode(ProtoReader* reader);
-
-  // Decode a protobuf message from reader. This just reads the sequence of
-  // fields, not taking into account any wrapping. This is suitable for the
-  // topmost encoded message.
-  bool DecodeData(ProtoReader* reader);
-
- private:
-  // Looks up the |FieldDescriptor| for decoding the next field. The descriptor
-  // must match the field number and wire type of the field. If no matching
-  // descriptor is found, |nullptr| is returned.
-  const FieldDescriptor* FindDescriptor(ProtoReader* reader) const;
-
-  // The object to decode to. This is a void pointer to keep the decoder generic
-  // and avoid type-specific code for each struct type. The decode function in
-  // the field descriptor casts back to the struct type.
-  void* object_;
-
-  // Descriptor table.
-  const FieldDescriptor* descriptors_;
-  size_t num_descriptors_;
-};
-
-}  // namespace proto
-}  // namespace nvram
-
-#endif  // NVRAM_MESSAGE_CODEC_H_
diff --git a/include/nvram/proto.hpp b/include/nvram/proto.hpp
deleted file mode 100644
index 4dee92e..0000000
--- a/include/nvram/proto.hpp
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-// This file implements a simple protobuf encoder and decoder. The high-level
-// idea is to use C++ structs as data containers corresponding to protobuf
-// messages. A descriptor must be provided for a struct via a
-// |nvram::DescriptorForType| specialization that declares the protobuf fields
-// to encode and decode.
-//  * Encoding works by going through the declared fields, and encode the
-//    corresponding struct members in protobuf wire format.
-//  * Decoding scans through the binary encoded message. It looks at the wire
-//    tag decoded form the message to recover the field number as well as
-//    the protobuf wire type (i.e. kind of encoding). The field number is then
-//    used to locate the struct field declaration so the appropriate decoding
-//    logic for the corresponding struct member can be invoked.
-//  * The main dispatch point that ties member types to decoding and encoding
-//    logic is the |nvram::proto::detail::Codec| template. The idea is that
-//    |Codec<Type>| provides encoding and decoding logic for |Type|.
-//
-// The API for encoding and decoding is straightforward. Consider the following
-// Employee struct and its descriptor:
-// type:
-//
-//   struct Employee {
-//     uint32_t id;
-//     std::string name;
-//     std::vector<uint32_t> reports;
-//   };
-//
-//   template <>
-//   struct DescriptorForType<Employee> {
-//     static constexpr auto kFields =
-//         MakeFieldList(MakeField(1, &Employee::id),
-//                       MakeField(2, &Employee::name),
-//                       MakeField(3, &Employee::reports));
-//   };
-//
-// Encoding is simple:
-//
-//   Employee employee;
-//   uint8_t buffer[SIZE];
-//   nvram::OutputStream stream(buffer, sizeof(buffer));
-//   if (!nvram::proto::Encode(employee, &stream)) {
-//     // Handle encoding failure.
-//   }
-//
-// Note that |nvram::proto::GetSize()| can be used to determine a sufficient
-// buffer size.
-//
-// Decoding is similar:
-//
-//   Employee employee;
-//   nvram::InputStreamBuffer stream(buffer_start, buffer_size);
-//   if (!nvram::proto::Decode(&employee, &stream)) {
-//     // Handle decoding failure.
-//   }
-//
-// Note that this file is not meant as a header to be included by all code that
-// needs to encode or decode messages. Rather, this header should only be
-// included by a .cpp file which can then instantiate the
-// |nvram::proto::Encode()| and |nvram::proto::Decode()| templates to obtain
-// encoders and decoders for the relevant message types. This approach results
-// in decode and encode logic getting compiled in only one translation unit,
-// which other code can link against.
-
-#ifndef NVRAM_PROTO_HPP_
-#define NVRAM_PROTO_HPP_
-
-extern "C" {
-#include <stdint.h>
-}
-
-#include <nvram/blob.h>
-#include <nvram/compiler.h>
-#include <nvram/io.h>
-#include <nvram/message_codec.h>
-#include <nvram/struct.h>
-#include <nvram/type_traits.h>
-#include <nvram/vector.h>
-
-namespace nvram {
-namespace proto {
-
-namespace detail {
-
-// A class template that performs encoding and decoding of a protobuf message
-// field of the C++ type |Type|. The base template is left undefined here,
-// specific implementations for relevant |Type|s are provided by template
-// specializations. Each specialization needs to provide the following members:
-//  * |static constexpr WireType kWireType| indicates the wire type used for
-//    encoded field data.
-//  * |static bool Encode(const Type& object, ProtoWriter* writer)| writes the
-//    encoded form of |object| to |writer|.
-//  * |static bool Decode(Type& object, ProtoReader* reader)| decodes a field
-//    from |reader| and places recovered data in |object|.
-//
-// |Codec| specializations are provided below for commonly-used types such as
-// integral and enum types, as well as structs with corresponding descriptors.
-// Additional specializations can be added as needed.
-template <typename Type, typename Enable = void>
-struct Codec {
-  // The assert below fails unconditionally, but must depend on the |Type|
-  // parameter so it only triggers at instantiation time. If this assert fires,
-  // then you are attempting to encode or decode a struct that contains a field
-  // of a C++ type for which there exists no code that implements encoding and
-  // decoding for that type. To add encoding/decoding support for a type, you
-  // can provide a Codec specialization.
-  static_assert(sizeof(Type) == 0,
-                "A Codec specialization must be provided for types "
-                "that are to be used with the protobuf encoder.");
-};
-
-namespace {
-
-// Codec specific message field encoding function. Note that this is marked
-// noinline to prevent the compiler from inlining |Codec::Encode| for every
-// occurrence of a field of type |Type|.
-template <typename Codec, typename Type>
-bool EncodeField(const Type& value, ProtoWriter* writer) NVRAM_NOINLINE {
-  return Codec::Encode(value, writer);
-}
-
-// Codec specific message field decoding function. Note that this is marked
-// noinline to prevent the compiler from inlining |Codec::Decode| for every
-// occurrence of a field of type |Type|.
-template <typename Codec, typename Type>
-bool DecodeField(Type& value, ProtoReader* reader) NVRAM_NOINLINE {
-  return Codec::Decode(value, reader);
-}
-
-}  // namespace
-
-// |Codec| specialization for Blob.
-template <>
-struct Codec<Blob> {
-  static constexpr WireType kWireType = WireType::kLengthDelimited;
-
-  static bool Encode(const Blob& blob, ProtoWriter* writer) {
-    return writer->WriteLengthDelimited(blob.data(), blob.size());
-  }
-
-  static bool Decode(Blob& blob, ProtoReader* reader) {
-    return blob.Resize(reader->field_size()) &&
-           reader->ReadLengthDelimited(blob.data(), blob.size());
-  }
-};
-
-// A helper to test whether a given |Type| should be handled by the Varint
-// |Codec| specialization. The |Type| needs to allow conversion from and to
-// |uint64_t|. This checks for static_cast conversion behavior instead of
-// implicit conversion in order to also match scoped enums.
-template <typename Type>
-struct IsVarintCompatible {
-  template <typename From, typename To>
-  struct IsCastConvertible {
-    template <typename T>
-    static decltype(static_cast<T>(declval<From>()), true_type()) test(int);
-
-    template <typename T>
-    static false_type test(...);
-
-    static constexpr bool value = decltype(test<To>(0))::value;
-  };
-
-  static constexpr bool value = IsCastConvertible<Type, uint64_t>::value &&
-                                IsCastConvertible<uint64_t, Type>::value;
-};
-
-// |Codec| specialization for varint-encoded numeric fields.
-template <typename Type>
-struct Codec<Type, typename enable_if<IsVarintCompatible<Type>::value>::Type> {
-  static constexpr WireType kWireType = WireType::kVarint;
-
-  static bool Encode(const Type& value, ProtoWriter* writer) {
-    return writer->WriteVarint(static_cast<uint64_t>(value));
-  }
-
-  static bool Decode(Type& value, ProtoReader* reader) {
-    uint64_t raw_value;
-    if (!reader->ReadVarint(&raw_value)) {
-      return false;
-    }
-    value = static_cast<Type>(raw_value);
-    return static_cast<uint64_t>(value) == raw_value;
-  }
-};
-
-// |Codec| specialization for |Vector|.
-template <typename ElementType>
-struct Codec<Vector<ElementType>> {
-  using ElementCodec = Codec<ElementType>;
-  static constexpr WireType kWireType = ElementCodec::kWireType;
-
-  static bool Encode(const Vector<ElementType>& vector, ProtoWriter* writer) {
-    for (const ElementType& elem : vector) {
-      if (!EncodeField<ElementCodec>(elem, writer)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  static bool Decode(Vector<ElementType>& vector, ProtoReader* reader) {
-    return vector.Resize(vector.size() + 1) &&
-           DecodeField<ElementCodec>(vector[vector.size() - 1], reader);
-  }
-};
-
-namespace {
-
-// |StructDescriptor| provides the |FieldDescriptor| table corresponding to
-// |StructType|. The table contains information about each field in the protobuf
-// encoding, e.g. field number and wire type.
-//
-// The |IndexSequence| template parameter is present purely for technical
-// reasons. It provides a sequence of indices, one for each entry in the field
-// declaration list for |StructType|. Having the index available simplifies
-// generation of the descriptor table entries.
-template <
-    typename StructType,
-    typename IndexSequence = decltype(
-        make_index_sequence<DescriptorForType<StructType>::kFields.kSize>())>
-struct StructDescriptor;
-
-template <typename StructType, size_t... indices>
-struct StructDescriptor<StructType, index_sequence<indices...>> {
- private:
-  static constexpr auto kFieldSpecList =
-      DescriptorForType<StructType>::kFields;
-  using FieldSpecs = typename remove_const<decltype(kFieldSpecList)>::Type;
-
-  // A helper function used to preform a compile-time sanity check on the
-  // declared field numbers to ensure that they're positive, unique and in
-  // ascending order.
-  template <typename FieldSpecList>
-  static constexpr bool CheckFieldNumbersAscending(
-      FieldSpecList list,
-      uint32_t previous_field_number) {
-    return list.kFieldSpec.kFieldNumber > previous_field_number &&
-           CheckFieldNumbersAscending(list.kTail, list.kFieldSpec.kFieldNumber);
-  }
-  static constexpr bool CheckFieldNumbersAscending(FieldSpecList<>, uint32_t) {
-    return true;
-  }
-
-  // If this fails, check your struct field declarations for the following:
-  //  * Field numbers must be positive.
-  //  * Field numbers must be unique.
-  //  * Fields must be declared in ascending field number order.
-  static_assert(CheckFieldNumbersAscending(kFieldSpecList, 0),
-                "Field numbers must be positive, unique and declared in "
-                "ascending order.");
-
-  // Provides the |FieldDescriptor| instance for the field specified by |index|.
-  // Note that |index| is *not* the proto field number, but the zero-based index
-  // in the field declaration list.
-  template <size_t index>
-  class FieldDescriptorBuilder {
-    static constexpr auto kFieldSpec = kFieldSpecList.template Get<index>();
-    using FieldSpecType = typename remove_const<decltype(kFieldSpec)>::Type;
-    using MemberType = typename FieldSpecType::MemberType;
-    using MemberCodec = Codec<FieldSpecType>;
-
-    // Encodes a member. Retrieves a reference to the member within |object| and
-    // calls the appropriate encoder.
-    static bool EncodeMember(const void* object, ProtoWriter* writer) {
-      constexpr auto spec = kFieldSpec;
-      return EncodeField<MemberCodec>(
-          spec.Get(*static_cast<const StructType*>(object)), writer);
-    };
-
-    // Decodes a member. Retrieves a const reference to the member within
-    // |object| and calls the appropriate decoder.
-    static bool DecodeMember(void* object, ProtoReader* reader) {
-      constexpr auto spec = kFieldSpec;
-      return DecodeField<MemberCodec>(
-          spec.Get(*static_cast<StructType*>(object)), reader);
-    };
-
-   public:
-    // Assemble the actual descriptor for the field. Note that this is still a
-    // compile-time constant (i.e. has no linkage). However, the constant is
-    // used below to initialize the entry in the static descriptor table.
-    static constexpr FieldDescriptor kDescriptor =
-        FieldDescriptor(kFieldSpec.kFieldNumber,
-                        MemberCodec::kWireType,
-                        &EncodeMember,
-                        &DecodeMember);
-  };
-
- public:
-  // Descriptor table size.
-  static constexpr size_t kNumDescriptors = kFieldSpecList.kSize;
-
-  // The actual descriptor table.
-  static constexpr FieldDescriptor kDescriptors[] = {
-      FieldDescriptorBuilder<indices>::kDescriptor...};
-};
-
-// Provide a definition of the |kDescriptors| array such that the descriptor
-// table gets emitted to static data.
-template <typename StructType, size_t... index>
-constexpr FieldDescriptor
-    StructDescriptor<StructType, index_sequence<index...>>::kDescriptors[];
-
-// Note that G++ versions before 5.0 have a bug in handling parameter pack
-// expansions that result in an empty array initializer. To work around this,
-// the following specialization is provided for empty field lists.
-template <typename StructType>
-struct StructDescriptor<StructType, index_sequence<>> {
-  static constexpr size_t kNumDescriptors = 0;
-  static constexpr FieldDescriptor* kDescriptors = nullptr;
-};
-
-// A convenience class to initialize |MessageEncoderBase| with the descriptor
-// table corresponding to |StructType| as determined by |StructDescriptor|.
-template <typename StructType>
-class MessageEncoder : public MessageEncoderBase {
- public:
-  MessageEncoder(const StructType& object)
-      : MessageEncoderBase(&object,
-                           StructDescriptor<StructType>::kDescriptors,
-                           StructDescriptor<StructType>::kNumDescriptors) {}
-
-  static bool Encode(const StructType& object, ProtoWriter* writer) {
-    return MessageEncoderBase::Encode(
-        &object, writer, StructDescriptor<StructType>::kDescriptors,
-        StructDescriptor<StructType>::kNumDescriptors);
-  }
-};
-
-// A convenience class to initialize |MessageDecoderBase| with the descriptor
-// table corresponding to |StructType| as determined by |StructDescriptor|.
-template <typename StructType>
-class MessageDecoder : public MessageDecoderBase {
- public:
-  MessageDecoder(StructType& object)
-      : MessageDecoderBase(&object,
-                           StructDescriptor<StructType>::kDescriptors,
-                           StructDescriptor<StructType>::kNumDescriptors) {}
-
-  static bool Decode(StructType& object, ProtoReader* reader) {
-    return MessageDecoderBase::Decode(
-        &object, reader, StructDescriptor<StructType>::kDescriptors,
-        StructDescriptor<StructType>::kNumDescriptors);
-  }
-};
-
-}  // namespace
-
-// |Codec| specialization for struct types. The second template parameter
-// evaluates to |void| if the appropriate |DescriptorForType| specialization
-// exists, enabling the |Codec| specialization for that case.
-//
-// Note that this template generates code for each struct type that needs to be
-// encoded and decoded. To avoid bloating the binary, we keep the type-dependent
-// code at the absolute minimum. The |MessageEncoder| and |MessageDecoder|
-// templates merely obtain the appropriate descriptor table for the struct type
-// and then invoke the type-agnostic encoder and decoder base classes.
-template <typename StructType>
-struct Codec<StructType,
-             decltype(
-                 static_cast<void>(DescriptorForType<StructType>::kFields))> {
-  static constexpr WireType kWireType = WireType::kLengthDelimited;
-
-  static bool Encode(const StructType& object, ProtoWriter* writer) {
-    return MessageEncoder<StructType>::Encode(object, writer);
-  }
-
-  static bool Decode(StructType& object, ProtoReader* reader) {
-    return MessageDecoder<StructType>::Decode(object, reader);
-  }
-};
-
-}  // namespace detail
-
-// Get the encoded size of an object.
-template <typename Struct>
-size_t GetSize(const Struct& object) {
-  detail::MessageEncoder<Struct> encoder(object);
-  return encoder.GetSize();
-}
-
-// Encode |object| and write the result to |stream|. Returns true if successful,
-// false if encoding fails. Encoding may fail because |stream| doesn't have
-// enough room to hold the encoded data.
-template <typename Struct>
-bool Encode(const Struct& object, OutputStreamBuffer* stream) {
-  ProtoWriter writer(stream);
-  detail::MessageEncoder<Struct> encoder(object);
-  return encoder.EncodeData(&writer);
-}
-
-// Decode |stream| and update |object| with the decoded information. Returns
-// true if successful, false if encoding fails. Failure conditions include:
-//  * Binary data isn't valid with respect to the protobuf wire format.
-//  * |stream| ends prematurely.
-//  * Memory allocation in |object| to hold decoded data fails.
-template <typename Struct>
-bool Decode(Struct* object, InputStreamBuffer* stream) {
-  ProtoReader reader(stream);
-  detail::MessageDecoder<Struct> decoder(*object);
-  return decoder.DecodeData(&reader);
-}
-
-}  // namespace proto
-}  // namespace nvram
-
-#endif  // NVRAM_PROTO_HPP_
diff --git a/include/nvram/struct.h b/include/nvram/struct.h
deleted file mode 100644
index 7d38f73..0000000
--- a/include/nvram/struct.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-// This file provides facilities to declare compile-time descriptors for C++
-// struct types. This enables generic code to access the declared struct
-// members in an object.
-//
-// For example, consider the following struct type:
-//
-//   struct Employee {
-//     uint32_t id;
-//     std::string name;
-//     std::vector<uint32_t> reports;
-//   };
-//
-// The descriptor is declared as follows, providing access to |Employee|'s
-// members and assigning a unique field number to each of them:
-//
-//   template <>
-//   struct DescriptorForType<Employee> {
-//     static constexpr auto kFields =
-//         MakeFieldList(MakeField(1, &Employee::id),
-//                       MakeField(2, &Employee::name),
-//                       MakeField(3, &Employee::reports));
-//   };
-//
-// Note that the |kFields| member is a constexpr, which creates a compile-time
-// constant, so the field meta data can be used in compile-time computations and
-// as template parameters.
-//
-// To access the declared members, there is a |Get()| member function template
-// on the declared field list, which allows to retrieve one of the field
-// specifications by index (zero-based declaration index, *not* field number).
-// Once you have the field spec for a field, you can use |FieldSpec::Get()| to
-// get a reference to the member within a struct instance. This can be used to
-// implement generic algorithms that make use of the descriptor behind the
-// scenes. Here is an example that shows how to build a generic comparator:
-//
-//   template <typename Struct>
-//   struct StructCompare {
-//     template <typename Member>
-//     int compareMember(const Member& left, const Member& right) {
-//       return left < right ? -1 : (right < left ? 1 : 0);
-//     }
-//
-//     template <size_t... indices>
-//     int compare(const Struct& left,
-//                 const Struct& right,
-//                 index_sequence<indices...>) {
-//       constexpr auto kFieldSpecList = DescriptorForType<Struct>::kFields;
-//       int results[] = {compareMember(
-//           kFieldSpecList.template Get<indices>().Get(left),
-//           kFieldSpecList.template Get<indices>().Get(right))...};
-//       for (int result : results) {
-//         if (result != 0) {
-//           return result;
-//         }
-//       }
-//
-//       return 0;
-//     }
-//
-//     bool operator()(const Struct& left, const Struct& right) {
-//       constexpr auto kFieldSpecList = DescriptorForType<Struct>::kFields;
-//       return compare(left, right,
-//                      make_index_sequence<kFieldSpecList.kSize>()) < 0;
-//     }
-//   };
-//
-// You can now use |StructCompare| as a key comparison function with std::set
-// like this:
-//
-//   std::set<Employee, StructCompare<Employee>> employees;
-//   employees.emplace(std::move(new_employee));
-//
-// The ability to write generic algorithms that can process arbitrarily-typed
-// struct fields comes at the cost of heavy usage of template constructs.
-// However, potential alternatives are not without drawbacks:
-//  * Avoiding generic code entirely and writing the necessary operations for
-//    each struct type manually is tedious and error-prone.
-//  * Tool-generated code is just as hard to comprehend and maintain, and code
-//    making use of the generated constructs may need to be generated as well.
-//  * For the intended use in message serialization, there are existing message
-//    serialization solutions such as protobuf. Unfortunately, our serialization
-//    code needs to run in resource-constrained environments that don't provide
-//    a C++ standard library (which is a dependency of the regular protobuf
-//    implementation), and the library weighs in as a non-trivial dependency in
-//    terms of code size.
-
-#ifndef NVRAM_STRUCT_H_
-#define NVRAM_STRUCT_H_
-
-#include <nvram/type_traits.h>
-
-namespace nvram {
-
-// This class template is used to resolve struct types to their corresponding
-// descriptors, which provide a list of struct fields that includes the field
-// numbers as well as the corresponding C++ struct members in |Struct|. See the
-// file comment above for an example.
-template <typename Struct>
-struct DescriptorForType;
-
-// |FieldSpec| describes a member field of the struct type |Struct|. The
-// template parameters capture the C++ |Member| type of the |Struct| member that
-// holds the field's data.
-//
-// Note that this class template is a literal type, i.e. can be used with
-// constexpr. As an implication, |FieldSpec| instances can be used as
-// compile-time data.
-template <typename Struct, typename Member>
-struct FieldSpec {
-  using MemberType = Member;
-
-  constexpr FieldSpec(uint32_t field_number, MemberType Struct::* member)
-      : kFieldNumber(field_number), kMember(member) {}
-
-  const MemberType& Get(const Struct& object) const {
-    return object.*kMember;
-  }
-
-  MemberType& Get(Struct& object) const {
-    return object.*kMember;
-  }
-
-  // The field number for this field.
-  const uint32_t kFieldNumber;
-
-  // A member pointer to the |Struct| member that holds the field data.
-  MemberType Struct::*const kMember;
-};
-
-// A helper function template that enables template argument deduction to be
-// used to construct |FieldSpec| instances.
-template <typename Struct, typename Member>
-constexpr FieldSpec<Struct, Member> MakeField(uint32_t field_number,
-                                              Member Struct::*member) {
-  return FieldSpec<Struct, Member>(field_number, member);
-};
-
-// A simple type list intended to hold field specification values.
-//
-// Note that |FieldSpecList| is a literal type so can be used with constexpr to
-// hold compile-time data.
-template <typename... FieldSpec>
-struct FieldSpecList;
-
-namespace {
-
-// A helper template that extracts the field spec at |index| from a field spec
-// list.
-template <size_t index, typename... FieldSpec>
-struct FieldSpecLookup;
-
-// Recursion step: This specialization matches if |index| is larger than 0, and
-// the |Get()| definition just forwards to the list tail.
-template <size_t index, typename FieldSpec, typename... Tail>
-struct FieldSpecLookup<index, FieldSpec, Tail...> {
-  using Prev = FieldSpecLookup<index - 1, Tail...>;
-  using Type = typename Prev::Type;
-  static constexpr Type Get(FieldSpecList<FieldSpec, Tail...> self) {
-    return Prev::Get(self.kTail);
-  }
-};
-
-// Recursion base case: |index| as reached 0, so |Get()| returns the field spec
-// corresponding to the current |FieldSpec|.
-template <typename FieldSpec, typename... Tail>
-struct FieldSpecLookup<0, FieldSpec, Tail...> {
-  using Type = FieldSpec;
-  static constexpr Type Get(FieldSpecList<FieldSpec, Tail...> self) {
-    return self.kFieldSpec;
-  }
-};
-
-// Produces an error message in case the provided |index| is too large, i.e.
-// doesn't match any field. This specialization only matches once the
-// |FieldSpec| parameters are exhausted.
-template <size_t index>
-struct FieldSpecLookup<index> {
-  // Note that |index < 0| will never be satisfied, so this static assert
-  // triggers unconditionally if this template specialization ever gets
-  // instantiated. It will only be instantiated if |index| exceeds the number of
-  // declared fields.
-  //
-  // Just putting |false| as the static_assert condition would seem a saner
-  // alternative, but doesn't work since the static_assert would then be
-  // evaluated at declaration time. Using the |index| parameter in the condition
-  // forces evaluation to take place at template instantiation time.
-  static_assert(index < 0, "Out-of-bounds |index| in field spec lookup.");
-};
-
-}  // namespace
-
-// |FieldSpecList| specialization that holds the data of the front-most element
-// of |FieldSpecList|'s |Fields| arguments. Note that this class contains a
-// nested |FieldSpecList| instance with the front-most element removed, thus
-// inheriting the members for subsequent |Fields| arguments.
-template <typename FieldSpec, typename... Tail>
-struct FieldSpecList<FieldSpec, Tail...> {
-  using List = FieldSpecList<FieldSpec, Tail...>;
-  using TailList = FieldSpecList<Tail...>;
-
-  constexpr FieldSpecList(FieldSpec field_spec, Tail... tail)
-      : kFieldSpec(field_spec), kTail(tail...) {}
-
-  template <size_t index>
-  constexpr typename FieldSpecLookup<index, FieldSpec, Tail...>::Type Get()
-      const {
-    return FieldSpecLookup<index, FieldSpec, Tail...>::Get(*this);
-  }
-
-  static constexpr size_t kSize = TailList::kSize + 1;
-  const FieldSpec kFieldSpec;
-  const TailList kTail;
-};
-
-// |FieldSpecList| specialization acting as the recursion base case. This
-// doesn't have further members and thus stops the expansion of
-// |FieldSpecList|'s |Fields| parameter.
-template <>
-struct FieldSpecList<> {
-  static constexpr size_t kSize = 0;
-};
-
-// Helper function template that enables convenient creation of |FieldSpecList|
-// instances by enabling template argument deduction.
-template <typename... FieldSpec>
-constexpr FieldSpecList<FieldSpec...> MakeFieldList(FieldSpec... field_spec) {
-  return FieldSpecList<FieldSpec...>(field_spec...);
-}
-
-}  // namespace nvram
-
-#endif  // NVRAM_STRUCT_H_
diff --git a/include/nvram/type_traits.h b/include/nvram/type_traits.h
deleted file mode 100644
index 2d3ce17..0000000
--- a/include/nvram/type_traits.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef NVRAM_TYPE_TRAITS_H_
-#define NVRAM_TYPE_TRAITS_H_
-
-extern "C" {
-#include <stddef.h>
-}
-
-// A subset of utilities similar to what is available in <type_traits>. We have
-// our own standalone version here since not all target platforms have a full
-// C++ standard library.
-
-namespace nvram {
-
-template <typename T>
-struct remove_const {
-  using Type = T;
-};
-template <typename T>
-struct remove_const<const T> {
-  using Type = T;
-};
-
-template <typename T>
-struct remove_reference {
-  using Type = T;
-};
-template <typename T>
-struct remove_reference<T&> {
-  using Type = T;
-};
-template <typename T>
-struct remove_reference<T&&> {
-  using Type = T;
-};
-
-template <bool value, typename T = void>
-struct enable_if {};
-
-template <typename T>
-struct enable_if<true, T> {
-  using Type = T;
-};
-
-template <typename T, T const_value>
-struct integral_constant {
-  static constexpr T value = const_value;
-};
-
-using true_type = integral_constant<bool, true>;
-using false_type = integral_constant<bool, false>;
-
-template <typename T>
-T declval();
-
-template <size_t... index>
-struct index_sequence {};
-
-template <size_t size, size_t... indices>
-struct make_index_sequence_builder {
-  using Type = typename make_index_sequence_builder<size - 1,
-                                                    size - 1,
-                                                    indices...>::Type;
-};
-
-template <size_t... indices>
-struct make_index_sequence_builder<0, indices...> {
-  using Type = index_sequence<indices...>;
-};
-
-template <size_t size>
-constexpr typename make_index_sequence_builder<size>::Type
-make_index_sequence(){
-  return typename make_index_sequence_builder<size>::Type();
-};
-
-}  // namespace nvram
-
-#endif  // NVRAM_TYPE_TRAITS_H_
diff --git a/io.cpp b/io.cpp
index c783d3c..faf9068 100644
--- a/io.cpp
+++ b/io.cpp
@@ -71,6 +71,8 @@
 
 }  // namespace
 
+InputStreamBuffer::InputStreamBuffer() = default;
+
 InputStreamBuffer::InputStreamBuffer(const void* data, size_t size)
     : InputStreamBuffer(data, static_cast<const uint8_t*>(data) + size) {}
 
@@ -80,6 +82,8 @@
   NVRAM_CHECK(pos_ <= end_);
 }
 
+InputStreamBuffer::~InputStreamBuffer() = default;
+
 bool InputStreamBuffer::Done() {
   return pos_ >= end_ && !Advance();
 }
@@ -139,6 +143,8 @@
       delegate_(delegate),
       remaining_(size) {}
 
+NestedInputStreamBuffer::~NestedInputStreamBuffer() = default;
+
 bool NestedInputStreamBuffer::Advance() {
   remaining_ -= end_ - delegate_->pos_;
   if (remaining_ == 0) {
@@ -151,6 +157,8 @@
   return status;
 }
 
+OutputStreamBuffer::OutputStreamBuffer() = default;
+
 OutputStreamBuffer::OutputStreamBuffer(void* data, size_t size)
     : OutputStreamBuffer(data, static_cast<uint8_t*>(data) + size) {}
 
@@ -159,6 +167,8 @@
   NVRAM_CHECK(pos_ <= end_);
 }
 
+OutputStreamBuffer::~OutputStreamBuffer() = default;
+
 bool OutputStreamBuffer::Done() {
   return pos_ >= end_ && !Advance();
 }
@@ -200,6 +210,8 @@
 CountingOutputStreamBuffer::CountingOutputStreamBuffer()
     : OutputStreamBuffer(scratch_space_, kScratchSpaceSize) {}
 
+CountingOutputStreamBuffer::~CountingOutputStreamBuffer() = default;
+
 bool CountingOutputStreamBuffer::Advance() {
   bytes_written_ += pos_ - scratch_space_;
   pos_ = scratch_space_;
@@ -212,6 +224,8 @@
 BlobOutputStreamBuffer::BlobOutputStreamBuffer(Blob* blob)
     : OutputStreamBuffer(blob->data(), blob->size()), blob_(blob) {}
 
+BlobOutputStreamBuffer::~BlobOutputStreamBuffer() = default;
+
 bool BlobOutputStreamBuffer::Advance() {
   ptrdiff_t offset = pos_ - blob_->data();
   if (!blob_->Resize(max<size_t>(blob_->size() * 2, 32))) {
diff --git a/message_codec.cpp b/message_codec.cpp
deleted file mode 100644
index d1df715..0000000
--- a/message_codec.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * 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.
- */
-
-#include <nvram/message_codec.h>
-
-namespace nvram {
-namespace proto {
-
-MessageEncoderBase::MessageEncoderBase(const void* object,
-                                       const FieldDescriptor* descriptors,
-                                       size_t num_descriptors)
-    : object_(object),
-      descriptors_(descriptors),
-      num_descriptors_(num_descriptors) {}
-
-bool MessageEncoderBase::Encode(const void* object,
-                                ProtoWriter* writer,
-                                const FieldDescriptor* descriptors,
-                                size_t num_descriptors) {
-  MessageEncoderBase encoder(object, descriptors, num_descriptors);
-  return encoder.Encode(writer);
-}
-
-size_t MessageEncoderBase::GetSize() {
-  CountingOutputStreamBuffer counting_stream;
-  ProtoWriter writer(&counting_stream);
-  return EncodeData(&writer) ? counting_stream.bytes_written() : 0;
-}
-
-bool MessageEncoderBase::Encode(ProtoWriter* writer) {
-  // We need to compute the total size of all struct fields up front in order to
-  // write a length delimiter that designates the end of the encoded nested
-  // message. Note that computing the size of |object| requires a second
-  // |EncodeData()| call in addition to the one that actually encodes the data.
-  // When handling nested message structures, each level triggers its own size
-  // computation, which are redundant with those performed by the levels above.
-  //
-  // For now, we just accept this inefficiency in the interest of keeping things
-  // simple and correct. If this ever becomes a performance problem for deeply
-  // nested structs here are some options:
-  //  * Reserve bytes in |writer| for the encoded size. Once |Encode()|
-  //    completes, it is known how many bytes were required, at which point the
-  //    size field can be updated. The drawback with this solution is that
-  //    varint encoding is variable length, so we'd have to write a degenerated
-  //    varint that may occupy more bytes than actually required.
-  //  * Cache encoded sizes in the struct. This is the solution implemented in
-  //    the regular protobuf implementation. This is relatively straightforward,
-  //    but at the expense of holding data in struct that doesn't really belong
-  //    there.
-  //  * Make a first pass over the struct tree, compute sizes and cache them in
-  //    some auxiliary data structure held in the encoder. This is probably the
-  //    cleanest solution, but comes at the expense of having to thread the size
-  //    cache data structure through the encoding logic.
-  return writer->WriteLengthHeader(GetSize()) && EncodeData(writer);
-}
-
-bool MessageEncoderBase::EncodeData(ProtoWriter* writer) {
-  for (size_t i = 0; i < num_descriptors_; ++i) {
-    const FieldDescriptor& desc = descriptors_[i];
-    writer->set_field_number(desc.field_number);
-    if (!desc.encode_function(object_, writer)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
-MessageDecoderBase::MessageDecoderBase(void* object,
-                                       const FieldDescriptor* descriptors,
-                                       size_t num_descriptors)
-    : object_(object),
-      descriptors_(descriptors),
-      num_descriptors_(num_descriptors) {}
-
-bool MessageDecoderBase::Decode(void* object,
-                                ProtoReader* reader,
-                                const FieldDescriptor* descriptors,
-                                size_t num_descriptors) {
-  MessageDecoderBase decoder(object, descriptors, num_descriptors);
-  return decoder.Decode(reader);
-}
-
-bool MessageDecoderBase::Decode(ProtoReader* reader) {
-  NestedInputStreamBuffer nested_stream_buffer(reader->stream_buffer(),
-                                               reader->field_size());
-  ProtoReader nested_reader(&nested_stream_buffer);
-  return DecodeData(&nested_reader) && nested_reader.Done();
-}
-
-bool MessageDecoderBase::DecodeData(ProtoReader* reader) {
-  while (!reader->Done()) {
-    if (!reader->ReadWireTag()) {
-      return false;
-    }
-    const FieldDescriptor* desc = FindDescriptor(reader);
-    if (desc) {
-      if (!desc->decode_function(object_, reader)) {
-        return false;
-      }
-    } else {
-      // Unknown field number or wire type mismatch. Skip field data.
-      if (!reader->SkipField()) {
-        return false;
-      }
-    }
-  }
-
-  return true;
-}
-
-const FieldDescriptor* MessageDecoderBase::FindDescriptor(
-    ProtoReader* reader) const {
-  for (size_t i = 0; i < num_descriptors_; ++i) {
-    const FieldDescriptor& desc = descriptors_[i];
-    if (reader->field_number() == desc.field_number &&
-        reader->wire_type() == desc.wire_type) {
-      return &desc;
-    }
-  }
-  return nullptr;
-}
-
-}  // namespace nvram
-}  // namespace proto