Пример #1
0
        public void ExecuteOperation(
            _IOTransfer request,
            _StreamQuery query,
            Boolean writeMode,
            _StreamOp operation
            )
        {
            var key = GenerateHash(query.RequestedAddress, request.Offset, request.Count);

            if (m_CompiledOperations.ContainsKey(key))
            {
                m_CompiledOperations[key](this, request.Buffer, operation);
            }
            else
            {
                CompiledAction compiledAction = null;
                m_CacheCount++;

                /* Begin building a new memory IO method */
                Type   typeReturn = typeof(void);
                Type[] typeParams = { this.GetType(), typeof(Byte[]), typeof(_StreamOp) };
                String methodName = "CompiledMemIO_" + key.ToString("X8");

                /* Declare a new dynamic method to host our generated code */
                DynamicMethod method = new DynamicMethod(methodName, typeReturn, typeParams, true);

                /* Get the IL emitter for the dynamic method instance */
                ILGenerator emitter = method.GetILGenerator();

                /* Setup some things of the method */
                emitter.DeclareLocal(typeof(Stream));
                var methodGeStream         = GetType().GetMethod("GeStream");
                var methodSetSteamPosition = typeof(Stream).GetMethod("set_Position");
                var methodInvoke           = typeof(_StreamOp).GetMethod("Invoke");

                /* Compile the whole operation into a method using the interpreter engine */
                _StreamIOInterpreter.RunOperation(request, query, writeMode,
                                                  (r, s) =>
                {
                    r = RunEmitter(emitter, methodGeStream, methodSetSteamPosition, methodInvoke, r, s);
                });

                emitter.Emit(OpCodes.Nop);
                emitter.Emit(OpCodes.Ret);

                compiledAction = (CompiledAction)method.CreateDelegate(typeof(CompiledAction));
                m_CompiledOperations.Add(key, compiledAction);

                compiledAction(this, request.Buffer, operation);
            }
        }
Пример #2
0
        private void ExecuteMemoryOperation(_IOTransfer request, _StreamQuery query, Boolean writeMode, _StreamOp op)
        {
            if (!m_UseCompiler)
            {
                if (query.StreamQuery.Count() > 0)
                {
                    _StreamIOInterpreter.RunOperation(request, query, writeMode, op);
                }
            }
            else
            {
                if (m_OpCompiler.CacheCount > CACHE_MAX)
                {
                    m_OpCompiler.ClearCache();
                }

                m_OpCompiler.ExecuteOperation(request, query, writeMode, op);
            }

            /* Increment the position */
            m_Position += request.Count;
        }
Пример #3
0
        public static void RunOperation(_IOTransfer _IOTransfer, _StreamQuery streamQuery, Boolean isWriteMode, _StreamOp operation)
        {
            Int32 index   = 0;
            var   list    = streamQuery.StreamQuery;
            Int32 count   = list.Count();
            Int64 address = streamQuery.RequestedAddress;

            foreach (var entry in list)
            {
                /* Skip entries that do not allow write operations */
                if (isWriteMode && !entry.Value.CanWrite)
                {
                    continue;
                }

                Boolean     inZone  = CheckInReadZone(streamQuery.RequestedAddress, _IOTransfer.Count, entry.Key, entry.Value);
                _IOTransfer request = _IOTransfer;

                if (index == 0)
                {
                    /* On first stream, determine whether if it is partially or completely inside the reading zone */
                    if (inZone)
                    {
                        /* Copy the whole stream into the buffer */
                        entry.Value.Position = 0;
                        request = new _IOTransfer(_IOTransfer.Buffer, _IOTransfer.Offset, (Int32)entry.Value.Length);
                    }
                    else
                    {
                        /* Only partially copy the steam into the buffer */
                        entry.Value.Position = ConvertToOffsetInStream(address, entry.Key);
                        request = new _IOTransfer(_IOTransfer.Buffer, _IOTransfer.Offset, _IOTransfer.Count);
                    }
                }
                else if (index == count - 1)
                {
                    /* If we are on the last stream, determine whether its inside partially or completely */
                    if (inZone)
                    {
                        /* Copy the whole stream into the buffer */
                        entry.Value.Position = 0;
                        request = new _IOTransfer(_IOTransfer.Buffer, ConvertToOffsetInBuffer(address, entry.Key) + _IOTransfer.Offset, (Int32)entry.Value.Length);
                    }
                    else
                    {
                        /* Partially copy the steam into the buffer */
                        entry.Value.Position = 0;
                        Int32 bufferOffset = ConvertToOffsetInBuffer(streamQuery.RequestedAddress, entry.Key) + _IOTransfer.Offset;
                        request = new _IOTransfer(_IOTransfer.Buffer, bufferOffset, _IOTransfer.Count - bufferOffset);
                    }
                }
                else
                {
                    /* At this point, the stream is completely in the reading zone, so alwasy do a full read */
                    entry.Value.Position = 0;
                    request = new _IOTransfer(_IOTransfer.Buffer, ConvertToOffsetInBuffer(address, entry.Key) + _IOTransfer.Offset, (Int32)entry.Value.Length);
                }

                operation(request, entry.Value);
                index++;
            }
        }