예제 #1
0
        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;
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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;
            }
        }
예제 #4
0
        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();
        }
예제 #5
0
        /// <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;
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }