blocxx
|
00001 /******************************************************************************* 00002 * Copyright (C) 2005, Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2006, Novell, Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of 00014 * Vintela, Inc., 00015 * nor Novell, Inc., 00016 * nor the names of its contributors or employees may be used to 00017 * endorse or promote products derived from this software without 00018 * specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00024 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00025 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00026 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00029 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00030 * POSSIBILITY OF SUCH DAMAGE. 00031 *******************************************************************************/ 00032 00033 00038 #include "blocxx/BLOCXX_config.h" 00039 #include "blocxx/TempFileEnumerationImplBase.hpp" 00040 #include "blocxx/EnumerationException.hpp" 00041 #include "blocxx/File.hpp" 00042 #include "blocxx/FileSystem.hpp" 00043 00044 namespace BLOCXX_NAMESPACE 00045 { 00046 00047 namespace 00048 { 00049 const UInt32 TEMPFILE_ENUMERATION_SIG = 0x4f57454e; // "OWEN" 00050 } 00051 00052 TempFileEnumerationImplBase::TempFileEnumerationImplBase() 00053 : m_size(0), m_Data() 00054 { 00055 UInt32 enumSig = TEMPFILE_ENUMERATION_SIG; 00056 m_Data.write(reinterpret_cast<const char*>(&enumSig), sizeof(enumSig)); 00057 if (!m_Data.good()) 00058 { 00059 BLOCXX_THROW(EnumerationException, "Failed to write signature to " 00060 "enumeration tempfile."); 00061 } 00062 // now we have to read the sig so that the temp file stream is 00063 // positioned correctly 00064 UInt32 tmpSig; 00065 m_Data.read(reinterpret_cast<char*>(&tmpSig), sizeof(tmpSig)); 00066 if (!m_Data.good()) 00067 { 00068 BLOCXX_THROW(EnumerationException, "Failed to read signature from " 00069 "enumeration tempfile."); 00070 } 00071 } 00072 00073 TempFileEnumerationImplBase::~TempFileEnumerationImplBase() 00074 { 00075 } 00076 bool 00077 TempFileEnumerationImplBase::hasMoreElements() const 00078 { 00079 00080 return m_size > 0; 00081 } 00082 size_t 00083 TempFileEnumerationImplBase::numberOfElements() const 00084 { 00085 return m_size; 00086 } 00087 void 00088 TempFileEnumerationImplBase::clear() 00089 { 00090 m_size = 0; 00091 m_Data.reset(); 00092 } 00093 bool 00094 TempFileEnumerationImplBase::usingTempFile() const 00095 { 00096 return m_Data.usingTempFile(); 00097 } 00098 00099 size_t 00100 TempFileEnumerationImplBase::readSize(String const& filename) 00101 { 00102 size_t size; 00103 // open the file and read the size that is written to the end of it. 00104 File f = FileSystem::openFile(filename); 00105 if (!f) 00106 { 00107 BLOCXX_THROW(EnumerationException, "Failed to open file"); 00108 } 00109 00110 // Check that the correct signature is on the file 00111 UInt32 fileSig; 00112 if (f.read(reinterpret_cast<char*>(&fileSig), sizeof(fileSig)) != sizeof(fileSig)) 00113 { 00114 BLOCXX_THROW(EnumerationException, "Failure to read enumeration " 00115 "signature"); 00116 } 00117 if (fileSig != TEMPFILE_ENUMERATION_SIG) 00118 { 00119 BLOCXX_THROW(EnumerationException, "Attempted to construct an " 00120 "enumeration from a file that does not have the correct " 00121 "signature"); 00122 } 00123 00124 off_t whence = f.seek(-static_cast<off_t>(sizeof(size)), SEEK_END); 00125 if (whence == -1) 00126 { 00127 BLOCXX_THROW(EnumerationException, "Failure to seek"); 00128 } 00129 if (f.read(reinterpret_cast<char*>(&size), sizeof(size), whence) != sizeof(size)) 00130 { 00131 BLOCXX_THROW(EnumerationException, "Failure to read enumeration " 00132 "size"); 00133 } 00134 if (f.close() == -1) 00135 { 00136 BLOCXX_THROW(EnumerationException, "Failure to close enumeration " 00137 "file"); 00138 } 00139 return size; 00140 } 00141 00142 void 00143 TempFileEnumerationImplBase::throwIfEmpty() const 00144 { 00145 if (!hasMoreElements()) 00146 { 00147 BLOCXX_THROW (EnumerationException, "Attempt to Extract from empty Enum"); 00148 } 00149 } 00150 00151 00152 } // end namespace BLOCXX_NAMESPACE 00153 00154 00155