Back to index

lightning-sunbird  0.9+nobinonly
nsImportEncodeScan.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 "nsCRT.h"
00040 #include "nsImportEncodeScan.h"
00041 
00042 #define       kBeginAppleSingle           0
00043 #define       kBeginDataFork                     1
00044 #define       kBeginResourceFork          2
00045 #define       kAddEntries                        3
00046 #define       kScanningDataFork           4
00047 #define       kScanningRsrcFork           5
00048 #define       kDoneWithFile               6
00049 
00050 PRUint32      gAppleSingleHeader[6] = {0x00051600, 0x00020000, 0, 0, 0, 0};
00051 #define kAppleSingleHeaderSize     (6 * sizeof( PRUint32))
00052 
00053 #ifdef _MAC_IMPORT_CODE
00054 #include "MoreFilesExtras.h"
00055 #include "MoreDesktopMgr.h"
00056 
00057 CInfoPBRec    gCatInfoPB;
00058 U32                  g2000Secs = 0;
00059 long          gGMTDelta = 0;
00060 
00061 long GetGmtDelta( void);
00062 U32 Get2000Secs( void);
00063 
00064 
00065 long GetGmtDelta( void)
00066 {
00067        MachineLocation myLocation;
00068        ReadLocation( &myLocation);
00069        long   myDelta = BitAnd( myLocation.u.gmtDelta, 0x00FFFFFF);
00070        if (BitTst( &myDelta, 23))
00071               myDelta = BitOr( myDelta, 0xFF000000);
00072        return( myDelta);
00073 }
00074 
00075 U32 Get2000Secs( void)
00076 {
00077        DateTimeRec   dr;
00078        dr.year = 2000;
00079        dr.month = 1;
00080        dr.day = 1;
00081        dr.hour = 0;
00082        dr.minute = 0;
00083        dr.second = 0;
00084        dr.dayOfWeek = 0;
00085        U32    result;
00086        DateToSeconds( &dr, &result);
00087        return( result);
00088 }
00089 #endif
00090 
00091 nsImportEncodeScan::nsImportEncodeScan()
00092 {
00093        m_pFile = nsnull;
00094        m_isAppleSingle = PR_FALSE;
00095        m_encodeScanState = 0;
00096        m_resourceForkSize = 0;
00097        m_dataForkSize = 0;
00098        m_pInputFile = nsnull;
00099 }
00100 
00101 nsImportEncodeScan::~nsImportEncodeScan()
00102 {
00103        NS_IF_RELEASE( m_pInputFile);
00104 }
00105 
00106 PRBool nsImportEncodeScan::InitEncodeScan( PRBool appleSingleEncode, nsIFileSpec *fileLoc, const char *pName, PRUint8 * pBuf, PRUint32 sz)
00107 {
00108        CleanUpEncodeScan();
00109        m_isAppleSingle = appleSingleEncode;
00110        m_encodeScanState = kBeginAppleSingle;
00111        m_pInputFile = fileLoc;
00112        NS_IF_ADDREF( m_pInputFile);
00113        m_useFileName = pName;
00114        m_pBuf = pBuf;
00115        m_bufSz = sz;
00116        if (!m_isAppleSingle) {
00117               PRBool open = PR_FALSE;
00118               nsresult rv = m_pInputFile->IsStreamOpen( &open);
00119               if (NS_FAILED( rv) || !open) {
00120                      rv = m_pInputFile->OpenStreamForReading();
00121                      if (NS_FAILED( rv))
00122                             return( PR_FALSE);
00123               }
00124 
00125               InitScan( m_pInputFile, pBuf, sz);
00126        }
00127        else {
00128        #ifdef _MAC_IMPORT_CODE
00129               // Fill in the file sizes
00130               m_resourceForkSize = fileLoc.GetMacFileSize( UFileLocation::eResourceFork);
00131               m_dataForkSize = fileLoc.GetMacFileSize( UFileLocation::eDataFork);
00132        #endif
00133        }
00134 
00135        return( PR_TRUE);
00136 }
00137 
00138 void nsImportEncodeScan::CleanUpEncodeScan( void)
00139 {
00140        NS_IF_RELEASE( m_pInputFile);
00141        m_pInputFile = nsnull;
00142 }
00143 
00144 
00145 // 26 + 12 per entry
00146 
00147 void nsImportEncodeScan::FillInEntries( int numEntries)
00148 {
00149 #ifdef _MAC_IMPORT_CODE
00150        int           len = m_useFileName.GetLength();
00151        if (len < 32)
00152               len = 32;
00153        long   entry[3];
00154        long   fileOffset = 26 + (12 * numEntries);
00155        entry[0] = 3;
00156        entry[1] = fileOffset;
00157        entry[2] = m_useFileName.GetLength();
00158        fileOffset += len;
00159        MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
00160        m_bytesInBuf += 12;         
00161        
00162        
00163        Str255 comment;
00164        comment[0] = 0;
00165        OSErr err = FSpDTGetComment( m_inputFileLoc, comment);
00166        if (comment[0] > 200)
00167               comment[0] = 200;
00168        entry[0] = 4;
00169        entry[1] = fileOffset;
00170        entry[2] = comment[0];
00171        fileOffset += 200;
00172        MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
00173        m_bytesInBuf += 12;         
00174        
00175        
00176        entry[0] = 8;
00177        entry[1] = fileOffset;
00178        entry[2] = 16;
00179        fileOffset += 16;
00180        MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
00181        m_bytesInBuf += 12;         
00182        
00183        entry[0] = 9;
00184        entry[1] = fileOffset;
00185        entry[2] = 32;
00186        fileOffset += 32;
00187        MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
00188        m_bytesInBuf += 12;         
00189 
00190        
00191        entry[0] = 10;
00192        entry[1] = fileOffset;
00193        entry[2] = 4;
00194        fileOffset += 4;
00195        MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
00196        m_bytesInBuf += 12;
00197        
00198        if (m_resourceForkSize) {
00199               entry[0] = 2;
00200               entry[1] = fileOffset;
00201               entry[2] = m_resourceForkSize;
00202               fileOffset += m_resourceForkSize;
00203               MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
00204               m_bytesInBuf += 12;         
00205        }
00206        
00207        if (m_dataForkSize) {
00208               entry[0] = 1;
00209               entry[1] = fileOffset;
00210               entry[2] = m_dataForkSize;
00211               fileOffset += m_dataForkSize;
00212               MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
00213               m_bytesInBuf += 12;
00214        }
00215        
00216 #endif        
00217 }
00218 
00219 PRBool nsImportEncodeScan::AddEntries( void)
00220 {
00221 #ifdef _MAC_IMPORT_CODE
00222        if (!g2000Secs) {
00223               g2000Secs = Get2000Secs();
00224               gGMTDelta = GetGmtDelta();
00225        }
00226        MemCpy( m_pBuf + m_bytesInBuf, (PC_S8) m_useFileName, m_useFileName.GetLength());
00227        m_bytesInBuf += m_useFileName.GetLength();              
00228        if (m_useFileName.GetLength() < 32) {
00229               int len = m_useFileName.GetLength();
00230               while (len < 32) {
00231                      *((P_S8)m_pBuf + m_bytesInBuf) = 0;
00232                      m_bytesInBuf++;
00233                      len++;
00234               }
00235        }
00236        
00237        Str255 comment;
00238        comment[0] = 0;
00239        OSErr err = FSpDTGetComment( m_inputFileLoc, comment);
00240        comment[0] = 200;
00241        MemCpy( m_pBuf + m_bytesInBuf, &(comment[1]), comment[0]);
00242        m_bytesInBuf += comment[0];
00243        
00244        long   dates[4];
00245        dates[0] = gCatInfoPB.hFileInfo.ioFlCrDat;
00246        dates[1] = gCatInfoPB.hFileInfo.ioFlMdDat;
00247        dates[2] = gCatInfoPB.hFileInfo.ioFlBkDat;
00248        dates[3] = 0x80000000;
00249        for (short i = 0; i < 3; i++) {
00250               dates[i] -= g2000Secs;
00251               dates[i] += gGMTDelta;
00252        }
00253        MemCpy( m_pBuf + m_bytesInBuf, dates, 16);
00254        m_bytesInBuf += 16;
00255        
00256        
00257        FInfo  fInfo = gCatInfoPB.hFileInfo.ioFlFndrInfo;
00258        FXInfo fxInfo = gCatInfoPB.hFileInfo.ioFlXFndrInfo;
00259        fInfo.fdFlags = 0;
00260        fInfo.fdLocation.h = 0;
00261        fInfo.fdLocation.v = 0;
00262        fInfo.fdFldr = 0;
00263        MemSet( &fxInfo, 0, sizeof( fxInfo));
00264        MemCpy( m_pBuf + m_bytesInBuf, &fInfo, 16);
00265        m_bytesInBuf += 16;
00266        MemCpy( m_pBuf + m_bytesInBuf, &fxInfo, 16);
00267        m_bytesInBuf += 16;
00268        
00269        
00270        dates[0] = 0;
00271        if ((gCatInfoPB.hFileInfo.ioFlAttrib & 1) != 0)
00272               dates[0] |= 1;
00273        MemCpy( m_pBuf + m_bytesInBuf, dates, 4);
00274        m_bytesInBuf += 4;
00275        
00276        
00277 #endif
00278        return( PR_TRUE);
00279 }
00280 
00281 PRBool nsImportEncodeScan::Scan( PRBool *pDone)
00282 {
00283        nsresult      rv;
00284 
00285        *pDone = PR_FALSE;
00286        if (m_isAppleSingle) {
00287               // Stuff the buffer with things needed to encode the file...
00288               // then just allow UScanFile to handle each fork, but be careful
00289               // when handling eof.
00290               switch( m_encodeScanState) {
00291                      case kBeginAppleSingle: {
00292                             #ifdef _MAC_IMPORT_CODE
00293                             OSErr err = GetCatInfoNoName( m_inputFileLoc.GetVRefNum(), m_inputFileLoc.GetParID(), m_inputFileLoc.GetFileNamePtr(), &gCatInfoPB);
00294                             if (err != noErr)
00295                                    return( FALSE);
00296                             #endif
00297                             m_eof = PR_FALSE;
00298                             m_pos = 0;
00299                             memcpy( m_pBuf, gAppleSingleHeader, kAppleSingleHeaderSize);
00300                             m_bytesInBuf = kAppleSingleHeaderSize;
00301                             int numEntries = 5;
00302                             if (m_dataForkSize)
00303                                    numEntries++;
00304                             if (m_resourceForkSize)
00305                                    numEntries++;
00306                             memcpy( m_pBuf + m_bytesInBuf, &numEntries, sizeof( numEntries));
00307                             m_bytesInBuf += sizeof( numEntries);
00308                             FillInEntries( numEntries);
00309                             m_encodeScanState = kAddEntries;
00310                             return( ScanBuffer( pDone));
00311                      }
00312                      break;
00313                      
00314                      case kBeginDataFork: {
00315                             if (!m_dataForkSize) {
00316                                    m_encodeScanState = kDoneWithFile;
00317                                    return( PR_TRUE);
00318                             }
00319                             // Initialize the scan of the data fork...
00320                             PRBool open = PR_FALSE;
00321                             rv = m_pInputFile->IsStreamOpen( &open);
00322                             if (!open)
00323                                    rv = m_pInputFile->OpenStreamForReading();
00324                             if (NS_FAILED( rv))
00325                                    return( PR_FALSE);   
00326                             m_encodeScanState = kScanningDataFork;
00327                             return( PR_TRUE);
00328                      }
00329                      break;
00330                      
00331                      case kScanningDataFork: {
00332                             PRBool result = FillBufferFromFile();
00333                             if (!result)
00334                                    return( PR_FALSE);
00335                             if (m_eof) {
00336                                    m_eof = PR_FALSE;
00337                                    result = ScanBuffer( pDone);
00338                                    if (!result)
00339                                           return( PR_FALSE);
00340                                    m_pInputFile->CloseStream();
00341                                    m_encodeScanState = kDoneWithFile;
00342                                    return( PR_TRUE);
00343                             }
00344                             else
00345                                    return( ScanBuffer( pDone));
00346                      }
00347                      break;
00348                      
00349                      case kScanningRsrcFork: {
00350                             PRBool result = FillBufferFromFile();
00351                             if (!result)
00352                                    return( PR_FALSE);
00353                             if (m_eof) {
00354                                    m_eof = PR_FALSE;
00355                                    result = ScanBuffer( pDone);
00356                                    if (!result)
00357                                           return( PR_FALSE);
00358                                    m_pInputFile->CloseStream();
00359                                    m_encodeScanState = kBeginDataFork;
00360                                    return( PR_TRUE);
00361                             }
00362                             else
00363                                    return( ScanBuffer( pDone));
00364                      }
00365                      break;
00366                      
00367                      case kBeginResourceFork: {
00368                             if (!m_resourceForkSize) {
00369                                    m_encodeScanState = kBeginDataFork;
00370                                    return( PR_TRUE);
00371                             }
00372                             /*
00373                             // FIXME: Open the resource fork on the Mac!!!
00374                             m_fH = UFile::OpenRsrcFileRead( m_inputFileLoc);
00375                             if (m_fH == TR_FILE_ERROR)
00376                                    return( FALSE);      
00377                             */
00378                             m_encodeScanState = kScanningRsrcFork;
00379                             return( PR_TRUE);
00380                      }
00381                      break;
00382                      
00383                      case kAddEntries: {
00384                             ShiftBuffer();
00385                             if (!AddEntries())
00386                                    return( PR_FALSE);
00387                             m_encodeScanState = kBeginResourceFork;
00388                             return( ScanBuffer( pDone));
00389                      }
00390                      break;
00391                      
00392                      case kDoneWithFile: {
00393                             ShiftBuffer();
00394                             m_eof = PR_TRUE;
00395                             if (!ScanBuffer( pDone))
00396                                    return( PR_FALSE);
00397                             *pDone = PR_TRUE;
00398                             return( PR_TRUE);
00399                      }
00400                      break;
00401               }
00402               
00403        }
00404        else
00405               return( nsImportScanFile::Scan( pDone));
00406               
00407        return( PR_FALSE);
00408 }
00409