private void TransformXmbToXml(byte[] eraFileEntryBuffer, string fullPath, Shell.EndianFormat byteOrder, Shell.ProcessorSize vaSize) { byte[] xmb_buffer; using (var xmb = new ECF.EcfFileXmb()) using (var ms = new System.IO.MemoryStream(eraFileEntryBuffer)) using (var es = new IO.EndianStream(ms, byteOrder, permissions: System.IO.FileAccess.Read)) { es.StreamMode = System.IO.FileAccess.Read; xmb.Serialize(es); xmb_buffer = xmb.FileData; } string xmb_path = fullPath; ResourceUtils.RemoveXmbExtension(ref xmb_path); var context = new Xmb.XmbFileContext() { PointerSize = vaSize, }; using (var ms = new System.IO.MemoryStream(xmb_buffer, false)) using (var s = new IO.EndianReader(ms, byteOrder)) { s.UserData = context; using (var xmbf = new Phoenix.Xmb.XmbFile()) { xmbf.Read(s); xmbf.ToXml(xmb_path); } } }
/// <summary>Define a string storage markup</summary> /// <param name="widthType">Width size of a single character of the string type</param> /// <param name="type">Storage method for this string type</param> /// <param name="byteOrder"></param> /// <param name="fixedLength">The storage fixed length (in characters) of this string type</param> public StringStorageMarkupAttribute(StringStorageWidthType widthType, StringStorageType type, Shell.EndianFormat byteOrder = Shell.EndianFormat.Little, short fixedLength = 0) { Contract.Requires(fixedLength >= 0); Storage = new StringStorage(widthType, type, byteOrder, fixedLength); }
/// <summary>Determine if the multi-byte character is a null character or not</summary> /// <param name="byteOrder">Byte order of the character data</param> /// <param name="characters">Buffer containing the character's bytes</param> /// <param name="offset">offset to start the null comparison at</param> /// <returns>True if <paramref name="characters"/> is null; all zeros</returns> /// <remarks> /// If <paramref name="byteOrder"/> is different from <see cref="Storage.ByteOrder"/>, this will /// byte-swap the bytes before returning /// </remarks> bool ReadStringMultiByteIsNull(Shell.EndianFormat byteOrder, byte[] characters, int offset) { bool result = false; if (mNullCharacterSize == sizeof(uint)) { if (byteOrder != mStorage.ByteOrder) { Bitwise.ByteSwap.SwapInt32(characters, offset); } result = characters[offset + 3] == 0; result &= characters[offset + 2] == 0; result &= characters[offset + 1] == 0; result &= characters[offset] == 0; } else if (mNullCharacterSize == sizeof(ushort)) { if (byteOrder != mStorage.ByteOrder) { Bitwise.ByteSwap.SwapInt16(characters, offset); } result = characters[offset + 1] == 0; result &= characters[offset] == 0; } else { throw new Debug.UnreachableException(mNullCharacterSize.ToString(KSoft.Util.InvariantCultureInfo)); } return(result); }
public static byte[] LowLevelCompress(byte[] bytes, Shell.EndianFormat byteOrder) { Contract.Requires <ArgumentNullException>(bytes != null); Contract.Ensures(Contract.Result <byte[]>() != null); byte[] result = new byte[sizeof(int)]; // Setup the decompressed size header byte[] size_bytes = BitConverter.GetBytes(bytes.Length); if (!byteOrder.IsSameAsRuntime()) { Bitwise.ByteSwap.SwapInt32(size_bytes, 0); } Array.Copy(size_bytes, result, size_bytes.Length); var zip = new ICSharpCode.SharpZipLib.Zip.Compression.Deflater( ICSharpCode.SharpZipLib.Zip.Compression.Deflater.BEST_COMPRESSION, false); { zip.SetInput(bytes); zip.Finish(); byte[] temp = new byte[bytes.Length]; int compressed_size = zip.Deflate(temp); Contract.Assert(compressed_size <= bytes.Length); Array.Resize(ref result, sizeof(int) + compressed_size); Array.Copy(temp, 0, result, sizeof(int), compressed_size); } return(result); }
public BlobChunkVerificationResultInfo OpenForWrite(Stream baseStream, long startPosition = 0, long length = TypeExtensions.kNoneInt64, Shell.EndianFormat endian = Shell.EndianFormat.Big) { Contract.Requires(IsClosed); Contract.Requires <ArgumentNullException>(baseStream != null); Contract.Requires <ArgumentException>(baseStream.CanSeek); Contract.Requires <ArgumentException>(baseStream.HasPermissions(FileAccess.Write)); Contract.Requires(length.IsNoneOrPositive()); var result = BlobChunkVerificationResultInfo.ValidResult; OpenUnderlyingStream(baseStream, FileAccess.Write, endian); OpenStartPosition(baseStream, startPosition); EndPosition = length.IsNotNone() ? StartPosition + length : length; mFooterPosition = TypeExtensions.kNoneInt64; UnderlyingStream.StreamMode = FileAccess.Write; if (EndPosition.IsNotNone()) { OpenVerifyAssumedStreamSize(ref result); } return(result); }
/// <summary>Change the order in which bytes are ordered to/from the stream</summary> /// <param name="newOrder">The new byte order to switch to</param> /// <remarks>If <paramref name="newOrder"/> is the same as <see cref="ByteOrder"/> nothing will happen</remarks> public void ChangeByteOrder(Shell.EndianFormat newOrder) { if (newOrder != ByteOrder) { ByteOrder = newOrder; mRequiresByteSwap = !mRequiresByteSwap; } }
public static ulong VectorElementSectionBitMaskInInt64(int startBitIndex, Shell.EndianFormat byteOrder = kVectorWordFormat) { Contract.Requires <ArgumentOutOfRangeException>(startBitIndex >= 0); return(byteOrder == Shell.EndianFormat.Big ? VectorElementSectionBitMaskInInt64BE(startBitIndex) : VectorElementSectionBitMaskInInt64LE(startBitIndex)); }
public static byte VectorElementBitMaskInBytes(int bitIndex, Shell.EndianFormat byteOrder = kVectorWordFormat) { Contract.Requires <ArgumentOutOfRangeException>(bitIndex >= 0); return(byteOrder == Shell.EndianFormat.Big ? VectorElementBitMaskInBytesBE(bitIndex) : VectorElementBitMaskInBytesLE(bitIndex)); }
public void Read(IO.EndianReader s) { mWidthType = (StringStorageWidthType)s.ReadByte(); mType = (StringStorageType)s.ReadByte(); mByteOrder = (Shell.EndianFormat)s.ReadByte(); s.Seek(sizeof(byte)); mFixedLength = s.ReadInt16(); s.Seek(sizeof(ushort)); }
/// <summary>Get the procedure for building a mask of a section of bits in a vector, relative to the vector's element size (<see cref="System.Int64"/>)</summary> /// <param name="proc"></param> /// <param name="byteOrder">Order in which bits are enumerated (first to last)</param> public static void GetVectorElementSectionBitMaskInT(out VectorElementBitMask <ulong> proc, Shell.EndianFormat byteOrder = kVectorWordFormat) { Contract.Ensures(Contract.ValueAtReturn(out proc) != null); proc = byteOrder == Shell.EndianFormat.Big ? (VectorElementBitMask <ulong>)VectorElementSectionBitMaskInInt64BE : (VectorElementBitMask <ulong>)VectorElementSectionBitMaskInInt64LE; }
/// <summary>Convenience method for C# "using" statements. Temporarily inverts the current byte order which is used for read/writes.</summary> /// <param name="switchTo">Byte order to switch to</param> /// <returns>Object which when Disposed will return this stream to its original <see cref="Shell.EndianFormat"/> state</returns> /// <remarks> /// If <paramref name="switchTo"/> is the same as <see cref="EndianStream.ByteOrder"/> /// then no actual object state changes will happen. However, this construct /// will continue to be usable and will Dispose of properly with no error /// </remarks> public IDisposable BeginEndianSwitch(Shell.EndianFormat switchTo) { if (switchTo == this.ByteOrder) { return(Util.NullDisposable); } return(new EndianFormatSwitchBlock(this)); }
void OpenUnderlyingStream(Stream baseStream, FileAccess permissions, Shell.EndianFormat endian, bool baseStreamOwner = false) { UnderlyingStream = new IO.EndianStream(baseStream, endian, streamOwner: this, name: "BlobStream", permissions: permissions); if (!baseStreamOwner) { UnderlyingStream.BaseStreamOwner = false; } }
/// <summary>Construct a new Pascal string storage definition</summary> /// <param name="widthType">Width size of a single character of this string definition</param> /// <param name="prefix">Length prefix size</param> /// <param name="byteOrder"></param> public StringStorage(StringStorageWidthType widthType, StringStorageLengthPrefix prefix, Shell.EndianFormat byteOrder = Shell.EndianFormat.Little) { mWidthType = widthType; mType = StringStorageType.Pascal; mByteOrder = byteOrder; mLengthPrefix = prefix; mFixedLength = 0; kHashCode = CalculateHashCode(mWidthType, mType, mByteOrder, mLengthPrefix, mFixedLength); }
public BinaryDataTreeMemoryPool(byte[] buffer, Shell.EndianFormat byteOrder = Shell.EndianFormat.Big) : this() { Contract.Requires(buffer != null); mPoolSize = (uint)buffer.Length; var ms = new System.IO.MemoryStream(buffer, false); mBuffer = new IO.EndianReader(ms, byteOrder, this); mBufferedDataRemaining = mPoolSize; }
public void Compute(Shell.EndianFormat byteOrder, uint value) { if (byteOrder == Shell.EndianFormat.Little) { ComputeLE(value); } else { ComputeBE(value); } }
/// <summary>Change the order in which bytes are ordered to/from the stream</summary> /// <param name="newOrder">The new byte order to switch to</param> /// <remarks>If <paramref name="newOrder"/> is the same as <see cref="ByteOrder"/> nothing will happen</remarks> public void ChangeByteOrder(Shell.EndianFormat newOrder) { if (Reader != null) { Reader.ChangeByteOrder(newOrder); } if (Writer != null) { Writer.ChangeByteOrder(newOrder); } }
/// <summary>Create a radix encoder using the given characters as the digits in the radix</summary> /// <param name="digits">Digits to use for the radix-encoded string</param> /// <param name="bytesEndian">Endian ordering of bytes input to Encode and output by Decode</param> /// <param name="includeProceedingZeros">True if we want ending zero bytes to be encoded</param> public RadixEncoding(string digits, Shell.EndianFormat bytesEndian = Shell.EndianFormat.Little, bool includeProceedingZeros = false) { Contract.Requires <ArgumentNullException>(digits != null); int radix = digits.Length; kDigits = digits; kBitsPerDigit = System.Math.Log(radix, 2); kRadixBig = new BigInteger(radix); kEndian = bytesEndian; kIncludeProceedingZeros = includeProceedingZeros; }
/// <summary></summary> /// <param name="s"></param> /// <param name="requiresSwitch">Is there an actual order switch even occurring?</param> public EndianFormatSwitchBlock(EndianReader s, bool requiresSwitch) { mStream = requiresSwitch ? s : null; if (requiresSwitch) // if not, don't do anything but keep the IDisposable wheel turning { mOldByteOrder = s.ByteOrder; mOldRequiresByteSwap = s.mRequiresByteSwap; s.ChangeByteOrder(mOldByteOrder.Invert()); } }
/// <summary>Construct a new string storage definition</summary> /// <param name="widthType">Width size of a single character of this string definition</param> /// <param name="type">Storage method for this string definition</param> /// <param name="byteOrder"></param> /// <param name="fixedLength">The storage fixed length (in characters) of this string definition</param> public StringStorage(StringStorageWidthType widthType, StringStorageType type, Shell.EndianFormat byteOrder = Shell.EndianFormat.Little, short fixedLength = 0) { Contract.Requires(!type.UsesLengthPrefix(), "Use ctor with StringStorageLengthPrefix instead"); Contract.Requires(fixedLength >= 0); Contract.Requires(fixedLength == 0 || !widthType.IsVariableWidth(), "Can't use a variable width encoding with fixed buffers!"); mWidthType = widthType; mType = type; mByteOrder = byteOrder; mLengthPrefix = StringStorageLengthPrefix.None; mFixedLength = fixedLength; kHashCode = CalculateHashCode(mWidthType, mType, mByteOrder, mLengthPrefix, mFixedLength); }
public EndianStream(Stream baseStream, Shell.EndianFormat byteOrder, object streamOwner = null, string name = null, FileAccess permissions = FileAccess.ReadWrite) { Contract.Requires <ArgumentNullException>(baseStream != null); BaseStream = baseStream; StreamPermissions = permissions; StreamMode = 0; if (baseStream.CanRead && permissions.CanRead()) { Reader = new EndianReader(baseStream, byteOrder, streamOwner, name); } if (baseStream.CanWrite && permissions.CanWrite()) { Writer = new EndianWriter(baseStream, byteOrder, streamOwner, name); } }
public void Serialize(IO.EndianStream s) { if (s.IsReading) { Endian = BinaryDataTreeHeader.PeekSignatureAsEndianFormat(s.Reader); } using (s.BeginEndianSwitch(this.Endian)) { if (s.IsReading) { ReadInternal(s); } else if (s.IsWriting) { WriteInternal(s); } } }
// #REVIEW: .NET 4.5: BinaryReader has 'bool leaveOpen' ctor #region Ctor /// <summary>Create a new binary reader which respects the endian format of the underlying stream's bytes</summary> /// <param name="input">Base stream to use as input</param> /// <param name="encoding">Character encoding to use. If null, <see cref="System.Text.UTF8Encoding"/> is assumed</param> /// <param name="byteOrder">Endian format for how we interpret the stream's bytes</param> /// <param name="streamOwner">Owner object of this stream, or null</param> /// <param name="name">Special name to associate with this stream</param> public EndianReader(Stream input, Encoding encoding, Shell.EndianFormat byteOrder, object streamOwner = null, string name = null) : base(input, encoding) { Contract.Requires <ArgumentNullException>(input != null); Contract.Requires <ArgumentNullException>(encoding != null); BaseStreamOwner = true; BaseAddress = Values.PtrHandle.Null32; ByteOrder = byteOrder; Owner = streamOwner; mStringEncoding = encoding; StreamName = name ?? "(unnamed)"; // If the stream is a different endian than the runtime, data will // be byte swapped of course //this.mRequiresByteSwap = Shell.Platform.Environment.ProcessorType.ByteOrder != byteOrder; mRequiresByteSwap = !byteOrder.IsSameAsRuntime(); }
int ReadStrCharArrayGetRealCountMultiByte(Shell.EndianFormat byteOrder, byte[] bytes) { if (ReadStringMultiByteIsNull(byteOrder, bytes, bytes.Length - mNullCharacterSize)) // padded string case { // find the first last index which isn't null for (int x = bytes.Length - (mNullCharacterSize * 2); x > mNullCharacterSize; x -= mNullCharacterSize) { if (!ReadStringMultiByteIsNull(byteOrder, bytes, x)) { return(x + mNullCharacterSize); } } return(0); // wtf! no characters, not cool, what a waste } else { return(TypeExtensions.kNone); // complete string case } }
public static void ConvertXmbToXml( string xmlFile, string xmbFile, Shell.EndianFormat endianFormat, Shell.ProcessorSize vaSize) { byte[] file_bytes = File.ReadAllBytes(xmbFile); using (var xmb_ms = new MemoryStream(file_bytes, false)) using (var xmb = new IO.EndianStream(xmb_ms, endianFormat, System.IO.FileAccess.Read)) using (var xml_ms = new MemoryStream(IntegerMath.kMega * 1)) { xmb.StreamMode = FileAccess.Read; ResourceUtils.XmbToXml(xmb, xml_ms, vaSize); using (var xml_fs = File.Create(xmlFile)) xml_ms.WriteTo(xml_fs); } }
/// <summary>Create a new binary reader which respects the endian format of the underlying stream's bytes</summary> /// <param name="input">Base stream to use as input</param> /// <param name="byteOrder">Endian format for how we interpret the stream's bytes</param> /// <param name="streamOwner">Owner object of this stream, or null</param> /// <param name="name">Special name to associate with this stream</param> /// <remarks>Defaults to <see cref="System.Text.UTF8Encoding"/> for the string encoding</remarks> public EndianReader(Stream input, Shell.EndianFormat byteOrder, object streamOwner = null, string name = null) : this(input, new UTF8Encoding(), byteOrder, streamOwner, name) { }
public BlobChunkVerificationResultInfo OpenRange(Stream baseStream, long startPosition = 0, long endPosition = TypeExtensions.kNoneInt64, FileAccess permissions = FileAccess.ReadWrite, Shell.EndianFormat endian = Shell.EndianFormat.Big) { Contract.Requires(IsClosed); Contract.Requires <ArgumentNullException>(baseStream != null); Contract.Requires <ArgumentException>(baseStream.CanSeek); Contract.Requires <ArgumentException>(permissions != 0, "Why do we have NO permissions?"); Contract.Requires <ArgumentException>(baseStream.HasPermissions(permissions)); Contract.Requires(endPosition.IsNoneOrPositive()); var result = BlobChunkVerificationResultInfo.ValidResult; OpenUnderlyingStream(baseStream, permissions, endian); OpenStartPosition(baseStream, startPosition); EndPosition = endPosition.IsNotNone() ? endPosition : baseStream.Length; mFooterPosition = TypeExtensions.kNoneInt64; OpenVerifyAssumedStreamSize(ref result); return(result); }
static int CalculateHashCode(StringStorageWidthType widthType, StringStorageType type, Shell.EndianFormat byteOrder, StringStorageLengthPrefix prefix, short fixedLength) { var encoder = new Bitwise.HandleBitEncoder(); encoder.Encode32(widthType, TypeExtensions.BitEncoders.StringStorageWidthType); encoder.Encode32(type, TypeExtensions.BitEncoders.StringStorageType); encoder.Encode32(byteOrder, TypeExtensions.BitEncoders.EndianFormat); if (type.UsesLengthPrefix()) { encoder.Encode32(prefix, TypeExtensions.BitEncoders.StringStorageLengthPrefix); } else if (fixedLength != 0) { encoder.Encode32((uint)fixedLength, 0x7FFF); } return((int)encoder.GetHandle32()); }
/// <summary>Create a new binary writer which respects the endian format of the underlying stream's bytes</summary> /// <param name="output">Base stream to use as output</param> /// <param name="byteOrder">Endian format for how we interpret the stream's bytes</param> /// <param name="streamOwner">Owner object of this stream, or null</param> /// <param name="name">Special name to associate with this stream</param> /// <remarks>Defaults to <see cref="System.Text.UTF8Encoding"/> for the string encoding</remarks> public EndianWriter(Stream output, Shell.EndianFormat byteOrder, object streamOwner = null, string name = null) : this(output, Encoding.UTF8, byteOrder, streamOwner, name) { }
public static bool IsSameAsRuntime(this Shell.EndianFormat ef) { return(ef == Shell.Platform.Environment.ProcessorType.ByteOrder); }
public static Shell.EndianFormat Invert(this Shell.EndianFormat ef) { return(ef == Shell.EndianFormat.Little ? Shell.EndianFormat.Big : Shell.EndianFormat.Little); }