byte[] ReadStrPascal(IO.BitStream s, out int actualCount, int prefixBitLength) { actualCount = TypeExtensions.kNone; if (prefixBitLength.IsNone()) { switch (mStorage.LengthPrefix) { case StringStorageLengthPrefix.Int8: prefixBitLength = Bits.kByteBitCount; break; case StringStorageLengthPrefix.Int16: prefixBitLength = Bits.kInt16BitCount; break; case StringStorageLengthPrefix.Int32: prefixBitLength = Bits.kInt32BitCount; break; } } int length; switch (mStorage.LengthPrefix) { case StringStorageLengthPrefix.Int7: throw new NotSupportedException(); case StringStorageLengthPrefix.Int8: length = s.ReadByte(prefixBitLength); break; case StringStorageLengthPrefix.Int16: length = s.ReadInt16(prefixBitLength); break; case StringStorageLengthPrefix.Int32: length = s.ReadInt32(prefixBitLength); break; default: throw new Debug.UnreachableException(); } return(s.ReadBytes(GetMaxCleanByteCount(length))); }
/// <summary>Read a single-byte CString from a bitstream</summary> /// <param name="s">Endian stream to read from</param> /// <param name="ms">Stream to write the character's bytes to</param> /// <param name="maxLength">Optional maximum length of this specific string</param> void ReadCStringSingleByte(IO.BitStream s, System.IO.MemoryStream ms, int maxLength) { byte character; if (maxLength > 0) { int x = 0; while ((character = s.ReadByte()) != 0 && ++x <= maxLength) { ms.WriteByte(character); } } else if (!mStorage.IsFixedLength) { while ((character = s.ReadByte()) != 0) { ms.WriteByte(character); } } else { byte[] characters = s.ReadBytes(mFixedLengthByteLength); int x; for (x = 0; x < characters.Length; x++) { if (characters[x] == 0) { break; } } ms.Write(characters, 0, x); } }
byte[] ReadStrCharArray(IO.BitStream s, int length, out int actualCount) { byte[] bytes = s.ReadBytes(mStorage.IsFixedLength ? mFixedLengthByteLength : GetMaxCleanByteCount(length)); actualCount = mNullCharacterSize == sizeof(byte) ? ReadStrCharArrayGetRealCountSingleByte(bytes) : ReadStrCharArrayGetRealCountMultiByte(mStorage.ByteOrder, bytes); return(bytes); }
/// <summary>Read a CString from a bitstream</summary> /// <param name="s">Bitstream to read from</param> /// <param name="length">Optional length specification</param> /// <param name="actualCount">On return, the actual character byte count, or -1 if all bytes are valid</param> /// <param name="maxLength">Optional maximum length of this specific string</param> /// <returns>The character's bytes for the string we're reading</returns> byte[] ReadStrCString(IO.BitStream s, int length, out int actualCount, int maxLength) { byte[] bytes; actualCount = TypeExtensions.kNone; // complete string case // the user was nice and saved us some CPU trying to feel around for the null // because we don't have a fixed length to speed things up if (!mStorage.IsFixedLength && length > 0) { bytes = s.ReadBytes(GetMaxCleanByteCount(length)); s.ReadUInt32(mNullCharacterSize * Bits.kByteBitCount); } // F**K: figure out the length ourselves. Or maybe we're a fixed length CString... // in which case we'll ignore anything the user tried to tell us about the length else { using (var ms = new System.IO.MemoryStream(!mStorage.IsFixedLength ? 512 : mStorage.FixedLength)) { // The N-byte methods take care of reading past the // null character, no need to do it in this case. if (mNullCharacterSize == 1) { ReadCStringSingleByte(s, ms, maxLength); } else { ReadCStringMultiByte(s, ms, maxLength); } // We use ToArray instead of GetArray so all of [ms] can theoretically be disposed of bytes = ms.ToArray(); } } return(bytes); }
/// <summary>Read a multi-byte CString from an endian stream</summary> /// <param name="s">Bitstream to read from</param> /// <param name="ms">Stream to write the character's bytes to</param> /// <param name="maxLength">Optional maximum length of this specific string</param> void ReadCStringMultiByte(IO.BitStream s, System.IO.MemoryStream ms, int maxLength) { byte[] characters; if (maxLength > 0) { int x = 0; characters = new byte[mNullCharacterSize]; while (!ReadStringMultiByteIsNull(mStorage.ByteOrder, s.Read(characters), 0) && ++x <= maxLength) { ms.Write(characters, 0, characters.Length); } } else if (!mStorage.IsFixedLength) { characters = new byte[mNullCharacterSize]; while (!ReadStringMultiByteIsNull(mStorage.ByteOrder, s.Read(characters), 0)) { ms.Write(characters, 0, characters.Length); } } else { characters = s.ReadBytes(mFixedLengthByteLength); int x; for (x = 0; x < characters.Length - mNullCharacterSize; x += mNullCharacterSize) { if (ReadStringMultiByteIsNull(mStorage.ByteOrder, characters, x)) { break; } } ms.Write(characters, 0, x); } }