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