public override sealed void Convert(byte[] input, int inputIndex, int inputSize, byte[] output, int outputIndex, int outputSize, bool flush, out int inputUsed, out int outputUsed, out bool completed) { if (inputSize != 0) { if (input == null) throw new System.ArgumentNullException(nameof(input)); if (inputIndex < 0 || inputIndex >= input.Length) throw new System.ArgumentOutOfRangeException(nameof(inputIndex)); if (inputSize < 0 || inputSize > input.Length - inputIndex) throw new System.ArgumentOutOfRangeException(nameof(inputSize)); } if (output == null) throw new System.ArgumentNullException(nameof(output)); if (outputIndex < 0 || outputIndex >= output.Length) throw new System.ArgumentOutOfRangeException(nameof(outputIndex)); if (outputSize < 1 || outputSize > output.Length - outputIndex) throw new System.ArgumentOutOfRangeException(nameof(outputSize)); inputUsed = inputIndex; outputUsed = outputIndex; var inputTotal = 0; if (encodedSize != 0) { var count = System.Math.Min(encodedSize, outputSize); System.Buffer.BlockCopy(encoded, encodedIndex, output, outputIndex, count); outputSize -= count; outputIndex += count; encodedSize -= count; if (encodedSize != 0) { encodedIndex += count; outputUsed = outputIndex - outputUsed; inputUsed = 0; completed = false; return; } encodedIndex = 0; } var flag = true; while (flag) { flag = false; switch (state) { case BinHexUtils.State.Starting: System.Buffer.BlockCopy(BinHexPrefix, 0, decoded, 0, BinHexPrefix.Length); decodedIndex = 0; decodedSize = BinHexPrefix.Length; state = BinHexUtils.State.Prefix; goto case 2; case BinHexUtils.State.Prefix: var count1 = System.Math.Min(decodedSize, outputSize); System.Buffer.BlockCopy(decoded, decodedIndex, output, outputIndex, count1); outputSize -= count1; outputIndex += count1; decodedSize -= count1; if (decodedSize != 0) { decodedIndex += count1; break; } decodedIndex = 0; previousByte = 256; repeatCount = 0; accumCount = 0; lineOffset = 1; lines = 0; checksum = 0; if (this.header != null) { var bytes = header.GetBytes(); System.Buffer.BlockCopy(bytes, 0, decoded, 0, bytes.Length); decodedSize = bytes.Length; decodedIndex = 0; macbinHeaderSize = 0; } else { macbinHeader = new byte[128]; macbinHeaderOffset = 0; macbinHeaderSize = macbinHeader.Length; } state = BinHexUtils.State.Header; goto case 4; case BinHexUtils.State.Header: if (macbinHeaderSize != 0) { var count2 = System.Math.Min(macbinHeaderSize, inputSize); System.Buffer.BlockCopy(input, inputIndex, macbinHeader, macbinHeaderOffset, count2); macbinHeaderOffset += count2; macbinHeaderSize -= count2; inputIndex += count2; inputSize -= count2; if (macbinHeaderSize == 0) { var header = new MacBinaryHeader(macbinHeader); macbinHeader = null; this.header = new BinHexHeader(header); var bytes = this.header.GetBytes(); System.Buffer.BlockCopy(bytes, 0, decoded, 0, bytes.Length); decodedSize = bytes.Length; decodedIndex = 0; } else break; } var inputMax1 = decodedSize; if (inputMax1 != 0) { flag = true; this.CompressAndEncode(decoded, ref decodedIndex, ref decodedSize, ref inputTotal, ref inputMax1, false, output, ref outputIndex, ref outputSize); } break; case BinHexUtils.State.Data: var inputMax2 = System.Math.Min(decodedSize, inputSize); if (inputMax2 != 0) { flag = true; this.CompressAndEncode(input, ref inputIndex, ref inputSize, ref decodedSize, ref inputMax2, true, output, ref outputIndex, ref outputSize); } break; case BinHexUtils.State.DataCRC: if (macbinHeaderSize != 0) { BinHexEncoder.IgnoreChunkFromInput(ref macbinHeaderSize, ref inputIndex, ref inputSize); if (macbinHeaderSize != 0) break; } var inputMax3 = decodedSize; if (inputMax3 != 0) { flag = true; this.CompressAndEncode(decoded, ref decodedIndex, ref decodedSize, ref inputTotal, ref inputMax3, false, output, ref outputIndex, ref outputSize); } break; case BinHexUtils.State.Resource: var inputMax4 = System.Math.Min(decodedSize, inputSize); if (inputMax4 != 0) { flag = true; this.CompressAndEncode(input, ref inputIndex, ref inputSize, ref decodedSize, ref inputMax4, true, output, ref outputIndex, ref outputSize); } break; case BinHexUtils.State.ResourceCRC: if (macbinHeaderSize != 0) { BinHexEncoder.IgnoreChunkFromInput(ref macbinHeaderSize, ref inputIndex, ref inputSize); if (macbinHeaderSize != 0) break; } var inputMax5 = decodedSize; if (inputMax5 != 0) { flag = true; this.CompressAndEncode(decoded, ref decodedIndex, ref decodedSize, ref inputTotal, ref inputMax5, false, output, ref outputIndex, ref outputSize); } break; case BinHexUtils.State.Ending: var count3 = System.Math.Min(decodedSize, outputSize); System.Buffer.BlockCopy(decoded, decodedIndex, output, outputIndex, count3); outputSize -= count3; outputIndex += count3; decodedSize -= count3; if (decodedSize != 0) { decodedIndex += count3; break; } decodedIndex = 0; state = BinHexUtils.State.Ended; goto case 11; case BinHexUtils.State.Ended: macbinHeaderSize = inputSize; BinHexEncoder.IgnoreChunkFromInput(ref macbinHeaderSize, ref inputIndex, ref inputSize); break; } if (encodedSize != 0) break; } if (flush && inputSize == 0 && (state != BinHexUtils.State.Ended && outputSize != 0)) throw new ByteEncoderException(Resources.EncodersStrings.BinHexEncoderDataCorruptCannotFinishEncoding); outputUsed = outputIndex - outputUsed; inputUsed = inputIndex - inputUsed; completed = inputSize == 0 && (!flush || state == BinHexUtils.State.Ended); if (!flush || !completed) return; state = BinHexUtils.State.Starting; }
private void CompressAndEncode(byte[] input, ref int inputOffset, ref int inputSize, ref int inputTotal, ref int inputMax, bool inputIsCRC, byte[] output, ref int outputOffset, ref int outputSize) { byte[] bytes = null; var index1 = 0; var num1 = 0; if (inputIsCRC) { bytes = input; index1 = inputOffset; num1 = inputMax; } do { int num2 = input[inputOffset++]; --inputSize; --inputTotal; --inputMax; if (num2 == previousByte && repeatCount < 254) { ++repeatCount; if (state >= BinHexUtils.State.ResourceCRC && inputMax == 0) num2 = 257; else goto label_35; } var numArray1 = new byte[5]; var num3 = 0; if (repeatCount >= 2) { ++repeatCount; var numArray2 = numArray1; var index2 = num3; var num4 = 1; var num5 = index2 + num4; var num6 = 144; numArray2[index2] = (byte) num6; var numArray3 = numArray1; var index3 = num5; var num7 = 1; num3 = index3 + num7; int num8 = (byte) repeatCount; numArray3[index3] = (byte) num8; repeatCount = 0; } else if (repeatCount != 0) { numArray1[num3++] = (byte) previousByte; if (previousByte == 144) numArray1[num3++] = 0; repeatCount = 0; } if (num2 <= byte.MaxValue) { numArray1[num3++] = (byte) num2; if (num2 == 144) numArray1[num3++] = 0; } var flag = false; if (state == BinHexUtils.State.ResourceCRC && inputMax == 0 && (accumCount + num3)%3 != 0) { numArray1[num3++] = 0; flag = true; } previousByte = num2; var index4 = 0; while (num3 != 0) { accumValue <<= 8; accumValue |= numArray1[index4]; ++accumCount; switch (accumCount) { case 1: encoded[encodedSize++] = Table[accumValue >> 2 & 63]; ++lineOffset; break; case 2: encoded[encodedSize++] = Table[accumValue >> 4 & 63]; ++lineOffset; break; case 3: encoded[encodedSize++] = Table[accumValue >> 6 & 63]; ++lineOffset; if (!flag || 1 != num3) { if (lineOffset == 64) { encoded[encodedSize++] = 13; encoded[encodedSize++] = 10; lineOffset = 0; ++lines; } encoded[encodedSize++] = Table[accumValue & 63]; ++lineOffset; } accumCount = 0; break; } if (lineOffset == 64) { encoded[encodedSize++] = 13; encoded[encodedSize++] = 10; lineOffset = 0; ++lines; } --num3; ++index4; } var count = System.Math.Min(encodedSize, outputSize); if (output != null) { System.Buffer.BlockCopy(encoded, encodedIndex, output, outputOffset, count); outputSize -= count; } outputOffset += count; encodedSize -= count; if (encodedSize != 0) { encodedIndex += count; break; } encodedIndex = 0; label_35: ; } while (inputMax != 0); switch (state) { case BinHexUtils.State.Header: if (decodedSize != 0) break; checksum = 0; if (0L != header.DataForkLength) { decodedSize = (int) header.DataForkLength; state = BinHexUtils.State.Data; break; } macbinHeaderSize = 0; checksum = BinHexUtils.CalculateCrc(checksum); decodedSize = BinHexUtils.MarshalUInt16(decoded, 0, checksum); decodedIndex = 0; state = BinHexUtils.State.DataCRC; break; case BinHexUtils.State.Data: var size1 = num1 - inputMax; checksum = BinHexUtils.CalculateCrc(bytes, index1, size1, checksum); if (decodedSize != 0) break; macbinHeaderSize = 0L >= header.ResourceForkLength ? 0 : (header.DataForkLength%128L != 0L ? (int) (128L - header.DataForkLength%128L) : 0); checksum = BinHexUtils.CalculateCrc(checksum); decodedSize = BinHexUtils.MarshalUInt16(decoded, 0, checksum); decodedIndex = 0; state = BinHexUtils.State.DataCRC; break; case BinHexUtils.State.DataCRC: if (decodedSize != 0) break; checksum = 0; if (0L != header.ResourceForkLength) { decodedSize = (int) header.ResourceForkLength; state = BinHexUtils.State.Resource; break; } macbinHeaderSize = 0; checksum = BinHexUtils.CalculateCrc(checksum); decodedSize = BinHexUtils.MarshalUInt16(decoded, 0, checksum); decodedIndex = 0; state = BinHexUtils.State.ResourceCRC; break; case BinHexUtils.State.Resource: var size2 = num1 - inputMax; checksum = BinHexUtils.CalculateCrc(bytes, index1, size2, checksum); if (decodedSize != 0) break; macbinHeaderSize = header.ResourceForkLength%128L != 0L ? (int) (128L - header.ResourceForkLength%128L) : 0; checksum = BinHexUtils.CalculateCrc(checksum); decodedSize = BinHexUtils.MarshalUInt16(decoded, 0, checksum); decodedIndex = 0; state = BinHexUtils.State.ResourceCRC; break; case BinHexUtils.State.ResourceCRC: if (decodedSize != 0) break; System.Buffer.BlockCopy(BinHexSuffix, 0, decoded, 0, BinHexSuffix.Length); decodedIndex = 0; decodedSize = BinHexSuffix.Length; state = BinHexUtils.State.Ending; break; default: throw new System.Exception(Resources.EncodersStrings.BinHexEncoderInternalError); } }
public BinHexEncoder() { state = BinHexUtils.State.Starting; }
public override sealed void Reset() { state = BinHexUtils.State.Starting; encodedSize = 0; }
private void TransitionState() { switch (state) { case BinHexUtils.State.HdrFileSize: if (scratch[0] > 63) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderFileNameTooLong); state = BinHexUtils.State.Header; bytesNeeded = scratch[0] + 21; break; case BinHexUtils.State.Header: header = new BinHexHeader(scratch); if (!this.DataForkOnly) { var bytes = header.GetBytes(); System.Buffer.BlockCopy(bytes, 0, extra, 0, bytes.Length); extraIndex = 0; extraSize = bytes.Length; } if (0L != header.DataForkLength) { state = BinHexUtils.State.Data; bytesNeeded = (int) header.DataForkLength; runningCRC = 0; break; } checksum = runningCRC; checksum = BinHexUtils.CalculateCrc(checksum); state = BinHexUtils.State.DataCRC; bytesNeeded = 2; scratchSize = scratch.Length; scratchIndex = 0; break; case BinHexUtils.State.Data: checksum = runningCRC; checksum = BinHexUtils.CalculateCrc(checksum); state = BinHexUtils.State.DataCRC; bytesNeeded = 2; scratchSize = scratch.Length; scratchIndex = 0; break; case BinHexUtils.State.DataCRC: if ((checksum & 65280) >> 8 != scratch[0] || (checksum & byte.MaxValue) != scratch[1]) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderBadCrc); if (this.DataForkOnly) { state = BinHexUtils.State.Ending; repeatCount = 0; encodedSize = 0; lineReady = false; break; } var length1 = header.DataForkLength%128L != 0L ? (int) (128L - header.DataForkLength%128L) : 0; if (length1 != 0) { System.Array.Clear(extra, 0, length1); extraSize = length1; } if (header.ResourceForkLength > 0L) { state = BinHexUtils.State.Resource; bytesNeeded = (int) header.ResourceForkLength; runningCRC = 0; break; } checksum = 0; checksum = BinHexUtils.CalculateCrc(checksum); state = BinHexUtils.State.ResourceCRC; bytesNeeded = 2; scratchSize = scratch.Length; scratchIndex = 0; break; case BinHexUtils.State.Resource: checksum = runningCRC; checksum = BinHexUtils.CalculateCrc(checksum); state = BinHexUtils.State.ResourceCRC; bytesNeeded = 2; scratchSize = scratch.Length; scratchIndex = 0; break; case BinHexUtils.State.ResourceCRC: if ((checksum & 65280) >> 8 != scratch[0] || (checksum & byte.MaxValue) != scratch[1]) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderBadResourceForkCrc); var length2 = header.ResourceForkLength%128L != 0L ? (int) (128L - header.ResourceForkLength%128L) : 0; if (length2 != 0) { System.Array.Clear(extra, 0, length2); extraSize = length2; } state = BinHexUtils.State.Ending; repeatCount = 0; encodedSize = 0; lineReady = false; break; default: throw new System.Exception(Resources.EncodersStrings.BinHexDecoderInternalError); } }
private bool ReadLine(byte[] input, ref int inputIndex, ref int inputSize, bool flush) { if (state == BinHexUtils.State.Ending) { inputIndex += inputSize; inputSize = 0; return false; } var flag = false; while (inputSize != 0 || flush && encodedSize != 0) { byte num = 10; if (inputSize != 0) { --inputSize; num = input[inputIndex++]; } if (num != 10) { if (encodedSize >= encoded.Length) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderLineTooLong); encoded[encodedSize++] = num; } else if (state == BinHexUtils.State.Starting) { for (var index = 0U; (long) index < (long) encodedSize; ++index) { if (!ByteEncoder.IsWhiteSpace(encoded[index])) { if ((uint) ((ulong) encodedSize - index) < BinHexPrologue.Length || !ByteEncoder.BeginsWithNI(encoded, (int) index, BinHexPrologue, BinHexPrologue.Length)) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderLineCorrupt); state = BinHexUtils.State.Started; repeatCheck = false; accumCount = 0; accum = 0; header = null; break; } } encodedSize = 0; } else { while (encodedSize != 0 && (encoded[encodedSize - 1] == 13 || encoded[encodedSize - 1] == 32 || encoded[encodedSize - 1] == 9)) --encodedSize; if (encodedSize == 0) { if (state != BinHexUtils.State.Started) ; } else { flag = true; encodedIndex = 0; break; } } } return flag; }
public override sealed void Reset() { state = BinHexUtils.State.Starting; lineReady = false; encodedSize = 0; repeatCount = 0; extraIndex = 0; extraSize = 0; }
public override sealed void Convert(byte[] input, int inputIndex, int inputSize, byte[] output, int outputIndex, int outputSize, bool flush, out int inputUsed, out int outputUsed, out bool completed) { if (inputSize != 0) { if (input == null) throw new System.ArgumentNullException(nameof(input)); if (inputIndex < 0 || inputIndex >= input.Length) throw new System.ArgumentOutOfRangeException(nameof(inputIndex)); if (inputSize < 0 || inputSize > input.Length - inputIndex) throw new System.ArgumentOutOfRangeException(nameof(inputSize)); } if (output == null) throw new System.ArgumentNullException(nameof(output)); if (outputIndex < 0 || outputIndex >= output.Length) throw new System.ArgumentOutOfRangeException(nameof(outputIndex)); if (outputSize < 1 || outputSize > output.Length - outputIndex) throw new System.ArgumentOutOfRangeException(nameof(outputSize)); inputUsed = inputIndex; outputUsed = outputIndex; do { if (extraSize != 0) { var count = System.Math.Min(extraSize, outputSize); System.Buffer.BlockCopy(extra, extraIndex, output, outputIndex, count); outputSize -= count; outputIndex += count; extraSize -= count; if (extraSize != 0) { extraIndex += count; goto label_45; } extraIndex = 0; } if (repeatCount != 0) { switch (state) { case BinHexUtils.State.Data: case BinHexUtils.State.Resource: this.OutputChunk(output, ref outputIndex, ref outputSize); break; default: this.OutputChunk(scratch, ref scratchIndex, ref scratchSize); break; } if (bytesNeeded == 0) this.TransitionState(); if (outputSize != 0) continue; } else if (lineReady) { var bT = encoded[encodedIndex++]; --encodedSize; if (encodedSize == 0) lineReady = false; if (!ByteEncoder.IsWhiteSpace(bT)) { if (state == BinHexUtils.State.Started) { if (58 != bT) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderFirstNonWhitespaceMustBeColon); state = BinHexUtils.State.HdrFileSize; bytesNeeded = 1; scratchSize = scratch.Length; scratchIndex = 0; runningCRC = 0; continue; } var num1 = (byte) (bT - 32U); var num2 = (int) num1 >= Dictionary.Length ? (byte) 127 : Dictionary[num1]; if (num2 == sbyte.MaxValue) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderFoundInvalidCharacter); if (accumCount == 0) { accum = num2; ++accumCount; continue; } accum = accum << 6 | num2; var num3 = (byte) (accum >> ShiftTabe[accumCount] & byte.MaxValue); ++accumCount; accumCount %= System.Runtime.InteropServices.Marshal.SizeOf(accum); if (repeatCheck) { repeatCheck = false; if (num3 == 0) { decodedByte = 144; repeatCount = 1; continue; } repeatCount = num3 - 1; continue; } if (144 == num3) { repeatCheck = true; continue; } decodedByte = num3; repeatCount = 1; } continue; } label_45: if (!lineReady) lineReady = this.ReadLine(input, ref inputIndex, ref inputSize, flush); else break; } while (lineReady); outputUsed = outputIndex - outputUsed; inputUsed = inputIndex - inputUsed; completed = inputSize == 0 && extraSize == 0 && repeatCount == 0 && !lineReady; if (!flush || !completed) return; if (state != BinHexUtils.State.Ending) throw new ByteEncoderException(Resources.EncodersStrings.BinHexDecoderDataCorrupt); this.Reset(); }