how to set this up in C++?

Programming, for all ages and all languages.
Post Reply
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

how to set this up in C++?

Post by earlz »

I am trying to make a simple disk image handling library..
basically what it will do is allow you to open up a file and use it as a disk image. Then you can read and write sectors and such to it..good for making prototype filesystem stuff..

I am having a problem determining how the constructor should be set up..
if I have something like "Disk(unsigned int size,string& filename)" then what do I do if filename doesn't exist? or if I can't create it?
but if I wait until a "open_disk(string& filename)" then it's not initialized until you call that...

what should I do!?
also, anyone see anything wrong with this basic class I made?

Code: Select all

class Disk{
	disk_geometry dg;
	public:
	//constructors..
	virtual ~Disk();
	Disk(disk_geometry *geo,string& filename);
	Disk(unsigned int c,unsigned int h,unsigned int s,const string& filename);
	Disk(const Disk& source);
	//Interface:
	virtual unsigned long long DiskSize(){
		return dg.bps*dg.spt*dg.cph*dg.hpd;
	}
	virtual char *ReadSector(unsigned int abs_sector); //?




};

pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Have a constructor with just the filename, with a 'has_init' boolean variable somewhere. Once a usable environment has been created, you can set has_init to true.

Other functions will check has_init before they attempt to do anything.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

hmm...one idea would be to use a stream handle(or whatever..I'm not familiar with most of the C++ IO)
that way your sure it is open...hmm...

I think that idea of yours is best guess though...
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Well if you use ifstream to read in the data, then you can use its fail() function to find out if it's good or not...

I'd suggest learning how to do C++ streaming i/o.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: how to set this up in C++?

Post by Candy »

hckr83 wrote:if I have something like "Disk(unsigned int size,string& filename)" then what do I do if filename doesn't exist? or if I can't create it?
throw cannot_create_file_exception();
but if I wait until a "open_disk(string& filename)" then it's not initialized until you call that...
_state = Error;
what should I do!?
Make a design choice - do you want the C++ method, the C method or the state method?

C method:

Code: Select all

makeDisk() {
    <do disk creation things>
   if (disk.state == Error) {
      <do disk deletion things>
      return 0;
   }
   return disk;
}
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

state=error?
do you mean have this like a public variable?

I don't really want to mess with exceptions right now..I just got through the first volume...tried skimming the second volume and it looks a bit overwhelming..

I don't really want to do it that C way...
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

hckr83 wrote:I don't really want to mess with exceptions right now..I just got through the first volume...tried skimming the second volume and it looks a bit overwhelming..

I don't really want to do it that C way...
It's difficult to do something without knowing how to do it. Just read...

By the by, what book are you reading?
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post by Kevin McGuire »

Code: Select all

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>


struct sVirtualDiskHeader
{
	uint32_t BytesPerSector;
	uint32_t SectorsPerTrack;
	uint32_t TracksPerHead;
	uint32_t Heads;
	uint32_t OtherInformation;
};
class cVirtualDiskFile
{
	private:
	sVirtualDiskHeader vdh;			/// virtual disk header.
	bool diskStateUsing;				/// was this object created from a disk file?
	char *diskStateFile;
	void *data;
	uint32_t dataSize;
	public:
	cVirtualDiskFile(char *file);
	~cVirtualDiskFile();

	bool SaveStateToDisk();
};

cVirtualDiskFile::cVirtualDiskFile(char *file)
{
	int fdescriptor;
	struct stat fdstat;
	/// copy file path from potential temporary location to a managed location by us.
	diskStateFile = (char*)malloc(strlen(file));
	strcpy(diskStateFile, file);
	fdescriptor = open(diskStateFile, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP);
	if(!fdescriptor)
	{
		diskStateUsing = false;
		return;
	}
	fstat(fdescriptor, &fdstat);
	if(read(fdescriptor, &vdh, sizeof(sVirtualDiskHeader)) < sizeof(sVirtualDiskHeader))
	{
		/// empty or corrupted file, just consider this a new image and error on save.
		memset(&vdh, 0, sizeof(sVirtualDiskHeader));
		close(fdescriptor);
		diskStateUsing = false;
		return;
	}
	/// could store the data size in the header..
	data = malloc(fdstat.st_size - sizeof(sVirtualDiskHeader));
	dataSize = fdstat.st_size - sizeof(sVirtualDiskHeader);
	read(fdescriptor, data, fdstat.st_size - sizeof(sVirtualDiskHeader));
	close(fdescriptor);
	diskStateUsing = true;
	return;
}

cVirtualDiskFile::~cVirtualDiskFile()
{
	/// we implied that we are using a disk file so I figure it is implied that we sync our
	/// memory state with the disk file state before deconstruction.
	if(diskStateUsing)
	{
		SaveStateToDisk();
	}
	free(data);
	if(diskStateFile)
	{
		free(diskStateFile);
	}
}

bool cVirtualDiskFile::SaveStateToDisk()
{
	int fdescriptor;
	fdescriptor = open(diskStateFile, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRGRP);
	if(!fdescriptor)
	{
		return false;
	}
	write(fdescriptor, &vdh, sizeof(sVirtualDiskHeader));
	write(fdescriptor, data, dataSize);
	close(fdescriptor);
	return true;
}

int main(int argc, char *argv[])
{
	cVirtualDiskFile vdf("test.data");
	return 0;
}
It constructs a object by opening a file and pulling that file state into memory. If a failure happens then it just considers that it is not using a disk state. You could have a method that checks a result code for the object to determine if something went wrong or just the application's implementation code will notice that some fields in the header are zero when it is supposed to be opening a existing disk image.

When you deconstruct the object it will write the data back to the disk file unless a failure happened in which it will assume to be in memory-only mode. You can also force a sync with the disk file by calling cVirtualDiskFile::SaveStateToDisk().
Post Reply