Sign in to follow this  

Problem writing to File

This topic is 4690 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) {
	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[i]->GetTouched() && (m_Files[i]->GetSizeofBuffer() > 0)) {
					if( m_Files[i]->GetPosition() > 0) {
						// Offset = File Position + ( Sizeof[Buffer] - Original Size )
						long iOffset = m_Files[i]->GetPosition() + 
							(m_Files[i]->GetSizeofBuffer() - m_Files[i]->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[i]->GetSizeofBuffer());
					p.pHandle->write( reinterpret_cast<char*> (m_Files[i]->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

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

This topic is 4690 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this