Sunday, June 15, 2008

Implementing SetFileTime and GetFileTime under OSX

Working through the link errors makes for some catching up on some things that I sketched out and did not complete. I have been looking at the file handling class, file streams and writing unit tests to make sure that the they are working properly as I flesh them out.

I have backed Cello file handling class more or less straight onto STL file streams. In this class there are a couple of methods SetFileTime, and GetFileTime. In the MFC version these are more-or-less straight wraps of the API calls SetFileTime, and GetFileTime:
 BOOL WINAPI SetFileTime(
__in HANDLE hFile,
__in_opt const FILETIME *lpCreationTime,
__in_opt const FILETIME *lpLastAccessTime,
__in_opt const FILETIME *lpLastWriteTime
);

Under OSX I have implemented them in terms of FSGetCatalogInfo and FSSetCatalogInfo. So, for example, the blood and guts of the SetFileTime method boils out like this:
 const char *path = (LPCSTR)m_dwsName;
FSRef fsRef;
Boolean isDirectory;
FSCatalogInfo fsCatalogInfo;

OSStatus err = FSPathMakeRef(reinterpret_cast(path), &fsRef, &isDirectory);
::ThrowIfOSErr(err);
err = FSGetCatalogInfo(&fsRef, kFSCatInfoAllDates, &fsCatalogInfo, NULL, NULL, NULL);
::ThrowIfOSErr(err);

fsCatalogInfo.createDate = *lpCreationTime;
fsCatalogInfo.contentModDate = *lpLastWriteTime;
fsCatalogInfo.accessDate = *lpLastWriteTime;

err = FSSetCatalogInfo(&fsRef, kFSCatInfoAllDates, &fsCatalogInfo);
::ThrowIfOSErr(err);
In my first cut I implemented FILETIME as a CFDate - however looking at FILETIME when writing the test cases I changed this to UTCDateTime which is actually practically the same.

The only wrinkle I have found is that the FSGetCatalogInfo ignore the fractional part in the UTCDateTime - which is something that tripped me in the Unit Tests

No comments: