LIB3MFMETHODIMP CCOMModelTexture2D::ReadFromFile(_In_z_ LPCWSTR pwszFilename)
	{
		try {
			if (pwszFilename == nullptr)
				throw CNMRException(NMR_ERROR_INVALIDPOINTER);

			CModelTexture2DResource * pTextureResource = getTexture2D();
			__NMRASSERT(pTextureResource);

			std::string sUTF8FileName = fnUTF16toUTF8(pwszFilename);
			PImportStream pImportStream = fnCreateImportStreamInstance(sUTF8FileName.c_str());

			CModel * pModel = pTextureResource->getModel();
			__NMRASSERT(pModel);
			
			pModel->removeAttachment(pTextureResource->getPath());
			pModel->addAttachment(pTextureResource->getPath(), PACKAGE_TEXTURE_RELATIONSHIP_TYPE, pImportStream);

			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}

	}
	LIB3MFMETHODIMP CCOMModelTexture2D::GetPathUTF8(_Out_opt_ LPSTR pszBuffer, _In_ ULONG cbBufferSize, _Out_ ULONG * pcbNeededChars)
	{
		try {
			if (cbBufferSize > MODEL_MAXSTRINGBUFFERLENGTH)
				throw CNMRException(NMR_ERROR_INVALIDBUFFERSIZE);

			CModelTexture2DResource * pTextureResource = getTexture2D();
			__NMRASSERT(pTextureResource);

			// Retrieve Path
			std::wstring sUTF16Path = pTextureResource->getPath();
			std::string sUTF8Path = fnUTF16toUTF8(sUTF16Path);

			// Safely call StringToBuffer
			nfUint32 nNeededChars = 0;
			fnStringToBufferSafe(sUTF8Path, pszBuffer, cbBufferSize, &nNeededChars);

			// Return length if needed
			if (pcbNeededChars)
				*pcbNeededChars = nNeededChars;


			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}


	}
	LIB3MFMETHODIMP CCOMModelComponentsObject::GetNameUTF8(_Out_opt_ LPSTR pszBuffer, _In_ ULONG cbBufferSize, _Out_opt_ ULONG * pcbNeededChars)
	{
		try {
			if (cbBufferSize > MODEL_MAXSTRINGBUFFERLENGTH)
				throw CNMRException(NMR_ERROR_INVALIDBUFFERSIZE);

			CModelComponentsObject * pObject = getComponentsObject();
			__NMRASSERT(pObject);

			std::wstring sUTF16Name = pObject->getName();
			std::string sUTF8Name = fnUTF16toUTF8(sUTF16Name);

			// Safely call StringToBuffer
			nfUint32 nNeededChars = 0;
			fnStringToBufferSafe(sUTF8Name, pszBuffer, cbBufferSize, &nNeededChars);

			// Return length if needed
			if (pcbNeededChars)
				*pcbNeededChars = nNeededChars;

			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}
	}
	CImportStream_GCC_Native::CImportStream_GCC_Native(_In_ const nfWChar * pwszFileName)
	{
		if (pwszFileName == nullptr)
			throw CNMRException(NMR_ERROR_INVALIDPARAM);

		std::wstring sFileName(pwszFileName);
#ifdef _WIN32
		m_Stream.open(sFileName.c_str(), std::ios::in | std::ios::binary);
#else
		std::string sUTF8Name = fnUTF16toUTF8(sFileName);
		m_Stream.open(sUTF8Name.c_str(), std::ios::in | std::ios::binary);
#endif
		if (m_Stream.fail())
			throw CNMRException(NMR_ERROR_COULDNOTOPENFILE);
	}
	LIB3MFMETHODIMP CCOMModelTexture2D::SetPath(_In_z_ LPCWSTR pwszPath)
	{
		try {
			if (pwszPath == nullptr)
				throw CNMRException(NMR_ERROR_INVALIDPOINTER);

			CModelTexture2DResource * pTextureResource = getTexture2D();
			__NMRASSERT(pTextureResource);

			std::wstring sPath(pwszPath);
			pTextureResource->setPath(fnUTF16toUTF8(sPath));

			return handleSuccess();
		}
		catch (CNMRException & Exception) {
			return handleNMRException(&Exception);
		}
		catch (...) {
			return handleGenericException();
		}

	}