Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

filebuffer.cpp

Go to the documentation of this file.
00001 //============================================================================= 
00002 //
00003 // XDFLengine library
00004 //
00005 //----------------------------------------------------------------------------- 
00006 //  FILEBUFFER.CPP
00007 //----------------------------------------------------------------------------- 
00013 //_____________________________________________________________________________
00014 //
00015 //  Copyright (C) 2003 Guillaume Baurand. All Rights Reserved.
00016 //
00017 //  This file is part of the XDFLengine project.
00018 //
00019 //  The XDFLengine is free software; you can redistribute it and/or modify
00020 //  it under the terms of the GNU General Public License as published by
00021 //  the Free Software Foundation; either version 2 of the License, or
00022 //  (at your option) any later version.
00023 //
00024 //  This program is distributed in the hope that it will be useful,
00025 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 //  GNU General Public License for more details.
00028 //
00029 //  You should have received a copy of the GNU General Public License
00030 //  along with this program; if not, write to the Free Software
00031 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
00032 //  USA.
00033 //
00034 //  For more information, 
00035 //      contact  : guillaume@baurand.net 
00036 //      or visit : http://xdflengine.sourceforge.net
00037 //
00038 //============================================================================= 
00039 
00040 //# include <sys/stat.h>
00041 #   include "filebuffer.hpp"
00042 
00043 
00044 BEGIN_XDFLENGINE_NS
00045 
00046 //============================================================================= 
00047 //  CLASS FILEBUFFER
00048 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00049 
00050 
00051     //_____________________________________________________________________
00052     //  Settmpdir
00053     //--------------------------------------------------------------------- 
00054     void FileBuffer::setTmpDir( const char* p_pszTmpDir) 
00055     {
00056         gs_pszFileBufferTmpDir = p_pszTmpDir;
00057     }
00058 
00059 // CONSTRUCTOR & DESTRUCTOR
00060     //_________________________________________________________________________
00061     //  FILEBUFFER
00062     //-------------------------------------------------------------------------
00063     FileBuffer::FileBuffer(const char* p_cFileName, bool p_boolReadOnly, unsigned int p_uiBufferSize)
00064     {
00065         m_boolReadOnly=p_boolReadOnly;
00066         m_bOpened=false;
00067         m_uiBufferSize=p_uiBufferSize;
00068         if( m_uiBufferSize == 0 ) m_uiBufferSize = FILEBUFFER_COPYBUF;
00069         m_pOut=0;
00070 
00071         if( p_cFileName)
00072         {
00073             strcpy( (char*) &m_cFN, p_cFileName);
00074             m_bOwnFile=false;
00075         }
00076         else
00077         {
00078             // Build file name
00079             strcpy((char*) &m_cFN, gs_pszFileBufferTmpDir);
00080             tmpnam((char*) &m_cFN+strlen(gs_pszFileBufferTmpDir));  
00081             m_bOwnFile=true;
00082             flush();
00083         }
00084 
00085         // Set default file open mode
00086         setMode("ab");
00087 
00088         DEBUG_CREATE(FileBuffer)
00089 
00090     }
00091 
00092     //_________________________________________________________________________
00093     //  ~FILEBUFFER
00094     //-------------------------------------------------------------------------
00095     FileBuffer::~FileBuffer()
00096     {
00097         DEBUG_DEL(FileBuffer)
00098         DEBUG_ECHO << "delete buffer " << m_cFN << "\n";
00099 
00100         if(m_bOwnFile && !m_boolReadOnly) delFile();
00101         else closefile();
00102         
00103     }
00104 
00105 
00106 // XMLSTREAMPROVIDER
00107 
00108     //_________________________________________________________________________
00109     //  OPERATOR >>
00110     //-------------------------------------------------------------------------
00111     XMLStreamProvider & FileBuffer::operator>>  ( XMLStreamConsumer& p_pStreamConsumer)
00112     {
00113         //---------------------------------------------------------------------
00114         void*               l_cBuf=0;
00115         int                 l_intRead;
00116         int                 l_intTotRead;
00117         unsigned int        l_written;
00118         //---------------------------------------------------------------------
00119 
00120         DEBUG_IN(FileBuffer::>>(XMLStreamConsumer))
00121 
00122         PREP_CATCH_XML_FLOW_ERROR;
00123 
00124         WATCH_XML_FLOW_ERROR {
00125 
00126             setMode("rb");
00127             openfile();
00128             rewind(m_pOut);         
00129 
00130             l_intRead=-1;
00131             l_intTotRead=0;
00132             l_written=0;
00133             l_cBuf = malloc(m_uiBufferSize+1);
00134 
00135             while( !( feof(m_pOut) || (l_intRead==0) ) )
00136             {
00137                 l_intRead = fread( l_cBuf, 1, m_uiBufferSize, m_pOut);
00138                 l_intTotRead+=l_intRead;
00139 
00140                 logout << "\t" << (char*) &m_cFN  << "   :   " << "read " << l_intRead << "bytes.\n";
00141 
00142                 if(l_intRead!=0)
00143                 {
00144                     l_written+=l_intRead;
00145                     // Write file content to output buffer  
00146                     p_pStreamConsumer.writeData((const char*)l_cBuf,l_intRead);
00147                     p_pStreamConsumer.commitStream(false);
00148                 }
00149 
00150                 // ERRCHECK : read file (tested)
00151                 if (ferror(m_pOut)) THROW_XMLFLOW_EXCEPTION ( ERRCODE_LOC_FILEBUFFER + ERRCODE_CAUSE_FILE , "Unable to read from file.", m_cFN,  "FileBuffer::operator>>", "", false );                 
00152             }
00153     
00154             closefile();
00155 
00156         } CATCH_XML_FLOW_ERROR_RELEASE_AND_RETURN;
00157         
00158     RELEASE_AND_RETURN: 
00159 
00160         // Release
00161         free( l_cBuf);
00162 
00163         DEBUG_OUT(FileBuffer::>>(XMLStreamConsumer))
00164             
00165         ON_XML_FLOW_ERROR_THROW;    
00166 
00167         return *this;
00168     }
00169 
00170 // XMLSTREAMCONSUMER
00171 
00172     //_________________________________________________________________________
00173     //  WRITE
00174     //-------------------------------------------------------------------------
00175     void FileBuffer::writeData( const char* p_pszData, unsigned int p_uiDataLen)
00176     {
00177         //---------------------------------------------------------------------
00178         int l_intwritten;
00179         //---------------------------------------------------------------------
00180 
00181         DEBUG_FUNC(FileBuffer::write)
00182 
00183         if (!m_boolReadOnly && p_uiDataLen>0)
00184         {
00185             setMode("ab");
00186             openfile();
00187 
00188             l_intwritten=fwrite( p_pszData, 1, p_uiDataLen, m_pOut);
00189             m_commitwritten+=l_intwritten;          
00190 
00191             // ERRCHECK : write to file (tested)
00192             if ( (l_intwritten==0) || (ferror(m_pOut))) THROW_XMLFLOW_EXCEPTION ( ERRCODE_LOC_FILEBUFFER + ERRCODE_CAUSE_FILE , "Unable to write to file." , m_cFN, "FileBuffer::write", "", false );   
00193         }
00194     }
00195 
00196 
00197     //_____________________________________________________________________
00198     //  COMMITSTREAM
00199     //---------------------------------------------------------------------
00200     //_____________________________________________________________________ 
00201     bool FileBuffer::commitStream(bool fFinal)
00202     {
00203         if (m_bOpened && !m_boolReadOnly && m_commitwritten>0)
00204         {
00205             logout << "\t" << (char*) &m_cFN  << "   :   " << "write " << m_commitwritten << " bytes.\n";
00206             fflush(m_pOut);
00207             if( fFinal) closefile();
00208         }
00209         m_commitwritten=0;
00210 
00211         return true;
00212     }
00213 
00214 // FILEBUFFER
00215 
00216     //_________________________________________________________________________
00217     //  FLUSH
00218     //-------------------------------------------------------------------------
00219     void FileBuffer::flush ()
00220     {
00221         DEBUG_FUNC(FileBuffer::flush)
00222         
00223         if (!m_boolReadOnly)
00224         {
00225             logout << "\t" << (char*) &m_cFN  << "   :   " << "flush file.\n";
00226             closefile();
00227             delFile();
00228         }
00229     }
00230 
00231 // PRIVATES
00232 
00233     //_________________________________________________________________________
00234     //  OPENFILE
00235     //-------------------------------------------------------------------------
00236     void FileBuffer::openfile()
00237     {
00238         DEBUG_FUNC(FileBuffer::openfile)
00239             
00240         PREP_CATCH_XML_FLOW_ERROR;
00241 
00242         WATCH_XML_FLOW_ERROR
00243         {
00244             if( !m_bOpened)
00245             {   
00246                 m_commitwritten=0;              
00247                 // open file
00248 
00249                 logout << "\t" << (char*) &m_cFN  << "   :   " <<  "open file.\n";
00250                 if( ! m_boolReadOnly) m_pOut=fopen( m_cFN, m_cMode);
00251                 else m_pOut=fopen( m_cFN, "rb");
00252                 m_bOpened=true;
00253 
00254                 // ERRCHECK : open file
00255                 if((!m_bOpened) || ferror(m_pOut) || (!m_pOut))
00256                 {
00257                     THROW_XMLFLOW_EXCEPTION ( ERRCODE_LOC_FILEBUFFER + ERRCODE_CAUSE_FILE , "Unable to open file." , m_cFN, "FileBuffer::openfile", "", false );
00258                 }
00259 
00260             }
00261         } CATCH_XML_FLOW_ERROR_RELEASE_AND_RETURN
00262         catch(...)
00263         {
00264             m_bOpened=false;
00265             THROW_XMLFLOW_EXCEPTION ( ERRCODE_LOC_FILEBUFFER + ERRCODE_CAUSE_FILE , "Unable to open file.", m_cFN, "FileBuffer::openfile", "", false );
00266         }       
00267 
00268     RELEASE_AND_RETURN: 
00269     
00270         ON_XML_FLOW_ERROR_THROW;
00271     }
00272 
00273     //_________________________________________________________________________
00274     //  CLOSEFILE
00275     //-------------------------------------------------------------------------
00276     void FileBuffer::closefile()
00277     {
00278         if( m_bOpened && (m_pOut !=0 ) )
00279         {
00280             logout << "\t" << (char*) &m_cFN  << "   :   " << "close file.\n";
00281 
00282             if( fclose(m_pOut) !=0 ) THROW_XMLFLOW_EXCEPTION ( ERRCODE_LOC_FILEBUFFER + ERRCODE_CAUSE_FILE , "Unable to close file.", m_cFN, "FileBuffer::closefile", "", false );
00283             m_bOpened=false;            
00284         }       
00285     }
00286 
00287 
00288     //_________________________________________________________________________
00289     //  SETMODE
00290     //-------------------------------------------------------------------------
00291     void FileBuffer::setMode( const char* p_cMode)
00292     {
00293         if(strcmp(p_cMode,m_cMode)!=0) 
00294         {
00295             closefile();
00296             strcpy( m_cMode, p_cMode);
00297         }
00298     }
00299 
00300 
00301     //_____________________________________________________________________
00302     //  DELFILE
00303     //---------------------------------------------------------------------
00304     void FileBuffer::delFile()
00305     {
00306         if( strlen((const char*) &m_cFN)>0)
00307         {
00308             closefile();
00309             logout << "\t" << (char*) &m_cFN  << "   :   " << "delete file.\n";
00310             remove( (const char*) &m_cFN);
00311         }
00312     }
00313 
00314 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00315 //=============================================================================
00316 
00317 END_XDFLENGINE_NS

Generated on Sat Oct 4 13:19:59 2003 for XDFLengine by doxygen1.3-rc2