00001 /* 00002 * PROPRIETARY INFORMATION. This software is proprietary to 00003 * Side Effects Software Inc., and is not to be reproduced, 00004 * transmitted, or disclosed in any way without written permission. 00005 * 00006 * Produced by: 00007 * Mark Elendt 00008 * Side Effects 00009 * 477 Richmond Street West 00010 * Toronto, Ontario 00011 * Canada M5V 3E7 00012 * 416-504-9876 00013 * 00014 * NAME: UT library (C++) 00015 * 00016 * COMMENTS: CPIO packetting for I/O 00017 * 00018 * USAGE: 00019 * To read from a CPIO archive: 00020 * 00021 * Memory intensive but safe methods 00022 * 00023 * myclass::readObject(istream &filestream, int binary) 00024 * { 00025 * UT_CPIO packet; 00026 * UT_WorkBuffer type; 00027 * istream *is; 00028 * 00029 * if (packet.open(filestream, type) == UT_CPIO_OK) 00030 * { 00031 * obj = myclass->addObject(type.buffer()); 00032 * is = packet.read(); // Read in the contents 00033 * obj->readData(*is, binary); 00034 * packet.close(filestream); // Correct position 00035 * } 00036 * else flagError(); 00037 * } 00038 * 00039 * myclass::writeObject(object *obj, ostream &filestream, int binary) 00040 * { 00041 * UT_CPIO packet; 00042 * ostream *os; 00043 * 00044 * if (os = packet.open()) // Open a CPIO packet for writing 00045 * { 00046 * obj->saveData(*os, binary); 00047 * // Now, flush the contents 00048 * if (packet.close(filestream, obj->getType()) != UT_CPIO_OK) 00049 * flagError(); 00050 * // If we're at the end, flag the EOF 00051 * if (lastObject) 00052 * packet.writeTrailer(filestream); 00053 * } 00054 * } 00055 * 00056 * Raw methods (not using the memory intensive mechanisms) 00057 * 00058 * myclass::readCommands(istream &filestream) 00059 * { 00060 * UT_CPIO packet; 00061 * UT_WorkBuffer pathname; 00062 * char buffer[SIZE]; 00063 * 00064 * if (packet.open(filestream, pathname) == UT_CPIO_OK) 00065 * { 00066 * if (pathname == "commands") // Read commands 00067 * { 00068 * long fileSize = packet.getFileSize(); 00069 * 00070 * while (fileSize > 0) 00071 * { 00072 * filestream.getline(buffer, SIZE); 00073 * fileSize -= strlen(buffer); 00074 * execute(buffer); 00075 * } 00076 * // Now, correct my position in case of overrun 00077 * packet.close(filestream); 00078 * } 00079 * } 00080 * } 00081 * 00082 * myclass::writeStuff(ostream &filestream) 00083 * { 00084 * UT_CPIO packet; 00085 * 00086 * if (packet.open(filestream, "commands") == UT_CPIO_OK) 00087 * { 00088 * for (i = 0; i < ncommands; i++) 00089 * os << command[i] << endl; 00090 * packet.close(filestream); 00091 * } 00092 * if (last) packet.writeTrailer(filestream); 00093 * } 00094 * 00095 */ 00096 00097 #ifndef __UT_CPIO_h__ 00098 #define __UT_CPIO_h__ 00099 00100 #include "UT_API.h" 00101 #include "UT_String.h" 00102 #include "UT_WorkBuffer.h" 00103 #include "UT_NTStreamUtil.h" 00104 00105 class UT_IStream; 00106 00107 enum { 00108 UT_CPIO_OK, 00109 UT_CPIO_EOF_OK, // End of file reached 00110 UT_CPIO_BINARY, // Binary CPIO format not supported yet 00111 UT_CPIO_BAD_EOF, // Unexpected EOF 00112 UT_CPIO_BAD_HEADER, // Bad header 00113 UT_CPIO_BAD_CONTENTS, // Bad contents in CPIO packet 00114 UT_CPIO_BAD_STREAM, // Bad stream (i.e. bad calling sequence) 00115 UT_CPIO_USER_ABORT // User cancelled reading the stream 00116 }; 00117 00118 class UT_API UT_CPIO { 00119 public: 00120 UT_CPIO(); 00121 virtual ~UT_CPIO(); 00122 00123 // This open will read a CPIO header from the stream. 00124 virtual int open(UT_IStream &is, UT_WorkBuffer &pathname); 00125 int open(UT_IStream &is, UT_String &pathname) 00126 { 00127 UT_WorkBuffer pathname_buffer; 00128 pathname_buffer.append(pathname); 00129 int result = open(is, pathname_buffer); 00130 pathname_buffer.copyIntoString(pathname); 00131 return result; 00132 } 00133 00134 // This opens after we have verified it is a true CPIO file. 00135 virtual int openPostCheck(UT_IStream &is, UT_WorkBuffer &pathname); 00136 int openPostCheck(UT_IStream &is, UT_String &pathname) 00137 { 00138 UT_WorkBuffer pathname_buffer; 00139 pathname_buffer.append(pathname); 00140 int result = openPostCheck(is, pathname_buffer); 00141 pathname_buffer.copyIntoString(pathname); 00142 return result; 00143 } 00144 00145 // A safe (but memory intensive) mechanism for reading from the file 00146 virtual UT_IStream *read(UT_IStream &is); 00147 00148 // Method to skip over the packet that's currently open 00149 virtual int skip(UT_IStream &is); 00150 00151 // After reading or skipping, closing will move the stream pointer 00152 // to the correct position. This is not a manditory method. In fact, 00153 // read packets should not be closed if the stream is cin. 00154 virtual int close(UT_IStream &is); 00155 00156 // Memory intensive method to write a packet, but it works if you're 00157 // sending data to cout or cerr streams 00158 virtual ostream *open(); 00159 virtual int close(ostream &os, const char *path, int bin=0); 00160 00161 // Non-memory intensive method to write a packet, it does not work when 00162 // writing to cout or cerr streams 00163 virtual int open(ostream &os, const char *path, int bin=0); 00164 virtual int close(ostream &os); 00165 00166 // When all packets have been written, please write a trailer 00167 virtual int writeTrailer(ostream &os); 00168 00169 long getFileSize() const { return myFileSize; } 00170 long getModTime() const { return myModTime; } 00171 00172 protected: 00173 UT_WorkBuffer myCurrentFile; 00174 UT_IStream *myIs; 00175 UT_OStrStream *myos; 00176 char *myData; // Data for the packet 00177 long myModTime; 00178 long myFileSize; // For non-memory intensive read 00179 long myHeaderStart; // For non-memory intensive write 00180 long myHeaderEnd; // End of header 00181 int myPacketTainted; // Is this packet being read tainted? 00182 }; 00183 00184 #endif
1.5.9