Problem writing to File

Started by
1 comment, last by bkt 19 years, 2 months ago
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) {
	m_Files.Sort();
	if(m_bTouched) {
		// check this now!!
		if(p.pHandle==NULL)
			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->seekp(0,std::ios::beg);
		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->seekg(h->iPosition,std::ios_base::beg);
								p.pHandle->read( reinterpret_cast<char*> (&buffer), sizeof(h->iSize) );
							}
				
							// setup the position with the offset
							h->iPosition = iOffset;
							p.pHandle->seekp(h->iPosition,std::ios_base::beg);
							p.pHandle->write( reinterpret_cast<char*> (&buffer), sizeof(buffer) );

							iOffset += h->iSize;
							// update the file table; free the buffer; move on
							m_Files[j]->Update(*h);
							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!
		p.pHandle->close();
		p.pHandle->clear();
		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());
		return;
	}
	
	// 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!
	stream.seekg(0,std::ios::end);
	size=stream.tellg();
	
	// reposition for reading
	stream.seekg(0,std::ios::beg);
	byte_t* buffer = new byte_t[size];	// allocate proper amount of memory
	stream.read( reinterpret_cast<char*> (buffer), size);
	stream.close();

	stream.open("blah.zip",std::ios::binary|std::ios::out);
	stream.seekp(0,std::ios::beg);
	stream.write( reinterpret_cast<char*> (buffer), size);
	stream.close();

	// 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_bTouched=true;
	m_Files.push_back( new CFile( h, buffer ) );
	return;
}
Header

typedef CFile*			ffile_t;
class CFileArray : public array_t<ffile_t> {
	public:
		~CFileArray(void) {
			for(iterator p=begin(); p != end(); p++)
				delete *p;
		}

		inline void Sort(void) {
			std::sort(begin(),end(), Sort_By_Position() );
		}
	private:
		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
-John "bKT" Bellone [homepage] [[email=j.bellone@flipsidesoftware.com]email[/email]]
Advertisement
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!
-John "bKT" Bellone [homepage] [[email=j.bellone@flipsidesoftware.com]email[/email]]
I'm going to take a look at it tonight after I get home; if anyone has any comments please leave them.
-John "bKT" Bellone [homepage] [[email=j.bellone@flipsidesoftware.com]email[/email]]

This topic is closed to new replies.

Advertisement