ciderpress/app/BNYArchive.h

219 lines
8.0 KiB
C++

/*
* CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms.
*/
/*
* Binary II support.
*/
#ifndef APP_BNYARCHIVE_H
#define APP_BNYARCHIVE_H
#include "GenericArchive.h"
class BnyArchive;
/*
* One file in a BNY archive.
*/
class BnyEntry : public GenericEntry {
public:
BnyEntry(BnyArchive* pArchive) :
fpArchive(pArchive), fIsSqueezed(false), fOffset(-1)
{}
virtual ~BnyEntry(void) {}
// retrieve thread data
virtual int ExtractThreadToBuffer(int which, char** ppText, long* pLength,
CString* pErrMsg) const;
virtual int ExtractThreadToFile(int which, FILE* outfp, ConvertEOL conv,
ConvertHighASCII convHA, CString* pErrMsg) const;
virtual long GetSelectionSerial(void) const { return -1; } // doesn't matter
virtual bool GetFeatureFlag(Feature feature) const {
if (feature == kFeaturePascalTypes || feature == kFeatureDOSTypes ||
feature == kFeatureHasSimpleAccess)
return false;
else
return true;
}
NuError TestEntry(CWnd* pMsgWnd);
bool GetSqueezed(void) const { return fIsSqueezed; }
void SetSqueezed(bool val) { fIsSqueezed = val; }
long GetOffset(void) const { return fOffset; }
void SetOffset(long offset) { fOffset = offset; }
enum {
kBNYBlockSize = 128,
};
private:
NuError CopyData(FILE* outfp, ConvertEOL conv, ConvertHighASCII convHA,
CString* pMsg) const;
//NuError BNYUnSqueeze(ExpandBuffer* outExp) const;
BnyArchive* fpArchive; // holds FILE* for archive
bool fIsSqueezed;
long fOffset;
};
/*
* BNY archive definition.
*/
class BnyArchive : public GenericArchive {
public:
BnyArchive(void) : fIsReadOnly(false), fFp(nil)
{}
virtual ~BnyArchive(void) { (void) Close(); }
// One-time initialization; returns an error string.
static CString AppInit(void);
virtual OpenResult Open(const WCHAR* filename, bool readOnly,
CString* pErrMsg);
virtual CString New(const WCHAR* filename, const void* options);
virtual CString Flush(void) { return ""; }
virtual CString Reload(void);
virtual bool IsReadOnly(void) const { return fIsReadOnly; };
virtual bool IsModified(void) const { return false; }
virtual void GetDescription(CString* pStr) const { *pStr = "Binary II"; }
virtual bool BulkAdd(ActionProgressDialog* pActionProgress,
const AddFilesDialog* pAddOpts)
{ ASSERT(false); return false; }
virtual bool AddDisk(ActionProgressDialog* pActionProgress,
const AddFilesDialog* pAddOpts)
{ ASSERT(false); return false; }
virtual bool CreateSubdir(CWnd* pMsgWnd, GenericEntry* pParentEntry,
const WCHAR* newName)
{ ASSERT(false); return false; }
virtual bool TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet);
virtual bool DeleteSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
{ ASSERT(false); return false; }
virtual bool RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
{ ASSERT(false); return false; }
virtual bool RenameVolume(CWnd* pMsgWnd, DiskFS* pDiskFS,
const WCHAR* newName)
{ ASSERT(false); return false; }
virtual CString TestVolumeName(const DiskFS* pDiskFS,
const WCHAR* newName) const
{ ASSERT(false); return "!"; }
virtual CString TestPathName(const GenericEntry* pGenericEntry,
const CString& basePath, const CString& newName, char newFssep) const
{ ASSERT(false); return "!"; }
virtual bool RecompressSelection(CWnd* pMsgWnd, SelectionSet* pSelSet,
const RecompressOptionsDialog* pRecompOpts)
{ ASSERT(false); return false; }
virtual XferStatus XferSelection(CWnd* pMsgWnd, SelectionSet* pSelSet,
ActionProgressDialog* pActionProgress, const XferFileOptions* pXferOpts)
{ ASSERT(false); return kXferFailed; }
virtual bool GetComment(CWnd* pMsgWnd, const GenericEntry* pEntry,
CString* pStr)
{ ASSERT(false); return false; }
virtual bool SetComment(CWnd* pMsgWnd, GenericEntry* pEntry,
const CString& str)
{ ASSERT(false); return false; }
virtual bool DeleteComment(CWnd* pMsgWnd, GenericEntry* pEntry)
{ ASSERT(false); return false; }
virtual bool SetProps(CWnd* pMsgWnd, GenericEntry* pEntry,
const FileProps* pProps)
{ ASSERT(false); return false; }
virtual void PreferencesChanged(void) {}
virtual long GetCapability(Capability cap);
friend class BnyEntry;
private:
virtual CString Close(void) {
if (fFp != nil) {
fclose(fFp);
fFp = nil;
}
return "";
}
virtual void XferPrepare(const XferFileOptions* pXferOpts)
{ ASSERT(false); }
virtual CString XferFile(FileDetails* pDetails, unsigned char** pDataBuf,
long dataLen, unsigned char** pRsrcBuf, long rsrcLen)
{ ASSERT(false); return "!"; }
virtual void XferAbort(CWnd* pMsgWnd)
{ ASSERT(false); }
virtual void XferFinish(CWnd* pMsgWnd)
{ ASSERT(false); }
virtual ArchiveKind GetArchiveKind(void) { return kArchiveBNY; }
virtual NuError DoAddFile(const AddFilesDialog* pAddOpts,
FileDetails* pDetails)
{ ASSERT(false); return kNuErrGeneric; }
enum {
kBNYBlockSize = BnyEntry::kBNYBlockSize,
kBNYMaxFileName = 64,
kBNYMaxNativeName = 48,
kBNYFlagCompressed = (1<<7),
kBNYFlagEncrypted = (1<<6),
kBNYFlagSparse = (1),
};
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
/*
* An entry in a Binary II archive. Each archive is essentially a stream
* of files; only the "filesToFollow" value gives any indication that
* something else follows this entry.
*
* We read this from the archive and then unpack it into GenericEntry
* fields in a BnyEntry.
*/
struct BnyFileEntry; // VC++6 needs these to access private enums
friend struct BnyFileEntry; // in this class
typedef struct BnyFileEntry {
ushort access;
ushort fileType;
ulong auxType;
uchar storageType;
ulong fileSize; /* in 512-byte blocks */
ushort prodosModDate;
ushort prodosModTime;
NuDateTime modWhen; /* computed from previous two fields */
ushort prodosCreateDate;
ushort prodosCreateTime;
NuDateTime createWhen; /* computed from previous two fields */
ulong eof;
ulong realEOF; /* eof is bogus for directories */
char fileName[kBNYMaxFileName+1];
char nativeName[kBNYMaxNativeName+1];
ulong diskSpace; /* in 512-byte blocks */
uchar osType; /* not exactly same as NuFileSysID */
ushort nativeFileType;
uchar phantomFlag;
uchar dataFlags; /* advisory flags */
uchar version;
uchar filesToFollow; /* #of files after this one */
uchar blockBuf[kBNYBlockSize];
} BnyFileEntry;
int LoadContents(void);
NuError LoadContentsCallback(BnyFileEntry* pEntry);
bool IsSqueezed(uchar one, uchar two);
bool IsDir(BnyFileEntry* pEntry);
NuError BNYRead(void* buf, size_t nbyte);
NuError BNYSeek(long offset);
void BNYConvertDateTime(unsigned short prodosDate,
unsigned short prodosTime, NuDateTime* pWhen);
NuError BNYDecodeHeader(BnyFileEntry* pEntry);
NuError BNYIterate(void);
FILE* fFp;
bool fIsReadOnly;
};
#endif /*APP_BNYARCHIVE_H*/