mirror of
https://github.com/fadden/ciderpress.git
synced 2024-11-26 17:49:21 +00:00
00e6b3ab5e
This updates GenericEntry's filename handling to be more careful about Mac OS Roman vs. Unicode. Most of the work is still done with a CP-1252 conversion instead of MOR, but we now do a proper conversion on the "display name", so we see the right thing in the content list and file viewer. Copy & paste, disk-to-file-archive, and file-archive-to-disk conversions should work (correctly) as before. Extracted files will still have "_" or "%AA" instead of a Unicode TRADE MARK SIGN, but that's fine for now -- we can extract and re-add the files losslessly. The filenames are now stored in CStrings rather than WCHAR*. Also, fixed a bad initializer in the file-archive-to-disk conversion dialog.
228 lines
7.6 KiB
C++
228 lines
7.6 KiB
C++
/*
|
|
* CiderPress
|
|
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
|
* See the file LICENSE for distribution terms.
|
|
*/
|
|
/*
|
|
* File name conversion.
|
|
*/
|
|
#ifndef APP_FILENAMECONV_H
|
|
#define APP_FILENAMECONV_H
|
|
|
|
#include "GenericArchive.h"
|
|
|
|
|
|
/*
|
|
* Proposal for an output pathname, based on the contents of a GenericEntry.
|
|
*/
|
|
class PathProposal {
|
|
public:
|
|
typedef GenericEntry::RecordKind RecordKind;
|
|
enum {
|
|
kDefaultStoredFssep = ':',
|
|
kLocalFssep = '\\', // PATH_SEP
|
|
kAltLocalFssep = '/' // PATH_SEP2
|
|
};
|
|
|
|
PathProposal(void) {
|
|
fStoredPathName = L":BOGUS:";
|
|
fStoredFssep = '[';
|
|
fFileType = 256;
|
|
fAuxType = 65536;
|
|
fThreadKind = 0;
|
|
|
|
fLocalPathName = L":HOSED:";
|
|
fLocalFssep = ']';
|
|
|
|
fPreservation = false;
|
|
fAddExtension = false;
|
|
fJunkPaths = false;
|
|
fStripDiskImageSuffix = false;
|
|
}
|
|
virtual ~PathProposal(void) {}
|
|
|
|
// init the "extract from archive" side from a GenericEntry struct
|
|
void Init(GenericEntry* pEntry) {
|
|
// TODO(Unicode): use Unicode/MOR conversion rather than CP-1252
|
|
fStoredPathName = pEntry->GetPathNameMOR();
|
|
fStoredFssep = pEntry->GetFssep();
|
|
//if (fStoredFssep == '\0') // e.g. embedded DOS 3.3 volume
|
|
// fStoredFssep = kDefaultStoredFssep;
|
|
fFileType = pEntry->GetFileType();
|
|
fAuxType = pEntry->GetAuxType();
|
|
//fThreadKind set from SelectionEntry
|
|
// reset the "output" fields
|
|
fLocalPathName = L":HOSED:";
|
|
fLocalFssep = ']';
|
|
// I expect these to be as-yet unset; check it
|
|
ASSERT(!fPreservation);
|
|
ASSERT(!fAddExtension);
|
|
ASSERT(!fJunkPaths);
|
|
}
|
|
|
|
// init the "add to archive" side
|
|
void Init(const WCHAR* localPathName) {
|
|
//ASSERT(basePathName[strlen(basePathName)-1] != kLocalFssep);
|
|
//fLocalPathName = localPathName + strlen(basePathName)+1;
|
|
fLocalPathName = localPathName;
|
|
fLocalFssep = kLocalFssep;
|
|
// reset the "output" fields
|
|
fStoredPathName = L":HOSED:";
|
|
fStoredFssep = '[';
|
|
fFileType = 0;
|
|
fAuxType = 0;
|
|
fThreadKind = GenericEntry::kDataThread;
|
|
// I expect these to be as-yet unset; check it
|
|
ASSERT(!fPreservation);
|
|
ASSERT(!fAddExtension);
|
|
ASSERT(!fJunkPaths);
|
|
}
|
|
|
|
/*
|
|
* Convert a pathname pulled out of an archive to something suitable for the
|
|
* local filesystem.
|
|
*
|
|
* The new pathname may be shorter (because characters were removed) or
|
|
* longer (if we add a "#XXYYYYZ" extension or replace chars with '%' codes).
|
|
*/
|
|
void ArchiveToLocal(void);
|
|
|
|
/*
|
|
* Convert a local path into something suitable for storage in an archive.
|
|
* Type preservation strings are interpreted and stripped as appropriate.
|
|
*
|
|
* This does *not* do filesystem-specific normalization here. (It could, but
|
|
* it's better to leave that for later so we can do uniqueification.)
|
|
*
|
|
* In the current implementation, fStoredPathName will always get smaller,
|
|
* but it would be unwise to rely on that.
|
|
*/
|
|
void LocalToArchive(const AddFilesDialog* pAddOpts);
|
|
|
|
/*
|
|
* Fields for the "archive" side.
|
|
*/
|
|
// pathname from record or full pathname from disk image
|
|
CString fStoredPathName;
|
|
// filesystem separator char (or '\0' for things like DOS 3.3)
|
|
char fStoredFssep;
|
|
// file type, aux type, and what piece of the file this is
|
|
unsigned long fFileType;
|
|
unsigned long fAuxType;
|
|
int fThreadKind; // GenericEntry, e.g. kDataThread
|
|
|
|
/*
|
|
* Fields for the "local" Side.
|
|
*/
|
|
// relative path of file for local filesystem
|
|
CString fLocalPathName;
|
|
// filesystem separator char for new path (always '\\' for us)
|
|
char fLocalFssep;
|
|
|
|
/*
|
|
* Flags.
|
|
*/
|
|
// filename/filetype preservation flags
|
|
bool fPreservation;
|
|
bool fAddExtension;
|
|
bool fJunkPaths;
|
|
bool fStripDiskImageSuffix;
|
|
|
|
/*
|
|
* Return a pointer to the three-letter representation of the file type name.
|
|
*/
|
|
static const WCHAR* FileTypeString(unsigned long fileType);
|
|
|
|
/*
|
|
* Find an entry in the type description table that matches both file type and
|
|
* aux type. If no match is found, NULL is returned.
|
|
*/
|
|
static const WCHAR* FileTypeDescription(long fileType, long auxType);
|
|
|
|
private:
|
|
/*
|
|
* Filename normalization for Win32 filesystems. You can't use [ \/:*?"<>| ]
|
|
* or control characters, and we're currently avoiding high-ASCII stuff.
|
|
*/
|
|
void Win32NormalizeFileName(const WCHAR* srcp, long srcLen,
|
|
char fssep, WCHAR** pDstp, long dstLen);
|
|
|
|
/*
|
|
* Normalize a file name to local filesystem conventions. The input
|
|
* is quite possibly *NOT* null-terminated, since it may represent a
|
|
* substring of a full pathname. Use "srcLen".
|
|
*
|
|
* The output filename is copied to *pDstp, which is advanced forward.
|
|
*
|
|
* The output buffer must be able to hold 3x the original string length.
|
|
*/
|
|
void NormalizeFileName(const WCHAR* srcp, long srcLen,
|
|
char fssep, WCHAR** pDstp, long dstLen);
|
|
|
|
/*
|
|
* Normalize a directory name to local filesystem conventions.
|
|
*/
|
|
void NormalizeDirectoryName(const WCHAR* srcp, long srcLen,
|
|
char fssep, WCHAR** pDstp, long dstLen);
|
|
|
|
/*
|
|
* Add a preservation string.
|
|
*
|
|
* "pathBuf" is assumed to have enough space to hold the current path
|
|
* plus kMaxPathGrowth more. It will be modified in place.
|
|
*/
|
|
void AddPreservationString(const WCHAR* pathBuf, WCHAR* extBuf);
|
|
|
|
/*
|
|
* Add a ".type" extension to the filename.
|
|
*
|
|
* We either need to retain the existing extension (possibly obscured by file
|
|
* type preservation) or append an extension based on the ProDOS file type.
|
|
*/
|
|
void AddTypeExtension(const WCHAR* pathBuf, WCHAR* extBuf);
|
|
|
|
/*
|
|
* Replace "oldc" with "newc". If we find an instance of "newc" already
|
|
* in the string, replace it with "newSubst".
|
|
*/
|
|
void ReplaceFssep(WCHAR* str, char oldc, char newc, char newSubst);
|
|
|
|
/*
|
|
* Try to figure out what file type is associated with a filename extension.
|
|
*
|
|
* This checks the standard list of ProDOS types (which should catch things
|
|
* like "TXT" and "BIN") and the separate list of recognized extensions.
|
|
*/
|
|
void LookupExtension(const WCHAR* ext);
|
|
|
|
/*
|
|
* Try to associate some meaning with the file extension.
|
|
*/
|
|
void InterpretExtension(const WCHAR* pathName);
|
|
|
|
/*
|
|
* Check to see if there's a preservation string on the filename. If so,
|
|
* set the filetype and auxtype information, and trim the preservation
|
|
* string off.
|
|
*/
|
|
bool ExtractPreservationString(WCHAR* pathName);
|
|
|
|
/*
|
|
* Remove NuLib2's normalization magic (e.g. "%2f" for '/').
|
|
*
|
|
* This always results in the filename staying the same length or getting
|
|
* smaller, so we can do it in place in the buffer.
|
|
*/
|
|
void DenormalizePath(WCHAR* pathBuf);
|
|
|
|
/*
|
|
* Remove a disk image suffix.
|
|
*
|
|
* Useful when adding disk images directly from a .SDK or .2MG file. We
|
|
* don't want them to retain their original suffix.
|
|
*/
|
|
void StripDiskImageSuffix(WCHAR* pathName);
|
|
};
|
|
|
|
#endif /*APP_FILENAMECONV_H*/
|