mirror of
https://github.com/fadden/ciderpress.git
synced 2024-11-25 10:30:53 +00:00
Improve filename handling when reading from archives
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.
This commit is contained in:
parent
b79498da50
commit
00e6b3ab5e
@ -636,8 +636,7 @@ int AcuArchive::CreateEntry(const AcuFileEntry* pEntry)
|
||||
* Create the new entry.
|
||||
*/
|
||||
pNewEntry = new AcuEntry(this);
|
||||
CString fileName(pEntry->fileName);
|
||||
pNewEntry->SetPathName(fileName);
|
||||
pNewEntry->SetPathNameMOR(pEntry->fileName);
|
||||
pNewEntry->SetFssep(kAcuFssep);
|
||||
pNewEntry->SetFileType(pEntry->fileType);
|
||||
pNewEntry->SetAuxType(pEntry->auxType);
|
||||
@ -754,7 +753,7 @@ bool AcuArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
while (pSelEntry != NULL) {
|
||||
pEntry = (AcuEntry*) pSelEntry->GetEntry();
|
||||
|
||||
LOGI(" Testing '%ls' (offset=%ld)", pEntry->GetDisplayName(),
|
||||
LOGD(" Testing '%ls' (offset=%ld)", (LPCWSTR) pEntry->GetDisplayName(),
|
||||
pEntry->GetOffset());
|
||||
|
||||
SET_PROGRESS_UPDATE2(0, pEntry->GetDisplayName(), NULL);
|
||||
@ -764,11 +763,11 @@ bool AcuArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
if (nerr == kNuErrAborted) {
|
||||
CString title;
|
||||
CheckedLoadString(&title, IDS_MB_APP_NAME);
|
||||
errMsg = "Cancelled.";
|
||||
errMsg = L"Cancelled.";
|
||||
pMsgWnd->MessageBox(errMsg, title, MB_OK);
|
||||
} else {
|
||||
errMsg.Format(L"Failed while testing '%ls': %hs.",
|
||||
pEntry->GetPathName(), NuStrError(nerr));
|
||||
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
}
|
||||
goto bail;
|
||||
|
@ -471,9 +471,9 @@ void MainWindow::OnActionsCreateSubdir(void)
|
||||
return;
|
||||
}
|
||||
|
||||
LOGI("Creating subdir in '%ls'", pEntry->GetPathName());
|
||||
LOGI("Creating subdir in '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
|
||||
|
||||
csDialog.fBasePath = pEntry->GetPathName();
|
||||
csDialog.fBasePath = pEntry->GetPathNameUNI();
|
||||
csDialog.fpArchive = fpOpenArchive;
|
||||
csDialog.fpParentEntry = pEntry;
|
||||
csDialog.fNewName = "New.Subdir";
|
||||
@ -638,7 +638,7 @@ void MainWindow::DoBulkExtract(SelectionSet* pSelSet,
|
||||
|
||||
GenericEntry* pEntry = pSelEntry->GetEntry();
|
||||
if (pEntry->GetDamaged()) {
|
||||
LOGI("Skipping '%ls' due to damage", pEntry->GetPathName());
|
||||
LOGI("Skipping '%ls' due to damage", (LPCWSTR) pEntry->GetPathNameUNI());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -686,7 +686,7 @@ void MainWindow::DoBulkExtract(SelectionSet* pSelSet,
|
||||
pEntry->GetFileType(),
|
||||
pEntry->GetAuxType(),
|
||||
ReformatterSourceFormat(pEntry->GetSourceFS()),
|
||||
pEntry->GetFileNameExtensionA());
|
||||
pEntry->GetFileNameExtensionMOR());
|
||||
pHolder->TestApplicability();
|
||||
}
|
||||
}
|
||||
@ -787,7 +787,8 @@ bool MainWindow::ExtractEntry(GenericEntry* pEntry, int thread,
|
||||
extractAs2MG = true;
|
||||
} else {
|
||||
LOGI("Not extracting funky image '%ls' as 2MG (len=%I64d)",
|
||||
pEntry->GetPathName(), pEntry->GetUncompressedLen());
|
||||
(LPCWSTR) pEntry->GetPathNameUNI(),
|
||||
pEntry->GetUncompressedLen());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -826,7 +827,7 @@ bool MainWindow::ExtractEntry(GenericEntry* pEntry, int thread,
|
||||
*/
|
||||
ASSERT(pExtOpts->fExtractPath.Right(1) == "\\");
|
||||
CString adjustedExtractPath(pExtOpts->fExtractPath);
|
||||
if (!pExtOpts->fStripFolderNames && pEntry->GetSubVolName() != NULL) {
|
||||
if (!pExtOpts->fStripFolderNames && !pEntry->GetSubVolName().IsEmpty()) {
|
||||
adjustedExtractPath += pEntry->GetSubVolName();
|
||||
adjustedExtractPath += "\\";
|
||||
}
|
||||
|
@ -470,8 +470,7 @@ NuError BnyArchive::LoadContentsCallback(BnyFileEntry* pEntry)
|
||||
* Create the new entry.
|
||||
*/
|
||||
pNewEntry = new BnyEntry(this);
|
||||
CString fileNameW(fileName);
|
||||
pNewEntry->SetPathName(fileNameW);
|
||||
pNewEntry->SetPathNameMOR(fileName);
|
||||
pNewEntry->SetFssep(kBNYFssep);
|
||||
pNewEntry->SetFileType(pEntry->fileType);
|
||||
pNewEntry->SetAuxType(pEntry->auxType);
|
||||
@ -853,7 +852,7 @@ bool BnyArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
while (pSelEntry != NULL) {
|
||||
pEntry = (BnyEntry*) pSelEntry->GetEntry();
|
||||
|
||||
LOGI(" Testing '%ls' (offset=%ld)", pEntry->GetDisplayName(),
|
||||
LOGI(" Testing '%ls' (offset=%ld)", (LPCWSTR) pEntry->GetDisplayName(),
|
||||
pEntry->GetOffset());
|
||||
|
||||
SET_PROGRESS_UPDATE2(0, pEntry->GetDisplayName(), NULL);
|
||||
@ -867,7 +866,7 @@ bool BnyArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
pMsgWnd->MessageBox(errMsg, title, MB_OK);
|
||||
} else {
|
||||
errMsg.Format(L"Failed while testing '%ls': %hs.",
|
||||
pEntry->GetPathName(), NuStrError(nerr));
|
||||
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
}
|
||||
goto bail;
|
||||
|
@ -202,7 +202,7 @@ CString MainWindow::CreateFileList(SelectionSet* pSelSet)
|
||||
pEntry = pSelEntry->GetEntry();
|
||||
ASSERT(pEntry != NULL);
|
||||
|
||||
fileName = DblDblQuote(pEntry->GetPathName());
|
||||
fileName = DblDblQuote(pEntry->GetPathNameUNI());
|
||||
subVol = pEntry->GetSubVolName();
|
||||
ContentList::MakeFileTypeDisplayString(pEntry, fileTypeBuf);
|
||||
fileType = DblDblQuote(fileTypeBuf); // Mac HFS types might have '"'?
|
||||
@ -292,7 +292,7 @@ HGLOBAL MainWindow::CreateFileCollection(SelectionSet* pSelSet)
|
||||
|
||||
if (pEntry->GetRecordKind() != GenericEntry::kRecordKindVolumeDir) {
|
||||
totalLength += sizeof(FileCollectionEntry);
|
||||
totalLength += (wcslen(pEntry->GetPathName()) +1) * sizeof(WCHAR);
|
||||
totalLength += (wcslen(pEntry->GetPathNameUNI()) +1) * sizeof(WCHAR);
|
||||
numFiles++;
|
||||
if (pEntry->GetRecordKind() != GenericEntry::kRecordKindDirectory) {
|
||||
totalLength += (long) pEntry->GetDataForkLen();
|
||||
@ -373,8 +373,7 @@ HGLOBAL MainWindow::CreateFileCollection(SelectionSet* pSelSet)
|
||||
pEntry = pSelEntry->GetEntry();
|
||||
ASSERT(pEntry != NULL);
|
||||
|
||||
CString displayName(pEntry->GetDisplayName());
|
||||
fpActionProgress->SetArcName(displayName);
|
||||
fpActionProgress->SetArcName(pEntry->GetDisplayName());
|
||||
|
||||
errStr = CopyToCollection(pEntry, &buf, &remainingLen);
|
||||
if (!errStr.IsEmpty()) {
|
||||
@ -460,7 +459,7 @@ CString MainWindow::CopyToCollection(GenericEntry* pEntry, void** pBuf,
|
||||
memset(&collEnt, 0x99, sizeof(collEnt));
|
||||
collEnt.signature = kEntrySignature;
|
||||
collEnt.dataOffset = sizeof(collEnt);
|
||||
collEnt.fileNameLen = (wcslen(pEntry->GetPathName()) +1) * sizeof(WCHAR);
|
||||
collEnt.fileNameLen = (wcslen(pEntry->GetPathNameUNI()) +1) * sizeof(WCHAR);
|
||||
if (pEntry->GetRecordKind() == GenericEntry::kRecordKindDirectory) {
|
||||
collEnt.dataLen = collEnt.rsrcLen = collEnt.cmmtLen = 0;
|
||||
} else {
|
||||
@ -490,7 +489,7 @@ CString MainWindow::CopyToCollection(GenericEntry* pEntry, void** pBuf,
|
||||
remLen -= sizeof(collEnt);
|
||||
|
||||
/* copy string with terminating null */
|
||||
memcpy(buf, pEntry->GetPathName(), collEnt.fileNameLen);
|
||||
memcpy(buf, pEntry->GetPathNameUNI(), collEnt.fileNameLen);
|
||||
buf += collEnt.fileNameLen;
|
||||
remLen -= collEnt.fileNameLen;
|
||||
|
||||
|
@ -62,8 +62,8 @@ static inline int MaxVal(int a, int b)
|
||||
int ContentList::OnCreate(LPCREATESTRUCT lpcs)
|
||||
{
|
||||
CString colHdrs[kNumVisibleColumns] = {
|
||||
"Pathname", "Type", "Aux", "Mod Date",
|
||||
"Format", "Size", "Ratio", "Packed", "Access"
|
||||
L"Pathname", L"Type", L"Aux", L"Mod Date",
|
||||
L"Format", L"Size", L"Ratio", L"Packed", L"Access"
|
||||
}; // these should come from string table, not hard-coded
|
||||
static int colFmt[kNumVisibleColumns] = {
|
||||
LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT, LVCFMT_LEFT,
|
||||
@ -90,7 +90,7 @@ int ContentList::OnCreate(LPCREATESTRUCT lpcs)
|
||||
LoadHeaderImages();
|
||||
CHeaderCtrl* pHeader = GetHeaderCtrl();
|
||||
if (pHeader == NULL)
|
||||
LOGI("GLITCH: couldn't get header ctrl");
|
||||
LOGW("GLITCH: couldn't get header ctrl");
|
||||
ASSERT(pHeader != NULL);
|
||||
pHeader->SetImageList(&fHdrImageList);
|
||||
|
||||
@ -114,7 +114,7 @@ int ContentList::OnCreate(LPCREATESTRUCT lpcs)
|
||||
|
||||
void ContentList::OnDestroy(void)
|
||||
{
|
||||
LOGI("ContentList OnDestroy");
|
||||
LOGD("ContentList OnDestroy");
|
||||
|
||||
ExportColumnWidths();
|
||||
CListCtrl::OnDestroy();
|
||||
@ -130,7 +130,7 @@ void ContentList::OnColumnClick(NMHDR* pnmh, LRESULT* pResult)
|
||||
{
|
||||
NM_LISTVIEW* pnmlv = (NM_LISTVIEW*) pnmh;
|
||||
|
||||
LOGI("OnColumnClick!!");
|
||||
LOGD("ContentList OnColumnClick");
|
||||
|
||||
if (fpLayout->GetSortColumn() == pnmlv->iSubItem)
|
||||
fpLayout->SetAscending(!fpLayout->GetAscending());
|
||||
@ -156,7 +156,7 @@ void ContentList::NewColumnWidths(void)
|
||||
int width = fpLayout->GetColumnWidth(i);
|
||||
if (width == ColumnLayout::kWidthDefaulted) {
|
||||
width = GetDefaultWidth(i);
|
||||
LOGI("Defaulting width %d to %d", i, width);
|
||||
LOGD("Defaulting width %d to %d", i, width);
|
||||
fpLayout->SetColumnWidth(i, width);
|
||||
}
|
||||
SetColumnWidth(i, width);
|
||||
@ -204,7 +204,7 @@ long* ContentList::GetSelectionSerials(long* pSelCount)
|
||||
long maxCount;
|
||||
|
||||
maxCount = GetSelectedCount();
|
||||
LOGI("GetSelectionSerials (maxCount=%d)", maxCount);
|
||||
LOGD("GetSelectionSerials (maxCount=%d)", maxCount);
|
||||
|
||||
if (maxCount > 0) {
|
||||
savedSel = new long[maxCount];
|
||||
@ -420,6 +420,7 @@ void ContentList::OnGetDispInfo(NMHDR* pnmh, LRESULT* pResult)
|
||||
wcscpy(plvdi->item.pszText, pEntry->GetDisplayName());
|
||||
}
|
||||
|
||||
#if 0 // no longer needed -- "display names" are converted to Unicode
|
||||
/*
|
||||
* Sanitize the string. This is really only necessary for
|
||||
* HFS, which has 8-bit "Macintosh Roman" filenames. The Win32
|
||||
@ -434,6 +435,7 @@ void ContentList::OnGetDispInfo(NMHDR* pnmh, LRESULT* pResult)
|
||||
str++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 1: // type
|
||||
MakeFileTypeDisplayString(pEntry, plvdi->item.pszText);
|
||||
@ -494,7 +496,7 @@ void ContentList::OnGetDispInfo(NMHDR* pnmh, LRESULT* pResult)
|
||||
/*
|
||||
* Helper functions for sort routine.
|
||||
*/
|
||||
static inline int CompareUnsignedLong(unsigned long u1, unsigned long u2)
|
||||
static inline int CompareUnsignedLong(uint32_t u1, uint32_t u2)
|
||||
{
|
||||
if (u1 < u2)
|
||||
return -1;
|
||||
|
@ -111,7 +111,7 @@ void ConvDiskOptionsDialog::ResetSizeControls(void)
|
||||
CString spaceReq;
|
||||
|
||||
LOGI("Resetting size controls");
|
||||
spaceReq.Format(IDS_CONVDISK_SPACEREQ, "(unknown)");
|
||||
spaceReq.Format(IDS_CONVDISK_SPACEREQ, L"(unknown)");
|
||||
pWnd = GetDlgItem(IDC_CONVDISK_SPACEREQ);
|
||||
ASSERT(pWnd != NULL);
|
||||
pWnd->SetWindowText(spaceReq);
|
||||
@ -129,8 +129,8 @@ void ConvDiskOptionsDialog::ResetSizeControls(void)
|
||||
|
||||
void ConvDiskOptionsDialog::LimitSizeControls(long totalBlocks, long blocksUsed)
|
||||
{
|
||||
LOGI("LimitSizeControls %ld %ld", totalBlocks, blocksUsed);
|
||||
LOGI("Full volume requires %ld bitmap blocks",
|
||||
LOGD("LimitSizeControls %ld %ld", totalBlocks, blocksUsed);
|
||||
LOGD("Full volume requires %ld bitmap blocks",
|
||||
NewDiskSize::GetNumBitmapBlocks_ProDOS(totalBlocks));
|
||||
|
||||
CWnd* pWnd;
|
||||
|
@ -951,7 +951,7 @@ int DiskArchive::InternalReload(CWnd* pMsgWnd)
|
||||
|
||||
int DiskArchive::LoadDiskFSContents(DiskFS* pDiskFS, const WCHAR* volName)
|
||||
{
|
||||
static const WCHAR* kBlankFileName = L"<blank filename>";
|
||||
static const char* kBlankFileNameMOR = "<blank filename>";
|
||||
A2File* pFile;
|
||||
DiskEntry* pNewEntry;
|
||||
DiskFS::SubVolume* pSubVol;
|
||||
@ -971,15 +971,15 @@ int DiskArchive::LoadDiskFSContents(DiskFS* pDiskFS, const WCHAR* volName)
|
||||
if (pNewEntry == NULL)
|
||||
return -1;
|
||||
|
||||
CString path(pFile->GetPathName());
|
||||
CStringA path(pFile->GetPathName());
|
||||
if (path.IsEmpty())
|
||||
path = kBlankFileName;
|
||||
path = kBlankFileNameMOR;
|
||||
if (DiskImg::UsesDOSFileStructure(pFile->GetFSFormat()) &&
|
||||
wantCoerceDOSFilenames)
|
||||
{
|
||||
InjectLowercase(&path);
|
||||
}
|
||||
pNewEntry->SetPathName(path);
|
||||
pNewEntry->SetPathNameMOR(path);
|
||||
if (volName[0] != '\0')
|
||||
pNewEntry->SetSubVolName(volName);
|
||||
pNewEntry->SetFssep(pFile->GetFssep());
|
||||
@ -2072,7 +2072,7 @@ bool DiskArchive::CreateSubdir(CWnd* pMsgWnd, GenericEntry* pParentEntry,
|
||||
if (pFile->IsVolumeDirectory()) {
|
||||
pathName = newName;
|
||||
} else {
|
||||
pathName = pParentEntry->GetPathName();
|
||||
pathName = pParentEntry->GetPathNameMOR();
|
||||
pathName += pParentEntry->GetFssep();
|
||||
pathName += newName;
|
||||
}
|
||||
@ -2192,9 +2192,10 @@ bool DiskArchive::DeleteSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
LOGI(" Deleting '%ls' from '%hs'", (LPCWSTR) pEntry->GetPathName(),
|
||||
LOGI(" Deleting '%ls' from '%hs'", (LPCWSTR) pEntry->GetPathNameUNI(),
|
||||
(LPCSTR) pFile->GetDiskFS()->GetVolumeName());
|
||||
SET_PROGRESS_UPDATE2(0, pEntry->GetPathName(), NULL);
|
||||
// TODO: should be using display name for progress updater?
|
||||
SET_PROGRESS_UPDATE2(0, pEntry->GetPathNameUNI(), NULL);
|
||||
|
||||
/*
|
||||
* Ask the DiskFS to delete the file. As soon as this completes,
|
||||
@ -2270,7 +2271,7 @@ bool DiskArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
RenameEntryDialog renameDlg(pMsgWnd);
|
||||
DiskEntry* pEntry = (DiskEntry*) pSelEntry->GetEntry();
|
||||
|
||||
LOGI(" Renaming '%ls'", pEntry->GetPathName());
|
||||
LOGI(" Renaming '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
|
||||
if (!SetRenameFields(pMsgWnd, pEntry, &renameDlg))
|
||||
break;
|
||||
|
||||
@ -2290,19 +2291,21 @@ bool DiskArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
dierr = pDiskFS->RenameFile(pFile, newNameA);
|
||||
if (dierr != kDIErrNone) {
|
||||
errMsg.Format(L"Unable to rename '%ls' to '%ls': %hs.",
|
||||
pEntry->GetPathName(), (LPCWSTR) renameDlg.fNewName,
|
||||
(LPCWSTR) pEntry->GetPathNameUNI(),
|
||||
(LPCWSTR) renameDlg.fNewName,
|
||||
DiskImgLib::DIStrError(dierr));
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
goto bail;
|
||||
}
|
||||
LOGD("Rename of '%ls' to '%ls' succeeded",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) renameDlg.fNewName);
|
||||
(LPCWSTR) pEntry->GetDisplayName(),
|
||||
(LPCWSTR) renameDlg.fNewName);
|
||||
} else if (result == IDCANCEL) {
|
||||
LOGI("Canceling out of remaining renames");
|
||||
break;
|
||||
} else {
|
||||
/* 3rd possibility is IDIGNORE, i.e. skip this entry */
|
||||
LOGI("Skipping rename of '%ls'", pEntry->GetDisplayName());
|
||||
LOGI("Skipping rename of '%ls'", (LPCWSTR) pEntry->GetDisplayName());
|
||||
}
|
||||
|
||||
pSelEntry = pSelSet->IterNext();
|
||||
@ -2341,20 +2344,20 @@ bool DiskArchive::SetRenameFields(CWnd* pMsgWnd, DiskEntry* pEntry,
|
||||
if (!pDiskFS->GetReadWriteSupported()) {
|
||||
CString errMsg;
|
||||
errMsg.Format(L"Unable to rename '%ls': operation not supported.",
|
||||
pEntry->GetPathName());
|
||||
(LPCWSTR) pEntry->GetPathNameUNI());
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
return false;
|
||||
}
|
||||
if (pDiskFS->GetFSDamaged()) {
|
||||
CString errMsg;
|
||||
errMsg.Format(L"Unable to rename '%ls': the disk it's on appears to be damaged.",
|
||||
pEntry->GetPathName());
|
||||
(LPCWSTR) pEntry->GetPathNameUNI());
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
pDialog->SetCanRenameFullPath(renameFullPath);
|
||||
pDialog->fOldName = pEntry->GetPathName();
|
||||
pDialog->fOldName = pEntry->GetPathNameUNI();
|
||||
pDialog->fFssep = pEntry->GetFssep();
|
||||
pDialog->fpArchive = this;
|
||||
pDialog->fpEntry = pEntry;
|
||||
@ -2576,7 +2579,7 @@ GenericArchive::XferStatus DiskArchive::XferSelection(CWnd* pMsgWnd,
|
||||
|
||||
if (pEntry->GetDamaged()) {
|
||||
LOGI(" XFER skipping damaged entry '%ls'",
|
||||
pEntry->GetDisplayName());
|
||||
(LPCWSTR) pEntry->GetDisplayName());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2584,15 +2587,14 @@ GenericArchive::XferStatus DiskArchive::XferSelection(CWnd* pMsgWnd,
|
||||
* Do a quick de-colonizing pass for non-ProDOS volumes, then prepend
|
||||
* the subvolume name (if any).
|
||||
*/
|
||||
fixedPathName = pEntry->GetPathName();
|
||||
fixedPathName = pEntry->GetPathNameUNI();
|
||||
if (fixedPathName.IsEmpty())
|
||||
fixedPathName = L"(no filename)";
|
||||
if (pEntry->GetFSFormat() != DiskImg::kFormatProDOS)
|
||||
fixedPathName.Replace(PathProposal::kDefaultStoredFssep, '.');
|
||||
if (pEntry->GetSubVolName() != NULL) {
|
||||
CString tmpStr;
|
||||
tmpStr = pEntry->GetSubVolName();
|
||||
tmpStr += (char)PathProposal::kDefaultStoredFssep;
|
||||
if (!pEntry->GetSubVolName().IsEmpty()) {
|
||||
CString tmpStr = pEntry->GetSubVolName();
|
||||
tmpStr += (char) PathProposal::kDefaultStoredFssep;
|
||||
tmpStr += fixedPathName;
|
||||
fixedPathName = tmpStr;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ END_MESSAGE_MAP()
|
||||
|
||||
void EditPropsDialog::InitProps(GenericEntry* pEntry)
|
||||
{
|
||||
fPathName = pEntry->GetPathName();
|
||||
fPathName = pEntry->GetPathNameUNI();
|
||||
fProps.fileType = pEntry->GetFileType();
|
||||
fProps.auxType = pEntry->GetAuxType();
|
||||
fProps.access = pEntry->GetAccess();
|
||||
|
@ -43,7 +43,8 @@ public:
|
||||
|
||||
// init the "extract from archive" side from a GenericEntry struct
|
||||
void Init(GenericEntry* pEntry) {
|
||||
fStoredPathName = pEntry->GetPathName();
|
||||
// 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;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "NufxArchive.h"
|
||||
#include "FileNameConv.h"
|
||||
#include "ContentList.h"
|
||||
#include "../reformat/ReformatBase.h"
|
||||
#include "Main.h"
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
@ -47,12 +48,7 @@
|
||||
*/
|
||||
|
||||
GenericEntry::GenericEntry(void)
|
||||
: fPathName(NULL),
|
||||
fFileName(NULL),
|
||||
fFileNameExtension(NULL),
|
||||
fFssep('\0'),
|
||||
fSubVolName(NULL),
|
||||
fDisplayName(NULL),
|
||||
: fFssep('\0'),
|
||||
fFileType(0),
|
||||
fAuxType(0),
|
||||
fAccess(0),
|
||||
@ -77,24 +73,24 @@ GenericEntry::GenericEntry(void)
|
||||
{
|
||||
}
|
||||
|
||||
GenericEntry::~GenericEntry(void)
|
||||
{
|
||||
delete[] fPathName;
|
||||
delete[] fSubVolName;
|
||||
delete[] fDisplayName;
|
||||
}
|
||||
GenericEntry::~GenericEntry(void) {}
|
||||
|
||||
void GenericEntry::SetPathName(const WCHAR* path)
|
||||
void GenericEntry::SetPathNameMOR(const char* path)
|
||||
{
|
||||
ASSERT(path != NULL && wcslen(path) > 0);
|
||||
if (fPathName != NULL)
|
||||
delete fPathName;
|
||||
fPathName = wcsdup(path);
|
||||
ASSERT(path != NULL && strlen(path) > 0);
|
||||
fPathNameMOR = path;
|
||||
// nuke the derived fields
|
||||
fFileName = NULL;
|
||||
fFileNameExtension = NULL;
|
||||
delete[] fDisplayName;
|
||||
fDisplayName = NULL;
|
||||
fFileName = L"";
|
||||
fFileNameExtension = L"";
|
||||
fDisplayName = L"";
|
||||
|
||||
/*
|
||||
* Generate the Unicode representation from the Mac OS Roman source.
|
||||
* For now, we just treat the input as CP-1252.
|
||||
*
|
||||
* TODO(Unicode)
|
||||
*/
|
||||
fPathNameUNI = fPathNameMOR;
|
||||
|
||||
/*
|
||||
* Warning: to be 100% pedantically correct here, we should NOT do this
|
||||
@ -103,62 +99,73 @@ void GenericEntry::SetPathName(const WCHAR* path)
|
||||
* the underscorage until the first GetPathName call.
|
||||
*/
|
||||
const Preferences* pPreferences = GET_PREFERENCES();
|
||||
if (pPreferences->GetPrefBool(kPrSpacesToUnder))
|
||||
SpacesToUnderscores(fPathName);
|
||||
if (pPreferences->GetPrefBool(kPrSpacesToUnder)) {
|
||||
SpacesToUnderscores(&fPathNameMOR);
|
||||
}
|
||||
}
|
||||
|
||||
const WCHAR* GenericEntry::GetFileName(void)
|
||||
const CString& GenericEntry::GetFileName(void)
|
||||
{
|
||||
ASSERT(fPathName != NULL);
|
||||
if (fFileName == NULL)
|
||||
fFileName = PathName::FilenameOnly(fPathName, fFssep);
|
||||
ASSERT(!fPathNameMOR.IsEmpty());
|
||||
if (fFileName.IsEmpty()) {
|
||||
fFileName = PathName::FilenameOnly(fPathNameUNI, fFssep);
|
||||
}
|
||||
return fFileName;
|
||||
}
|
||||
|
||||
const WCHAR* GenericEntry::GetFileNameExtension(void)
|
||||
const CString& GenericEntry::GetFileNameExtension(void)
|
||||
{
|
||||
ASSERT(fPathName != NULL);
|
||||
if (fFileNameExtension == NULL)
|
||||
fFileNameExtension = PathName::FindExtension(fPathName, fFssep);
|
||||
ASSERT(!fPathNameMOR.IsEmpty());
|
||||
if (fFileNameExtension.IsEmpty()) {
|
||||
fFileNameExtension = PathName::FindExtension(fPathNameUNI, fFssep);
|
||||
}
|
||||
return fFileNameExtension;
|
||||
}
|
||||
|
||||
CStringA GenericEntry::GetFileNameExtensionA(void)
|
||||
const CStringA& GenericEntry::GetFileNameExtensionMOR(void)
|
||||
{
|
||||
return GetFileNameExtension();
|
||||
ASSERT(!fPathNameMOR.IsEmpty());
|
||||
if (fFileNameExtensionMOR.IsEmpty()) {
|
||||
CString str = PathName::FindExtension(fPathNameUNI, fFssep);
|
||||
// TODO(Unicode): either get the extension from the MOR filename,
|
||||
// or convert this properly from Unicode to MOR (not CP-1252).
|
||||
fFileNameExtensionMOR = str;
|
||||
}
|
||||
return fFileNameExtensionMOR;
|
||||
}
|
||||
|
||||
void GenericEntry::SetSubVolName(const WCHAR* name)
|
||||
{
|
||||
delete[] fSubVolName;
|
||||
fSubVolName = NULL;
|
||||
if (name != NULL) {
|
||||
fSubVolName = wcsdup(name);
|
||||
}
|
||||
fSubVolName = name;
|
||||
}
|
||||
|
||||
const WCHAR* GenericEntry::GetDisplayName(void) const
|
||||
// Simple Mac OS Roman to Unicode conversion.
|
||||
static CString ConvertMORToUNI(const CStringA& strMOR)
|
||||
{
|
||||
ASSERT(fPathName != NULL);
|
||||
if (fDisplayName != NULL)
|
||||
return fDisplayName;
|
||||
|
||||
// TODO: hmm...
|
||||
GenericEntry* pThis = const_cast<GenericEntry*>(this);
|
||||
|
||||
int len = wcslen(fPathName) +1;
|
||||
if (fSubVolName != NULL)
|
||||
len += wcslen(fSubVolName) +1;
|
||||
pThis->fDisplayName = new WCHAR[len];
|
||||
if (fSubVolName != NULL) {
|
||||
WCHAR xtra[2] = { DiskFS::kDIFssep, '\0' };
|
||||
wcscpy(pThis->fDisplayName, fSubVolName);
|
||||
wcscat(pThis->fDisplayName, xtra);
|
||||
} else {
|
||||
pThis->fDisplayName[0] = '\0';
|
||||
// We know that all MOR characters are represented in Unicode with a
|
||||
// single BMP code point, so we know that strlen(MOR) == wcslen(UNI).
|
||||
const int len = strMOR.GetLength();
|
||||
CString strUNI;
|
||||
WCHAR* uniBuf = strUNI.GetBuffer(len);
|
||||
for (int i = 0; i < len; i++) {
|
||||
uniBuf[i] = ReformatText::ConvertMacRomanToUTF16(strMOR[i]);
|
||||
}
|
||||
wcscat(pThis->fDisplayName, fPathName);
|
||||
return pThis->fDisplayName;
|
||||
strUNI.ReleaseBuffer(len);
|
||||
return strUNI;
|
||||
}
|
||||
|
||||
const CString& GenericEntry::GetDisplayName(void) const
|
||||
{
|
||||
ASSERT(!fPathNameMOR.IsEmpty());
|
||||
if (!fDisplayName.IsEmpty()) {
|
||||
return fDisplayName;
|
||||
}
|
||||
|
||||
if (!fSubVolName.IsEmpty()) {
|
||||
fDisplayName = fSubVolName + (WCHAR) DiskFS::kDIFssep;
|
||||
}
|
||||
fDisplayName += ConvertMORToUNI(fPathNameMOR);
|
||||
return fDisplayName;
|
||||
}
|
||||
|
||||
const WCHAR* GenericEntry::GetFileTypeString(void) const
|
||||
@ -166,13 +173,9 @@ const WCHAR* GenericEntry::GetFileTypeString(void) const
|
||||
return PathProposal::FileTypeString(fFileType);
|
||||
}
|
||||
|
||||
/*static*/ void GenericEntry::SpacesToUnderscores(WCHAR* buf)
|
||||
/*static*/ void GenericEntry::SpacesToUnderscores(CStringA* pStr)
|
||||
{
|
||||
while (*buf != '\0') {
|
||||
if (*buf == ' ')
|
||||
*buf = '_';
|
||||
buf++;
|
||||
}
|
||||
pStr->Replace(' ', '_');
|
||||
}
|
||||
|
||||
/*static*/ bool GenericEntry::CheckHighASCII(const uint8_t* buffer,
|
||||
@ -1091,7 +1094,7 @@ void SelectionSet::AddToSet(GenericEntry* pEntry, int threadMask)
|
||||
{
|
||||
SelectionEntry* pSelEntry;
|
||||
|
||||
LOGV(" Sel '%ls'", pEntry->GetPathName());
|
||||
LOGV(" Sel '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
|
||||
|
||||
if (!(threadMask & GenericEntry::kAllowVolumeDir) &&
|
||||
pEntry->GetRecordKind() == GenericEntry::kRecordKindVolumeDir)
|
||||
@ -1197,7 +1200,7 @@ void SelectionSet::Dump(void)
|
||||
|
||||
pEntry = fEntryHead;
|
||||
while (pEntry != NULL) {
|
||||
LOGI(" : name='%ls'", pEntry->GetEntry()->GetPathName());
|
||||
LOGI(" : name='%ls'", (LPCWSTR) pEntry->GetEntry()->GetPathNameUNI());
|
||||
pEntry = pEntry->GetNext();
|
||||
}
|
||||
}
|
||||
|
@ -191,14 +191,29 @@ public:
|
||||
long GetIndex(void) const { return fIndex; }
|
||||
void SetIndex(long idx) { fIndex = idx; }
|
||||
|
||||
const WCHAR* GetPathName(void) const { return fPathName; }
|
||||
void SetPathName(const WCHAR* path);
|
||||
const WCHAR* GetFileName(void);
|
||||
const WCHAR* GetFileNameExtension(void); // returns e.g. ".SHK"
|
||||
CStringA GetFileNameExtensionA(void);
|
||||
/*
|
||||
* Set the pathname. This comes from a file archive or disk image,
|
||||
* so it's always in Mac OS Roman format.
|
||||
*
|
||||
* Calling this will invalidate any strings previously returned by
|
||||
* GetPathName*(), GetFileName*(), and GetDisplayName().
|
||||
*/
|
||||
void SetPathNameMOR(const char* pathNameMOR);
|
||||
|
||||
const CStringA& GetPathNameMOR(void) const { return fPathNameMOR; }
|
||||
const CString& GetPathNameUNI(void) const { return fPathNameUNI; }
|
||||
const CString& GetFileName(void);
|
||||
const CString& GetFileNameExtension(void); // returns e.g. ".SHK"
|
||||
const CStringA& GetFileNameExtensionMOR(void);
|
||||
/*
|
||||
* Returns the "display" name. This is a combination of the sub-volume
|
||||
* name and the path name. This string is intended for display only,
|
||||
* and may include characters that aren't legal on the filesystem.
|
||||
*/
|
||||
const CString& GetDisplayName(void) const;
|
||||
|
||||
void SetSubVolName(const WCHAR* name);
|
||||
const WCHAR* GetSubVolName(void) const { return fSubVolName; }
|
||||
const WCHAR* GetDisplayName(void) const; // not really "const"
|
||||
const CString& GetSubVolName(void) const { return fSubVolName; }
|
||||
|
||||
char GetFssep(void) const { return fFssep; }
|
||||
void SetFssep(char fssep) { fFssep = fssep; }
|
||||
@ -287,19 +302,32 @@ public:
|
||||
size_t len, ConvertEOL* pConv, ConvertHighASCII* pConvHA,
|
||||
bool* pLastCR);
|
||||
|
||||
protected:
|
||||
private:
|
||||
/*
|
||||
* Convert spaces to underscores, modifying the string.
|
||||
*/
|
||||
static void SpacesToUnderscores(WCHAR* buf);
|
||||
static void SpacesToUnderscores(CStringA* pStr);
|
||||
|
||||
private:
|
||||
WCHAR* fPathName;
|
||||
const WCHAR* fFileName; // points within fPathName
|
||||
const WCHAR* fFileNameExtension; // points within fPathName
|
||||
/*
|
||||
* This represents a file from an archive or disk image, so the Mac OS
|
||||
* Roman representation is the "true" version. The Unicode version
|
||||
* is how we will use it on Windows (e.g. for file extraction), so
|
||||
* it will be a CP-1252 conversion until the various libraries
|
||||
* support UTF-16 filenames.
|
||||
*
|
||||
* The "display name" is only used for display, and should do a proper
|
||||
* MOR to Unicode conversion so the file name looks right.
|
||||
*/
|
||||
|
||||
CStringA fPathNameMOR; // original path name, Mac OS Roman chars
|
||||
CString fPathNameUNI; // Unicode conversion
|
||||
CString fFileName; // filename component of fPathNameUNI
|
||||
CString fFileNameExtension; // filename extension from fPathNameUNI
|
||||
CStringA fFileNameExtensionMOR;
|
||||
char fFssep;
|
||||
WCHAR* fSubVolName; // sub-volume prefix, or NULL if none
|
||||
WCHAR* fDisplayName; // combination of sub-vol and path
|
||||
CString fSubVolName; // sub-volume prefix, or NULL if none
|
||||
mutable CString fDisplayName; // combination of sub-vol and path
|
||||
uint32_t fFileType;
|
||||
uint32_t fAuxType;
|
||||
uint32_t fAccess;
|
||||
|
@ -1422,11 +1422,11 @@ void MainWindow::HandleDoubleClick(void)
|
||||
if (pEntry == NULL)
|
||||
return;
|
||||
|
||||
LOGI(" Double-click GOT '%ls'", pEntry->GetPathName());
|
||||
LOGI(" Double-click got '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
|
||||
const WCHAR* ext;
|
||||
long fileType, auxType;
|
||||
|
||||
ext = PathName::FindExtension(pEntry->GetPathName(), pEntry->GetFssep());
|
||||
ext = PathName::FindExtension(pEntry->GetPathNameUNI(), pEntry->GetFssep());
|
||||
fileType = pEntry->GetFileType();
|
||||
auxType = pEntry->GetAuxType();
|
||||
|
||||
@ -1587,7 +1587,7 @@ int MainWindow::TmpExtractForExternal(GenericEntry* pEntry)
|
||||
{
|
||||
const WCHAR* ext;
|
||||
|
||||
ext = PathName::FindExtension(pEntry->GetPathName(), pEntry->GetFssep());
|
||||
ext = PathName::FindExtension(pEntry->GetPathNameUNI(), pEntry->GetFssep());
|
||||
|
||||
WCHAR nameBuf[MAX_PATH];
|
||||
UINT unique;
|
||||
|
@ -796,8 +796,7 @@ NuResult NufxArchive::ContentFunc(NuArchive* pArchive, void* vpRecord)
|
||||
|
||||
pNewEntry = new NufxEntry(pArchive);
|
||||
|
||||
CStringW filenameW(pRecord->filenameMOR);
|
||||
pNewEntry->SetPathName(filenameW);
|
||||
pNewEntry->SetPathNameMOR(pRecord->filenameMOR);
|
||||
pNewEntry->SetFssep(NuGetSepFromSysInfo(pRecord->recFileSysInfo));
|
||||
pNewEntry->SetFileType(pRecord->recFileType);
|
||||
pNewEntry->SetAuxType(pRecord->recExtraType);
|
||||
@ -1389,7 +1388,7 @@ bool NufxArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
pEntry = (NufxEntry*) pSelEntry->GetEntry();
|
||||
|
||||
LOGI(" Testing %ld '%ls'", pEntry->GetRecordIdx(),
|
||||
pEntry->GetPathName());
|
||||
(LPCWSTR) pEntry->GetPathNameUNI());
|
||||
nerr = NuTestRecord(fpArchive, pEntry->GetRecordIdx());
|
||||
if (nerr != kNuErrNone) {
|
||||
if (nerr == kNuErrAborted) {
|
||||
@ -1399,7 +1398,7 @@ bool NufxArchive::TestSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
pMsgWnd->MessageBox(errMsg, title, MB_OK);
|
||||
} else {
|
||||
errMsg.Format(L"Failed while testing '%ls': %hs.",
|
||||
pEntry->GetPathName(), NuStrError(nerr));
|
||||
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
}
|
||||
goto bail;
|
||||
@ -1443,7 +1442,7 @@ bool NufxArchive::DeleteSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
pEntry = (NufxEntry*) pSelEntry->GetEntry();
|
||||
|
||||
LOGI(" Deleting %ld '%ls'", pEntry->GetRecordIdx(),
|
||||
pEntry->GetPathName());
|
||||
(LPCWSTR) pEntry->GetPathNameUNI());
|
||||
nerr = NuDeleteRecord(fpArchive, pEntry->GetRecordIdx());
|
||||
if (nerr != kNuErrNone) {
|
||||
errMsg.Format(L"Unable to delete record %d: %hs.",
|
||||
@ -1512,12 +1511,12 @@ bool NufxArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
SelectionEntry* pSelEntry = pSelSet->IterNext();
|
||||
while (pSelEntry != NULL) {
|
||||
NufxEntry* pEntry = (NufxEntry*) pSelEntry->GetEntry();
|
||||
LOGI(" Renaming '%ls'", pEntry->GetPathName());
|
||||
LOGD(" Renaming '%ls'", (LPCWSTR) pEntry->GetPathNameUNI());
|
||||
|
||||
RenameEntryDialog renameDlg(pMsgWnd);
|
||||
renameDlg.SetCanRenameFullPath(renameFullPath);
|
||||
renameDlg.SetCanChangeFssep(true);
|
||||
renameDlg.fOldName = pEntry->GetPathName();
|
||||
renameDlg.fOldName = pEntry->GetPathNameUNI();
|
||||
renameDlg.fFssep = pEntry->GetFssep();
|
||||
renameDlg.fpArchive = this;
|
||||
renameDlg.fpEntry = pEntry;
|
||||
@ -1530,19 +1529,19 @@ bool NufxArchive::RenameSelection(CWnd* pMsgWnd, SelectionSet* pSelSet)
|
||||
nerr = NuRename(fpArchive, pEntry->GetRecordIdx(),
|
||||
newNameA, renameDlg.fFssep);
|
||||
if (nerr != kNuErrNone) {
|
||||
errMsg.Format(L"Unable to rename '%ls': %hs.", pEntry->GetPathName(),
|
||||
NuStrError(nerr));
|
||||
errMsg.Format(L"Unable to rename '%ls': %hs.",
|
||||
(LPCWSTR) pEntry->GetPathNameUNI(), NuStrError(nerr));
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
break;
|
||||
}
|
||||
LOGI("Rename of '%ls' to '%ls' succeeded",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) renameDlg.fNewName);
|
||||
LOGD("Rename of '%ls' to '%ls' succeeded",
|
||||
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) renameDlg.fNewName);
|
||||
} else if (result == IDCANCEL) {
|
||||
LOGI("Canceling out of remaining renames");
|
||||
break;
|
||||
} else {
|
||||
/* 3rd possibility is IDIGNORE, i.e. skip this entry */
|
||||
LOGI("Skipping rename of '%ls'", pEntry->GetDisplayName());
|
||||
LOGI("Skipping rename of '%ls'", (LPCWSTR) pEntry->GetDisplayName());
|
||||
}
|
||||
|
||||
pSelEntry = pSelSet->IterNext();
|
||||
@ -1606,7 +1605,7 @@ CString NufxArchive::TestPathName(const GenericEntry* pGenericEntry,
|
||||
pEntry = GetEntries();
|
||||
while (pEntry != NULL) {
|
||||
if (pEntry != pGenericEntry &&
|
||||
ComparePaths(pEntry->GetPathName(), pEntry->GetFssep(),
|
||||
ComparePaths(pEntry->GetPathNameUNI(), pEntry->GetFssep(),
|
||||
newName, newFssep) == 0)
|
||||
{
|
||||
errMsg = L"An entry with that name already exists.";
|
||||
@ -1726,7 +1725,7 @@ bool NufxArchive::RecompressSelection(CWnd* pMsgWnd, SelectionSet* pSelSet,
|
||||
ASSERT(pEntry != NULL);
|
||||
CString dispStr;
|
||||
dispStr.Format(L"Failed while recompressing '%ls': %ls.",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
goto bail;
|
||||
}
|
||||
@ -1774,14 +1773,14 @@ bool NufxArchive::RecompressThread(NufxEntry* pEntry, int threadKind,
|
||||
char* buf = NULL;
|
||||
long len = 0;
|
||||
|
||||
LOGI(" Recompressing %ld '%ls'", pEntry->GetRecordIdx(),
|
||||
pEntry->GetDisplayName());
|
||||
LOGD(" Recompressing %ld '%ls'", pEntry->GetRecordIdx(),
|
||||
(LPCWSTR) pEntry->GetDisplayName());
|
||||
|
||||
/* get a copy of the thread header */
|
||||
pEntry->FindThreadInfo(threadKind, &thread, pErrMsg);
|
||||
if (!pErrMsg->IsEmpty()) {
|
||||
pErrMsg->Format(L"Unable to locate thread for %ls (type %d)",
|
||||
pEntry->GetDisplayName(), threadKind);
|
||||
(LPCWSTR) pEntry->GetDisplayName(), threadKind);
|
||||
goto bail;
|
||||
}
|
||||
threadID = NuGetThreadID(&thread);
|
||||
@ -1789,7 +1788,8 @@ bool NufxArchive::RecompressThread(NufxEntry* pEntry, int threadKind,
|
||||
/* if it's already in the target format, skip it */
|
||||
if (thread.thThreadFormat == pRecompOpts->fCompressionType) {
|
||||
LOGI("Skipping (fmt=%d) '%ls'",
|
||||
pRecompOpts->fCompressionType, pEntry->GetDisplayName());
|
||||
pRecompOpts->fCompressionType,
|
||||
(LPCWSTR) pEntry->GetDisplayName());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1802,7 +1802,7 @@ bool NufxArchive::RecompressThread(NufxEntry* pEntry, int threadKind,
|
||||
goto bail; /* abort anything that was pending */
|
||||
} else if (result != IDOK) {
|
||||
pErrMsg->Format(L"Failed while extracting '%ls': %ls",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) subErrMsg);
|
||||
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) subErrMsg);
|
||||
goto bail;
|
||||
}
|
||||
*pSizeInMemory += len;
|
||||
@ -1884,13 +1884,24 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
|
||||
/* in case we start handling CRC errors better */
|
||||
if (pEntry->GetDamaged()) {
|
||||
LOGI(" XFER skipping damaged entry '%ls'",
|
||||
pEntry->GetDisplayName());
|
||||
(LPCWSTR) pEntry->GetDisplayName());
|
||||
continue;
|
||||
}
|
||||
|
||||
LOGD(" XFER converting '%ls'", pEntry->GetDisplayName());
|
||||
LOGD(" XFER converting '%ls'", (LPCWSTR) pEntry->GetDisplayName());
|
||||
|
||||
fileDetails.SetStrippedLocalPathName(pEntry->GetDisplayName());
|
||||
// Generate a name that is the combination of the sub-volume name
|
||||
// (if any) and the path name. This is likely the same as the
|
||||
// "display name", but that is officially for display only, and
|
||||
// shouldn't be used for this.
|
||||
CString xferName;
|
||||
const CString& subVolName = pEntry->GetSubVolName();
|
||||
if (!subVolName.IsEmpty()) {
|
||||
xferName = subVolName + (WCHAR) DiskFS::kDIFssep;
|
||||
}
|
||||
xferName += pEntry->GetPathNameUNI();
|
||||
|
||||
fileDetails.SetStrippedLocalPathName(xferName);
|
||||
fileDetails.SetFssep(PathProposal::kDefaultStoredFssep);
|
||||
fileDetails.SetFileSysFmt(DiskImg::kFormatUnknown);
|
||||
fileDetails.SetFileType(pEntry->GetFileType());
|
||||
@ -1935,7 +1946,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
|
||||
goto bail; /* abort anything that was pending */
|
||||
} else if (result != IDOK) {
|
||||
dispMsg.Format(L"Failed while extracting '%ls': %ls.",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
ShowFailureMsg(pMsgWnd, dispMsg, IDS_FAILED);
|
||||
goto bail;
|
||||
}
|
||||
@ -1956,7 +1967,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
|
||||
goto bail; /* abort anything that was pending */
|
||||
} else if (result != IDOK) {
|
||||
dispMsg.Format(L"Failed while extracting '%ls': %ls.",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
ShowFailureMsg(pMsgWnd, dispMsg, IDS_FAILED);
|
||||
goto bail;
|
||||
}
|
||||
@ -1979,7 +1990,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
|
||||
goto bail; /* abort anything that was pending */
|
||||
} else if (result != IDOK) {
|
||||
dispMsg.Format(L"Failed while extracting '%ls': %ls.",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
ShowFailureMsg(pMsgWnd, dispMsg, IDS_FAILED);
|
||||
goto bail;
|
||||
}
|
||||
@ -1991,7 +2002,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
|
||||
|
||||
if (dataLen < 0 && rsrcLen < 0) {
|
||||
LOGI(" XFER: WARNING: nothing worth transferring in '%ls'",
|
||||
pEntry->GetDisplayName());
|
||||
(LPCWSTR) pEntry->GetDisplayName());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2000,7 +2011,7 @@ GenericArchive::XferStatus NufxArchive::XferSelection(CWnd* pMsgWnd,
|
||||
if (!errMsg.IsEmpty()) {
|
||||
LOGI("XferFile failed!");
|
||||
errMsg.Format(L"Failed while transferring '%ls': %ls.",
|
||||
pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
(LPCWSTR) pEntry->GetDisplayName(), (LPCWSTR) errMsg);
|
||||
ShowFailureMsg(pMsgWnd, errMsg, IDS_FAILED);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -764,10 +764,10 @@ int ViewFilesDialog::ReformatPrep(GenericEntry* pEntry)
|
||||
pEntry->GetFileType(),
|
||||
pEntry->GetAuxType(),
|
||||
MainWindow::ReformatterSourceFormat(pEntry->GetSourceFS()),
|
||||
pEntry->GetFileNameExtensionA());
|
||||
pEntry->GetFileNameExtensionMOR());
|
||||
|
||||
/* figure out which reformatters apply to this file */
|
||||
LOGI("Testing reformatters");
|
||||
LOGD("Testing reformatters");
|
||||
fpHolder->TestApplicability();
|
||||
|
||||
return 0;
|
||||
|
13
mdc/Main.cpp
13
mdc/Main.cpp
@ -674,7 +674,9 @@ static const char gFileTypeNames[256][4] = {
|
||||
* Sanitize a string. The Mac likes to stick control characters into
|
||||
* things, e.g. ^C and ^M, and uses high ASCII for special characters.
|
||||
*
|
||||
* TODO: use Mac Roman unicode translation instead
|
||||
* TODO(Unicode): we could do a Mac OS Roman to Unicode conversion, but
|
||||
* we'd probably want to output UTF-8 (which Windows accessories like
|
||||
* Notepad *are* able to read).
|
||||
*/
|
||||
static void MacSanitize(char* str)
|
||||
{
|
||||
@ -687,7 +689,7 @@ static void MacSanitize(char* str)
|
||||
int MainWindow::LoadDiskFSContents(DiskFS* pDiskFS, const char* volName,
|
||||
ScanOpts* pScanOpts)
|
||||
{
|
||||
static const char* kBlankFileName = "<blank filename>";
|
||||
static const char* kBlankFileNameMOR = "<blank filename>";
|
||||
DiskFS::SubVolume* pSubVol = NULL;
|
||||
A2File* pFile;
|
||||
|
||||
@ -714,11 +716,10 @@ int MainWindow::LoadDiskFSContents(DiskFS* pDiskFS, const char* volName,
|
||||
const char* ccp = pFile->GetPathName();
|
||||
ASSERT(ccp != NULL);
|
||||
if (strlen(ccp) == 0)
|
||||
ccp = kBlankFileName;
|
||||
ccp = kBlankFileNameMOR;
|
||||
|
||||
CString path(ccp);
|
||||
if (DiskImg::UsesDOSFileStructure(pFile->GetFSFormat()) && 0)
|
||||
{
|
||||
CStringA path(ccp);
|
||||
if (DiskImg::UsesDOSFileStructure(pFile->GetFSFormat()) && 0) {
|
||||
InjectLowercase(&path);
|
||||
}
|
||||
|
||||
|
@ -284,6 +284,13 @@ public:
|
||||
kRTFFlagColorTable = 1, // include color table
|
||||
};
|
||||
|
||||
// Convert a Mac OS Roman character value (from a IIgs document) to
|
||||
// its UTF-16 Unicode equivalent. This also includes a conversion
|
||||
// for the control characters.
|
||||
static uint16_t ConvertMacRomanToUTF16(uint8_t ch) {
|
||||
return kUTF16Conv[ch];
|
||||
}
|
||||
|
||||
protected:
|
||||
void RTFBegin(int flags = 0);
|
||||
void RTFEnd(void);
|
||||
@ -373,20 +380,13 @@ protected:
|
||||
|
||||
// Convert a Mac OS Roman character value (from a IIgs document) to
|
||||
// an 8-bit Windows CP1252 equivalent.
|
||||
uint8_t ConvertMacRomanTo1252(uint8_t ch) {
|
||||
static uint8_t ConvertMacRomanTo1252(uint8_t ch) {
|
||||
if (ch < 128)
|
||||
return ch;
|
||||
else
|
||||
return kCP1252Conv[ch-128];
|
||||
}
|
||||
|
||||
// Convert a Mac OS Roman character value (from a IIgs document) to
|
||||
// its UTF-16 Unicode equivalent. This also includes a conversion
|
||||
// for the control characters.
|
||||
uint16_t ConvertMacRomanToUTF16(uint8_t ch) {
|
||||
return kUTF16Conv[ch];
|
||||
}
|
||||
|
||||
void CheckGSCharConv(void);
|
||||
|
||||
private:
|
||||
|
@ -627,29 +627,29 @@ void VectorizeString(WCHAR* mangle, WCHAR** argv, int* pArgc)
|
||||
* Convert a sub-string to lower case according to rules for English book
|
||||
* titles. Assumes the initial string is in all caps.
|
||||
*/
|
||||
static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
|
||||
static void DowncaseSubstring(CStringA* pStr, int startPos, int endPos,
|
||||
bool prevWasSpace)
|
||||
{
|
||||
static const WCHAR* shortWords[] = {
|
||||
L"of", L"the", L"a", L"an", L"and", L"to", L"in"
|
||||
static const char* shortWords[] = {
|
||||
"of", "the", "a", "an", "and", "to", "in"
|
||||
};
|
||||
static const WCHAR* leaveAlone[] = {
|
||||
L"BBS", L"3D"
|
||||
static const char* leaveAlone[] = {
|
||||
"BBS", "3D"
|
||||
};
|
||||
static const WCHAR* justLikeThis[] = {
|
||||
L"ProDOS", L"IIe", L"IIc", L"IIgs"
|
||||
static const char* justLikeThis[] = {
|
||||
"ProDOS", "IIe", "IIc", "IIgs"
|
||||
};
|
||||
CString token;
|
||||
CStringA token;
|
||||
bool firstCap = true;
|
||||
int i;
|
||||
|
||||
token = pStr->Mid(startPos, endPos - startPos);
|
||||
LOGV(" TOKEN: '%ls'", (LPCWSTR) token);
|
||||
LOGV(" TOKEN: '%s'", (LPCSTR) token);
|
||||
|
||||
/* these words are left alone */
|
||||
for (i = 0; i < NELEM(leaveAlone); i++) {
|
||||
if (token.CompareNoCase(leaveAlone[i]) == 0) {
|
||||
LOGV(" Leaving alone '%ls'", (LPCWSTR) token);
|
||||
LOGV(" Leaving alone '%s'", (LPCSTR) token);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -657,7 +657,7 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
|
||||
/* words with specific capitalization */
|
||||
for (i = 0; i < NELEM(justLikeThis); i++) {
|
||||
if (token.CompareNoCase(justLikeThis[i]) == 0) {
|
||||
LOGI(" Setting '%ls' to '%ls'", (LPCWSTR) token, justLikeThis[i]);
|
||||
LOGI(" Setting '%s' to '%s'", (LPCSTR) token, justLikeThis[i]);
|
||||
for (int j = startPos; j < endPos; j++)
|
||||
pStr->SetAt(j, justLikeThis[i][j - startPos]);
|
||||
return;
|
||||
@ -668,7 +668,7 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
|
||||
if (prevWasSpace) {
|
||||
for (i = 0; i < NELEM(shortWords); i++) {
|
||||
if (token.CompareNoCase(shortWords[i]) == 0) {
|
||||
LOGV(" No leading cap for '%ls'", (LPCWSTR) token);
|
||||
LOGV(" No leading cap for '%s'", (LPCSTR) token);
|
||||
firstCap = false;
|
||||
break;
|
||||
}
|
||||
@ -676,9 +676,9 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
|
||||
}
|
||||
|
||||
/* check for roman numerals; we leave those capitalized */
|
||||
CString romanTest = token.SpanIncluding(L"IVX");
|
||||
CString romanTest = token.SpanIncluding("IVX");
|
||||
if (romanTest.GetLength() == token.GetLength()) {
|
||||
LOGV(" Looks like roman numerals '%ls'", (LPCWSTR) token);
|
||||
LOGV(" Looks like roman numerals '%s'", (LPCSTR) token);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -690,10 +690,10 @@ static void DowncaseSubstring(CString* pStr, int startPos, int endPos,
|
||||
}
|
||||
}
|
||||
|
||||
void InjectLowercase(CString* pStr)
|
||||
void InjectLowercase(CStringA* pStr)
|
||||
{
|
||||
int len = pStr->GetLength();
|
||||
static const WCHAR* kGapChars = L" .:&-+/\\()<>@*";
|
||||
static const char kGapChars[] = " .:&-+/\\()<>@*";
|
||||
int startPos, endPos;
|
||||
|
||||
//*pStr = "AND PRODOS FOR THE IIGS";
|
||||
@ -701,7 +701,7 @@ void InjectLowercase(CString* pStr)
|
||||
//LOGI("InjectLowercase: '%ls'", (LPCWSTR) *pStr);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
WCHAR ch = pStr->GetAt(i);
|
||||
char ch = pStr->GetAt(i);
|
||||
if (ch >= 'a' && ch <= 'z') {
|
||||
LOGI("Found lowercase 0x%04x, skipping InjectLower", ch);
|
||||
return;
|
||||
@ -711,10 +711,10 @@ void InjectLowercase(CString* pStr)
|
||||
startPos = 0;
|
||||
while (startPos < len) {
|
||||
/* find start of token */
|
||||
WCHAR ch;
|
||||
char ch;
|
||||
do {
|
||||
ch = pStr->GetAt(startPos);
|
||||
if (wcschr(kGapChars, ch) == NULL)
|
||||
if (strchr(kGapChars, ch) == NULL)
|
||||
break;
|
||||
startPos++;
|
||||
} while (startPos < len);
|
||||
@ -725,7 +725,7 @@ void InjectLowercase(CString* pStr)
|
||||
endPos = startPos + 1;
|
||||
while (endPos < len) {
|
||||
ch = pStr->GetAt(endPos);
|
||||
if (wcschr(kGapChars, ch) != NULL)
|
||||
if (strchr(kGapChars, ch) != NULL)
|
||||
break;
|
||||
endPos++;
|
||||
}
|
||||
|
@ -253,11 +253,11 @@ const WCHAR* Stristr(const WCHAR* string1, const WCHAR* string2);
|
||||
void VectorizeString(WCHAR* mangle, WCHAR** argv, int* pArgc);
|
||||
|
||||
/*
|
||||
* Convert parts of the filename to lower case.
|
||||
* Convert parts of the Mac OS Roman filename to lower case.
|
||||
*
|
||||
* If the name already has lowercase characters, do nothing.
|
||||
*/
|
||||
void InjectLowercase(CString* pStr);
|
||||
void InjectLowercase(CStringA* pStr);
|
||||
|
||||
/*
|
||||
* Test to see if a sub-string matches a value in a set of strings. The set
|
||||
|
Loading…
Reference in New Issue
Block a user