Example #1
0
        public void ExecuteFinishStepTest()
        {
            //Arrange
            const EncoderState encoderState = EncoderState.Cancelled;
            const string       fileHash     = "fileHash";
            const string       errorMessage = "errorMessage";

            var pipelineStep = new FinishStep(_pipelineMediator.Object, _restClient.Object, _tempFileManager.Object);
            var stepData     = new UploadStepData()
            {
                EncoderState = encoderState,
                FileHash     = fileHash,
                ErrorMessage = errorMessage
            };

            pipelineStep.SetData(stepData);


            //Act
            pipelineStep.Execute(It.IsAny <CancellationTokenSourceWrapper>());

            //Assert
            _tempFileManager.Verify(m => m.DeleteAllTempFiles());
            _restClient.Verify(m => m.FinishTask(encoderState, fileHash, errorMessage), Times.Once());
        }
Example #2
0
        private void WriteHorizontalCodes(EncoderState state, bool startingColor, int firstSpan, int secondSpan)
        {
            state.Writer.Write(HorizontalCodes[0], HorizontalCodes[1]);

            WriteHorizontalSpan(state, startingColor, firstSpan);
            WriteHorizontalSpan(state, !startingColor, secondSpan);
        }
Example #3
0
 private EncoderStatus CreateEncoderStatus(EncoderState encoderState, string errorMessage)
 {
     return(new EncoderStatus
     {
         EncoderState = encoderState,
         ErrorMessage = errorMessage
     });
 }
Example #4
0
 private EncoderStatus CreateEncoderStatus(EncoderState encoderState, string errorMessage)
 {
     return new EncoderStatus
     {
         EncoderState = encoderState,
         ErrorMessage = errorMessage
     };
 }
Example #5
0
        public IRestRequest FinishTaskRequestCreate(string resource, EncoderState encoderState, string fileId, string errorMessage)
        {
            IRestRequest request = RequestCreate(resource, Method.POST);

            request.AddHeader("X-HTTP-Method-Override", "DELETE");
            request.AddParameter(EncoderStatusParameters.Result, encoderState);
            request.AddParameter(EncoderStatusParameters.FileId, fileId);
            request.AddParameter(EncoderStatusParameters.Message, errorMessage);

            return(request);
        }
Example #6
0
        private static string FormatIr(MethodBody methodBody)
        {
            var encoder     = new EncoderState();
            var encodedImpl = encoder.Encode(methodBody.Implementation);

            return(Les2LanguageService.Value.Print(
                       encodedImpl,
                       options: new LNodePrinterOptions
            {
                IndentString = new string(' ', 4)
            }));
        }
 /// <summary>
 /// Notify the encoder that the input stream is finished.
 /// If the return value is HSER_FINISH_MORE, there is still more output, so call poll() and repeat
 /// </summary>
 /// <returns>Refer to HSE_finish_res in original C version heatshrink</returns>
 public EncoderFinishResult Finish()
 {
     _flags |= FlagIsFinishing;
     if (Constants.EnableLogging)
     {
         Console.WriteLine("-- setting is_finishing flag");
     }
     if (_state == EncoderState.NotFull)
     {
         _state = EncoderState.Filled;
     }
     return(_state == EncoderState.Done ? EncoderFinishResult.Done : EncoderFinishResult.More);
 }
Example #8
0
        private static string FormatIr(Flame.Compiler.MethodBody methodBody)
        {
            // TODO: deduplicate this logic (it also appears in IL2LLVM and ILOpt)
            var encoder     = new EncoderState();
            var encodedImpl = encoder.Encode(methodBody.Implementation);

            return(Les2LanguageService.Value.Print(
                       encodedImpl,
                       options: new LNodePrinterOptions
            {
                IndentString = new string(' ', 4)
            }));
        }
        /// <summary>
        /// Reset the encoder
        /// </summary>
        public void Reset()
        {
            Array.Clear(_buffer, 0, _buffer.Length);
            _inputSize      = 0;
            _state          = EncoderState.NotFull;
            _matchScanIndex = 0;
            _flags          = 0;
            _bitIndex       = 0x80;
            _currentByte    = 0x00;
            _matchLength    = 0;

            _outgoingBits      = 0x0000;
            _outgoingBitsCount = 0;
        }
Example #10
0
        public void FinishTaskTest()
        {
            //Arrange
            const EncoderState encoderState = EncoderState.Failed;
            const string       fileHash     = "fileHash";
            const string       errorMessage = "errorMessage";

            _restHelper.Setup(m => m.FinishTaskRequestCreate(Resource, encoderState, fileHash, errorMessage)).Returns(_request.Object);

            //Act
            _encodeWebClient.FinishTask(encoderState, fileHash, errorMessage);

            //Assert
            _restHelper.Verify(m => m.GetResponse(_request.Object), Times.Once());
        }
Example #11
0
        public int Encode(Stream input, long inputStreamStartOffset, int width, int height, Stream output)
        {
            var rowLengthInBytes = (((int)width + 31) / 32) * 4; //bmp row data is in a multiple of 4 bytes

            // do not .Seek() the output. The caller may want us to append to the end. We store the starting position
            //here so we can return how many bytes were written.
            var outputStartPosition = output.Position;

            var state = new EncoderState()
            {
                CodingReader    = new BitReader(new byte[rowLengthInBytes], width), //this will get swapped to referenceReader on the first run
                ReferenceReader = new BitReader(new byte[rowLengthInBytes], width),
                Writer          = new BitWriter(output),
                Width           = width
            };

            //fill the current row with all 1's. It'll be used as the reference row for the first real image row.
            for (int i = 0; i < state.CodingReader.Buffer.Length; i++)
            {
                state.CodingReader.Buffer[i] = 0xff;
            }

            for (int row = 0; row < height; row++)
            {
                //swap current into previous and reuse the previous as the next current
                //for the first iteration of this loop the current row is all 1's
                var tempReader = state.ReferenceReader;
                state.ReferenceReader = state.CodingReader;
                state.CodingReader    = tempReader;

                //fill the current row data from the stream
                input.Seek(inputStreamStartOffset, SeekOrigin.Begin);
                input.Seek(rowLengthInBytes * (height - 1 - row), SeekOrigin.Current);
                input.Read(state.CodingReader.Buffer, 0, rowLengthInBytes);

                EncodeRowGroup4(state);
            }

            //EOFB. Not really needed for files but it doesn't hurt and some encoders write it.
            state.Writer.Write(0, 8);
            state.Writer.Write(16, 8);
            state.Writer.Write(1, 8);

            state.Writer.Flush();

            //return # of bytes written to output stream.
            return((int)(output.Position - outputStartPosition));
        }
        /// <summary>
        /// Sink up to size bytes from buffer + offset into the encoder.
        /// inputSize is set to the number of bytes actually sunk (in case a buffer was filled)
        /// </summary>
        /// <param name="buffer">The buffer to be filled into the encoder</param>
        /// <param name="offset">The offset of the buffer to be filled</param>
        /// <param name="size">Number of bytes to be filled</param>
        /// <param name="inputSize">Number of bytes actually sunk</param>
        /// <returns>Refer to HSE_sink_res in original C version heatshrink</returns>
        public EncoderSinkResult Sink(byte[] buffer, int offset, int size, out int inputSize)
        {
            inputSize = 0;

            if (buffer == null)
            {
                return(EncoderSinkResult.Null);
            }

            /* Sinking more content after saying the content is done, tsk tsk */
            if (IsFinishing())
            {
                return(EncoderSinkResult.Misuse);
            }

            /* Sinking more content before processing is done */
            if (_state != EncoderState.NotFull)
            {
                return(EncoderSinkResult.Misuse);
            }

            var writeOffset = GetInputOffset() + _inputSize;
            var ibs         = GetInputBufferSize();
            var rem         = ibs - _inputSize;
            var cpSz        = rem < size ? rem : size;

            Array.Copy(buffer, offset, _buffer, writeOffset, cpSz);
            inputSize   = cpSz;
            _inputSize += cpSz;

            if (Constants.EnableLogging)
            {
                Console.WriteLine($"-- sunk {cpSz} bytes (of {size}) into encoder at {writeOffset}, input buffer now has {_inputSize}");
            }
            if (cpSz == rem)
            {
                if (Constants.EnableLogging)
                {
                    Console.WriteLine("-- internal buffer is now full");
                }
                _state = EncoderState.Filled;
            }
            return(EncoderSinkResult.Ok);
        }
Example #13
0
        private void EncodeRowGroup4(EncoderState state)
        {
            int  a0      = -1; //start just before the first element
            bool a0Color = true;

            while (a0 < state.Width)
            {
                if (a0 > -1)
                {
                    a0Color = state.CodingReader.GetBit(a0);
                }

                int a1 = state.CodingReader.GetNextMatchingBit(a0, !a0Color);
                int b1 = state.ReferenceReader.GetNextMatchingBit(a0, !a0Color);
                int b2 = state.ReferenceReader.GetNextMatchingBit(b1, a0Color);

                if (a0 == -1)
                {
                    a0 = 0;  // for the rest of the math to work.
                }
                if (b2 < a1) //pass mode
                {
                    WritePassCode(state);
                    a0 = b2;
                }
                else //horizontal or vertical
                {
                    int deltab1a1 = b1 - a1;

                    if (-3 <= deltab1a1 && deltab1a1 <= 3) //vertical
                    {
                        WriteVerticalCode(state, deltab1a1);
                        a0 = a1;
                    }
                    else //horizontal
                    {
                        int a2 = state.CodingReader.GetNextMatchingBit(a1, a0Color);
                        WriteHorizontalCodes(state, a0Color, a1 - a0, a2 - a1);

                        a0 = a2;
                    }
                }
            }
        }
Example #14
0
        public void FinishTaskRequestCreateTest()
        {
            //Arrange
            const string       resource     = "resource";
            const string       errorMessage = "errorMessage";
            const string       fileHash     = "fileId";
            const EncoderState encoderState = EncoderState.Completed;


            //Act
            var request = _helper.FinishTaskRequestCreate(resource, encoderState, fileHash, errorMessage);

            //Assert
            Assert.AreEqual(Method.POST, request.Method);
            Assert.AreEqual(resource, request.Resource);
            Assert.IsTrue(request.Parameters.Any(p => p.Type == ParameterType.Cookie && p.Name == _settings.CookieName && (string)p.Value == _settings.CookieValue));
            Assert.IsTrue(request.Parameters.Any(p => p.Name == EncoderStatusParameters.Result && (EncoderState)p.Value == encoderState));
            Assert.IsTrue(request.Parameters.Any(p => p.Name == EncoderStatusParameters.Message && (string)p.Value == errorMessage));
            Assert.IsTrue(request.Parameters.Any(p => p.Name == EncoderStatusParameters.FileHash && (string)p.Value == fileHash));
            Assert.IsTrue(request.Parameters.Any(p => p.Name == "X-HTTP-Method-Override" && (string)p.Value == "DELETE"));
        }
Example #15
0
        public void PickCorrectElement()
        {
            var a = new A();
            var b = new B();
            var c = new D();

            var codec = new PiecewiseCodec <object>();

            codec = codec.Add(new CodecElement <A, LNode>(
                                  "A",
                                  (obj, state) => LNode.Call((Symbol)"A"),
                                  (node, state) => a));
            codec = codec.Add(new CodecElement <B, LNode>(
                                  "B",
                                  (obj, state) => LNode.Call((Symbol)"B"),
                                  (node, state) => b));
            codec = codec.Add(new CodecElement <C, LNode>(
                                  "C",
                                  (obj, state) => LNode.Call((Symbol)"C"),
                                  (node, state) => c));

            var encoder = new EncoderState();
            var decoder = new DecoderState(log, new TypeResolver().ReadOnlyView);

            ConstantCodecTest.AssertRoundTrip <object, LNode>(
                a,
                obj => codec.Encode(obj, encoder),
                enc => codec.Decode(enc, decoder));

            ConstantCodecTest.AssertRoundTrip <object, LNode>(
                b,
                obj => codec.Encode(obj, encoder),
                enc => codec.Decode(enc, decoder));

            ConstantCodecTest.AssertRoundTrip <object, LNode>(
                c,
                obj => codec.Encode(obj, encoder),
                enc => codec.Decode(enc, decoder));
        }
Example #16
0
        public void SetDataWhithStepDataTest()
        {
            //Arrange
            const EncoderState encoderState = EncoderState.Cancelled;
            const string       message      = "message";

            var mediator  = new Mock <IStepMediator>();
            var webClient = new Mock <IEncodeWebClient>();

            var pipelineStep = new PipelineStepStub(mediator.Object, webClient.Object);
            var stepData     = new StepData()
            {
                EncoderState = encoderState,
                ErrorMessage = message
            };

            //Act
            pipelineStep.SetData(stepData);

            //Assert
            Assert.AreEqual(encoderState, pipelineStep.ProtectedStepData.EncoderState);
            Assert.AreEqual(message, pipelineStep.ProtectedStepData.ErrorMessage);
        }
Example #17
0
        private void WriteHorizontalSpan(EncoderState state, bool color, int spanLength)
        {
            uint[] terminatingCodes = color ? WhiteTerminatingCodes : BlackTerminatingCodes;
            uint[] makeUpCodes      = color ? WhiteMakeUpCodes : BlackMakeUpCodes;

            int count = spanLength;

            // The make-up code for 2560 will be written as often as required:
            while (count >= 2624)
            {
                state.Writer.Write(makeUpCodes[39 * 2], makeUpCodes[39 * 2 + 1]); // Magic: 2560
                count -= 2560;
            }
            // A make-up code for a multiple of 64 will be written if required:
            if (count > 63)
            {
                int line = count / 64 - 1;
                state.Writer.Write(makeUpCodes[line * 2], makeUpCodes[line * 2 + 1]);
                count -= (line + 1) * 64;
            }
            // And finally the terminating code for the remaining value (0 through 63):
            state.Writer.Write(terminatingCodes[count * 2], terminatingCodes[count * 2 + 1]);
        }
Example #18
0
        private void WriteVerticalCode(EncoderState state, int deltab1a1)
        {
            var verticalIndex = deltab1a1 + 3;

            state.Writer.Write(VerticalCodes[verticalIndex * 2], VerticalCodes[verticalIndex * 2 + 1]);
        }
Example #19
0
        public IRestRequest FinishTaskRequestCreate(string resource, EncoderState encoderState, string fileId, string errorMessage)
        {
            IRestRequest request = RequestCreate(resource, Method.POST);
            request.AddHeader("X-HTTP-Method-Override", "DELETE");
            request.AddParameter(EncoderStatusParameters.Result, encoderState);
            request.AddParameter(EncoderStatusParameters.FileId, fileId);
            request.AddParameter(EncoderStatusParameters.Message, errorMessage);

            return request;
        }
Example #20
0
        /// <summary>
        /// Writes a CIL method body, analyzes it as Flame IR,
        /// emits that as CIL and checks that the outcome matches
        /// what we'd expect.
        /// </summary>
        /// <param name="returnType">
        /// The return type of the method body.
        /// </param>
        /// <param name="parameterTypes">
        /// The parameter types of the method body.
        /// </param>
        /// <param name="localTypes">
        /// The local variable types of the method body.
        /// </param>
        /// <param name="emitBody">
        /// A function that writes the method body.
        /// </param>
        /// <param name="oracle">
        /// A printed version of the expected method body.
        /// </param>
        private void RoundtripStaticMethodBody(
            TypeReference returnType,
            IReadOnlyList <TypeReference> parameterTypes,
            IReadOnlyList <TypeReference> localTypes,
            Action <Mono.Cecil.Cil.ILProcessor> emitBody,
            string oracle)
        {
            // Define a method.
            var methodDef = CreateStaticMethodDef(returnType, parameterTypes);

            // Emit the source CIL.
            var cilBody = new Mono.Cecil.Cil.MethodBody(methodDef);

            foreach (var localType in localTypes)
            {
                cilBody.Variables.Add(new Mono.Cecil.Cil.VariableDefinition(localType));
            }

            emitBody(cilBody.GetILProcessor());
            cilBody.Optimize();

            // Analyze it as Flame IR.
            var irBody = ClrMethodBodyAnalyzer.Analyze(
                cilBody,
                new Parameter(TypeHelpers.BoxIfReferenceType(corlib.Resolve(returnType))),
                default(Parameter),
                parameterTypes
                .Select((type, i) => new Parameter(TypeHelpers.BoxIfReferenceType(corlib.Resolve(type)), "param_" + i))
                .ToArray(),
                corlib);

            // Register analyses.
            irBody = new global::Flame.Compiler.MethodBody(
                irBody.ReturnParameter,
                irBody.ThisParameter,
                irBody.Parameters,
                irBody.Implementation
                .WithAnalysis(LazyBlockReachabilityAnalysis.Instance)
                .WithAnalysis(NullabilityAnalysis.Instance)
                .WithAnalysis(new EffectfulInstructionAnalysis())
                .WithAnalysis(PredecessorAnalysis.Instance)
                .WithAnalysis(RelatedValueAnalysis.Instance)
                .WithAnalysis(LivenessAnalysis.Instance)
                .WithAnalysis(InterferenceGraphAnalysis.Instance)
                .WithAnalysis(ValueUseAnalysis.Instance)
                .WithAnalysis(ConservativeInstructionOrderingAnalysis.Instance));

            // Optimize the IR a tiny bit.
            irBody = irBody.WithImplementation(
                irBody.Implementation.Transform(
                    AllocaToRegister.Instance,
                    CopyPropagation.Instance,
                    new ConstantPropagation(),
                    SwitchSimplification.Instance,
                    DeadValueElimination.Instance,
                    InstructionSimplification.Instance,
                    new JumpThreading(true),
                    DeadBlockElimination.Instance,
                    new SwitchLowering(corlib.Resolver.TypeEnvironment),
                    CopyPropagation.Instance,
                    InstructionSimplification.Instance,
                    DeadValueElimination.Instance,
                    InstructionReordering.Instance,
                    new JumpThreading(false)));

            // Turn Flame IR back into CIL.
            var newCilBody = ClrMethodBodyEmitter.Compile(irBody, methodDef, corlib.Resolver.TypeEnvironment);

            // Check that the resulting CIL matches the expected CIL.
            var actual = FormatMethodBody(newCilBody);

            actual = actual.Trim().Replace("\r", "");
            oracle = oracle.Trim().Replace("\r", "");
            if (actual != oracle)
            {
                var encoder     = new EncoderState();
                var encodedImpl = encoder.Encode(irBody.Implementation);

                var actualIr = Les2LanguageService.Value.Print(
                    encodedImpl,
                    options: new LNodePrinterOptions
                {
                    IndentString = new string(' ', 4)
                });

                log.Log(
                    new LogEntry(
                        Severity.Message,
                        "emitted CIL-oracle mismatch",
                        "round-tripped CIL does not match the oracle. CIL emit output:",
                        new Paragraph(new WrapBox(actual, 0, -actual.Length)),
                        DecorationSpan.MakeBold("remark: Flame IR:"),
                        new Paragraph(new WrapBox(actualIr, 0, -actualIr.Length))));
            }
            Assert.AreEqual(oracle, actual);
        }
Example #21
0
 public void FinishTask(EncoderState encoderState, string fileId, string errorMessage)
 {
     IRestRequest request = _restHelper.FinishTaskRequestCreate(Resource, encoderState, fileId, errorMessage);
     _restHelper.GetResponse(request);
 }
Example #22
0
        /// <summary>
        /// Writes a CIL method body, analyzes it as Flame IR
        /// and checks that the result is what we'd expect.
        /// </summary>
        /// <param name="returnType">
        /// The return type of the method body.
        /// </param>
        /// <param name="parameterTypes">
        /// The parameter types of the method body.
        /// </param>
        /// <param name="emitBody">
        /// A function that writes the method body.
        /// </param>
        /// <param name="oracle">
        /// The expected Flame IR flow graph, as LESv2.
        /// </param>
        private void AnalyzeStaticMethodBody(
            TypeReference returnType,
            IReadOnlyList <TypeReference> parameterTypes,
            IReadOnlyList <TypeReference> localTypes,
            Action <Mono.Cecil.Cil.ILProcessor> emitBody,
            string oracle)
        {
            var methodDef = new MethodDefinition(
                "f",
                MethodAttributes.Public | MethodAttributes.Static,
                returnType);

            foreach (var type in parameterTypes)
            {
                methodDef.Parameters.Add(new ParameterDefinition(type));
                int index = methodDef.Parameters.Count - 1;
                methodDef.Parameters[index].Name = "param_" + index;
            }

            var cilBody = new Mono.Cecil.Cil.MethodBody(methodDef);

            foreach (var localType in localTypes)
            {
                cilBody.Variables.Add(new Mono.Cecil.Cil.VariableDefinition(localType));
            }

            emitBody(cilBody.GetILProcessor());

            var irBody = ClrMethodBodyAnalyzer.Analyze(
                cilBody,
                new Parameter(TypeHelpers.BoxIfReferenceType(corlib.Resolve(returnType))),
                default(Parameter),
                parameterTypes
                .Select((type, i) => new Parameter(TypeHelpers.BoxIfReferenceType(corlib.Resolve(type)), "param_" + i))
                .ToArray(),
                corlib);

            var encoder     = new EncoderState();
            var encodedImpl = encoder.Encode(irBody.Implementation);

            var actual = Les2LanguageService.Value.Print(
                encodedImpl,
                options: new LNodePrinterOptions
            {
                IndentString = new string(' ', 4)
            });

            if (actual.Trim() != oracle.Trim())
            {
                log.Log(
                    new LogEntry(
                        Severity.Message,
                        "CIL analysis-oracle mismatch",
                        "analyzed CIL does not match the oracle. CIL analysis output:"));
                // TODO: ugly hack to work around wrapping.
                Console.Error.WriteLine(actual.Trim());
            }

            Assert.AreEqual(
                actual.Trim(),
                oracle.Trim());
        }
        /// <summary>
        /// Poll for output from the encoder, copying at most size bytes into buffer + offset
        /// (setting outputSize to the actual amount copied)
        /// </summary>
        /// <param name="buffer">The buffer to be filled from the encoder</param>
        /// <param name="offset">The offset of the buffer to be filled</param>
        /// <param name="size">Number of bytes to be filled</param>
        /// <param name="outputSize">Number of bytes actually polled</param>
        /// <returns>Refer to HSE_poll_res in original C version heatshrink</returns>
        public EncoderPollResult Poll(byte[] buffer, int offset, int size, out int outputSize)
        {
            outputSize = 0;

            if (buffer == null)
            {
                return(EncoderPollResult.Null);
            }
            if (size == 0)
            {
                if (Constants.EnableLogging)
                {
                    Console.WriteLine("-- MISUSE: output buffer size is 0");
                }
                return(EncoderPollResult.Misuse);
            }

            while (true)
            {
                if (Constants.EnableLogging)
                {
                    Console.WriteLine($"-- polling, state {Convert.ToInt32(_state)} ({StateNames[_state]}), flags 0x{_flags:x2}");
                }

                var inState = _state;
                switch (inState)
                {
                case EncoderState.NotFull:
                    return(EncoderPollResult.Empty);

                case EncoderState.Filled:
                    DoIndexing();
                    _state = EncoderState.Search;
                    break;

                case EncoderState.Search:
                    _state = StStepSearch();
                    break;

                case EncoderState.YieldTagBit:
                    _state = StYieldTagBit(buffer, offset, size, ref outputSize);
                    break;

                case EncoderState.YieldLiteral:
                    _state = StYieldLiteral(buffer, offset, size, ref outputSize);
                    break;

                case EncoderState.YieldBackrefIndex:
                    _state = StYieldBackrefIndex(buffer, offset, size, ref outputSize);
                    break;

                case EncoderState.YieldBackrefLength:
                    _state = StYieldBackrefLength(buffer, offset, size, ref outputSize);
                    break;

                case EncoderState.SaveBacklog:
                    _state = StSaveBacklog();
                    break;

                case EncoderState.FlushBits:
                    _state = StFlushBitBuffer(buffer, offset, size, ref outputSize);
                    return(EncoderPollResult.Empty);

                case EncoderState.Done:
                    return(EncoderPollResult.Empty);

                default:
                    if (Constants.EnableLogging)
                    {
                        Console.WriteLine($"-- bad state {StateNames[_state]}");
                    }
                    return(EncoderPollResult.Misuse);
                }

                /* Check if output buffer is exhausted. */
                if (_state == inState && outputSize == size)
                {
                    return(EncoderPollResult.More);
                }
            }
        }
Example #24
0
 private void WritePassCode(EncoderState state)
 {
     state.Writer.Write(PassCodes[0], PassCodes[1]);
 }