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