Jump to content
  • Advertisement
Sign in to follow this  

Problem writing to File

This topic is 4999 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Maybe I've been just looking at this code for too long (I guess that happens to everyone) but I just can't seem to find the problem. I've tested my methods of opening a file up and storing the information in a buffer; but I can't seem to write it to my archive file. I end up with just the file header; some more eyes looking at it will usually uncover problems! Source
//j: save one of our beautiful archive files; yay! fun! fun!
bool CFileArchive::Save(Archive_T& p) {
	if(m_bTouched) {
		// check this now!!
			p.pHandle = new fstream_t(p.szPath.c_str(),std::ios::binary|std::ios::out|std::ios::in);
		SysLog(__FUNCTION__,"Path %s; Files %d",p.szPath.c_str(),m_Files.size());

		// we need to store the current position
		long iPos=0;

		// start at the top and write the header
		p.pHandle->write( reinterpret_cast<char*> (&p.pHeader), sizeof(p.pHeader) );

		// write the offset
		p.pHandle->write( 0, sizeof(byte_t)*ARCHIVE_FILE_OFFSET );
		iPos = p.pHandle->tellp();
		if(m_Files.size() > 0) {
			m_iNumFiles = static_cast<unsigned int> (m_Files.size());
			// run through and determine if who's going to need to be rewritten and realign the data
			for(uint i=0; i < m_iNumFiles; i++) {
				// we need to check to make sure that we've been touched first
				// also need to make sure that there's something in the buffer to go by
				if( m_Files->GetTouched() && (m_Files->GetSizeofBuffer() > 0)) {
					if( m_Files->GetPosition() > 0) {
						// Offset = File Position + ( Sizeof[Buffer] - Original Size )
						long iOffset = m_Files->GetPosition() + 
							(m_Files->GetSizeofBuffer() - m_Files->GetSize());

						// since everything is in proper order; we only need to poll the files under this one
						for(uint j = i; j < m_iNumFiles; j++) {
							Archive_FileTable_T* h = m_Files[j]->GetFormatted();
							byte_t* buffer=m_Files[j]->GetBuffer();

							if(buffer[0] == '\0') {
								// go to the position of the current header location and read in
								p.pHandle->read( reinterpret_cast<char*> (&buffer), sizeof(h->iSize) );
							// setup the position with the offset
							h->iPosition = iOffset;
							p.pHandle->write( reinterpret_cast<char*> (&buffer), sizeof(buffer) );

							iOffset += h->iSize;
							// update the file table; free the buffer; move on
							m_Files[j]->Close(); // if this needed to be written; free write!
							delete h; h=NULL;
					// we need to start writing data now!
					p.pHandle->seekp( iPos, std::ios::beg );
					long iSizeOfBuffer = sizeof(m_Files->GetSizeofBuffer());
					p.pHandle->write( reinterpret_cast<char*> (m_Files->GetBuffer()), iSizeOfBuffer);
					iPos = p.pHandle->tellp();
			// write a byte offset between the file data and file table
			p.pHandle->seekp( iPos, std::ios_base::beg );
			p.pHandle->write( 0, sizeof(byte_t)*ARCHIVE_FILE_OFFSET );
			iPos = p.pHandle->tellp();

			// go to the header's start position and run amuck!
			p.pHandle->seekp( iPos, std::ios_base::beg );
			for(uint j=0; j < m_iNumFiles; j++) {
				Archive_FileTable_T* h=m_Files[j]->GetFormatted();
				p.pHandle->write( reinterpret_cast<char*> (&h), sizeof(h) );
		// close up shop; we're done!
		return true;
	// nothing changed; nothing saved
	return true;

void CFileArchive::AddFile(string_t szFilepath) {
	// check to make sure we have a path to work with
	if(szFilepath[0] == '\0') {
		SysBug(__FUNCTION__,"File path is NULL; cannot add file to archive %s",m_szPath.c_str());
	// we need to open up a stream to grab the buffer
	fstream_t stream; stream.open(szFilepath.c_str(),std::ios::binary|std::ios::in);
	unsigned long size;
	// lip smacking good!
	// reposition for reading
	byte_t* buffer = new byte_t[size];	// allocate proper amount of memory
	stream.read( reinterpret_cast<char*> (buffer), size);

	stream.write( reinterpret_cast<char*> (buffer), size);

	// let's create the file table entry for this item!
	Archive_FileTable_T h;
	h.iFlags			= 0;
	h.iPosition			= 0;
	h.iSize				= size;
	h.szPath			= szFilepath;
	h.szHash			= MD5String((char*)buffer); // grab the hash data

	SysLog(__FUNCTION__,"Hash %s; Path %s; Size %d",h.szHash,h.szPath.c_str(),size);

	// throw onto the table
	m_Files.push_back( new CFile( h, buffer ) );
typedef CFile*			ffile_t;
class CFileArray : public array_t<ffile_t> {
		~CFileArray(void) {
			for(iterator p=begin(); p != end(); p++)
				delete *p;

		inline void Sort(void) {
			std::sort(begin(),end(), Sort_By_Position() );
		struct Sort_By_Position {
			bool operator() (ffile_t& start,ffile_t& end) {
				return (start->GetPosition() < end->GetPosition());
Now let me explain some of this; "Touched" means that the file has been opened or added to the archive since the last save; when a file is added (or opened) the archive is also flagged as being "touched." "Position" is the position (bytes) where it should be located in a file; a new file added has a position of 0 (not yet written). This is what my logger brings up:
CFileArchive::AddFile  	02-12-2005 12:05 PM   Hash a681c6a002989832645ed26b766c7afa; Path k8v_audio.zip; Size 24184662
CFileArchive::Save   	02-12-2005 12:05 PM   Path test.eaf; Files 1
commandInterpret   	02-12-2005 12:05 PM    eafpack -p test.eaf k8v_audio.zip

Share this post

Link to post
Share on other sites
Anyone have some insight? I've got a paper to write for Monday so I'm not sure how much I'll get to look at it for the rest of the weekend. Hopefully I'll take a stab at it tomorrow night; but some guidance would definately be appreciated. I know it's a lot of code to sift through (messy in some places too!) if you have any suggestions please feel free to shoot away. You only get better at something by having someone else critque your work.

Thanks guys!

Share this post

Link to post
Share on other sites
I'm going to take a look at it tonight after I get home; if anyone has any comments please leave them.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!