mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-10 18:00:15 +01:00
410 lines
10 KiB
C++
410 lines
10 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "nscore.h"
|
|
#include "nsCRT.h"
|
|
#include "nsImportEncodeScan.h"
|
|
|
|
#define kBeginAppleSingle 0
|
|
#define kBeginDataFork 1
|
|
#define kBeginResourceFork 2
|
|
#define kAddEntries 3
|
|
#define kScanningDataFork 4
|
|
#define kScanningRsrcFork 5
|
|
#define kDoneWithFile 6
|
|
|
|
PRUint32 gAppleSingleHeader[6] = {0x00051600, 0x00020000, 0, 0, 0, 0};
|
|
#define kAppleSingleHeaderSize (6 * sizeof( PRUint32))
|
|
|
|
#ifdef _MAC_IMPORT_CODE
|
|
#include "MoreFilesExtras.h"
|
|
#include "MoreDesktopMgr.h"
|
|
|
|
CInfoPBRec gCatInfoPB;
|
|
U32 g2000Secs = 0;
|
|
long gGMTDelta = 0;
|
|
|
|
long GetGmtDelta( void);
|
|
U32 Get2000Secs( void);
|
|
|
|
|
|
long GetGmtDelta( void)
|
|
{
|
|
MachineLocation myLocation;
|
|
ReadLocation( &myLocation);
|
|
long myDelta = BitAnd( myLocation.u.gmtDelta, 0x00FFFFFF);
|
|
if (BitTst( &myDelta, 23))
|
|
myDelta = BitOr( myDelta, 0xFF000000);
|
|
return( myDelta);
|
|
}
|
|
|
|
U32 Get2000Secs( void)
|
|
{
|
|
DateTimeRec dr;
|
|
dr.year = 2000;
|
|
dr.month = 1;
|
|
dr.day = 1;
|
|
dr.hour = 0;
|
|
dr.minute = 0;
|
|
dr.second = 0;
|
|
dr.dayOfWeek = 0;
|
|
U32 result;
|
|
DateToSeconds( &dr, &result);
|
|
return( result);
|
|
}
|
|
#endif
|
|
|
|
nsImportEncodeScan::nsImportEncodeScan()
|
|
{
|
|
m_pFile = nsnull;
|
|
m_isAppleSingle = PR_FALSE;
|
|
m_encodeScanState = 0;
|
|
m_resourceForkSize = 0;
|
|
m_dataForkSize = 0;
|
|
m_pInputFile = nsnull;
|
|
}
|
|
|
|
nsImportEncodeScan::~nsImportEncodeScan()
|
|
{
|
|
NS_IF_RELEASE( m_pInputFile);
|
|
}
|
|
|
|
PRBool nsImportEncodeScan::InitEncodeScan( PRBool appleSingleEncode, nsIFileSpec *fileLoc, const char *pName, PRUint8 * pBuf, PRUint32 sz)
|
|
{
|
|
CleanUpEncodeScan();
|
|
m_isAppleSingle = appleSingleEncode;
|
|
m_encodeScanState = kBeginAppleSingle;
|
|
m_pInputFile = fileLoc;
|
|
NS_IF_ADDREF( m_pInputFile);
|
|
m_useFileName = pName;
|
|
m_pBuf = pBuf;
|
|
m_bufSz = sz;
|
|
if (!m_isAppleSingle) {
|
|
PRBool open = PR_FALSE;
|
|
nsresult rv = m_pInputFile->IsStreamOpen( &open);
|
|
if (NS_FAILED( rv) || !open) {
|
|
rv = m_pInputFile->OpenStreamForReading();
|
|
if (NS_FAILED( rv))
|
|
return( PR_FALSE);
|
|
}
|
|
|
|
InitScan( m_pInputFile, pBuf, sz);
|
|
}
|
|
else {
|
|
#ifdef _MAC_IMPORT_CODE
|
|
// Fill in the file sizes
|
|
m_resourceForkSize = fileLoc.GetMacFileSize( UFileLocation::eResourceFork);
|
|
m_dataForkSize = fileLoc.GetMacFileSize( UFileLocation::eDataFork);
|
|
#endif
|
|
}
|
|
|
|
return( PR_TRUE);
|
|
}
|
|
|
|
void nsImportEncodeScan::CleanUpEncodeScan( void)
|
|
{
|
|
NS_IF_RELEASE( m_pInputFile);
|
|
m_pInputFile = nsnull;
|
|
}
|
|
|
|
|
|
// 26 + 12 per entry
|
|
|
|
void nsImportEncodeScan::FillInEntries( int numEntries)
|
|
{
|
|
#ifdef _MAC_IMPORT_CODE
|
|
int len = m_useFileName.GetLength();
|
|
if (len < 32)
|
|
len = 32;
|
|
long entry[3];
|
|
long fileOffset = 26 + (12 * numEntries);
|
|
entry[0] = 3;
|
|
entry[1] = fileOffset;
|
|
entry[2] = m_useFileName.GetLength();
|
|
fileOffset += len;
|
|
MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
|
|
m_bytesInBuf += 12;
|
|
|
|
|
|
Str255 comment;
|
|
comment[0] = 0;
|
|
OSErr err = FSpDTGetComment( m_inputFileLoc, comment);
|
|
if (comment[0] > 200)
|
|
comment[0] = 200;
|
|
entry[0] = 4;
|
|
entry[1] = fileOffset;
|
|
entry[2] = comment[0];
|
|
fileOffset += 200;
|
|
MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
|
|
m_bytesInBuf += 12;
|
|
|
|
|
|
entry[0] = 8;
|
|
entry[1] = fileOffset;
|
|
entry[2] = 16;
|
|
fileOffset += 16;
|
|
MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
|
|
m_bytesInBuf += 12;
|
|
|
|
entry[0] = 9;
|
|
entry[1] = fileOffset;
|
|
entry[2] = 32;
|
|
fileOffset += 32;
|
|
MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
|
|
m_bytesInBuf += 12;
|
|
|
|
|
|
entry[0] = 10;
|
|
entry[1] = fileOffset;
|
|
entry[2] = 4;
|
|
fileOffset += 4;
|
|
MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
|
|
m_bytesInBuf += 12;
|
|
|
|
if (m_resourceForkSize) {
|
|
entry[0] = 2;
|
|
entry[1] = fileOffset;
|
|
entry[2] = m_resourceForkSize;
|
|
fileOffset += m_resourceForkSize;
|
|
MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
|
|
m_bytesInBuf += 12;
|
|
}
|
|
|
|
if (m_dataForkSize) {
|
|
entry[0] = 1;
|
|
entry[1] = fileOffset;
|
|
entry[2] = m_dataForkSize;
|
|
fileOffset += m_dataForkSize;
|
|
MemCpy( m_pBuf + m_bytesInBuf, entry, 12);
|
|
m_bytesInBuf += 12;
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
PRBool nsImportEncodeScan::AddEntries( void)
|
|
{
|
|
#ifdef _MAC_IMPORT_CODE
|
|
if (!g2000Secs) {
|
|
g2000Secs = Get2000Secs();
|
|
gGMTDelta = GetGmtDelta();
|
|
}
|
|
MemCpy( m_pBuf + m_bytesInBuf, (PC_S8) m_useFileName, m_useFileName.GetLength());
|
|
m_bytesInBuf += m_useFileName.GetLength();
|
|
if (m_useFileName.GetLength() < 32) {
|
|
int len = m_useFileName.GetLength();
|
|
while (len < 32) {
|
|
*((P_S8)m_pBuf + m_bytesInBuf) = 0;
|
|
m_bytesInBuf++;
|
|
len++;
|
|
}
|
|
}
|
|
|
|
Str255 comment;
|
|
comment[0] = 0;
|
|
OSErr err = FSpDTGetComment( m_inputFileLoc, comment);
|
|
comment[0] = 200;
|
|
MemCpy( m_pBuf + m_bytesInBuf, &(comment[1]), comment[0]);
|
|
m_bytesInBuf += comment[0];
|
|
|
|
long dates[4];
|
|
dates[0] = gCatInfoPB.hFileInfo.ioFlCrDat;
|
|
dates[1] = gCatInfoPB.hFileInfo.ioFlMdDat;
|
|
dates[2] = gCatInfoPB.hFileInfo.ioFlBkDat;
|
|
dates[3] = 0x80000000;
|
|
for (short i = 0; i < 3; i++) {
|
|
dates[i] -= g2000Secs;
|
|
dates[i] += gGMTDelta;
|
|
}
|
|
MemCpy( m_pBuf + m_bytesInBuf, dates, 16);
|
|
m_bytesInBuf += 16;
|
|
|
|
|
|
FInfo fInfo = gCatInfoPB.hFileInfo.ioFlFndrInfo;
|
|
FXInfo fxInfo = gCatInfoPB.hFileInfo.ioFlXFndrInfo;
|
|
fInfo.fdFlags = 0;
|
|
fInfo.fdLocation.h = 0;
|
|
fInfo.fdLocation.v = 0;
|
|
fInfo.fdFldr = 0;
|
|
MemSet( &fxInfo, 0, sizeof( fxInfo));
|
|
MemCpy( m_pBuf + m_bytesInBuf, &fInfo, 16);
|
|
m_bytesInBuf += 16;
|
|
MemCpy( m_pBuf + m_bytesInBuf, &fxInfo, 16);
|
|
m_bytesInBuf += 16;
|
|
|
|
|
|
dates[0] = 0;
|
|
if ((gCatInfoPB.hFileInfo.ioFlAttrib & 1) != 0)
|
|
dates[0] |= 1;
|
|
MemCpy( m_pBuf + m_bytesInBuf, dates, 4);
|
|
m_bytesInBuf += 4;
|
|
|
|
|
|
#endif
|
|
return( PR_TRUE);
|
|
}
|
|
|
|
PRBool nsImportEncodeScan::Scan( PRBool *pDone)
|
|
{
|
|
nsresult rv;
|
|
|
|
*pDone = PR_FALSE;
|
|
if (m_isAppleSingle) {
|
|
// Stuff the buffer with things needed to encode the file...
|
|
// then just allow UScanFile to handle each fork, but be careful
|
|
// when handling eof.
|
|
switch( m_encodeScanState) {
|
|
case kBeginAppleSingle: {
|
|
#ifdef _MAC_IMPORT_CODE
|
|
OSErr err = GetCatInfoNoName( m_inputFileLoc.GetVRefNum(), m_inputFileLoc.GetParID(), m_inputFileLoc.GetFileNamePtr(), &gCatInfoPB);
|
|
if (err != noErr)
|
|
return( FALSE);
|
|
#endif
|
|
m_eof = PR_FALSE;
|
|
m_pos = 0;
|
|
memcpy( m_pBuf, gAppleSingleHeader, kAppleSingleHeaderSize);
|
|
m_bytesInBuf = kAppleSingleHeaderSize;
|
|
int numEntries = 5;
|
|
if (m_dataForkSize)
|
|
numEntries++;
|
|
if (m_resourceForkSize)
|
|
numEntries++;
|
|
memcpy( m_pBuf + m_bytesInBuf, &numEntries, sizeof( numEntries));
|
|
m_bytesInBuf += sizeof( numEntries);
|
|
FillInEntries( numEntries);
|
|
m_encodeScanState = kAddEntries;
|
|
return( ScanBuffer( pDone));
|
|
}
|
|
break;
|
|
|
|
case kBeginDataFork: {
|
|
if (!m_dataForkSize) {
|
|
m_encodeScanState = kDoneWithFile;
|
|
return( PR_TRUE);
|
|
}
|
|
// Initialize the scan of the data fork...
|
|
PRBool open = PR_FALSE;
|
|
rv = m_pInputFile->IsStreamOpen( &open);
|
|
if (!open)
|
|
rv = m_pInputFile->OpenStreamForReading();
|
|
if (NS_FAILED( rv))
|
|
return( PR_FALSE);
|
|
m_encodeScanState = kScanningDataFork;
|
|
return( PR_TRUE);
|
|
}
|
|
break;
|
|
|
|
case kScanningDataFork: {
|
|
PRBool result = FillBufferFromFile();
|
|
if (!result)
|
|
return( PR_FALSE);
|
|
if (m_eof) {
|
|
m_eof = PR_FALSE;
|
|
result = ScanBuffer( pDone);
|
|
if (!result)
|
|
return( PR_FALSE);
|
|
m_pInputFile->CloseStream();
|
|
m_encodeScanState = kDoneWithFile;
|
|
return( PR_TRUE);
|
|
}
|
|
else
|
|
return( ScanBuffer( pDone));
|
|
}
|
|
break;
|
|
|
|
case kScanningRsrcFork: {
|
|
PRBool result = FillBufferFromFile();
|
|
if (!result)
|
|
return( PR_FALSE);
|
|
if (m_eof) {
|
|
m_eof = PR_FALSE;
|
|
result = ScanBuffer( pDone);
|
|
if (!result)
|
|
return( PR_FALSE);
|
|
m_pInputFile->CloseStream();
|
|
m_encodeScanState = kBeginDataFork;
|
|
return( PR_TRUE);
|
|
}
|
|
else
|
|
return( ScanBuffer( pDone));
|
|
}
|
|
break;
|
|
|
|
case kBeginResourceFork: {
|
|
if (!m_resourceForkSize) {
|
|
m_encodeScanState = kBeginDataFork;
|
|
return( PR_TRUE);
|
|
}
|
|
/*
|
|
// FIXME: Open the resource fork on the Mac!!!
|
|
m_fH = UFile::OpenRsrcFileRead( m_inputFileLoc);
|
|
if (m_fH == TR_FILE_ERROR)
|
|
return( FALSE);
|
|
*/
|
|
m_encodeScanState = kScanningRsrcFork;
|
|
return( PR_TRUE);
|
|
}
|
|
break;
|
|
|
|
case kAddEntries: {
|
|
ShiftBuffer();
|
|
if (!AddEntries())
|
|
return( PR_FALSE);
|
|
m_encodeScanState = kBeginResourceFork;
|
|
return( ScanBuffer( pDone));
|
|
}
|
|
break;
|
|
|
|
case kDoneWithFile: {
|
|
ShiftBuffer();
|
|
m_eof = PR_TRUE;
|
|
if (!ScanBuffer( pDone))
|
|
return( PR_FALSE);
|
|
*pDone = PR_TRUE;
|
|
return( PR_TRUE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
else
|
|
return( nsImportScanFile::Scan( pDone));
|
|
|
|
return( PR_FALSE);
|
|
}
|
|
|