Port files under /data to Aug 11 version.
ReadableFontData.Search*() not ported since they're already in another CL under review.



git-svn-id: http://sfntly.googlecode.com/svn/trunk/cpp/src@55 672e30a5-4c29-85ac-ac6d-611c735e0a51
diff --git a/sfntly/data/byte_array.cc b/sfntly/data/byte_array.cc
index 5502185..c820adc 100644
--- a/sfntly/data/byte_array.cc
+++ b/sfntly/data/byte_array.cc
@@ -34,51 +34,57 @@
   return filled_length_;
 }
 
-byte_t ByteArray::Get(int32_t index) {
-  return InternalGet(index);
+int32_t ByteArray::Get(int32_t index) {
+  return InternalGet(index) & 0xff;
 }
 
 int32_t ByteArray::Get(int32_t index, ByteVector* b) {
   assert(b);
-  return Get(index, b, 0, b->size());
+  return Get(index, &((*b)[0]), 0, b->size());
 }
 
 int32_t ByteArray::Get(int32_t index,
-                       ByteVector* b,
+                       byte_t* b,
                        int32_t offset,
                        int32_t length) {
   assert(b);
   if (index < 0 || index >= filled_length_) {
-    return -1;
+    return 0;
   }
   int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
-  if (actual_length < 0) {
-      return -1;
-  }
   return InternalGet(index, b, offset, actual_length);
 }
 
-bool ByteArray::Put(int32_t index, byte_t b) {
+void ByteArray::Put(int32_t index, byte_t b) {
   if (index < 0 || index >= Size()) {
-    return false;
+#if defined (SFNTLY_NO_EXCEPTION)
+    return;
+#else
+    throw IndexOutOfBoundException(
+        "Attempt to write outside the bounds of the data");
+#endif
   }
-  bool result = InternalPut(index, b);
+  InternalPut(index, b);
   filled_length_ = std::max<int32_t>(filled_length_, index + 1);
-  return result;
 }
 
 int32_t ByteArray::Put(int index, ByteVector* b) {
   assert(b);
-  return Put(index, b, 0, b->size());
+  return Put(index, &((*b)[0]), 0, b->size());
 }
 
 int32_t ByteArray::Put(int32_t index,
-                       ByteVector* b,
+                       byte_t* b,
                        int32_t offset,
                        int32_t length) {
   assert(b);
   if (index < 0 || index >= Size()) {
+#if defined (SFNTLY_NO_EXCEPTION)
     return 0;
+#else
+    throw IndexOutOfBoundException(
+        "Attempt to write outside the bounds of the data");
+#endif
   }
   int32_t actual_length = std::min<int32_t>(length, Size() - index);
   int32_t bytes_written = InternalPut(index, b, offset, actual_length);
@@ -106,8 +112,9 @@
   int32_t index = 0;
   int32_t remaining_length = length;
   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
-  while ((bytes_read = Get(index + src_offset, &b, 0, buffer_length)) > 0) {
-    int bytes_written = array->Put(index + dst_offset, &b, 0, bytes_read);
+  while ((bytes_read =
+              Get(index + src_offset, &(b[0]), 0, buffer_length)) > 0) {
+    int bytes_written = array->Put(index + dst_offset, &(b[0]), 0, bytes_read);
     if (bytes_written != bytes_read) {
 #if defined (SFNTLY_NO_EXCEPTION)
       return 0;
@@ -131,7 +138,7 @@
   int32_t bytes_read = 0;
   int32_t index = 0;
   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
-  while ((bytes_read = Get(index + offset, &b, 0, buffer_length)) > 0) {
+  while ((bytes_read = Get(index + offset, &(b[0]), 0, buffer_length)) > 0) {
     os->Write(&b, 0, bytes_read);
     index += bytes_read;
     buffer_length = std::min<int32_t>(b.size(), length - index);
@@ -145,7 +152,7 @@
   int32_t index = 0;
   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
   while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
-    if (Put(index, &b, 0, bytes_read) != bytes_read) {
+    if (Put(index, &(b[0]), 0, bytes_read) != bytes_read) {
 #if defined (SFNTLY_NO_EXCEPTION)
       return 0;
 #else
@@ -165,7 +172,7 @@
   int32_t index = 0;
   int32_t buffer_length = COPY_BUFFER_SIZE;
   while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
-    if (Put(index, &b, 0, bytes_read) != bytes_read) {
+    if (Put(index, &b[0], 0, bytes_read) != bytes_read) {
 #if defined (SFNTLY_NO_EXCEPTION)
       return 0;
 #else
diff --git a/sfntly/data/byte_array.h b/sfntly/data/byte_array.h
index 9ac56c0..3375244 100644
--- a/sfntly/data/byte_array.h
+++ b/sfntly/data/byte_array.h
@@ -24,56 +24,62 @@
 
 namespace sfntly {
 
-// An interface abstraction to a byte array. Can be implemented to map to
-// various types of data storage.
+// An abstraction to a contiguous array of bytes.
 // C++ port of this class assumes that the data are stored in a linear region
 // like std::vector.
 class ByteArray : virtual public RefCount {
  public:
   virtual ~ByteArray();
 
-  // Get the current filled and readable length of the array.
+  // Gets the current filled and readable length of the array.
   int32_t Length();
 
-  // Get the maximum size of the array. This is the maximum number of bytes that
+  // Gets the maximum size of the array. This is the maximum number of bytes that
   // the array can hold and all of it may not be filled with data or even fully
   // allocated yet.
   int32_t Size();
 
+  // Determines whether or not this array is growable or of fixed size.
   bool growable() { return growable_; }
+
   int32_t SetFilledLength(int32_t filled_length);
 
-  // Get the byte from the given index.
-  virtual byte_t Get(int32_t index);
+  // Gets the byte from the given index.
+  // @param index the index into the byte array
+  // @return the byte or -1 if reading beyond the bounds of the data
+  virtual int32_t Get(int32_t index);
 
-  // Get the bytes from the given index and fill the buffer with them. As many
+  // Gets the bytes from the given index and fill the buffer with them. As many
   // bytes as will fit into the buffer are read unless that would go past the
   // end of the array.
+  // @param index the index into the byte array
+  // @param b the buffer to put the bytes read into
+  // @return the number of bytes read from the buffer
   virtual int32_t Get(int32_t index, ByteVector* b);
 
-  // Get the bytes from the given index and fill the buffer with them starting
+  // Gets the bytes from the given index and fill the buffer with them starting
   // at the offset given. As many bytes as the specified length are read unless
   // that would go past the end of the array.
   // @param index the index into the byte array
   // @param b the buffer to put the bytes read into
   // @param offset the location in the buffer to start putting the bytes
   // @param length the number of bytes to put into the buffer
-  // @return the number of bytes put into the buffer
+  // @return the number of bytes read from the buffer
   virtual int32_t Get(int32_t index,
-                      ByteVector* b,
+                      byte_t* b,
                       int32_t offset,
                       int32_t length);
 
-  // Put the specified byte into the array at the given index unless that would
+  // Puts the specified byte into the array at the given index unless that would
   // be beyond the length of the array and it isn't growable.
-  virtual bool Put(int32_t index, byte_t b);
+  virtual void Put(int32_t index, byte_t b);
 
-  // Put the specified bytes into the array at the given index. The entire
+  // Puts the specified bytes into the array at the given index. The entire
   // buffer is put into the array unless that would extend beyond the length and
   // the array isn't growable.
   virtual int32_t Put(int32_t index, ByteVector* b);
 
-  // Put the specified bytes into the array at the given index. All of the bytes
+  // Puts the specified bytes into the array at the given index. All of the bytes
   // specified are put into the array unless that would extend beyond the length
   // and the array isn't growable. The bytes to be put into the array are those
   // in the buffer from the given offset and for the given length.
@@ -83,22 +89,22 @@
   // @param length the number of bytes to copy into the array
   // @return the number of bytes actually written
   virtual int32_t Put(int32_t index,
-                      ByteVector* b,
+                      byte_t* b,
                       int32_t offset,
                       int32_t length);
 
-  // Fully copy this ByteArray to another ByteArray to the extent that the
+  // Fully copies this ByteArray to another ByteArray to the extent that the
   // destination array has storage for the data copied.
   virtual int32_t CopyTo(ByteArray* array);
 
-  // Copy a segment of this ByteArray to another ByteArray.
+  // Copies a segment of this ByteArray to another ByteArray.
   // @param array the destination
   // @param offset the offset in this ByteArray to start copying from
   // @param length the maximum length in bytes to copy
   // @return the number of bytes copied
   virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length);
 
-  // Copy this ByteArray to another ByteArray.
+  // Copies this ByteArray to another ByteArray.
   // @param dstOffset the offset in the destination array to start copying to
   // @param array the destination
   // @param srcOffset the offset in this ByteArray to start copying from
@@ -109,9 +115,25 @@
                          int32_t src_offset,
                          int32_t length);
 
+  // Copies this ByteArray to an OutputStream.
+  // @param os the destination
+  // @return the number of bytes copied
   virtual int32_t CopyTo(OutputStream* os);
+
+  // Copies this ByteArray to an OutputStream.
+  // @param os the destination
+  // @param offset
+  // @param length
+  // @return the number of bytes copied
   virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+  // Copies from the InputStream into this ByteArray.
+  // @param is the source
+  // @param length the number of bytes to copy
   virtual bool CopyFrom(InputStream* is, int32_t length);
+
+  // Copies everything from the InputStream into this ByteArray.
+  // @param is the source
   virtual bool CopyFrom(InputStream* is);
 
  protected:
@@ -122,24 +144,52 @@
   ByteArray(int32_t filled_length, int32_t storage_length);
   void Init(int32_t filled_length, int32_t storage_length, bool growable);
 
-  virtual bool InternalPut(int32_t index, byte_t b) = 0;
+  // Internal subclass API
+
+  // Stores the byte at the index given.
+  // @param index the location to store at
+  // @param b the byte to store
+  virtual void InternalPut(int32_t index, byte_t b) = 0;
+
+  // Stores the array of bytes at the given index.
+  // @param index the location to store at
+  // @param b the bytes to store
+  // @param offset the offset to start from in the byte array
+  // @param length the length of the byte array to store from the offset
+  // @return the number of bytes actually stored
   virtual int32_t InternalPut(int32_t index,
-                              ByteVector* b,
+                              byte_t* b,
                               int32_t offset,
                               int32_t length) = 0;
+
+  // Gets the byte at the index given.
+  // @param index the location to get from
+  // @return the byte stored at the index
   virtual byte_t InternalGet(int32_t index) = 0;
+
+  // Gets the bytes at the index given of the given length.
+  // @param index the location to start getting from
+  // @param b the array to put the bytes into
+  // @param offset the offset in the array to put the bytes into
+  // @param length the length of bytes to read
+  // @return the number of bytes actually ready
   virtual int32_t InternalGet(int32_t index,
-                              ByteVector* b,
+                              byte_t* b,
                               int32_t offset,
                               int32_t length) = 0;
+
+  // Close this instance of the ByteArray.
   virtual void Close() = 0;
 
   // C++ port only, raw pointer to the first element of storage.
   virtual byte_t* Begin() = 0;
 
+  // Java toString() not ported.
+
   static const int32_t COPY_BUFFER_SIZE;
 
  private:
+  //bool bound_;  // unused, comment out
   int32_t filled_length_;
   int32_t storage_length_;
   bool growable_;
diff --git a/sfntly/data/font_data.cc b/sfntly/data/font_data.cc
index 437a810..ccc2a19 100644
--- a/sfntly/data/font_data.cc
+++ b/sfntly/data/font_data.cc
@@ -58,7 +58,7 @@
 
 FontData::FontData(FontData* data, int32_t offset) {
   Init(data->array_);
-  Bound(offset);
+  Bound(data->bound_offset_ + offset);
 }
 
 FontData::~FontData() {}
diff --git a/sfntly/data/font_data.h b/sfntly/data/font_data.h
index ab5cf54..6ac4d5d 100644
--- a/sfntly/data/font_data.h
+++ b/sfntly/data/font_data.h
@@ -48,13 +48,14 @@
 
 class FontData : virtual public RefCount {
  public:
-  // Get the maximum size of the FontData. This is the maximum number of bytes
+  // Gets the maximum size of the FontData. This is the maximum number of bytes
   // that the font data can hold and all of it may not be filled with data or
   // even fully allocated yet.
-  // @return the size of this array
+  // @return the maximum size of this font data
   virtual int32_t Size() const;
 
-  // Sets limits on the size of the FontData. The font data is
+  // Sets limits on the size of the FontData. The FontData is then only
+  // visible within the bounds set.
   // @param offset the start of the new bounds
   // @param length the number of bytes in the bounded array
   // @return true if the bounding range was successful; false otherwise
@@ -69,19 +70,19 @@
   virtual bool Bound(int32_t offset);
 
   // Makes a slice of this FontData. The returned slice will share the data with
-  // the original FontData.
+  // the original <code>FontData</code>.
   // @param offset the start of the slice
   // @param length the number of bytes in the slice
   // @return a slice of the original FontData
   virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length) = 0;
 
   // Makes a bottom bound only slice of this array. The returned slice will
-  // share the data with the original FontData.
+  // share the data with the original <code>FontData</code>.
   // @param offset the start of the slice
   // @return a slice of the original FontData
   virtual CALLER_ATTACH FontData* Slice(int32_t offset) = 0;
 
-  // Get the length of the data.
+  // Gets the length of the data.
   virtual int32_t Length() const;
 
  protected:
@@ -102,7 +103,17 @@
   virtual ~FontData();
 
   void Init(ByteArray* ba);
+
+  // Gets the offset in the underlying data taking into account any bounds on
+  // the data.
+  // @param offset the offset to get the bound compensated offset for
+  // @return the bound compensated offset
   int32_t BoundOffset(int32_t offset);
+
+  // Gets the length in the underlying data taking into account any bounds on the data.
+  // @param offset the offset that the length is being used at
+  // @param length the length to get the bound compensated length for
+  // @return the bound compensated length
   int32_t BoundLength(int32_t offset, int32_t length);
 
   // TODO(arthurhsu): style guide violation: refactor this protected member
diff --git a/sfntly/data/font_input_stream.cc b/sfntly/data/font_input_stream.cc
index a1fbe44..dcf8be3 100644
--- a/sfntly/data/font_input_stream.cc
+++ b/sfntly/data/font_input_stream.cc
@@ -25,7 +25,7 @@
 }
 
 FontInputStream::FontInputStream(InputStream* is, size_t length)
-    : stream_(is), position_(0), length_(length), bounded_(false) {
+    : stream_(is), position_(0), length_(length), bounded_(true) {
 }
 
 FontInputStream::~FontInputStream() {
diff --git a/sfntly/data/font_input_stream.h b/sfntly/data/font_input_stream.h
index 7404825..5d9959d 100644
--- a/sfntly/data/font_input_stream.h
+++ b/sfntly/data/font_input_stream.h
@@ -22,6 +22,25 @@
 
 namespace sfntly {
 
+// An input stream for reading font data.
+// The data types used are as listed:
+// BYTE       8-bit unsigned integer.
+// CHAR       8-bit signed integer.
+// USHORT     16-bit unsigned integer.
+// SHORT      16-bit signed integer.
+// UINT24     24-bit unsigned integer.
+// ULONG      32-bit unsigned integer.
+// LONG       32-bit signed integer.
+// Fixed      32-bit signed fixed-point number (16.16)
+// FUNIT      Smallest measurable distance in the em space.
+// FWORD      16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD     16-bit unsigned integer (USHORT) that describes a quantity in
+//            FUnits.
+// F2DOT14    16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME  Date represented in number of seconds since 12:00 midnight,
+//               January 1, 1904. The value is represented as a signed 64-bit
+//               integer.
+
 // Note: Original class inherits from Java's FilterOutputStream, which wraps
 //       an InputStream within.  In C++, we directly do the wrapping without
 //       defining another layer of abstraction.  The wrapped output stream is
@@ -29,10 +48,18 @@
 //       stream).
 class FontInputStream : public InputStream {
  public:
+  // Constructor.
+  // @param is input stream to wrap
   explicit FontInputStream(InputStream* is);
+
+  // Constructor for a bounded font input stream.
+  // @param is input stream to wrap
+  // @param length the maximum length of bytes to read
   FontInputStream(InputStream* is, size_t length);
+
   virtual ~FontInputStream();
 
+
   virtual int32_t Available();
   virtual void Close();
   virtual void Mark(int32_t readlimit);
@@ -43,6 +70,8 @@
   virtual int32_t Read(ByteVector* buffer);
   virtual int32_t Read(ByteVector* buffer, int32_t offset, int32_t length);
 
+  // Get the current position in the stream in bytes.
+  // @return the current position in bytes
   virtual int64_t position() { return position_; }
 
   virtual int32_t ReadChar();
diff --git a/sfntly/data/font_output_stream.cc b/sfntly/data/font_output_stream.cc
index a88a29e..3422a22 100644
--- a/sfntly/data/font_output_stream.cc
+++ b/sfntly/data/font_output_stream.cc
@@ -43,11 +43,35 @@
   }
 }
 
-void FontOutputStream::Write(ByteVector* b, int32_t offset, int32_t length) {
-  if (stream_ && b) {
-    stream_->Write(b, offset, length);
-    position_ += length;
+void FontOutputStream::Write(ByteVector* b, int32_t off, int32_t len) {
+  assert(b);
+  assert(stream_);
+  if (off < 0 || len < 0 || off + len < 0 ||
+      static_cast<size_t>(off + len) > b->size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#else
+    return;
+#endif
   }
+
+  stream_->Write(b, off, len);
+  position_ += len;
+}
+
+void FontOutputStream::Write(byte_t* b, int32_t off, int32_t len) {
+  assert(b);
+  assert(stream_);
+  if (off < 0 || len < 0 || off + len < 0) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#else
+    return;
+#endif
+  }
+
+  stream_->Write(b, off, len);
+  position_ += len;
 }
 
 void FontOutputStream::WriteChar(byte_t c) {
diff --git a/sfntly/data/font_output_stream.h b/sfntly/data/font_output_stream.h
index 6938b66..f420af4 100644
--- a/sfntly/data/font_output_stream.h
+++ b/sfntly/data/font_output_stream.h
@@ -22,11 +22,27 @@
 
 namespace sfntly {
 
-// Note: Original class inherits from Java's FilterOutputStream, which wraps
-//       an InputStream within.  In C++, we directly do the wrapping without
-//       defining another layer of abstraction.  The wrapped output stream is
-//       *NOT* reference counted (because it's meaningless to ref-count an I/O
-//       stream).
+// An output stream for writing font data.
+// The data types used are as listed:
+// BYTE       8-bit unsigned integer.
+// CHAR       8-bit signed integer.
+// USHORT     16-bit unsigned integer.
+// SHORT      16-bit signed integer.
+// UINT24     24-bit unsigned integer.
+// ULONG      32-bit unsigned integer.
+// LONG       32-bit signed integer.
+// Fixed      32-bit signed fixed-point number (16.16)
+// FUNIT      Smallest measurable distance in the em space.
+// FWORD      16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD     16-bit unsigned integer (USHORT) that describes a quantity in
+//            FUnits.
+// F2DOT14    16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME  Date represented in number of seconds since 12:00 midnight,
+//               January 1, 1904. The value is represented as a signed 64-bit
+//               integer.
+
+// Note: The wrapped output stream is *NOT* reference counted (because it's
+//       meaningless to ref-count an I/O stream).
 class FontOutputStream : public OutputStream {
  public:
   explicit FontOutputStream(OutputStream* os);
@@ -36,7 +52,8 @@
 
   virtual void Write(byte_t b);
   virtual void Write(ByteVector* b);
-  virtual void Write(ByteVector* b, int32_t offset, int32_t len);
+  virtual void Write(ByteVector* b, int32_t off, int32_t len);
+  virtual void Write(byte_t* b, int32_t off, int32_t len);
   virtual void WriteChar(byte_t c);
   virtual void WriteUShort(int32_t us);
   virtual void WriteShort(int32_t s);
@@ -46,10 +63,13 @@
   virtual void WriteFixed(int32_t l);
   virtual void WriteDateTime(int64_t date);
 
+  // Note: C++ port only.
   virtual void Flush();
   virtual void Close();
 
  private:
+  // Note: we do not use the variable name out as in Java because it has
+  //       special meaning in VC++ and will be very confusing.
   OutputStream* stream_;
   size_t position_;
 };
diff --git a/sfntly/data/growable_memory_byte_array.cc b/sfntly/data/growable_memory_byte_array.cc
index 9e1a043..c335614 100644
--- a/sfntly/data/growable_memory_byte_array.cc
+++ b/sfntly/data/growable_memory_byte_array.cc
@@ -17,6 +17,7 @@
 #include "sfntly/data/growable_memory_byte_array.h"
 
 #include <limits.h>
+#include <string.h>
 
 #include <algorithm>
 
@@ -24,28 +25,37 @@
 
 GrowableMemoryByteArray::GrowableMemoryByteArray()
     : ByteArray(0, INT_MAX, true) {
+  // Note: We did not set an initial size of array like Java because STL
+  //       implementation will determine the best strategy.
 }
 
 GrowableMemoryByteArray::~GrowableMemoryByteArray() {}
 
-bool GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
-  if ((size_t)index >= b_.capacity()) {
-    b_.resize((size_t)(index + 1) << 2);  // Grow exponentially.
+int32_t GrowableMemoryByteArray::CopyTo(OutputStream* os,
+                                        int32_t offset,
+                                        int32_t length) {
+  assert(os);
+  os->Write(&b_, offset, length);
+  return length;
+}
+
+void GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
+  if ((size_t)index >= b_.size()) {
+    b_.resize((size_t)(index + 1));
   }
   b_[index] = b;
-  return true;
 }
 
 int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
-                                             ByteVector* b,
+                                             byte_t* b,
                                              int32_t offset,
                                              int32_t length) {
-  if ((size_t)index + length >= b_.capacity()) {
-    b_.resize((size_t)(index + length + 1) << 2);
+  if ((size_t)index + length >= b_.size()) {
+    // Note: We grow one byte more than Java version. VC debuggers shows
+    //       data better this way.
+    b_.resize((size_t)(index + length + 1));
   }
-  std::copy(b->begin() + offset,
-            b->begin() + (offset + length),
-            b_.begin() + index);
+  std::copy(b + offset, b + offset + length, b_.begin() + index);
   return length;
 }
 
@@ -54,12 +64,10 @@
 }
 
 int32_t GrowableMemoryByteArray::InternalGet(int32_t index,
-                                             ByteVector* b,
+                                             byte_t* b,
                                              int32_t offset,
                                              int32_t length) {
-  std::copy(b_.begin() + index,
-            b_.begin() + (index + length),
-            b->begin() + offset);
+  memcpy(b + offset, &(b_[0]) + index, length);
   return length;
 }
 
diff --git a/sfntly/data/growable_memory_byte_array.h b/sfntly/data/growable_memory_byte_array.h
index dc59f62..0e35de6 100644
--- a/sfntly/data/growable_memory_byte_array.h
+++ b/sfntly/data/growable_memory_byte_array.h
@@ -21,23 +21,37 @@
 
 namespace sfntly {
 
-// Note: this is not really a port of Java version. Instead, this wraps a
-//       std::vector inside and let it grow by calling resize()
+// Note: This is not really a port of Java version. Instead, this wraps a
+//       std::vector inside and let it grow by calling resize().
 class GrowableMemoryByteArray : public ByteArray,
                                 public RefCounted<GrowableMemoryByteArray> {
  public:
   GrowableMemoryByteArray();
   virtual ~GrowableMemoryByteArray();
+  virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+  // Make gcc -Woverloaded-virtual happy.
+  virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
+  virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+    return ByteArray::CopyTo(array, offset, length);
+  }
+  virtual int32_t CopyTo(int32_t dst_offset,
+                         ByteArray* array,
+                         int32_t src_offset,
+                         int32_t length) {
+    return ByteArray::CopyTo(dst_offset, array, src_offset, length);
+  }
+  virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
 
  protected:
-  virtual bool InternalPut(int32_t index, byte_t b);
+  virtual void InternalPut(int32_t index, byte_t b);
   virtual int32_t InternalPut(int32_t index,
-                              ByteVector* b,
+                              byte_t* b,
                               int32_t offset,
                               int32_t length);
   virtual byte_t InternalGet(int32_t index);
   virtual int32_t InternalGet(int32_t index,
-                              ByteVector* b,
+                              byte_t* b,
                               int32_t offset,
                               int32_t length);
   virtual void Close();
diff --git a/sfntly/data/memory_byte_array.cc b/sfntly/data/memory_byte_array.cc
index 0138b21..d6c9c48 100644
--- a/sfntly/data/memory_byte_array.cc
+++ b/sfntly/data/memory_byte_array.cc
@@ -20,25 +20,27 @@
 
 namespace sfntly {
 
-// Note: this constructor can fail under low-memory situation.
 MemoryByteArray::MemoryByteArray(int32_t length)
     : ByteArray(0, length), b_(NULL), allocated_(true) {
 }
 
-MemoryByteArray::MemoryByteArray(byte_t* b, int32_t buffer_length)
-    : ByteArray(buffer_length, buffer_length), b_(b), allocated_(false) {
-}
-
-MemoryByteArray::MemoryByteArray(byte_t* b,
-                                 int32_t buffer_length,
-                                 int32_t filled_length)
-    : ByteArray(filled_length, buffer_length), b_(b), allocated_(false) {
+MemoryByteArray::MemoryByteArray(byte_t* b, int32_t filled_length)
+    : ByteArray(filled_length, filled_length), b_(b), allocated_(false) {
+  assert(b);
 }
 
 MemoryByteArray::~MemoryByteArray() {
   Close();
 }
 
+int32_t MemoryByteArray::CopyTo(OutputStream* os,
+                                int32_t offset,
+                                int32_t length) {
+  assert(os);
+  os->Write(b_, offset, length);
+  return length;
+}
+
 void MemoryByteArray::Init() {
   if (allocated_ && b_ == NULL) {
     b_ = new byte_t[Size()];
@@ -46,18 +48,18 @@
   }
 }
 
-bool MemoryByteArray::InternalPut(int32_t index, byte_t b) {
+void MemoryByteArray::InternalPut(int32_t index, byte_t b) {
   Init();
   b_[index] = b;
-  return true;
 }
 
 int32_t MemoryByteArray::InternalPut(int32_t index,
-                                     ByteVector* b,
+                                     byte_t* b,
                                      int32_t offset,
                                      int32_t length) {
+  assert(b);
   Init();
-  memcpy(b_ + index, &((*b)[offset]), length);
+  memcpy(b_ + index, b + offset, length);
   return length;
 }
 
@@ -67,11 +69,12 @@
 }
 
 int32_t MemoryByteArray::InternalGet(int32_t index,
-                                     ByteVector* b,
+                                     byte_t* b,
                                      int32_t offset,
                                      int32_t length) {
+  assert(b);
   Init();
-  memcpy(&((*b)[offset]), b_ + index, length);
+  memcpy(b + offset, b_ + index, length);
   return length;
 }
 
diff --git a/sfntly/data/memory_byte_array.h b/sfntly/data/memory_byte_array.h
index 171dcc7..9de5230 100644
--- a/sfntly/data/memory_byte_array.h
+++ b/sfntly/data/memory_byte_array.h
@@ -23,20 +23,47 @@
 
 class MemoryByteArray : public ByteArray, public RefCounted<MemoryByteArray> {
  public:
+  // Construct a new MemoryByteArray with a new array of the size given. It is
+  // assumed that none of the array is filled and readable.
   explicit MemoryByteArray(int32_t length);
-  MemoryByteArray(byte_t* b, int32_t buffer_length);
-  MemoryByteArray(byte_t* b, int32_t buffer_length, int32_t filled_length);
+
+  // Note: not implemented due to dangerous operations in constructor.
+  //explicit MemoryByteArray(ByteVector* b);
+
+  // Construct a new MemoryByteArray using byte array.
+  // @param b the byte array that provides the actual storage
+  // @param filled_length the index of the last byte in the array has data
+  // Note: This is different from Java version, it does not take over the
+  //       ownership of b.  Caller is responsible for handling the lifetime
+  //       of b.  C++ port also assumes filled_length is buffer_length since
+  //       there is not a reliable way to identify the actual size of buffer.
+  MemoryByteArray(byte_t* b, int32_t filled_length);
+
   virtual ~MemoryByteArray();
+  virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+  // Make gcc -Woverloaded-virtual happy.
+  virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
+  virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+    return ByteArray::CopyTo(array, offset, length);
+  }
+  virtual int32_t CopyTo(int32_t dst_offset,
+                         ByteArray* array,
+                         int32_t src_offset,
+                         int32_t length) {
+    return ByteArray::CopyTo(dst_offset, array, src_offset, length);
+  }
+  virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
 
  protected:
-  virtual bool InternalPut(int32_t index, byte_t b);
+  virtual void InternalPut(int32_t index, byte_t b);
   virtual int32_t InternalPut(int32_t index,
-                              ByteVector* b,
+                              byte_t* b,
                               int32_t offset,
                               int32_t length);
   virtual byte_t InternalGet(int32_t index);
   virtual int32_t InternalGet(int32_t index,
-                              ByteVector* b,
+                              byte_t* b,
                               int32_t offset,
                               int32_t length);
   virtual void Close();
diff --git a/sfntly/data/readable_font_data.cc b/sfntly/data/readable_font_data.cc
index 904e7db..8f43575 100644
--- a/sfntly/data/readable_font_data.cc
+++ b/sfntly/data/readable_font_data.cc
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include "sfntly/data/memory_byte_array.h"
 #include "sfntly/data/readable_font_data.h"
 #include "sfntly/data/writable_font_data.h"
 #include "sfntly/port/exception_type.h"
@@ -28,6 +29,18 @@
 
 ReadableFontData::~ReadableFontData() {}
 
+// TODO(arthurhsu): re-investigate the memory model of this function.  It's
+//                  not too useful without copying, but it's not performance
+//                  savvy to do copying.
+CALLER_ATTACH
+ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
+  assert(b);
+  ByteArrayPtr ba = new MemoryByteArray(b->size());
+  ba->Put(0, b);
+  ReadableFontDataPtr wfd = new ReadableFontData(ba);
+  return wfd.Detach();
+}
+
 int64_t ReadableFontData::Checksum() {
   // TODO(arthurhsu): IMPLEMENT: atomicity
   if (!checksum_set_) {
@@ -42,15 +55,29 @@
 }
 
 int32_t ReadableFontData::ReadUByte(int32_t index) {
-  return 0xff & array_->Get(BoundOffset(index));
+  int32_t b = array_->Get(BoundOffset(index));
+#if !defined (SFNTLY_NO_EXCEPTION)
+  if (b < 0) {
+    throw IndexOutOfBoundException(
+        "Index attempted to be read from is out of bounds", index);
+  }
+#endif
+  return b;
 }
 
 int32_t ReadableFontData::ReadByte(int32_t index) {
-  return (array_->Get(BoundOffset(index)) << 24) >> 24;
+  int32_t b = array_->Get(BoundOffset(index));
+#if !defined (SFNTLY_NO_EXCEPTION)
+  if (b < 0) {
+    throw IndexOutOfBoundException(
+        "Index attempted to be read from is out of bounds", index);
+  }
+#endif
+  return (b << 24) >> 24;
 }
 
 int32_t ReadableFontData::ReadBytes(int32_t index,
-                                    ByteVector* b,
+                                    byte_t* b,
                                     int32_t offset,
                                     int32_t length) {
   return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
@@ -88,7 +115,7 @@
     throw ArithmeticException("Long value too large to fit into an integer.");
   }
 #endif
-  return ((int32_t)ulong) & ~0x80000000;
+  return static_cast<int32_t>(ulong);
 }
 
 int32_t ReadableFontData::ReadLong(int32_t index) {
@@ -164,17 +191,6 @@
       checksum_(0) {
 }
 
-/* OpenType checksum
-ULONG
-CalcTableChecksum(ULONG *Table, ULONG Length)
-{
-ULONG Sum = 0L;
-ULONG *Endptr = Table+((Length+3) & ~3) / sizeof(ULONG);
-while (Table < EndPtr)
-  Sum += *Table++;
-return Sum;
-}
-*/
 void ReadableFontData::ComputeChecksum() {
   // TODO(arthurhsu): IMPLEMENT: synchronization/atomicity
   int64_t sum = 0;
diff --git a/sfntly/data/readable_font_data.h b/sfntly/data/readable_font_data.h
index b1ca846..e7b3170 100644
--- a/sfntly/data/readable_font_data.h
+++ b/sfntly/data/readable_font_data.h
@@ -24,13 +24,36 @@
 
 class WritableFontData;
 class OutputStream;
+
+// Writable font data wrapper. Supports reading of data primitives in the
+// TrueType / OpenType spec.
+// The data types used are as listed:
+// BYTE       8-bit unsigned integer.
+// CHAR       8-bit signed integer.
+// USHORT     16-bit unsigned integer.
+// SHORT      16-bit signed integer.
+// UINT24     24-bit unsigned integer.
+// ULONG      32-bit unsigned integer.
+// LONG       32-bit signed integer.
+// Fixed      32-bit signed fixed-point number (16.16)
+// FUNIT      Smallest measurable distance in the em space.
+// FWORD      16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD     16-bit unsigned integer (USHORT) that describes a quantity in
+//            FUnits.
+// F2DOT14    16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME  Date represented in number of seconds since 12:00 midnight,
+//               January 1, 1904. The value is represented as a signed 64-bit
+//               integer.
+
 class ReadableFontData : public FontData,
                          public RefCounted<ReadableFontData> {
  public:
   explicit ReadableFontData(ByteArray* array);
   virtual ~ReadableFontData();
 
-  // Get a computed checksum for the data. This checksum uses the OpenType spec
+  static CALLER_ATTACH ReadableFontData* CreateReadableFontData(ByteVector* b);
+
+  // Gets a computed checksum for the data. This checksum uses the OpenType spec
   // calculation. Every ULong value (32 bit unsigned) in the data is summed and
   // the resulting value is truncated to 32 bits. If the data length in bytes is
   // not an integral multiple of 4 then any remaining bytes are treated as the
@@ -45,32 +68,120 @@
   // @param ranges the range bounds to use for the checksum
   void SetCheckSumRanges(const IntegerList& ranges);
 
+  // Read the UBYTE at the given index.
+  // @param index index into the font data
+  // @return the UBYTE; -1 if outside the bounds of the font data
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadUByte(int32_t index);
+
+  // Read the BYTE at the given index.
+  // @param index index into the font data
+  // @return the BYTE
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadByte(int32_t index);
-  virtual int32_t ReadBytes(int32_t index, ByteVector* b, int32_t offset,
+
+  // Read the bytes at the given index into the array.
+  // @param index index into the font data
+  // @param b the destination for the bytes read
+  // @param offset offset in the byte array to place the bytes
+  // @param length the length of bytes to read
+  // @return the number of bytes actually read; -1 if the index is outside the
+  //         bounds of the font data
+  virtual int32_t ReadBytes(int32_t index,
+                            byte_t* b,
+                            int32_t offset,
                             int32_t length);
+
+  // Read the CHAR at the given index.
+  // @param index index into the font data
+  // @return the CHAR
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadChar(int32_t index);
+
+  // Read the USHORT at the given index.
+  // @param index index into the font data
+  // @return the USHORT
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadUShort(int32_t index);
+
+  // Read the SHORT at the given index.
+  // @param index index into the font data
+  // @return the SHORT
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadShort(int32_t index);
+
+  // Read the UINT24 at the given index.
+  // @param index index into the font data
+  // @return the UINT24
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadUInt24(int32_t index);
+
+  // Read the ULONG at the given index.
+  // @param index index into the font data
+  // @return the ULONG
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int64_t ReadULong(int32_t index);
+
+  // Read the ULONG at the given index as int32_t.
+  // @param index index into the font data
+  // @return the ULONG
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadULongAsInt(int32_t index);
+
+  // Read the LONG at the given index.
+  // @param index index into the font data
+  // @return the LONG
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadLong(int32_t index);
+
+  // Read the Fixed at the given index.
+  // @param index index into the font data
+  // @return the Fixed
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadFixed(int32_t index);
+
+  // Read the LONGDATETIME at the given index.
+  // @param index index into the font data
+  // @return the LONGDATETIME
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int64_t ReadDateTimeAsLong(int32_t index);
 
+  // Read the FWORD at the given index.
+  // @param index index into the font data
+  // @return the FWORD
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadFWord(int32_t index);
+
+  // Read the UFWORD at the given index.
+  // @param index index into the font data
+  // @return the UFWORD
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t ReadFUFWord(int32_t index);
 
-  virtual int32_t CopyTo(OutputStream* os);
-  virtual int32_t CopyTo(WritableFontData* wfd);
-  virtual int32_t CopyTo(ByteArray* ba);
-
-  // TODO(arthurhsu): IMPLEMENT
+  // Note: Not ported because they just throw UnsupportedOperationException()
+  //       in Java.
   /*
   virtual int32_t ReadFUnit(int32_t index);
   virtual int64_t ReadF2Dot14(int32_t index);
-  virtual int64_t ReadLongDateTime(int32_t index);
+  */
+
+  // Copy the FontData to an OutputStream.
+  // @param os the destination
+  // @return number of bytes copied
+  // @throws IOException
+  virtual int32_t CopyTo(OutputStream* os);
+
+  // Copy the FontData to a WritableFontData.
+  // @param wfd the destination
+  // @return number of bytes copied
+  // @throws IOException
+  virtual int32_t CopyTo(WritableFontData* wfd);
+
+  // Make gcc -Woverloaded-virtual happy.
+  virtual int32_t CopyTo(ByteArray* ba);
+
+  // TODO(dfilimon): Implementation of following in review, need to merge.
+  /*
   virtual int32_t SearchUShort(int32_t start, int32_t length, int32_t key);
   virtual int32_t SearchUShort(int32_t start_index, int32_t start_offset,
                                int32_t count_index, int32_t count_offset,
@@ -85,14 +196,18 @@
   // @param offset the start of the slice
   // @param length the number of bytes in the slice
   // @return a slice of the original FontData
+  // Note: C++ polymorphism requires return type to be consistent
   virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
 
   // Makes a bottom bound only slice of this array. The returned slice will
   // share the data with the original FontData.
   // @param offset the start of the slice
   // @return a slice of the original FontData
+  // Note: C++ polymorphism requires return type to be consistent
   virtual CALLER_ATTACH FontData* Slice(int32_t offset);
 
+  // Not Ported: toString()
+
  protected:
   // Constructor. Creates a bounded wrapper of another ReadableFontData from the
   // given offset until the end of the original ReadableFontData.
@@ -104,10 +219,24 @@
   // given offset until the end of the original ReadableFontData.
   // @param data data to wrap
   // @param offset the start of this data's view of the original data
+  // @param length the length of the other FontData to use
   ReadableFontData(ReadableFontData* data, int32_t offset, int32_t length);
 
  private:
+  // Compute the checksum for the font data using any ranges set for the
+  // calculation.
   void ComputeChecksum();
+
+  // Do the actual computation of the checksum for a range using the
+  // TrueType/OpenType checksum algorithm. The range used is from the low bound
+  // to the high bound in steps of four bytes. If any of the bytes within that 4
+  // byte segment are not readable then it will considered a zero for
+  // calculation.
+  // Only called from within a synchronized method so it does not need to be
+  // synchronized itself.
+  // @param lowBound first position to start a 4 byte segment on
+  // @param highBound last possible position to start a 4 byte segment on
+  // @return the checksum for the total range
   int64_t ComputeCheckSum(int32_t low_bound, int32_t high_bound);
 
   bool checksum_set_;  // TODO(arthurhsu): IMPLEMENT: must be set atomically.
diff --git a/sfntly/data/writable_font_data.cc b/sfntly/data/writable_font_data.cc
index 5f694be..c690956 100644
--- a/sfntly/data/writable_font_data.cc
+++ b/sfntly/data/writable_font_data.cc
@@ -40,7 +40,9 @@
   return wfd.Detach();
 }
 
-// static
+// TODO(arthurhsu): re-investigate the memory model of this function.  It's
+//                  not too useful without copying, but it's not performance
+//                  savvy to do copying.
 CALLER_ATTACH
 WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
   ByteArrayPtr ba = new GrowableMemoryByteArray();
@@ -54,18 +56,19 @@
   return 1;
 }
 
-int32_t WritableFontData::WriteBytes(int32_t offset,
-                                     ByteVector* b,
-                                     int32_t index,
+int32_t WritableFontData::WriteBytes(int32_t index,
+                                     byte_t* b,
+                                     int32_t offset,
                                      int32_t length) {
-  return array_->Put(BoundOffset(offset),
+  return array_->Put(BoundOffset(index),
                      b,
-                     index,
-                     BoundLength(offset, length));
+                     offset,
+                     BoundLength(index, length));
 }
 
 int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
-  return WriteBytes(index, b, 0, b->size());
+  assert(b);
+  return WriteBytes(index, &((*b)[0]), 0, b->size());
 }
 
 int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
@@ -115,8 +118,8 @@
   return WriteULong(index, l);
 }
 
-int32_t WritableFontData::WriteFixed(int32_t index, int32_t l) {
-  return WriteLong(index, l);
+int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) {
+  return WriteLong(index, f);
 }
 
 int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) {
diff --git a/sfntly/data/writable_font_data.h b/sfntly/data/writable_font_data.h
index ceefb30..f674ae1 100644
--- a/sfntly/data/writable_font_data.h
+++ b/sfntly/data/writable_font_data.h
@@ -21,6 +21,8 @@
 
 namespace sfntly {
 
+// Writable font data wrapper. Supports writing of data primitives in the
+// TrueType / OpenType spec.
 class WritableFontData : public ReadableFontData {
  public:
   explicit WritableFontData(ByteArray* ba);
@@ -30,7 +32,6 @@
   // positive then a fixed size font data object will be created. If the length
   // is zero or less then a growable font data object will be created and the
   // size will be used as an estimate to help in allocating the original space.
-  //
   // @param length if length > 0 create a fixed length font data; otherwise
   //        create a growable font data
   // @return a new writable font data
@@ -39,29 +40,114 @@
   // Constructs a writable font data object. The new font data object will wrap
   // the bytes passed in to the factory and it will take make a copy of those
   // bytes.
-  //
   // @param b the byte vector to wrap
   // @return a new writable font data
   static CALLER_ATTACH WritableFontData* CreateWritableFontData(ByteVector* b);
 
+  // Write a byte at the given index.
+  // @param index index into the font data
+  // @param b the byte to write
+  // @return the number of bytes written
   virtual int32_t WriteByte(int32_t index, byte_t b);
-  virtual int32_t WriteBytes(int32_t offset,
-                             ByteVector* b,
-                             int32_t index,
+
+  // Write the bytes from the array.
+  // @param index index into the font data
+  // @param b the source for the bytes to be written
+  // @param offset offset in the byte array
+  // @param length the length of the bytes to be written
+  // @return the number of bytes actually written; -1 if the index is outside
+  //         the FontData's range
+  virtual int32_t WriteBytes(int32_t index,
+                             byte_t* b,
+                             int32_t offset,
                              int32_t length);
+
+  // Write the bytes from the array.
+  // @param index index into the font data
+  // @param b the source for the bytes to be written
+  // @return the number of bytes actually written; -1 if the index is outside
+  //         the FontData's range
   virtual int32_t WriteBytes(int32_t index, ByteVector* b);
+
+  // Write the CHAR at the given index.
+  // @param index index into the font data
+  // @param c the CHAR
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteChar(int32_t index, byte_t c);
+
+  // Write the USHORT at the given index.
+  // @param index index into the font data
+  // @param us the USHORT
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteUShort(int32_t index, int32_t us);
+
+  // Write the USHORT at the given index in little endian format.
+  // @param index index into the font data
+  // @param us the USHORT
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteUShortLE(int32_t index, int32_t us);
+
+  // Write the SHORT at the given index.
+  // @param index index into the font data
+  // @param s the SHORT
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteShort(int32_t index, int32_t s);
+
+  // Write the UINT24 at the given index.
+  // @param index index into the font data
+  // @param ui the UINT24
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteUInt24(int32_t index, int32_t ui);
+
+  // Write the ULONG at the given index.
+  // @param index index into the font data
+  // @param ul the ULONG
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteULong(int32_t index, int64_t ul);
+
+  // Write the ULONG at the given index in little endian format.
+  // @param index index into the font data
+  // @param ul the ULONG
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteULongLE(int32_t index, int64_t ul);
+
+  // Write the LONG at the given index.
+  // @param index index into the font data
+  // @param l the LONG
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteLong(int32_t index, int64_t l);
-  virtual int32_t WriteFixed(int32_t index, int32_t l);
+
+  // Write the Fixed at the given index.
+  // @param index index into the font data
+  // @param f the Fixed
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
+  virtual int32_t WriteFixed(int32_t index, int32_t f);
+
+  // Write the LONGDATETIME at the given index.
+  // @param index index into the font data
+  // @param date the LONGDATETIME
+  // @return the number of bytes actually written
+  // @throws IndexOutOfBoundsException if index is outside the FontData's range
   virtual int32_t WriteDateTime(int32_t index, int64_t date);
 
+  // Copy from the InputStream into this FontData.
+  // @param is the source
+  // @param length the number of bytes to copy
+  // @throws IOException
   virtual void CopyFrom(InputStream* is, int32_t length);
+
+  // Copy everything from the InputStream into this FontData.
+  // @param is the source
+  // @throws IOException
   virtual void CopyFrom(InputStream* is);
 
   // Makes a slice of this FontData. The returned slice will share the data with
@@ -78,7 +164,15 @@
   virtual CALLER_ATTACH FontData* Slice(int32_t offset);
 
  private:
+  // Constructor with a lower bound.
+  // @param data other WritableFontData object to share data with
+  // @param offset offset from the other WritableFontData's data
   WritableFontData(WritableFontData* data, int32_t offset);
+
+  // Constructor with lower bound and a length bound.
+  // @param data other WritableFontData object to share data with
+  // @param offset offset from the other WritableFontData's data
+  // @param length length of other WritableFontData's data to use
   WritableFontData(WritableFontData* data, int32_t offset, int32_t length);
 };
 typedef Ptr<WritableFontData> WritableFontDataPtr;
diff --git a/sfntly/glyph_table.cc b/sfntly/glyph_table.cc
index 99e7c06..79c10dd 100644
--- a/sfntly/glyph_table.cc
+++ b/sfntly/glyph_table.cc
@@ -593,7 +593,7 @@
   }
   int32_t tsize = TransformationSize(contour);
   transformation->resize(tsize);
-  data_->ReadBytes(index, transformation, 0, tsize);
+  data_->ReadBytes(index, &((*transformation)[0]), 0, tsize);
 }
 
 int32_t GlyphTable::CompositeGlyph::InstructionSize() {
diff --git a/sfntly/name_table.cc b/sfntly/name_table.cc
index d65f251..649baed 100644
--- a/sfntly/name_table.cc
+++ b/sfntly/name_table.cc
@@ -477,7 +477,7 @@
   int32_t length = NameLength(index);
   b->clear();
   b->resize(length);
-  data_->ReadBytes(NameOffset(index), b, 0, length);
+  data_->ReadBytes(NameOffset(index), &((*b)[0]), 0, length);
 }
 
 void NameTable::NameAsBytes(int32_t platform_id,
diff --git a/sfntly/os2_table.cc b/sfntly/os2_table.cc
index 5b6181d..24ef4e9 100644
--- a/sfntly/os2_table.cc
+++ b/sfntly/os2_table.cc
@@ -167,7 +167,7 @@
 void OS2Table::Panose(ByteVector* value) {
   value->clear();
   value->resize(10);
-  data_->ReadBytes(Offset::kPanose, value, 0, 10);
+  data_->ReadBytes(Offset::kPanose, &((*value)[0]), 0, 10);
 }
 
 int64_t OS2Table::UlUnicodeRange1() {
@@ -189,7 +189,7 @@
 void OS2Table::AchVendId(ByteVector* b) {
   b->clear();
   b->resize(4);
-  data_->ReadBytes(Offset::kAchVendId, b, 0, 4);
+  data_->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
 }
 
 int32_t OS2Table::FsSelection() {
diff --git a/sfntly/port/exception_type.h b/sfntly/port/exception_type.h
index 2ba199a..ddeb95b 100644
--- a/sfntly/port/exception_type.h
+++ b/sfntly/port/exception_type.h
@@ -23,18 +23,23 @@
 
 #include <exception>
 #include <string>
+#include <sstream>
 
 namespace sfntly {
 
 class Exception : public std::exception {
  public:
-  explicit Exception(const char* message) throw() {
+  Exception() : what_("Unknown exception") {}
+  explicit Exception(const char* message) throw() { SetMessage(message); }
+  virtual ~Exception() throw() {}
+  virtual const char* what() const throw() { return what_.c_str(); }
+
+ protected:
+  void SetMessage(const char* message) throw() {
     try {
       what_ = message;
     } catch (...) {}
   }
-  virtual ~Exception() throw() {}
-  virtual const char* what() const throw() { return what_.c_str(); }
 
  private:
   std::string what_;
@@ -45,6 +50,15 @@
   IndexOutOfBoundException() throw() : Exception("Index out of bound") {}
   explicit IndexOutOfBoundException(const char* message) throw()
       : Exception(message) {}
+  IndexOutOfBoundException(const char* message, int32_t index) throw() {
+    try {
+      std::ostringstream msg;
+      msg << message;
+      msg << ":";
+      msg << index;
+      SetMessage(msg.str().c_str());
+    } catch (...) {}
+  }
   virtual ~IndexOutOfBoundException() throw() {}
 };
 
diff --git a/sfntly/port/memory_output_stream.cc b/sfntly/port/memory_output_stream.cc
index 5ddeec2..f2ff2e3 100644
--- a/sfntly/port/memory_output_stream.cc
+++ b/sfntly/port/memory_output_stream.cc
@@ -31,9 +31,27 @@
 void MemoryOutputStream::Write(ByteVector* buffer,
                                int32_t offset,
                                int32_t length) {
-  store_.insert(store_.end(),
-                buffer->begin() + offset,
-                buffer->begin() + offset + length);
+  assert(buffer);
+  if (offset >= 0 && length > 0) {
+    store_.insert(store_.end(),
+                  buffer->begin() + offset,
+                  buffer->begin() + offset + length);
+  } else {
+#if !defined(SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+  }
+}
+
+void MemoryOutputStream::Write(byte_t* buffer, int32_t offset, int32_t length) {
+  assert(buffer);
+  if (offset >= 0 && length > 0) {
+    store_.insert(store_.end(), buffer + offset, buffer + offset + length);
+  } else {
+#if !defined(SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundException();
+#endif
+  }
 }
 
 void MemoryOutputStream::Write(byte_t b) {
@@ -41,6 +59,9 @@
 }
 
 byte_t* MemoryOutputStream::Get() {
+  if (store_.empty()) {
+    return NULL;
+  }
   return &(store_[0]);
 }
 
diff --git a/sfntly/port/memory_output_stream.h b/sfntly/port/memory_output_stream.h
index a0befea..8983ab0 100644
--- a/sfntly/port/memory_output_stream.h
+++ b/sfntly/port/memory_output_stream.h
@@ -36,6 +36,7 @@
   virtual void Flush() {}  // no-op
   virtual void Write(ByteVector* buffer);
   virtual void Write(ByteVector* buffer, int32_t offset, int32_t length);
+  virtual void Write(byte_t* buffer, int32_t offset, int32_t length);
   virtual void Write(byte_t b);
 
   byte_t* Get();
diff --git a/sfntly/port/output_stream.h b/sfntly/port/output_stream.h
index c5d71cf..d813333 100644
--- a/sfntly/port/output_stream.h
+++ b/sfntly/port/output_stream.h
@@ -30,8 +30,15 @@
   virtual void Close() = 0;
   virtual void Flush() = 0;
   virtual void Write(ByteVector* buffer) = 0;
-  virtual void Write(ByteVector* buffer, int32_t offset, int32_t length) = 0;
   virtual void Write(byte_t b) = 0;
+
+  // Note: C++ port offered both versions of Write() here.  The first one is
+  //       better because it does check bounds.  The second one is there for
+  //       performance concerns.
+  virtual void Write(ByteVector* buffer, int32_t offset, int32_t length) = 0;
+
+  // Note: Caller is responsible for the boundary of buffer.
+  virtual void Write(byte_t* buffer, int32_t offset, int32_t length) = 0;
 };
 
 }  // namespace sfntly
diff --git a/sfntly/tag.h b/sfntly/tag.h
index d802351..9a548f6 100644
--- a/sfntly/tag.h
+++ b/sfntly/tag.h
@@ -83,11 +83,8 @@
 };
 
 // Create integer tag value for human readable tag name.
-inline int32_t GenerateTag(char a, char b, char c, char d) {
-  return (((int32_t)(a) << 24) |
-          ((int32_t)(b) << 16) |
-          ((int32_t)(c) <<  8) |
-           (int32_t)(d));
+inline int32_t GenerateTag(int32_t a, int32_t b, int32_t c, int32_t d) {
+  return (a << 24) | (b << 16) | (c << 8) | d;
 }
 
 // Translate tag to human readable string.
diff --git a/test/byte_array_test.cc b/test/byte_array_test.cc
index 74b5290..40a6489 100644
--- a/test/byte_array_test.cc
+++ b/test/byte_array_test.cc
@@ -51,7 +51,7 @@
   while (index < ba->Length()) {
     actual_window_size =
         std::min<int32_t>(actual_window_size, b->size() - index);
-    int32_t bytes_read = ba->Get(index, b, index, actual_window_size);
+    int32_t bytes_read = ba->Get(index, &((*b)[0]), index, actual_window_size);
     index += bytes_read;
   }
 }
diff --git a/test/font_data_test.cc b/test/font_data_test.cc
index 5a80fb3..4de6fff 100644
--- a/test/font_data_test.cc
+++ b/test/font_data_test.cc
@@ -48,7 +48,7 @@
 
   int32_t index = 0;
   while (index < rfd->Length()) {
-    int32_t bytes_read = rfd->ReadBytes(index, &buffer, 0, buffer.size());
+    int32_t bytes_read = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size());
     EXPECT_GE(bytes_read, 0);
     std::copy(buffer.begin(), buffer.begin() + bytes_read, b->begin() + index);
     index += bytes_read;
@@ -62,7 +62,8 @@
   while (index < rfd->Length()) {
     int32_t actual_window_size =
         std::min<int32_t>(window_size, b->size() - index);
-    int32_t bytes_read = rfd->ReadBytes(index, b, index, actual_window_size);
+    int32_t bytes_read =
+        rfd->ReadBytes(index, &((*b)[0]), index, actual_window_size);
     EXPECT_GE(bytes_read, 0);
     index += bytes_read;
   }
@@ -81,8 +82,8 @@
   ByteVector buffer(buffer_size);
   int32_t index = 0;
   while (index < rfd->Length()) {
-    int32_t bytesRead = rfd->ReadBytes(index, &buffer, 0, buffer.size());
-    wfd->WriteBytes(index, &buffer, 0, buffer.size());
+    int32_t bytesRead = rfd->ReadBytes(index, &(buffer[0]), 0, buffer.size());
+    wfd->WriteBytes(index, &(buffer[0]), 0, buffer.size());
     index += bytesRead;
   }
 }
@@ -94,8 +95,8 @@
   int32_t index = 0;
   while (index < rfd->Length()) {
     int32_t sliding_size = std::min<int32_t>(window_size, b.size() - index);
-    int32_t bytes_read = rfd->ReadBytes(index, &b, index, sliding_size);
-    wfd->WriteBytes(index, &b, index, sliding_size);
+    int32_t bytes_read = rfd->ReadBytes(index, &(b[0]), index, sliding_size);
+    wfd->WriteBytes(index, &(b[0]), index, sliding_size);
     index += bytes_read;
   }
 }
diff --git a/test/font_parsing_test.cc b/test/font_parsing_test.cc
index ee794d1..3dcbda2 100644
--- a/test/font_parsing_test.cc
+++ b/test/font_parsing_test.cc
@@ -65,7 +65,7 @@
   wfd.Attach(gdef_builder->Data());
   ByteVector b;
   b.resize(TTF_LENGTH[SAMPLE_TTF_GDEF]);
-  wfd->ReadBytes(0, &b, 0, TTF_LENGTH[SAMPLE_TTF_GDEF]);
+  wfd->ReadBytes(0, &(b[0]), 0, TTF_LENGTH[SAMPLE_TTF_GDEF]);
   EXPECT_EQ(memcmp(&(b[0]), TTF_GDEF_DATA, TTF_LENGTH[SAMPLE_TTF_GDEF]), 0);
 
   // Header table
@@ -91,8 +91,8 @@
     wfd1.Attach(builder1->Data());
     WritableFontDataPtr wfd2;
     wfd2.Attach(builder2->Data());
-    wfd1->ReadBytes(0, &b1, 0, TTF_LENGTH[i]);
-    wfd2->ReadBytes(0, &b2, 0, TTF_LENGTH[i]);
+    wfd1->ReadBytes(0, &(b1[0]), 0, TTF_LENGTH[i]);
+    wfd2->ReadBytes(0, &(b2[0]), 0, TTF_LENGTH[i]);
     EXPECT_EQ(memcmp(&(b1[0]), &(b2[0]), TTF_LENGTH[i]), 0);
   }