00001 // directory.cc 00002 // Routines to manage a directory of file names. 00003 // 00004 // The directory is a table of fixed length entries; each 00005 // entry represents a single file, and contains the file name, 00006 // and the location of the file header on disk. The fixed size 00007 // of each directory entry means that we have the restriction 00008 // of a fixed maximum size for file names. 00009 // 00010 // The constructor initializes an empty directory of a certain size; 00011 // we use ReadFrom/WriteBack to fetch the contents of the directory 00012 // from disk, and to write back any modifications back to disk. 00013 // 00014 // Also, this implementation has the restriction that the size 00015 // of the directory cannot expand. In other words, once all the 00016 // entries in the directory are used, no more files can be created. 00017 // Fixing this is one of the parts to the assignment. 00018 // 00019 // Copyright (c) 1992-1993 The Regents of the University of California. 00020 // All rights reserved. See copyright.h for copyright notice and limitation 00021 // of liability and disclaimer of warranty provisions. 00022 00023 #include "copyright.h" 00024 #include "utility.h" 00025 #include "filehdr.h" 00026 #include "directory.h" 00027 00028 //---------------------------------------------------------------------- 00029 // Directory::Directory 00030 // Initialize a directory; initially, the directory is completely 00031 // empty. If the disk is being formatted, an empty directory 00032 // is all we need, but otherwise, we need to call FetchFrom in order 00033 // to initialize it from disk. 00034 // 00035 // "size" is the number of entries in the directory 00036 //---------------------------------------------------------------------- 00037 00038 Directory::Directory(int size) 00039 { 00040 table = new DirectoryEntry[size]; 00041 tableSize = size; 00042 for (int i = 0; i < tableSize; i++) 00043 table[i].inUse = FALSE; 00044 } 00045 00046 //---------------------------------------------------------------------- 00047 // Directory::~Directory 00048 // De-allocate directory data structure. 00049 //---------------------------------------------------------------------- 00050 00051 Directory::~Directory() 00052 { 00053 delete [] table; 00054 } 00055 00056 //---------------------------------------------------------------------- 00057 // Directory::FetchFrom 00058 // Read the contents of the directory from disk. 00059 // 00060 // "file" -- file containing the directory contents 00061 //---------------------------------------------------------------------- 00062 00063 void 00064 Directory::FetchFrom(OpenFile *file) 00065 { 00066 (void) file->ReadAt((char *)table, tableSize * sizeof(DirectoryEntry), 0); 00067 } 00068 00069 //---------------------------------------------------------------------- 00070 // Directory::WriteBack 00071 // Write any modifications to the directory back to disk 00072 // 00073 // "file" -- file to contain the new directory contents 00074 //---------------------------------------------------------------------- 00075 00076 void 00077 Directory::WriteBack(OpenFile *file) 00078 { 00079 (void) file->WriteAt((char *)table, tableSize * sizeof(DirectoryEntry), 0); 00080 } 00081 00082 //---------------------------------------------------------------------- 00083 // Directory::FindIndex 00084 // Look up file name in directory, and return its location in the table of 00085 // directory entries. Return -1 if the name isn't in the directory. 00086 // 00087 // "name" -- the file name to look up 00088 //---------------------------------------------------------------------- 00089 00090 int 00091 Directory::FindIndex(char *name) 00092 { 00093 for (int i = 0; i < tableSize; i++) 00094 if (table[i].inUse && !strncmp(table[i].name, name, FileNameMaxLen)) 00095 return i; 00096 return -1; // name not in directory 00097 } 00098 00099 //---------------------------------------------------------------------- 00100 // Directory::Find 00101 // Look up file name in directory, and return the disk sector number 00102 // where the file's header is stored. Return -1 if the name isn't 00103 // in the directory. 00104 // 00105 // "name" -- the file name to look up 00106 //---------------------------------------------------------------------- 00107 00108 int 00109 Directory::Find(char *name) 00110 { 00111 int i = FindIndex(name); 00112 00113 if (i != -1) 00114 return table[i].sector; 00115 return -1; 00116 } 00117 00118 //---------------------------------------------------------------------- 00119 // Directory::Add 00120 // Add a file into the directory. Return TRUE if successful; 00121 // return FALSE if the file name is already in the directory, or if 00122 // the directory is completely full, and has no more space for 00123 // additional file names. 00124 // 00125 // "name" -- the name of the file being added 00126 // "newSector" -- the disk sector containing the added file's header 00127 //---------------------------------------------------------------------- 00128 00129 bool 00130 Directory::Add(char *name, int newSector) 00131 { 00132 if (FindIndex(name) != -1) 00133 return FALSE; 00134 00135 for (int i = 0; i < tableSize; i++) 00136 if (!table[i].inUse) { 00137 table[i].inUse = TRUE; 00138 strncpy(table[i].name, name, FileNameMaxLen); 00139 table[i].sector = newSector; 00140 return TRUE; 00141 } 00142 return FALSE; // no space. Fix when we have extensible files. 00143 } 00144 00145 //---------------------------------------------------------------------- 00146 // Directory::Remove 00147 // Remove a file name from the directory. Return TRUE if successful; 00148 // return FALSE if the file isn't in the directory. 00149 // 00150 // "name" -- the file name to be removed 00151 //---------------------------------------------------------------------- 00152 00153 bool 00154 Directory::Remove(char *name) 00155 { 00156 int i = FindIndex(name); 00157 00158 if (i == -1) 00159 return FALSE; // name not in directory 00160 table[i].inUse = FALSE; 00161 return TRUE; 00162 } 00163 00164 //---------------------------------------------------------------------- 00165 // Directory::List 00166 // List all the file names in the directory. 00167 //---------------------------------------------------------------------- 00168 00169 void 00170 Directory::List() 00171 { 00172 for (int i = 0; i < tableSize; i++) 00173 if (table[i].inUse) 00174 printf("%s\n", table[i].name); 00175 } 00176 00177 //---------------------------------------------------------------------- 00178 // Directory::Print 00179 // List all the file names in the directory, their FileHeader locations, 00180 // and the contents of each file. For debugging. 00181 //---------------------------------------------------------------------- 00182 00183 void 00184 Directory::Print() 00185 { 00186 FileHeader *hdr = new FileHeader; 00187 00188 printf("Directory contents:\n"); 00189 for (int i = 0; i < tableSize; i++) 00190 if (table[i].inUse) { 00191 printf("Name: %s, Sector: %d\n", table[i].name, table[i].sector); 00192 hdr->FetchFrom(table[i].sector); 00193 hdr->Print(); 00194 } 00195 printf("\n"); 00196 delete hdr; 00197 }
1.2.14 written by Dimitri van Heesch,
© 1997-2002