+++ /dev/null
-#include "stdafx.h"\r
-/*\r
-* Copyright (c) 2007-2010 SlimDX Group\r
-* \r
-* Permission is hereby granted, free of charge, to any person obtaining a copy\r
-* of this software and associated documentation files (the "Software"), to deal\r
-* in the Software without restriction, including without limitation the rights\r
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-* copies of the Software, and to permit persons to whom the Software is\r
-* furnished to do so, subject to the following conditions:\r
-* \r
-* The above copyright notice and this permission notice shall be included in\r
-* all copies or substantial portions of the Software.\r
-* \r
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-* THE SOFTWARE.\r
-*/\r
-\r
-#include "DataStream.h"\r
-#include "Utilities.h"\r
-#include "multimedia/WaveStream.h"\r
-\r
-#include "SlimDXException.h"\r
-\r
-using namespace System;\r
-using namespace System::Collections::Generic;\r
-using namespace System::IO;\r
-using namespace System::Reflection;\r
-using namespace System::Globalization;\r
-using namespace SlimDX::Multimedia;\r
-\r
-namespace SlimDX\r
-{\r
- Utilities::Utilities()\r
- {\r
- }\r
-\r
- generic<typename T> where T : value class\r
- array<T>^ Utilities::ReadRange( ID3DXBuffer *buffer, int count )\r
- {\r
- if( count < 0 )\r
- throw gcnew ArgumentOutOfRangeException( "count" );\r
-\r
- if (buffer == NULL)\r
- return nullptr;\r
- \r
- size_t elementSize = sizeof(T);\r
- array<T>^ result = gcnew array<T>( count );\r
-\r
- pin_ptr<T> pinnedBuffer = &result[0];\r
- memcpy( pinnedBuffer, buffer->GetBufferPointer(), count * elementSize );\r
-\r
- buffer->Release();\r
-\r
- return result;\r
- }\r
- \r
- //TODO: This needs review upon interface refactor.\r
- GUID Utilities::GetNativeGuidForType( Type^ type )\r
- {\r
- if( type == nullptr )\r
- throw gcnew ArgumentNullException( "type" );\r
- \r
- // This will only work for ComObjects.\r
- if( !type->IsSubclassOf( ComObject::typeid ) )\r
- return GUID_NULL;\r
- \r
- // This should never fail (i.e., should never return null) since we now know the type is a ComObject subclass.\r
- //TODO: Old comobjects have this private, new ones public. blah blah. this needs to be moved to an attribute anyway\r
- // or it won't work with interfaces.\r
- PropertyInfo^ nativeInterfaceProperty = type->GetProperty( "NativeInterface", BindingFlags::NonPublic | BindingFlags::Static );\r
- if( nativeInterfaceProperty == nullptr ) \r
- nativeInterfaceProperty = type->GetProperty( "NativeInterface" );\r
-\r
- Guid nativeInterface = static_cast<Guid>( nativeInterfaceProperty->GetValue( nullptr, nullptr ) );\r
- \r
- return ConvertManagedGuid( nativeInterface );\r
- }\r
- \r
- Guid Utilities::ConvertNativeGuid( const GUID &guid )\r
- {\r
- if( guid == GUID_NULL )\r
- return Guid::Empty;\r
-\r
- Guid result(\r
- guid.Data1,\r
- guid.Data2,\r
- guid.Data3,\r
- guid.Data4[0],\r
- guid.Data4[1],\r
- guid.Data4[2], \r
- guid.Data4[3],\r
- guid.Data4[4],\r
- guid.Data4[5],\r
- guid.Data4[6],\r
- guid.Data4[7]\r
- );\r
-\r
- return result;\r
- }\r
-\r
- GUID Utilities::ConvertManagedGuid( Guid guid )\r
- {\r
- if( guid == Guid::Empty )\r
- return GUID_NULL;\r
-\r
- GUID result;\r
- array<Byte>^ bytes = guid.ToByteArray();\r
- pin_ptr<unsigned char> pinned_bytes = &bytes[0];\r
- memcpy( &result, pinned_bytes, sizeof(GUID) );\r
-\r
- return result;\r
- }\r
- \r
- int Utilities::SizeOfFormatElement( DXGI_FORMAT format )\r
- {\r
- switch( format )\r
- {\r
- case DXGI_FORMAT_R32G32B32A32_TYPELESS:\r
- case DXGI_FORMAT_R32G32B32A32_FLOAT:\r
- case DXGI_FORMAT_R32G32B32A32_UINT:\r
- case DXGI_FORMAT_R32G32B32A32_SINT:\r
- return 128;\r
- \r
- case DXGI_FORMAT_R32G32B32_TYPELESS:\r
- case DXGI_FORMAT_R32G32B32_FLOAT:\r
- case DXGI_FORMAT_R32G32B32_UINT:\r
- case DXGI_FORMAT_R32G32B32_SINT:\r
- return 96;\r
- \r
- case DXGI_FORMAT_R16G16B16A16_TYPELESS:\r
- case DXGI_FORMAT_R16G16B16A16_FLOAT:\r
- case DXGI_FORMAT_R16G16B16A16_UNORM:\r
- case DXGI_FORMAT_R16G16B16A16_UINT:\r
- case DXGI_FORMAT_R16G16B16A16_SNORM:\r
- case DXGI_FORMAT_R16G16B16A16_SINT:\r
- case DXGI_FORMAT_R32G32_TYPELESS:\r
- case DXGI_FORMAT_R32G32_FLOAT:\r
- case DXGI_FORMAT_R32G32_UINT:\r
- case DXGI_FORMAT_R32G32_SINT:\r
- case DXGI_FORMAT_R32G8X24_TYPELESS:\r
- case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:\r
- case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:\r
- case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:\r
- return 64;\r
- \r
- case DXGI_FORMAT_R10G10B10A2_TYPELESS:\r
- case DXGI_FORMAT_R10G10B10A2_UNORM:\r
- case DXGI_FORMAT_R10G10B10A2_UINT:\r
- case DXGI_FORMAT_R11G11B10_FLOAT:\r
- case DXGI_FORMAT_R8G8B8A8_TYPELESS:\r
- case DXGI_FORMAT_R8G8B8A8_UNORM:\r
- case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:\r
- case DXGI_FORMAT_R8G8B8A8_UINT:\r
- case DXGI_FORMAT_R8G8B8A8_SNORM:\r
- case DXGI_FORMAT_R8G8B8A8_SINT:\r
- case DXGI_FORMAT_R16G16_TYPELESS:\r
- case DXGI_FORMAT_R16G16_FLOAT:\r
- case DXGI_FORMAT_R16G16_UNORM:\r
- case DXGI_FORMAT_R16G16_UINT:\r
- case DXGI_FORMAT_R16G16_SNORM:\r
- case DXGI_FORMAT_R16G16_SINT:\r
- case DXGI_FORMAT_R32_TYPELESS:\r
- case DXGI_FORMAT_D32_FLOAT:\r
- case DXGI_FORMAT_R32_FLOAT:\r
- case DXGI_FORMAT_R32_UINT:\r
- case DXGI_FORMAT_R32_SINT:\r
- case DXGI_FORMAT_R24G8_TYPELESS:\r
- case DXGI_FORMAT_D24_UNORM_S8_UINT:\r
- case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:\r
- case DXGI_FORMAT_X24_TYPELESS_G8_UINT:\r
- case DXGI_FORMAT_B8G8R8A8_UNORM:\r
- case DXGI_FORMAT_B8G8R8X8_UNORM:\r
- return 32;\r
- \r
- case DXGI_FORMAT_R8G8_TYPELESS:\r
- case DXGI_FORMAT_R8G8_UNORM:\r
- case DXGI_FORMAT_R8G8_UINT:\r
- case DXGI_FORMAT_R8G8_SNORM:\r
- case DXGI_FORMAT_R8G8_SINT:\r
- case DXGI_FORMAT_R16_TYPELESS:\r
- case DXGI_FORMAT_R16_FLOAT:\r
- case DXGI_FORMAT_D16_UNORM:\r
- case DXGI_FORMAT_R16_UNORM:\r
- case DXGI_FORMAT_R16_UINT:\r
- case DXGI_FORMAT_R16_SNORM:\r
- case DXGI_FORMAT_R16_SINT:\r
- case DXGI_FORMAT_B5G6R5_UNORM:\r
- case DXGI_FORMAT_B5G5R5A1_UNORM:\r
- return 16;\r
- \r
- case DXGI_FORMAT_R8_TYPELESS:\r
- case DXGI_FORMAT_R8_UNORM:\r
- case DXGI_FORMAT_R8_UINT:\r
- case DXGI_FORMAT_R8_SNORM:\r
- case DXGI_FORMAT_R8_SINT:\r
- case DXGI_FORMAT_A8_UNORM:\r
- return 8;\r
- \r
- // Compressed format; http://msdn2.microsoft.com/en-us/library/bb694531(VS.85).aspx\r
- case DXGI_FORMAT_BC2_TYPELESS:\r
- case DXGI_FORMAT_BC2_UNORM:\r
- case DXGI_FORMAT_BC2_UNORM_SRGB:\r
- case DXGI_FORMAT_BC3_TYPELESS:\r
- case DXGI_FORMAT_BC3_UNORM:\r
- case DXGI_FORMAT_BC3_UNORM_SRGB:\r
- case DXGI_FORMAT_BC5_TYPELESS:\r
- case DXGI_FORMAT_BC5_UNORM:\r
- case DXGI_FORMAT_BC5_SNORM:\r
- return 128;\r
- \r
- // Compressed format; http://msdn2.microsoft.com/en-us/library/bb694531(VS.85).aspx\r
- case DXGI_FORMAT_R1_UNORM:\r
- case DXGI_FORMAT_BC1_TYPELESS:\r
- case DXGI_FORMAT_BC1_UNORM:\r
- case DXGI_FORMAT_BC1_UNORM_SRGB:\r
- case DXGI_FORMAT_BC4_TYPELESS:\r
- case DXGI_FORMAT_BC4_UNORM:\r
- case DXGI_FORMAT_BC4_SNORM:\r
- return 64;\r
- \r
- // Compressed format; http://msdn2.microsoft.com/en-us/library/bb694531(VS.85).aspx\r
- case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:\r
- return 32;\r
- \r
- // These are compressed, but bit-size information is unclear.\r
- case DXGI_FORMAT_R8G8_B8G8_UNORM:\r
- case DXGI_FORMAT_G8R8_G8B8_UNORM:\r
- return 32;\r
-\r
- case DXGI_FORMAT_UNKNOWN:\r
- default:\r
- throw gcnew InvalidOperationException( "Cannot determine format element size; invalid format specified." );\r
- }\r
- }\r
- \r
- Drawing::Rectangle Utilities::ConvertRect(RECT rect)\r
- {\r
- return Drawing::Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);\r
- }\r
-\r
- void Utilities::ConvertRect(System::Drawing::Rectangle& source, RECT& dest)\r
- {\r
- dest.top = source.Top;\r
- dest.bottom = source.Bottom;\r
- dest.left = source.Left;\r
- dest.right = source.Right;\r
- }\r
-\r
- array<Byte>^ Utilities::ReadStream( Stream^ stream, DataStream^* dataStream )\r
- {\r
- int length = 0;\r
-\r
- return ReadStream( stream, length, dataStream );\r
- }\r
-\r
- array<Byte>^ Utilities::ReadStream( Stream^ stream, int% readLength, DataStream^* dataStream )\r
- {\r
- if( stream == nullptr )\r
- throw gcnew ArgumentNullException( "stream" );\r
- if( !stream->CanRead )\r
- throw gcnew NotSupportedException();\r
-\r
- if( readLength > stream->Length - stream->Position )\r
- throw gcnew ArgumentOutOfRangeException( "readLength" );\r
- if( readLength == 0 )\r
- readLength = static_cast<int>( stream->Length - stream->Position );\r
- if( readLength < 0 )\r
- throw gcnew ArgumentOutOfRangeException( "readLength" );\r
- if( readLength == 0 )\r
- return gcnew array<Byte>( 0 );\r
-\r
- //if we're reading a DataStream, don't return anything and send back the casted DataStream\r
- DataStream^ ds = dynamic_cast<DataStream^>( stream );\r
- if( ds != nullptr && dataStream != NULL )\r
- {\r
- *dataStream = ds;\r
- return nullptr;\r
- }\r
-\r
- //It turns out this can fail because MemoryStream keeps an exposable parameter, and defaults it to\r
- //false, so that most of the time, MemoryStream->GetBuffer() can't be used. We might use reflection\r
- //to pull the internal array directly. Until then, MemoryStream can literally GO FUCK ITS OWN INTERFACE.\r
- /*//if we're reading an entire memory stream from beginning to end, just return the internal buffer\r
- MemoryStream^ ms = dynamic_cast<MemoryStream^>( stream );\r
- if( ms != nullptr && stream->Position == 0 && readLength == stream->Length )\r
- {\r
- return ms->GetBuffer();\r
- }*/\r
-\r
- WaveStream^ ws = dynamic_cast<WaveStream^>( stream );\r
- if( ws != nullptr && dataStream != NULL && ws->InternalMemory != nullptr )\r
- {\r
- *dataStream = ws->InternalMemory;\r
- return nullptr;\r
- }\r
-\r
- array<Byte>^ buffer = gcnew array<Byte>( readLength ); \r
- int bytesRead = 0;\r
- while( bytesRead < readLength )\r
- bytesRead += stream->Read( buffer, bytesRead, readLength - bytesRead );\r
-\r
- return buffer;\r
- }\r
- \r
- void Utilities::CheckArrayBounds( Array^ data, int offset, int% count )\r
- {\r
- if( data == nullptr )\r
- throw gcnew ArgumentNullException( "data" );\r
-\r
- CheckBounds( 0, data->Length, offset, count );\r
- }\r
- \r
- void Utilities::CheckBounds( int lowerBound, int size, int offset, int% count )\r
- {\r
- if( offset < lowerBound )\r
- throw gcnew ArgumentOutOfRangeException( "offset" );\r
- if( count < 0 )\r
- throw gcnew ArgumentOutOfRangeException( "count" );\r
- if( offset + count > size )\r
- throw gcnew ArgumentException( "The sum of offset and count is greater than the buffer length." );\r
- \r
- if( count == 0 )\r
- count = size - offset;\r
- }\r
- \r
- generic<typename T>\r
- bool Utilities::CheckElementEquality( array<T>^ left, array<T>^ right )\r
- {\r
- if( left->Length != right->Length )\r
- return false;\r
- \r
- for( int index = 0; index < left->Length; ++index )\r
- {\r
- if( !left[index]->Equals( right[index] ) ) \r
- {\r
- return false;\r
- }\r
- }\r
- \r
- return true;\r
- }\r
- \r
- generic<typename T>\r
- bool Utilities::CheckElementEquality( IList<T>^ left, IList<T>^ right )\r
- {\r
- if( left->Count != right->Count )\r
- return false;\r
- \r
- for( int index = 0; index < left->Count; ++index )\r
- {\r
- if( !left[index]->Equals( right[index] ) ) \r
- {\r
- return false;\r
- }\r
- }\r
- \r
- return true;\r
- }\r
- \r
- String^ Utilities::BufferToString( ID3DXBuffer *buffer )\r
- {\r
- if( buffer != NULL )\r
- {\r
- String^ string = gcnew String( reinterpret_cast<const char*>( buffer->GetBufferPointer() ) );\r
- buffer->Release();\r
- return string;\r
- }\r
- else\r
- {\r
- return String::Empty;\r
- }\r
- }\r
-\r
- String^ Utilities::BlobToString( ID3D10Blob *blob )\r
- {\r
- if( blob != NULL )\r
- {\r
- String^ string = gcnew String( reinterpret_cast<const char*>( blob->GetBufferPointer() ) );\r
- blob->Release();\r
- return string; \r
- }\r
- else\r
- return String::Empty;\r
- }\r
-\r
- void Utilities::FreeNativeString( LPCSTR string )\r
- {\r
- if( string == NULL )\r
- return;\r
-\r
- System::Runtime::InteropServices::Marshal::FreeHGlobal( IntPtr( const_cast<void*>( reinterpret_cast<const void*>( string ) ) ) );\r
- }\r
-\r
- void Utilities::FreeNativeString( LPSTR string )\r
- {\r
- if( string == NULL )\r
- return;\r
-\r
- System::Runtime::InteropServices::Marshal::FreeHGlobal( IntPtr( reinterpret_cast<void*>( string ) ) );\r
- }\r
-\r
- LPSTR Utilities::AllocateNativeString( String^ value )\r
- {\r
- if( value == nullptr || String::IsNullOrEmpty( value ) )\r
- return NULL;\r
- else\r
- return reinterpret_cast<LPSTR>( System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( value ).ToPointer() );\r
- }\r
-\r
- generic<typename T>\r
- T Utilities::FromIntToT( int value )\r
- {\r
- if( T::typeid->IsEnum )\r
- return safe_cast<T>( static_cast<int>( value ) );\r
- else if( T::typeid == float::typeid )\r
- return safe_cast<T>( *reinterpret_cast<float*>( &value ) );\r
- else\r
- return safe_cast<T>( Convert::ChangeType( static_cast<int>( value ), T::typeid, CultureInfo::InvariantCulture ) );\r
- }\r
-}
\ No newline at end of file