     bytes
 
 
+class ArrayCodec
+
+  # An array codec is a special case. It wraps a format codec, but prefixes
+  # it with a uint32 length value. It will first read the length, then read
+  # than many of the values from the byte array.
+
+  lengthCodec: new IntegerCodec(4, signed: false)
+
+  constructor: (@valueType) ->
+    @valueCodec = codecs[@valueType]
+    unless @valueCodec?
+      throw new Exception("Invalid array value type #{valueType}")
+
+  fromByteArray: (bytes, byteIndex, littleEndian) ->
+    # First read the number of elements in the array
+    length = @lengthCodec.fromByteArray(bytes, byteIndex, littleEndian)
+    byteIndex += @lengthCodec.length
+
+    # Then read all the elements
+    if length > 0
+      values = new Array(length)
+      for index in [0...length]
+        values[index] = @valueCodec.fromByteArray(bytes, byteIndex,
+                                                  littleEndian)
+        byteIndex += @valueCodec.length
+      @length = @lengthCodec.length + length * @valueCodec.length
+      values
+    else
+      @length = @lengthCodec.length
+      []
+
+  toByteArray: (values, littleEndian) ->
+    length = values?.length or 0
+    bytes = @lengthCodec.toByteArray(length, littleEndian)
+    if length > 0
+      for value in values
+        bytes = bytes.concat(@valueCodec.toByteArray(value, littleEndian))
+    bytes
+
+
 class StringCodec
 
   # The string codec is another special case. JavaScript strings are UTF-16,


class IntegerCodec

  constructor: (@length, @signed) ->
    @bitLength = @length * 8
    if @signed
      @signBit = Math.pow(2, @bitLength - 1)

  # FIXME: Could probably do this a bit more efficiently by encoding UTF-8
  # ourselves instead of using encodeURIComponent.

  lengthCodec: new IntegerCodec(4, signed: false)

  fromByteArray: (bytes, byteIndex, littleEndian) ->
    # First read the number of characters in the string
    length = @lengthCodec.fromByteArray(bytes, byteIndex, littleEndian)
    byteIndex += @lengthCodec.length

    # Then read the characters. The string is in UTF-8 format, so we'll need
    # to convert it back into UTF-16.
    if length > 0
      string = ''
      for i in [byteIndex...byteIndex + length]
        string += String.fromCharCode(bytes[i])
      @length = @lengthCodec.length + length
      decodeURIComponent(escape(string))
    else
      @length = @lengthCodec.length
      ''

  toByteArray: (string, littleEndian) ->
    if string
      utf8 = unescape(encodeURIComponent(string))
      length = utf8.length
      bytes = @lengthCodec.toByteArray(length, littleEndian)
      for i in [0...utf8.length]
        bytes.push(utf8.charCodeAt(i))
      bytes
    else
      # Undefined or empty string, just send a zero length
      @lengthCodec.toByteArray(0, littleEndian)


# This is a set of codecs that can be used by fields to convert typed values
