public static void ReleaseBuffer(InteropBuffer buffer) { if (buffer == null) return; if (buffer.Locked) throw new InvalidOperationException(TextResources.ExceptionMsg_InteropBufferNotUnlocked); if (!buffer.Reserved) throw new ArgumentException(); VerifyPoolConsistency(); lock (Buffers) { if (Array.IndexOf(Buffers, buffer) == -1) { if (buffer.Size > maximumAvailableBufferSize) { if (NextAvailableBufferIndex <= Buffers.Length - 1) { Buffers[NextAvailableBufferIndex].Dispose(true); Buffers[NextAvailableBufferIndex] = buffer; maximumAvailableBufferSize = buffer.Size; } } else buffer.Dispose(true); } else NextAvailableBufferIndex--; buffer.Reserved = false; } }
private static void VerifyPoolConsistency() { if (Disposed) throw new ObjectDisposedException("InteropBufferPool"); if (Buffers == null) { NextAvailableBufferIndex = 0; maximumAvailableBufferSize = DefaultMaximumAvailableBufferSize; Buffers = new InteropBuffer[DefaultBuffersCount]; for (int i = 0; i < DefaultBuffersCount; i++) Buffers[i] = new InteropBuffer(maximumAvailableBufferSize); } }
public static InteropBuffer AcquireBuffer(int size) { if (size <= 0) throw new ArgumentOutOfRangeException("size"); VerifyPoolConsistency(); lock (Buffers) { InteropBuffer buffer = null; if (NextAvailableBufferIndex > Buffers.Length - 1 || size > maximumAvailableBufferSize) buffer = new InteropBuffer(size); else { int index = Array.FindIndex<InteropBuffer>(Buffers, delegate(InteropBuffer _buffer) { if (_buffer.Size >= size) return true; else return false; }); if (index == -1 || index < NextAvailableBufferIndex) buffer = new InteropBuffer(size); else { buffer = Buffers[index]; NextAvailableBufferIndex++; } } buffer.Reserved = true; return buffer; } }
private static void PrepareBlobBuffer(ref InteropBuffer buffer, int blobSize) { if (buffer.Size < blobSize) { if (buffer.Locked) buffer.Unlock(); InteropBufferPool.ReleaseBuffer(buffer); buffer = InteropBufferPool.AcquireBuffer(blobSize); } buffer.Lock(); }
/// <summary> /// Gets the event timestamp. /// </summary> /// <param name="dbEventInfo">[REF] <see cref="DBEVENTINFO"/> struct.</param> /// <param name="blobBuffer">Buffer to reuse.</param> /// <param name="timestamp">[OUT] Timestamp.</param> private static void GetEventTimestamp(ref DBEVENTINFO dbEventInfo, InteropBuffer blobBuffer, out DateTime timestamp) { try { DBTIMETOSTRING timeToString = new DBTIMETOSTRING("s D"); timeToString.MaxBytes = blobBuffer.Size; timeToString.Output = blobBuffer.IntPtr; unsafe { MirandaContext.Current.CallServiceUnsafe(MS_DB_TIME_TIMESTAMPTOSTRING, (void*)dbEventInfo.Timestamp, &timeToString); } timestamp = DateTime.Parse(Translate.ToString(timeToString.Output, StringEncoding.Ansi)); } catch (FormatException) { timestamp = DateTime.MinValue; } }
/// <summary> /// Get the event information from a <see cref="DBEVENTINFO"/> struct. /// </summary> /// <param name="dbEventInfo">[REF] <see cref="DBEVENTINFO"/> struct.</param> /// <param name="mirandaHandle">Event handle (the blob buffer will be populated if not null).</param> /// <param name="blobBuffer">Buffer to use for blob marshaling.</param> /// <param name="type">[OUT] Event type.</param> /// <param name="flags">[OUT] Event flags.</param> /// <param name="data">[OUT] Event data.</param> /// <param name="owningModule">[OUT] Event related module.</param> /// <param name="timestamp">[OUT] Event timestamp.</param> private static void GetEventInfo(ref DBEVENTINFO dbEventInfo, IntPtr eventHandle, InteropBuffer blobBuffer, out DatabaseEventType type, out DatabaseEventProperties flags, out string data, out Protocol owningModule, out DateTime timestamp) { MirandaContext context = MirandaContext.Current; unsafe { // If the event handle is set, we probably want to populate the blob buffer... if (eventHandle != IntPtr.Zero) PopulateBlobBuffer(ref dbEventInfo, eventHandle); type = (DatabaseEventType)dbEventInfo.EventType; flags = (DatabaseEventProperties)dbEventInfo.Flags; data = GetEventData(ref dbEventInfo); } owningModule = GetEventModule(ref dbEventInfo); GetEventTimestamp(ref dbEventInfo, blobBuffer, out timestamp); }
/// <summary> /// Prepares the <see cref="DBEVENTINFO"/> for information extraction and the blob buffer. /// </summary> /// <param name="eventHandle">Event handle.</param> /// <param name="dbEventInfo">[OUT] DB event info to marshal data into.</param> /// <param name="buffer">[OUT] Locked Blob buffer.</param> private unsafe static void PrepareDbEventInfo(IntPtr eventHandle, out DBEVENTINFO dbEventInfo, out InteropBuffer buffer) { int blobSize = MirandaContext.Current.CallServiceUnsafe(MS_DB_EVENT_GETBLOBSIZE, eventHandle.ToPointer(), null); if (blobSize == -1) throw new MirandaException(String.Format(TextResources.ExceptionMsg_Formatable2_MirandaServiceReturnedFailure, MS_DB_EVENT_GETBLOBSIZE, blobSize.ToString())); // Acquire a buffer for the blob buffer = InteropBufferPool.AcquireBuffer(blobSize); buffer.Lock(); dbEventInfo = new DBEVENTINFO(blobSize, buffer.IntPtr); }