home *** CD-ROM | disk | FTP | other *** search
- // ----------- node.c++
-
- // =======================================
- // Parody file Node class member functions
- // =======================================
-
- #include <unistd.h>
- #include <stdio.h>
-
- #include "parody.h"
-
- // -------- construct a file header
- FileHeader::FileHeader(pString filename)
- {
- deletednode = highestnode = 0;
- newfile = (pBool) (access(filename, 0) != 0);
- // ----- open the file
- nfile.open(filename, ios::in | ios::out);
- if (!newfile) {
- // ------- read the header
- nfile.read((char *)&highestnode, sizeof highestnode);
- nfile.read((char *)&deletednode, sizeof deletednode);
- nfile.seekp(nfile.tellg());
- }
- else {
- // ------- write the header
- nfile.write((char *)&highestnode, sizeof highestnode);
- nfile.write((char *)&deletednode, sizeof deletednode);
- nfile.seekg(nfile.tellp());
- }
- origdeletednode = deletednode;
- orighighestnode = highestnode;
- }
-
- FileHeader::~FileHeader()
- {
- if (deletednode != origdeletednode ||
- highestnode != orighighestnode) {
- // ---- the file header has changed
- nfile.seekp(0);
- nfile.write((char *)&highestnode, sizeof highestnode);
- nfile.write((char *)&deletednode, sizeof deletednode);
- }
- nfile.close();
- }
-
- void
- FileHeader::Flush()
- {
- if (deletednode != origdeletednode ||
- highestnode != orighighestnode) {
- // ---- the file header has changed
- nfile.seekp(0);
- nfile.write((char *)&highestnode, sizeof highestnode);
- nfile.write((char *)&deletednode, sizeof deletednode);
- }
- nfile.flush();
- }
-
- // ------- appropriate a new node
- NodeNbr FileHeader::NewNode()
- {
- NodeNbr newnode;
- if (deletednode) {
- newnode = deletednode;
- Node node(this, newnode);
- deletednode = node.NextNode();
- node.SetNextNode(0);
- }
- else
- newnode = ++highestnode;
- return newnode;
- }
-
- // ----------- construct a new node
- Node::Node(FileHeader *hd, NodeNbr node)
- {
- nextnode = 0;
- nodechanged = deletenode = pFalse;
- nodenbr = node;
- owner = hd;
- if (nodenbr) {
- fstream& nf = owner->Nfile();
-
- long nad = NodeAddress();
- nf.seekg(nad);
- // ------- read the header
- nf.read((char *) &nextnode, sizeof nextnode);
- nf.seekp(nf.tellg());
-
- if (nf.eof() || nf.fail()) {
- nf.clear();
- // ----- appending a new node
- nf.seekp(nad);
- nf.write((char *) &nextnode, sizeof nextnode);
- nf.seekg(nf.tellp());
- }
- }
- }
-
- // ------- assignment operator
- Node& Node::operator=(Node &node)
- {
- nextnode = node.nextnode;
- owner = node.owner;
- nodenbr = node.nodenbr;
- nodechanged = node.nodechanged;
- deletenode = node.deletenode;
- return *this;
- }
-
- // ------- destroy the node
- Node::~Node()
- {
- if (owner && nodenbr && (nodechanged || deletenode)) {
- fstream& nf = owner->Nfile();
- if (deletenode) {
- nextnode = owner->DeletedNode();
- owner->SetDeletedNode(nodenbr);
- }
- nf.seekp(NodeAddress());
- // ------- write the header
- nf.write((char *) &nextnode, sizeof nextnode);
- if (deletenode) {
- // ------ zero fill the deleted node
- char fill[nodedatalength];
- memset(fill, 0, nodedatalength);
- nf.write(fill, nodedatalength);
- }
- nf.sync();
- }
- }
-
- // ---------- compute the disk address of a node
- long Node::NodeAddress()
- {
- long adr = nodenbr-1;
- adr *= nodelength;
- adr += fileheadersize;
- return adr;
- }
-