public int ReadLength()
        {
            int length = (int)ReadUInt32V();

            if (length < 0)
            {
                throw CodecException.BufferOutOfSpace();
            }

            return(length);
        }
        public void WriteUInt8(byte val)
        {
            if (buffer_left_size_ < 1)
            {
                throw CodecException.BufferOutOfSpace();
            }

            buffer_[buffer_pos_] = val;

            buffer_pos_       += 1;
            buffer_left_size_ -= 1;
        }
        public void WriteUInt16(ushort val)
        {
            if (buffer_left_size_ < 2)
            {
                throw CodecException.BufferOutOfSpace();
            }

            buffer_[buffer_pos_]     = (byte)(val >> 8);
            buffer_[buffer_pos_ + 1] = (byte)(val);

            buffer_pos_       += 2;
            buffer_left_size_ -= 2;
        }
        public byte ReadUInt8()
        {
            if (buffer_left_size_ < 1)
            {
                throw CodecException.BufferOutOfSpace();
            }

            byte val = buffer_[buffer_pos_];

            buffer_pos_       += 1;
            buffer_left_size_ -= 1;

            return(val);
        }
        public void WriteUInt32(uint val)
        {
            if (buffer_left_size_ < 4)
            {
                throw CodecException.BufferOutOfSpace();
            }

            buffer_[buffer_pos_]     = (byte)(val >> 24);
            buffer_[buffer_pos_ + 1] = (byte)(val >> 16);
            buffer_[buffer_pos_ + 2] = (byte)(val >> 8);
            buffer_[buffer_pos_ + 3] = (byte)(val);

            buffer_pos_       += 4;
            buffer_left_size_ -= 4;
        }
        public void WriteBytes(byte[] val)
        {
            int length = val.Length;

            WriteLength(length);
            if (buffer_left_size_ < length)
            {
                throw CodecException.BufferOutOfSpace();
            }

            Buffer.BlockCopy(val, 0, buffer_, buffer_pos_, length);

            buffer_pos_       += length;
            buffer_left_size_ -= length;
        }
        public ushort ReadUInt16()
        {
            if (buffer_left_size_ < 2)
            {
                throw CodecException.BufferOutOfSpace();
            }

            ushort val = (ushort)(buffer_[buffer_pos_ + 1] |
                                  buffer_[buffer_pos_] << 8);

            buffer_pos_       += 2;
            buffer_left_size_ -= 2;

            return(val);
        }
        public void WriteString(string val)
        {
            // EncoderFallbackException
            int length = Encoding.UTF8.GetByteCount(val);

            WriteLength(length);
            if (buffer_left_size_ < length)
            {
                throw CodecException.BufferOutOfSpace();
            }

            // EncoderFallbackException
            Encoding.UTF8.GetBytes(val, 0, val.Length, buffer_, buffer_pos_);

            buffer_pos_       += length;
            buffer_left_size_ -= length;
        }
        public uint ReadUInt32()
        {
            if (buffer_left_size_ < 4)
            {
                throw CodecException.BufferOutOfSpace();
            }

            uint val = (uint)buffer_[buffer_pos_ + 3] |
                       (uint)buffer_[buffer_pos_ + 2] << 8 |
                       (uint)buffer_[buffer_pos_ + 1] << 16 |
                       (uint)buffer_[buffer_pos_] << 24;

            buffer_pos_       += 4;
            buffer_left_size_ -= 4;

            return(val);
        }
        public void WriteUInt64(ulong val)
        {
            if (buffer_left_size_ < 8)
            {
                throw CodecException.BufferOutOfSpace();
            }

            buffer_[buffer_pos_]     = (byte)(val >> 56);
            buffer_[buffer_pos_ + 1] = (byte)(val >> 48);
            buffer_[buffer_pos_ + 2] = (byte)(val >> 40);
            buffer_[buffer_pos_ + 3] = (byte)(val >> 32);
            buffer_[buffer_pos_ + 4] = (byte)(val >> 24);
            buffer_[buffer_pos_ + 5] = (byte)(val >> 16);
            buffer_[buffer_pos_ + 6] = (byte)(val >> 8);
            buffer_[buffer_pos_ + 7] = (byte)(val);

            buffer_pos_       += 8;
            buffer_left_size_ -= 8;
        }
        public ulong ReadUInt64()
        {
            if (buffer_left_size_ < 8)
            {
                throw CodecException.BufferOutOfSpace();
            }

            ulong val = (ulong)buffer_[buffer_pos_ + 7] |
                        (ulong)buffer_[buffer_pos_ + 6] << 8 |
                        (ulong)buffer_[buffer_pos_ + 5] << 16 |
                        (ulong)buffer_[buffer_pos_ + 4] << 24 |
                        (ulong)buffer_[buffer_pos_ + 3] << 32 |
                        (ulong)buffer_[buffer_pos_ + 2] << 40 |
                        (ulong)buffer_[buffer_pos_ + 1] << 48 |
                        (ulong)buffer_[buffer_pos_] << 56;

            buffer_pos_       += 8;
            buffer_left_size_ -= 8;

            return(val);
        }
        public byte[] ReadBytes()
        {
            int length = ReadLength();

            if (length <= 0)
            {
                return(new byte[0]);
            }

            if (buffer_left_size_ < length)
            {
                throw CodecException.BufferOutOfSpace();
            }

            byte[] val = new byte[length];
            Buffer.BlockCopy(buffer_, buffer_pos_, val, 0, length);

            buffer_pos_       += length;
            buffer_left_size_ -= length;

            return(val);
        }
        public string ReadString()
        {
            int length = ReadLength();

            if (length <= 0)
            {
                return("");
            }

            if (buffer_left_size_ < length)
            {
                throw CodecException.BufferOutOfSpace();
            }

            // ArgumentException
            // DecoderFallbackException
            string val = Encoding.UTF8.GetString(
                buffer_, buffer_pos_, length);

            buffer_pos_       += length;
            buffer_left_size_ -= length;

            return(val);
        }