Example #1
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;
     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;
 }
Example #2
0
 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);
     }
 }
Example #3
0
 public BinHexEncoder()
 {
     state = BinHexUtils.State.Starting;
 }
Example #4
0
 public override sealed void Reset()
 {
     state = BinHexUtils.State.Starting;
     encodedSize = 0;
 }
Example #5
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);
     }
 }
Example #6
0
 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;
 }
Example #7
0
 public override sealed void Reset()
 {
     state = BinHexUtils.State.Starting;
     lineReady = false;
     encodedSize = 0;
     repeatCount = 0;
     extraIndex = 0;
     extraSize = 0;
 }
Example #8
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();
 }