Click here to Skip to main content
15,886,632 members
Articles / Desktop Programming / Windows Forms

BSEtunes

Rate me:
Please Sign up or sign in to vote.
4.67/5 (11 votes)
24 Apr 2010CPOL4 min read 64.6K   4.3K   58  
BSEtunes is a MySQL based, full manageable, networkable single or multiuser jukebox application
//  Widows Media Format Utils classes
//
//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER 
//  REMAINS UNCHANGED.
//
//  Email:  yetiicb@hotmail.com
//
//  Copyright (C) 2002-2004 Idael Cardoso. 
//

using System;
using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;

namespace BSE.Platten.Audio.WMFSDK
{
    /// <summary>
    /// Helper class who encapsulates INSSBuffer buffers.
    /// </summary>
    [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly")]
    public class NSSBuffer
    {
        private INSSBuffer m_Buffer;
        private uint m_Length;
        private uint m_MaxLength;
        private IntPtr m_BufferPtr;
        private uint m_Position;

        /// <summary>
        /// NSSBuffer constructor
        /// </summary>
        /// <param name="buff">INSSBuffer to wrap</param>
        public NSSBuffer(INSSBuffer buff)
        {
            m_Buffer = buff;
            m_Buffer.GetBufferAndLength(out m_BufferPtr, out m_Length);
            m_Buffer.GetMaxLength(out m_MaxLength);
        }

        /// <summary>
        /// Length of the buffer. Wraps INSSBuffer.GetLength and INSSBuffer.SetLength
        /// </summary>
        public uint Length
        {
            get
            {
                return m_Length;
            }
            set
            {
                if (value <= m_MaxLength)
                {
                    m_Buffer.SetLength(value);
                    m_Length = value;
                    if (m_Position > m_Length)
                    {
                        m_Position = m_Length;
                    }
                }
                else
                {
                    throw new ArgumentOutOfRangeException();
                }
            }
        }

        /// <summary>
        /// Read/Write the position for Read or Write operations
        /// </summary>
        public uint Position
        {
            get
            {
                return m_Position;
            }
            set
            {
                if (value <= m_Length)
                {
                    m_Position = value;
                }
                else
                {
                    throw new ArgumentOutOfRangeException();
                }
            }
        }

        /// <summary>
        /// Reference to the internal INSSBuffer
        /// </summary>
        public INSSBuffer Buffer
        {
            get { return m_Buffer; }
        }

        /// <summary>
        /// Reads from the wrapped buffer to a byte array. 
        /// Position is increased by the number of bytes read.
        /// </summary>
        /// <param name="buffer">Destination byte array</param>
        /// <param name="offset">Position in the destination array where to start copying</param>
        /// <param name="count">Number of bytes to read</param>
        /// <returns>Number of bytes read. Zero means than Position was at buffer length.</returns>
        public int Read(byte[] buffer, int offset, int count)
        {
            if (m_Position < m_Length)
            {
                IntPtr src = (IntPtr)(m_BufferPtr.ToInt32() + m_Position);
                int ToCopy = Math.Min(count, (int)(this.Length - this.Position));
                Marshal.Copy(src, buffer, offset, ToCopy);
                m_Position += (uint)ToCopy;
                return ToCopy;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// Write to the wrapped buffer from a byte array. 
        /// Position is increased by the number of byte written
        /// </summary>
        /// <param name="buffer">Source byte array</param>
        /// <param name="offset">Index from where start copying</param>
        /// <param name="count">Number of bytes to copy</param>
        public void Write(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset");
            }
            if ((count <= 0) || ((m_Position + count) > m_Length))
            {
                throw new ArgumentOutOfRangeException("count");
            }
            IntPtr dest = (IntPtr)(m_BufferPtr.ToInt32() + m_Position);
            Marshal.Copy(buffer, offset, dest, count);
            m_Position += (uint)count;
        }
    }

    /// <summary>
    /// Managed buffer that implements the INSSBuffer interface. 
    /// When passing this buffer to unmanaged code you must 
    /// take in account that it is not a safe operation because 
    /// managed heap could be exposed through the pointer returned by
    /// INSSBuffer methods.
    /// </summary>
    internal class ManBuffer : INSSBuffer
    {
        private uint m_UsedLength;
        private uint m_MaxLength;
        private byte[] m_Buffer;
        private GCHandle handle;

        /// <summary>
        /// Create a buffer with specified size
        /// </summary>
        /// <param name="size">Maximun size of buffer</param>
        public ManBuffer(uint size)
        {
            m_Buffer = new byte[size];
            m_MaxLength = m_UsedLength = size;
            handle = GCHandle.Alloc(m_Buffer, GCHandleType.Pinned);
        }
        ~ManBuffer()
        {
            handle.Free();
        }

        /// <summary>
        /// How many bytes are currently used in the buffer. 
        /// Equivalent to INSSBuffer.GetLentgh and INSSBuffer.SetLength
        /// </summary>
        public uint UsedLength
        {
            get { return m_UsedLength; }
            set
            {
                if (value <= m_MaxLength)
                {
                    m_UsedLength = value;
                }
                else
                {
                    throw new ArgumentException();
                }
            }
        }

        /// <summary>
        /// Maximun buffer size. Equivalent to INSSBuffer.GetMaxLength
        /// </summary>
        public uint MaxLength
        {
            get { return m_MaxLength; }
        }

        /// <summary>
        /// Internal byte array that contain buffer data.
        /// </summary>
        public byte[] Buffer
        {
            get { return m_Buffer; }
        }

        #region INSSBuffer Members

        public void GetLength(out uint pdwLength)
        {
            pdwLength = m_UsedLength;
        }

        public void SetLength(uint dwLength)
        {
            UsedLength = dwLength;
        }

        public void GetMaxLength(out uint pdwLength)
        {
            pdwLength = m_MaxLength;
        }

        public void GetBuffer(out IntPtr ppdwBuffer)
        {
            ppdwBuffer = handle.AddrOfPinnedObject();
        }

        public void GetBufferAndLength(out IntPtr ppdwBuffer, out uint pdwLength)
        {
            ppdwBuffer = handle.AddrOfPinnedObject();
            pdwLength = m_UsedLength;
        }

        #endregion

    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions