|
Isis 3.0 Object Programmers' Reference |
Home |
00001 00024 #include <fstream> 00025 #include <sstream> 00026 #include <cstring> 00027 #include "Blob.h" 00028 #include "Pvl.h" 00029 #include "Filename.h" 00030 #include "iException.h" 00031 #include "iException.h" 00032 #include "iException.h" 00033 #include "Message.h" 00034 00035 using namespace std; 00036 namespace Isis { 00043 Blob::Blob (const std::string &name, const std::string &type) { 00044 p_blobName = name; 00045 p_buffer = NULL; 00046 p_labelFile = ""; 00047 p_nbytes = 0; 00048 p_type = type; 00049 00050 p_blobPvl.SetName(p_type); 00051 p_blobPvl += Isis::PvlKeyword("Name",p_blobName); 00052 p_blobPvl += Isis::PvlKeyword("StartByte",0); 00053 p_blobPvl += Isis::PvlKeyword("Bytes",0); 00054 } 00055 00064 Blob::Blob (const std::string &name, const std::string &type, const std::string &file) { 00065 p_blobName = name; 00066 p_buffer = NULL; 00067 p_nbytes = 0; 00068 p_type = type; 00069 p_labelFile = Filename(file).Expanded(); 00070 00071 Read(file); 00072 } 00073 00079 Blob::Blob (const Blob& other) { 00080 p_blobPvl = other.p_blobPvl; 00081 p_blobName = other.p_blobName; 00082 p_startByte = other.p_startByte; 00083 p_nbytes = other.p_nbytes; 00084 p_type = other.p_type; 00085 p_detached = other.p_detached; 00086 p_labelFile = other.p_labelFile; 00087 00088 p_buffer = NULL; 00089 00090 if(other.p_buffer) { 00091 p_buffer = new char[p_nbytes]; 00092 00093 for(int i = 0; i < p_nbytes; i++) { 00094 p_buffer[i] = other.p_buffer[i]; 00095 } 00096 } 00097 } 00098 00100 Blob::~Blob() { 00101 if (p_buffer != NULL) delete [] p_buffer; 00102 } 00103 00111 Blob &Blob::operator=(const Blob &other) { 00112 p_blobPvl = other.p_blobPvl; 00113 p_blobName = other.p_blobName; 00114 p_startByte = other.p_startByte; 00115 p_nbytes = other.p_nbytes; 00116 p_type = other.p_type; 00117 p_detached = other.p_detached; 00118 p_labelFile = other.p_labelFile; 00119 00120 p_buffer = NULL; 00121 00122 if(other.p_buffer) { 00123 p_buffer = new char[p_nbytes]; 00124 00125 for(int i = 0; i < p_nbytes; i++) { 00126 p_buffer[i] = other.p_buffer[i]; 00127 } 00128 } 00129 00130 return *this; 00131 } 00132 00141 void Blob::Read (const std::string &file) { 00142 // Expand the filename 00143 string temp(Filename(file).Expanded()); 00144 00145 // Open the file 00146 fstream istm; 00147 istm.open(temp.c_str(),std::ios::in); 00148 if (!istm) { 00149 string message = Isis::Message::FileOpen(temp); 00150 throw Isis::iException::Message(Isis::iException::Io,message,_FILEINFO_); 00151 } 00152 00153 // Get the pvl 00154 try { 00155 Isis::Pvl pvl; 00156 try { 00157 istm >> pvl; 00158 } 00159 catch (Isis::iException &e) { 00160 istm.close(); 00161 string msg = "Invalid " + p_type + " label format"; 00162 throw Isis::iException::Message(Isis::iException::Pvl,msg,_FILEINFO_); 00163 } 00164 00165 // Check pvl and read from the stream 00166 Read(pvl,istm); 00167 } 00168 catch (Isis::iException &e) { 00169 istm.close(); 00170 string msg = "Unable to open " + p_type + " [" + p_blobName + 00171 "] in file [" + temp + "]"; 00172 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00173 } 00174 00175 istm.close(); 00176 } 00177 00178 // Read blob from an open file (probably a cube) 00179 void Blob::Read (Isis::Pvl &pvl, std::fstream &istm) { 00180 try { 00181 Find(pvl); 00182 ReadInit(); 00183 if (p_detached != "") { 00184 fstream dstm; 00185 dstm.open(p_detached.c_str(),std::ios::in); 00186 if (!dstm) { 00187 string message = Isis::Message::FileOpen(p_detached); 00188 throw Isis::iException::Message(Isis::iException::Io,message,_FILEINFO_); 00189 } 00190 ReadData(dstm); 00191 } 00192 else { 00193 ReadData(istm); 00194 } 00195 } 00196 catch (Isis::iException &e) { 00197 string msg = "Unable to read " + p_type + " [" + p_blobName + "]"; 00198 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00199 } 00200 } 00201 00202 // Search PVL for the desire blob 00203 void Blob::Find (Isis::Pvl &pvl) { 00204 bool found = false; 00205 try { 00206 // Search for the blob name 00207 Isis::iString blobName = p_blobName; 00208 blobName.UpCase(); 00209 for (int o=0; o<pvl.Objects(); o++) { 00210 Isis::PvlObject &obj = pvl.Object(o); 00211 if (obj.IsNamed(p_type)) { 00212 Isis::iString curName = (string) obj["Name"]; 00213 curName.UpCase(); 00214 if (blobName == curName) { 00215 p_blobPvl = obj; 00216 found = true; 00217 break; 00218 } 00219 else { 00220 if (p_type == "OriginalLabel" && curName == "ORIGINALLABEL") { 00221 p_blobPvl = obj; 00222 found = true; 00223 break; 00224 } 00225 } 00226 } 00227 } 00228 } 00229 catch (Isis::iException &e) { 00230 string msg = "Invalid " + p_type + " label format"; 00231 throw Isis::iException::Message(Isis::iException::Pvl,msg,_FILEINFO_); 00232 } 00233 00234 // Did we find it? 00235 if (!found) { 00236 string msg = "Unable to find " + p_type + " [" + p_blobName + "]"; 00237 throw Isis::iException::Message(Isis::iException::Programmer,msg,_FILEINFO_); 00238 } 00239 00240 // Ok the blob exists so we need to prep for reading the binary data 00241 try { 00242 p_startByte = p_blobPvl["StartByte"]; 00243 p_nbytes = p_blobPvl["Bytes"]; 00244 p_detached = ""; 00245 if (p_blobPvl.HasKeyword("^"+p_type)) { 00246 string path = ""; 00247 if (p_labelFile != "") { 00248 path = Filename(p_labelFile).Path() + "/"; 00249 } 00250 p_detached = path + (std::string) p_blobPvl["^"+p_type]; 00251 p_blobPvl.DeleteKeyword("^"+p_type); 00252 } 00253 } 00254 catch (Isis::iException &e) { 00255 string msg = "Invalid " + p_type + " label format"; 00256 throw Isis::iException::Message(Isis::iException::Pvl,msg,_FILEINFO_); 00257 } 00258 } 00259 00267 void Blob::ReadData (std::fstream &stream) { 00268 // Read the binary data 00269 if (p_buffer != NULL) delete [] p_buffer; 00270 p_buffer = new char[p_nbytes]; 00271 00272 streampos sbyte = p_startByte - 1; 00273 stream.seekg(sbyte,std::ios::beg); 00274 if (!stream.good()) { 00275 string msg = "Error preparing to read data from " + p_type + 00276 " [" + p_blobName + "]"; 00277 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00278 } 00279 00280 stream.read(p_buffer,p_nbytes); 00281 if (!stream.good()) { 00282 string msg = "Error reading data from " + p_type + " [" + p_blobName + "]"; 00283 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00284 } 00285 } 00286 00296 void Blob::Write(const std::string &file) { 00297 // Determine the size of the label and write it out 00298 try { 00299 WriteInit(); 00300 Isis::Pvl pvl; 00301 pvl.AddObject(p_blobPvl); 00302 ostringstream os; 00303 os << pvl << endl; 00304 os.seekp(0,std::ios::end); 00305 Isis::BigInt nbytes = (Isis::BigInt) os.tellp() + (Isis::BigInt) 64; 00306 p_startByte = nbytes + 1 + 1; // 1-based; 00307 pvl.FindObject(p_type)["StartByte"] = p_startByte; 00308 pvl.FindObject(p_type)["Bytes"] = p_nbytes; 00309 pvl.Write(file); 00310 00311 // Prepare and write the binary data 00312 fstream stream; 00313 ios::openmode flags = std::ios::in | std::ios::binary | std::ios::out; 00314 stream.open(file.c_str(),flags); 00315 if (!stream) { 00316 string message = "Unable to open [" + file + "]"; 00317 throw Isis::iException::Message(Isis::iException::Io,message,_FILEINFO_); 00318 } 00319 00320 streampos sbyte = p_startByte - 1; 00321 stream.seekp(sbyte,std::ios::beg); 00322 if (!stream.good()) { 00323 stream.close(); 00324 string msg = "Error preparing to write data to " + 00325 p_type + " [" + p_blobName + "]"; 00326 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00327 } 00328 00329 WriteData(stream); 00330 stream.close(); 00331 } 00332 catch (Isis::iException &e) { 00333 string msg = "Unable to create " + p_type + " file [" + file + "]"; 00334 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00335 } 00336 } 00337 00345 void Blob::Write(Isis::Pvl &pvl, std::fstream &stm, 00346 const std::string &detachedFilename) { 00347 // Handle 64-bit I/O 00348 WriteInit(); 00349 00350 // Find out where they wanted to write the blob 00351 streampos sbyte = stm.tellp(); 00352 sbyte += 1; 00353 00354 // Find out where the end-of-file is 00355 stm.seekp(0,std::ios::end); 00356 streampos eofbyte = stm.tellp(); 00357 eofbyte += 1; 00358 00359 // Handle detached blobs 00360 if (detachedFilename != "") { 00361 p_blobPvl += Isis::PvlKeyword("^"+p_type,detachedFilename); 00362 } 00363 00364 // See if the blob is already in the file 00365 p_blobPvl["StartByte"] = (Isis::BigInt) sbyte; 00366 p_blobPvl["Bytes"] = p_nbytes; 00367 00368 bool found = false; 00369 for (int i=0; i<pvl.Objects(); i++) { 00370 if (pvl.Object(i).Name() == p_blobPvl.Name()) { 00371 PvlObject &obj = pvl.Object(i); 00372 if ((string) obj["Name"] == (string) p_blobPvl["Name"]) { 00373 found = true; 00374 00375 Isis::BigInt oldSbyte = obj["StartByte"]; 00376 int oldNbytes = (int) obj["Bytes"]; 00377 00378 // Does it fit in the old space 00379 if (p_nbytes <= oldNbytes) { 00380 p_blobPvl["StartByte"] = obj["StartByte"]; 00381 sbyte = oldSbyte; 00382 } 00383 00384 // Was the old space at the end of the file 00385 else if (((oldSbyte + oldNbytes) == eofbyte) && 00386 (eofbyte >= sbyte)) { 00387 p_blobPvl["StartByte"] = obj["StartByte"]; 00388 sbyte = oldSbyte; 00389 } 00390 00391 // Put it at the requested position/end of the file 00392 else { 00393 // Leave this here for clarity 00394 } 00395 00396 obj = p_blobPvl; 00397 } 00398 } 00399 } 00400 00401 // Didn't find the same blob so add it to the labels 00402 if (!found) { 00403 pvl.AddObject(p_blobPvl); 00404 } 00405 00406 stm.seekp((Isis::BigInt) sbyte-(Isis::BigInt)1); 00407 WriteData(stm); 00408 00409 // Handle detached blobs 00410 if (detachedFilename != "") { 00411 p_blobPvl.DeleteKeyword("^"+p_type); 00412 } 00413 } 00414 00422 void Blob::WriteData(std::fstream &stream) { 00423 stream.write(p_buffer,p_nbytes); 00424 if (!stream.good()) { 00425 string msg = "Error writing data to " + p_type + " [" + p_blobName + "]"; 00426 throw Isis::iException::Message(Isis::iException::Io,msg,_FILEINFO_); 00427 } 00428 } 00429 00437 bool IsBlob(Isis::PvlObject &obj) { 00438 if (obj.IsNamed("TABLE")) return true; 00439 return false; 00440 } 00441 } // end namespace isis 00442