TempFileEnumerationImplBase.cpp

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

Generated on Fri Jun 16 15:39:09 2006 for blocxx by  doxygen 1.4.6