예제 #1
0
        /// <summary>
        /// Read a string from the stream.
        /// <remarks>
        /// We optimize strings by maintaining a hash table of each unique string
        /// we have seen.  Each string is sent with as an integer index into the table.
        /// When a new string is encountered, it's index is followed by the string value.
        /// </remarks>
        /// </summary>
        /// <returns>Returns the string</returns>
        public string ReadString()
        {
            // Dropping string tables is pretty easy!
            if (m_MajorVersion > 1)
            {
                return(ReadStringDirect());
            }

            /*
             * The rest of this method is for protocol version 1.0
             */
            string stringValue; // string to be returned

            var index = (int)ReadUInt32();

            if (index == 0)
            {
                return(null);
            }

            // check if this is a token we've never seen before.
            // If so, the value follows and we should add it to the token list.
            if (--index == m_Strings.Count)
            {
                stringValue = ReadStringDirect();
                m_Strings.AddOrGet(stringValue);
            }
            else
            {
                stringValue = m_Strings[index];
                CompensateForPossibleSerializationError(stringValue);
            }

            return(stringValue);
        }
예제 #2
0
        /// <summary>
        /// Write a string to the stream.
        /// <remarks>
        /// We optimize strings by maintaining a hash table of each unique string
        /// we have seen.  Each string is sent with as an integer index into the table.
        /// When a new string is encountered, it's index is followed by the string value.
        /// </remarks>
        /// </summary>
        public void Write(string value)
        {
            if (m_MajorVersion > 1)
            {
                WriteString(value);
                return;
            }

            if (value == null)
            {
                WriteByte(0);
                return;
            }

            // The AddOrGet method first checks if the string is already in the table.
            // If so, it just returns the existing index.  Otherwise, it adds the
            // string to the end of the table and returns the index.  In that case,
            // we can detect that this is the first time that a string has been
            // seen by checking if the returned index is too large relative to the
            // Count property before the AddOrGet.
            int newStringIndex = m_Strings.Count + 1; // this line must be called before AddOrGet
            int stringIndex    = m_Strings.AddOrGet(value) + 1;

            Write((UInt32)stringIndex);

            // If we've just added a new string to the table, the index should be equal to
            // the previous count of strings. We have added 1 to the index values because we
            // use zero-based indexing in the string table but 1-based indexing over the wire.
            if (stringIndex == newStringIndex)
            {
                WriteString(value);
            }
            else if (stringIndex > newStringIndex)
            {
                throw new GibraltarException(
                          "Something went wrong with string serialization, we got a bogus index from our string table: " + stringIndex);
            }
        }