/// <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); }
/// <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); } }