예제 #1
0
        public bool WriteTo2(WriteBuffer buffer)
        {
            // 0. init header
            // 1. loop on header
            // 2. loop on Key, if any
            // 3. loop on Data, if any
            // 4. done
            switch (state)
            {
            case STATE_INITIAL:
                PrepareHeader();
                state = STATE_WRITE_HEADER;
                goto case STATE_WRITE_HEADER;

            case STATE_WRITE_HEADER:
                writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset);
                if (writeOffset < headerLength)
                {
                    return(true);
                }

                if (Key.Length > 0)
                {
                    writeOffset = 0;
                    state       = STATE_WRITE_KEY;
                    goto case STATE_WRITE_KEY;
                }
                goto case STATE_PREPARE_BODY;

            case STATE_WRITE_KEY:
                writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset);
                if (writeOffset < Key.Length)
                {
                    return(true);
                }
                goto case STATE_PREPARE_BODY;

            case STATE_PREPARE_BODY:
                if (Data.Count > 0)
                {
                    writeOffset = 0;
                    state       = STATE_WRITE_BODY;
                    goto case STATE_WRITE_BODY;
                }

                break;

            case STATE_WRITE_BODY:
                writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset);
                if (writeOffset < Data.Count)
                {
                    return(true);
                }
                break;
            }

            state = STATE_DONE;

            return(false);
        }
예제 #2
0
        private static ReadBuffer UnpackSequences(ReadBuffer packedData, byte seqMarker)
        {
            var remaining = packedData;
            var result    = new WriteBuffer();

            while (remaining.Length > 0)
            {
                var value = remaining[0];
                remaining = remaining.Drop(1);
                if (value != seqMarker)
                {
                    result.Append(value);
                }
                else
                {
                    var sequence = remaining.TakeUntil(seqMarker);
                    var count    = remaining[sequence.Length + 1];
                    for (int i = 0; i < count; i++)
                    {
                        result.Append(sequence);
                    }
                    remaining = remaining.Drop(sequence.Length + 2);
                }
            }
            return(result.ToReadBuffer());
        }
예제 #3
0
		public bool WriteTo(WriteBuffer buffer)
		{
			// 0. init header
			// 1. loop on header
			// 2. loop on Key, if any
			// 3. loop on Data, if any
			// 4. done
			switch (state)
			{
				case STATE_INITIAL: goto init;
				case STATE_WRITE_HEADER: goto write_header;
				case STATE_WRITE_KEY: goto write_key;
				case STATE_WRITE_BODY: goto write_body;
				default: return false;
			}

			// TODO put these inside switch..case
		init:
			PrepareHeader();
			state = STATE_WRITE_HEADER;

		write_header:
			writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset);
			if (writeOffset < headerLength) return true;

			if (Key.Length > 0)
			{
				writeOffset = 0;
				state = STATE_WRITE_KEY;
			}
			else goto pre_body;

		write_key:
			writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset);
			if (writeOffset < Key.Length) return true;

		pre_body:
			if (Data.Count > 0)
			{
				writeOffset = 0;
				state = STATE_WRITE_BODY;
			}
			else goto done;

		write_body:
			writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset);
			if (writeOffset < Data.Count) return true;

		done:
			state = STATE_DONE;

			return false;
		}
예제 #4
0
        private static ReadBuffer UnpackRLE(ReadBuffer packedData)
        {
            int escCount  = packedData[0] & 0x7f;
            var escCodes  = packedData.Slice(1, escCount);
            var rleData   = packedData.Drop(escCount + 1);
            var escLookup = new byte[0x100];

            for (int i = 0; i < escCount; i++)
            {
                escLookup[escCodes[i]] = (byte)(i + 1);
            }

            bool compressed  = (packedData[0] & 0x80) == 0;
            var  encodedData = compressed ? UnpackSequences(rleData, escCodes[1]) : rleData;

            var result = new WriteBuffer();

            while (encodedData.Length > 0)
            {
                var code = escLookup[encodedData[0]];
                switch (code)
                {
                case 0:
                    result.Append(encodedData[0]);
                    encodedData = encodedData.Drop(1);
                    break;

                case 1:
                    result.AppendRepeat(encodedData[2], encodedData[1]);
                    encodedData = encodedData.Drop(3);
                    break;

                case 3:
                    result.AppendRepeat(encodedData[3], encodedData[1] + (((int)encodedData[2]) << 8));
                    encodedData = encodedData.Drop(4);
                    break;

                default:
                    result.AppendRepeat(encodedData[1], code - 1);
                    encodedData = encodedData.Drop(2);
                    break;
                }
            }

            return(result.ToReadBuffer());
        }
예제 #5
0
        private static ReadBuffer UnpackVLE(ReadBuffer packedData)
        {
            var widthsCount   = packedData[0];
            var widths        = packedData.Slice(1, widthsCount);
            var alphabetCount = widths.Select(val => (int)val).Sum();
            var alphabet      = packedData.Slice(1 + widthsCount, alphabetCount);

            var dictionary = new HuffmanTree(widths, alphabet);
            var stream     = EnumerateBits(packedData.Drop(1 + widthsCount + alphabetCount));

            var result = new WriteBuffer();

            while (true)
            {
                int value = dictionary.DecodeByte(stream);
                if (value < 0)
                {
                    break;
                }
                result.Append((byte)value);
            }

            return(result.ToReadBuffer());
        }
예제 #6
0
		public bool WriteTo2(WriteBuffer buffer)
		{
			// 0. init header
			// 1. loop on header
			// 2. loop on Key, if any
			// 3. loop on Data, if any
			// 4. done
			switch (state)
			{
				case STATE_INITIAL:
					PrepareHeader();
					state = STATE_WRITE_HEADER;
					goto case STATE_WRITE_HEADER;

				case STATE_WRITE_HEADER:
					writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset);
					if (writeOffset < headerLength) return true;

					if (Key.Length > 0)
					{
						writeOffset = 0;
						state = STATE_WRITE_KEY;
						goto case STATE_WRITE_KEY;
					}
					goto case STATE_PREPARE_BODY;

				case STATE_WRITE_KEY:
					writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset);
					if (writeOffset < Key.Length) return true;
					goto case STATE_PREPARE_BODY;

				case STATE_PREPARE_BODY:
					if (Data.Count > 0)
					{
						writeOffset = 0;
						state = STATE_WRITE_BODY;
						goto case STATE_WRITE_BODY;
					}

					break;

				case STATE_WRITE_BODY:
					writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset);
					if (writeOffset < Data.Count) return true;
					break;
			}

			state = STATE_DONE;

			return false;
		}
예제 #7
0
        public bool WriteTo(WriteBuffer buffer)
        {
            // 0. init header
            // 1. loop on header
            // 2. loop on Key, if any
            // 3. loop on Data, if any
            // 4. done
            switch (state)
            {
            case STATE_INITIAL: goto init;

            case STATE_WRITE_HEADER: goto write_header;

            case STATE_WRITE_KEY: goto write_key;

            case STATE_WRITE_BODY: goto write_body;

            default: return(false);
            }

            // TODO put these inside switch..case
init:
            PrepareHeader();
            state = STATE_WRITE_HEADER;

write_header:
            writeOffset += buffer.Append(header, writeOffset, headerLength - writeOffset);
            if (writeOffset < headerLength)
            {
                return(true);
            }

            if (Key.Length > 0)
            {
                writeOffset = 0;
                state       = STATE_WRITE_KEY;
            }
            else
            {
                goto pre_body;
            }

write_key:
            writeOffset += buffer.Append(Key.Array, writeOffset, Key.Length - writeOffset);
            if (writeOffset < Key.Length)
            {
                return(true);
            }

pre_body:
            if (Data.Count > 0)
            {
                writeOffset = 0;
                state       = STATE_WRITE_BODY;
            }
            else
            {
                goto done;
            }

write_body:
            writeOffset += buffer.Append(Data.Array, Data.Offset + writeOffset, Data.Count - writeOffset);
            if (writeOffset < Data.Count)
            {
                return(true);
            }

done:
            state = STATE_DONE;

            return(false);
        }