mirror of
https://github.com/depp/syncfiles.git
synced 2024-12-22 02:29:56 +00:00
Parse project file header
On opening a project, SyncFiles will now parse the project header and present an error message if there are any problems with the header.
This commit is contained in:
parent
f8c84387ca
commit
08e5f10ce4
@ -26,9 +26,12 @@ static const OSType kFileTypes[] = {kTypeProject};
|
||||
// HandleOpen handles the Open menu command.
|
||||
static void HandleOpen(void)
|
||||
{
|
||||
StandardFileReply sfreply;
|
||||
StandardFileReply reply;
|
||||
|
||||
StandardGetFile(NULL, ARRAY_COUNT(kFileTypes), kFileTypes, &sfreply);
|
||||
StandardGetFile(NULL, ARRAY_COUNT(kFileTypes), kFileTypes, &reply);
|
||||
if (reply.sfGood) {
|
||||
ProjectOpen(&reply.sfFile, reply.sfScript);
|
||||
}
|
||||
}
|
||||
|
||||
// HandleClose handles a request to close the given window.
|
||||
|
115
macos/project.c
115
macos/project.c
@ -47,6 +47,8 @@ boundary. This is just to make it easier to read hexdumps.
|
||||
|
||||
#define kVersion 0x10000
|
||||
|
||||
#define kMaxChunkCount 32
|
||||
|
||||
// clang-format off
|
||||
|
||||
// Magic cookie that identifies project files.
|
||||
@ -199,6 +201,119 @@ void ProjectNew(void)
|
||||
ProjectCreateWindow(project);
|
||||
}
|
||||
|
||||
// ProjectReadError displays an error message encountered when trying to read a
|
||||
// project.
|
||||
static void ProjectReadError(ProjectHandle project, ErrorCode err, OSErr osErr)
|
||||
{
|
||||
StrFileName name;
|
||||
|
||||
memcpy(name, (*project)->fileSpec.name, sizeof(StrFileName));
|
||||
ShowError(kErrCouldNotReadProject, err, osErr, name);
|
||||
}
|
||||
|
||||
// ProjectRead reads the project from disk. Returns true on success.
|
||||
static Boolean ProjectRead(ProjectHandle project)
|
||||
{
|
||||
struct ProjectHeader header;
|
||||
struct ProjectChunk **chunks;
|
||||
short fileRef;
|
||||
long count, size;
|
||||
ErrorCode err;
|
||||
OSErr osErr;
|
||||
int nchunks;
|
||||
UInt32 headerCRC, gotCRC;
|
||||
|
||||
chunks = NULL;
|
||||
err = kErrNone;
|
||||
osErr = 0;
|
||||
|
||||
fileRef = (*project)->fileRef;
|
||||
osErr = SetFPos(fileRef, fsFromStart, 0);
|
||||
if (osErr != 0) {
|
||||
goto error;
|
||||
}
|
||||
count = sizeof(header);
|
||||
osErr = FSRead(fileRef, &count, &header);
|
||||
if (osErr != 0) {
|
||||
goto error;
|
||||
}
|
||||
if (count < sizeof(header) ||
|
||||
memcmp(header.magic, kMagic, sizeof(kMagic)) != 0 ||
|
||||
header.chunkCount > kMaxChunkCount) {
|
||||
err = kErrProjectDamaged;
|
||||
goto error;
|
||||
}
|
||||
headerCRC = header.crc32;
|
||||
header.crc32 = 0;
|
||||
gotCRC = CRC32Update(0, &header, sizeof(header));
|
||||
nchunks = header.chunkCount;
|
||||
if (nchunks > 0) {
|
||||
size = sizeof(struct ProjectChunk) * nchunks;
|
||||
chunks = (struct ProjectChunk **)NewHandle(size);
|
||||
if (chunks == NULL) {
|
||||
err = kErrOutOfMemory;
|
||||
osErr = MemError();
|
||||
goto error;
|
||||
}
|
||||
count = size;
|
||||
osErr = FSRead(fileRef, &count, *chunks);
|
||||
if (osErr != 0) {
|
||||
goto error;
|
||||
}
|
||||
if (count < size) {
|
||||
err = kErrProjectDamaged;
|
||||
goto error;
|
||||
}
|
||||
gotCRC = CRC32Update(gotCRC, *chunks, size);
|
||||
}
|
||||
if (headerCRC != gotCRC) {
|
||||
err = kErrProjectDamaged;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// TODO: read project data
|
||||
|
||||
if (chunks != NULL) {
|
||||
DisposeHandle((Handle)chunks);
|
||||
}
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (chunks != NULL) {
|
||||
DisposeHandle((Handle)chunks);
|
||||
}
|
||||
ProjectReadError(project, err, osErr);
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProjectOpen(FSSpec *spec, ScriptCode script)
|
||||
{
|
||||
ProjectHandle project;
|
||||
struct Project *projectp;
|
||||
short fileRef;
|
||||
OSErr err;
|
||||
|
||||
err = FSpOpenDF(spec, fsRdWrPerm, &fileRef);
|
||||
if (err != noErr) {
|
||||
ShowError(kErrCouldNotReadProject, kErrNone, err, spec->name);
|
||||
return;
|
||||
}
|
||||
project = ProjectNewObject();
|
||||
if (project == NULL) {
|
||||
FSClose(fileRef);
|
||||
return;
|
||||
}
|
||||
projectp = *project;
|
||||
projectp->fileRef = fileRef;
|
||||
memcpy(&projectp->fileSpec, spec, sizeof(FSSpec));
|
||||
projectp->fileScript = script;
|
||||
|
||||
ProjectRead(project);
|
||||
|
||||
ProjectDelete(project);
|
||||
// ProjectCreateWindow(project);
|
||||
}
|
||||
|
||||
void ProjectAdjustMenus(ProjectHandle project, MenuHandle fileMenu)
|
||||
{
|
||||
(void)project;
|
||||
|
@ -10,6 +10,9 @@ typedef struct Project **ProjectHandle;
|
||||
// ProjectNew creates a new empty synchronization project.
|
||||
void ProjectNew(void);
|
||||
|
||||
// ProjectOpen opens an existing synchronization project.
|
||||
void ProjectOpen(FSSpec *spec, ScriptCode script);
|
||||
|
||||
// ProjectAdjustMenus adjusts menus before selecting a menu item.
|
||||
void ProjectAdjustMenus(ProjectHandle project, MenuHandle fileMenu);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user