Back to index

lightning-sunbird  0.9+nobinonly
ImportOutFile.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nscore.h"
00039 #include "nsString.h"
00040 #include "nsCRT.h"
00041 #include "ImportOutFile.h"
00042 #include "ImportCharSet.h"
00043 
00044 #include "ImportDebug.h"
00045 
00046 /*
00047 #ifdef _MAC
00048 #define       kMacNoCreator        '????'
00049 #define kMacTextFile        'TEXT'
00050 #else
00051 #define       kMacNoCreator        0
00052 #define kMacTextFile        0
00053 #endif
00054 */
00055 
00056 ImportOutFile::ImportOutFile()
00057 {
00058        m_ownsFileAndBuffer = PR_FALSE;
00059        m_pos = 0;
00060        m_pBuf = nsnull;
00061        m_bufSz = 0;
00062        m_pFile = nsnull;
00063        m_pTrans = nsnull;
00064        m_pTransOut = nsnull;
00065        m_pTransBuf = nsnull;
00066 }
00067 
00068 ImportOutFile::ImportOutFile( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz)
00069 {
00070        m_pTransBuf = nsnull;
00071        m_pTransOut = nsnull;
00072        m_pTrans = nsnull;
00073        m_ownsFileAndBuffer = PR_FALSE;
00074        InitOutFile( pSpec, pBuf, sz);
00075 }
00076 
00077 ImportOutFile::~ImportOutFile()
00078 {
00079        if (m_ownsFileAndBuffer) {
00080               Flush();
00081               if (m_pBuf)
00082                      delete [] m_pBuf;
00083        }
00084        
00085        NS_IF_RELEASE( m_pFile);
00086 
00087        if (m_pTrans)
00088               delete m_pTrans;
00089        if (m_pTransOut)
00090               delete m_pTransOut;
00091        if (m_pTransBuf)
00092               delete m_pTransBuf;
00093 }
00094 
00095 PRBool ImportOutFile::Set8bitTranslator( nsImportTranslator *pTrans)
00096 {
00097        if (!Flush())
00098               return( PR_FALSE);
00099 
00100        m_engaged = PR_FALSE;
00101        m_pTrans = pTrans;
00102        m_supports8to7 = pTrans->Supports8bitEncoding();
00103 
00104 
00105        return( PR_TRUE);
00106 }
00107 
00108 PRBool ImportOutFile::End8bitTranslation( PRBool *pEngaged, nsCString& useCharset, nsCString& encoding)
00109 {
00110        if (!m_pTrans)
00111               return( PR_FALSE);
00112 
00113 
00114        PRBool bResult = Flush();
00115        if (m_supports8to7 && m_pTransOut) {
00116               if (bResult)
00117                      bResult = m_pTrans->FinishConvertToFile( m_pTransOut);
00118               if (bResult)
00119                      bResult = Flush();
00120        }
00121 
00122        if (m_supports8to7) {
00123               m_pTrans->GetCharset( useCharset);
00124               m_pTrans->GetEncoding( encoding);
00125        }
00126        else
00127               useCharset.Truncate();
00128        *pEngaged = m_engaged;
00129        delete m_pTrans;
00130        m_pTrans = nsnull;
00131        if (m_pTransOut)
00132               delete m_pTransOut;
00133        m_pTransOut = nsnull;
00134        if (m_pTransBuf)
00135               delete m_pTransBuf;
00136        m_pTransBuf = nsnull;
00137 
00138        return( bResult);
00139 }
00140 
00141 PRBool ImportOutFile::InitOutFile( nsIFileSpec *pSpec, PRUint32 bufSz)
00142 {
00143        if (!bufSz)
00144               bufSz = 32 * 1024;   
00145        if (!m_pBuf) {
00146               m_pBuf = new PRUint8[ bufSz];
00147        }
00148        
00149        // m_fH = UFile::CreateFile( oFile, kMacNoCreator, kMacTextFile);
00150        PRBool open = PR_FALSE;
00151        nsresult rv = pSpec->IsStreamOpen( &open);
00152        if (NS_FAILED( rv) || !open) {
00153               rv = pSpec->OpenStreamForWriting();
00154               if (NS_FAILED( rv)) {
00155                      IMPORT_LOG0( "Couldn't create outfile\n");
00156                      delete [] m_pBuf;
00157                      m_pBuf = nsnull;
00158                      return( PR_FALSE);
00159               }
00160        }
00161        m_pFile = pSpec;
00162        NS_ADDREF( m_pFile);
00163        m_ownsFileAndBuffer = PR_TRUE;
00164        m_pos = 0;
00165        m_bufSz = bufSz;
00166 
00167        return( PR_TRUE);
00168 }
00169 
00170 void ImportOutFile::InitOutFile( nsIFileSpec *pSpec, PRUint8 * pBuf, PRUint32 sz)
00171 {
00172        m_ownsFileAndBuffer = PR_FALSE;
00173        m_pFile = pSpec;
00174        NS_IF_ADDREF( m_pFile);
00175        m_pBuf = pBuf;
00176        m_bufSz = sz;
00177        m_pos = 0;
00178 }
00179 
00180 
00181 
00182 PRBool ImportOutFile::Flush( void)
00183 {
00184        if (!m_pos)
00185               return( PR_TRUE);
00186 
00187        PRUint32      transLen;
00188        PRBool        duddleyDoWrite = PR_FALSE;
00189 
00190        // handle translations if appropriate
00191        if (m_pTrans) {
00192               if (m_engaged && m_supports8to7) {
00193                      // Markers can get confused by this crap!!!
00194                      // TLR: FIXME: Need to update the markers based on
00195                      // the difference between the translated len and untranslated len
00196 
00197                      if (!m_pTrans->ConvertToFile(  m_pBuf, m_pos, m_pTransOut, &transLen))
00198                             return( PR_FALSE);
00199                      if (!m_pTransOut->Flush())
00200                             return( PR_FALSE);
00201                      // now update our buffer...
00202                      if (transLen < m_pos) {
00203                             memcpy( m_pBuf, m_pBuf + transLen, m_pos - transLen);
00204                      }
00205                      m_pos -= transLen;
00206               }
00207               else if (m_engaged) {
00208                      // does not actually support translation!
00209                      duddleyDoWrite = PR_TRUE;
00210               }
00211               else {
00212                      // should we engage?
00213                      PRUint8 *     pChar = m_pBuf;
00214                      PRUint32      len = m_pos;
00215                      while (len) {
00216                             if (!ImportCharSet::IsUSAscii( *pChar))
00217                                    break;
00218                             pChar++;
00219                             len--;
00220                      }
00221                      if (len) {
00222                             m_engaged = PR_TRUE;
00223                             if (m_supports8to7) {
00224                                    // allocate our translation output buffer and file...
00225                                    m_pTransBuf = new PRUint8[m_bufSz];
00226                                    m_pTransOut = new ImportOutFile( m_pFile, m_pTransBuf, m_bufSz);
00227                                    return( Flush());
00228                             }
00229                             else
00230                                    duddleyDoWrite = PR_TRUE;
00231                      }
00232                      else {
00233                             duddleyDoWrite = PR_TRUE;
00234                      }
00235               }
00236        }
00237        else
00238               duddleyDoWrite = PR_TRUE;
00239 
00240        if (duddleyDoWrite) {
00241               PRInt32 written = 0;
00242               nsresult rv = m_pFile->Write( (const char *)m_pBuf, (PRInt32)m_pos, &written);
00243               if (NS_FAILED( rv) || ((PRUint32)written != m_pos))
00244                      return( PR_FALSE);
00245               m_pos = 0;
00246        }
00247        
00248        return( PR_TRUE);
00249 }
00250 
00251 PRBool ImportOutFile::WriteU8NullTerm( const PRUint8 * pSrc, PRBool includeNull) 
00252 {
00253        while (*pSrc) {
00254               if (m_pos >= m_bufSz) {
00255                      if (!Flush())
00256                             return( PR_FALSE);
00257               }
00258               *(m_pBuf + m_pos) = *pSrc;
00259               m_pos++;
00260               pSrc++;
00261        }
00262        if (includeNull) {
00263               if (m_pos >= m_bufSz) {
00264                      if (!Flush())
00265                             return( PR_FALSE);
00266               }
00267               *(m_pBuf + m_pos) = 0;
00268               m_pos++;
00269        }
00270 
00271        return( PR_TRUE);
00272 }
00273 
00274 PRBool ImportOutFile::SetMarker( int markerID)
00275 {
00276        if (!Flush()) {
00277               return( PR_FALSE);
00278        }
00279 
00280        if (markerID < kMaxMarkers) {
00281               PRInt32 pos = 0;
00282               nsresult rv;
00283               if (m_pFile) {
00284                      rv = m_pFile->Tell( &pos);
00285                      if (NS_FAILED( rv)) {
00286                             IMPORT_LOG0( "*** Error, Tell failed on output stream\n");
00287                             return( PR_FALSE);
00288                      }
00289               }
00290               m_markers[markerID] = (PRUint32)pos + m_pos;
00291        }
00292 
00293        return( PR_TRUE);
00294 }
00295 
00296 void ImportOutFile::ClearMarker( int markerID)
00297 {
00298        if (markerID < kMaxMarkers)
00299               m_markers[markerID] = 0;
00300 }
00301 
00302 PRBool ImportOutFile::WriteStrAtMarker( int markerID, const char *pStr)
00303 {
00304        if (markerID >= kMaxMarkers)
00305               return( PR_FALSE);
00306 
00307        if (!Flush())
00308               return( PR_FALSE);
00309        nsresult      rv;
00310        PRInt32              pos;
00311        rv = m_pFile->Tell( &pos);
00312        if (NS_FAILED( rv))
00313               return( PR_FALSE);
00314        rv = m_pFile->Seek( (PRInt32) m_markers[markerID]);
00315        if (NS_FAILED( rv))
00316               return( PR_FALSE);
00317        PRInt32 written;
00318        rv = m_pFile->Write( pStr, strlen( pStr), &written);
00319        if (NS_FAILED( rv))
00320               return( PR_FALSE);
00321 
00322        rv = m_pFile->Seek( pos);
00323        if (NS_FAILED( rv))
00324               return( PR_FALSE);
00325 
00326        return( PR_TRUE);
00327 }
00328