Reading from CStdioFile into vectorchar

Started by
0 comments, last by Zahlman 16 years, 5 months ago
Quick question. When I try to read from CStdioFile.Read(void* Buffer, int nRead) i get a thrown exception. I'm sure this works in VS2003, but now it throws an exception in SetString

bool CObjLoader::Open(CString &File, vector<float> &Vertex, vector<int> &Index, vector<float> &Normal, vector<float> &Texture)
{
	CStdioFile ObjFile;
	CFileException Exception;
	int Length;
	int Position = 0;
	
	try 
	{
		ObjFile.Open(File, CStdioFile::modeRead | CStdioFile::shareExclusive | CStdioFile::typeText, &Exception);	
	}
	catch (CFileException Exception)
	{
		int Cause = Exception.m_cause;
		// to do : advanced recovery...
	}

	CString Buffer;
	Length = (int)ObjFile.GetLength();

	vector<char> vBuffer;
	vBuffer.resize(Length);

	ObjFile.Read(&vBuffer, Length);

	ObjFile.Close();
	m_pHeader.clear();

	Count(TypeVertex);
	Count(TypeIndex);
	Count(TypeNormal);
	Count(TypeTexture);

	Convert_FloatStream(TypeVertex, Vertex);
	Convert_IntStream(Index);
	Convert_FloatStream(TypeNormal, Normal);
	if (m_pHeader.back() > 0) 
		Convert_FloatStream(TypeTexture, Texture);

	return true;
}

The exception thrown is in... "Unhandled exception at 0x7c81eb33 in objmfc.exe: Microsoft C++ exception: CFileException at memory location 0x0012fba8.."

	void SetString( __in_ecount(nLength) PCXSTR pszSrc, __in int nLength )
	{
		if( nLength == 0 )
		{
			Empty();
		}
		else
		{
			// It is possible that pszSrc points to a location inside of our 
			// buffer.  GetBuffer() might change m_pszData if (1) the buffer 
			// is shared or (2) the buffer is too small to hold the new 
			// string.  We detect this aliasing, and modify pszSrc to point
			// into the newly allocated buffer instead.
			
			if(pszSrc == NULL)
				AtlThrow(E_INVALIDARG);			
				
			UINT nOldLength = GetLength();
			UINT_PTR nOffset = pszSrc-GetString();
			// If 0 <= nOffset <= nOldLength, then pszSrc points into our 
			// buffer

			PXSTR pszBuffer = GetBuffer( nLength );
			if( nOffset <= nOldLength )
			{
#if _SECURE_ATL
                CopyCharsOverlapped( pszBuffer, nLength, 
					pszBuffer+nOffset, nLength );
#else
				CopyCharsOverlapped( pszBuffer, pszBuffer+nOffset, nLength );
#endif
			}
			else
			{
#if _SECURE_ATL
				CopyChars( pszBuffer, nLength, pszSrc, nLength );
#else
				CopyChars( pszBuffer, pszSrc, nLength );
#endif
			}
			ReleaseBufferSetLength( nLength ); <-- references this line
		}
	}


I get the feeling its something to do with the new secure code that MS has implemented in VS2005. Thanks Craig
Advertisement
1) Why are you using all that Microsoft-specific stuff just to open and read a file? The standard library provides all you need. (Does that .open call *really* expect you to pass a *pointer to a CFileException object* as a parameter? BTW, you do realise that if you catch an exception, the 'CFileException Exception' referred to is NOT the same variable as the one you declared earlier?)

2) Stop automatically using boolean return values as a "status code". You can't force the calling code to check it, and in many cases (as here) you only ever end up returning true. The net result is adding huge amounts of useless complication to the code in order to propagate return values around. This is what exceptions are for.

3) You're trying to read into memory starting at the location of the vector *object*, not that vector's *allocation*. You want &(vBuffer[0]) rather than &vBuffer.

But we don't need to read things all in one go, either...

void ObjLoader::Open(const string& filename, vector<float>& vertices, vector<int>& indices, vector<float>& normals, vector<float>& textures) {	ifstream file;	// if anything goes wrong, bail out immediately. Because of reading to	// a temporary buffer, we have a strong exception guarantee.	file.exceptions(ios::eofbit | ios::badbit | ios::failbit);	file.open(filename.c_str());		// One of the main reasons for using vectors is so that you don't have	// to know the size ahead of time. If you really need better performance	// than the following affords, prove it, and I'll see what I can do.	vector<char> buffer;	char c;	while (file.get(c)) { buffer.push_back(c); }	// No need to close the file explicitly.	// Er... where exactly do you *do something* with the file contents we just read? And where do all these Type* things come from? What are they?	m_pHeader.clear();	Count(TypeVertex);	Count(TypeIndex);	Count(TypeNormal);	Count(TypeTexture);	Convert_FloatStream(TypeVertex, vertices);	Convert_IntStream(indices);	Convert_FloatStream(TypeNormal, normals);	if (m_pHeader.back() > 0) 		Convert_FloatStream(TypeTexture, textures);}

This topic is closed to new replies.

Advertisement