Last revised: 14May2003 GLG
2003-May-14 -- Minor Update of MacBinary Toolkit 2
This is a minor update. It fixes a couple of latent bugs and improves the clarity of functionality of built-in factory selection. It also adds the JNI-based MacOSXForker imp as one of MacPlatform's known built-in imps, which it will now prefer to use when it's available. Some of the documentation was also expanded.
- Available FileForker Implementations now contains an Applet Usage Considerations section. Also, a "Usage Considerations" sub-section was added for each section describing imps. In particular, notes were added about where to place MacOSXForker's JNI-lib.
- MacPlatform's mapping between platform and FileForker implementations was completely replaced. The new code is based on the glguerin.util.Implicator class and its nested Implicator.Chain class. This eliminated several static methods, replacing them with one method getFactoryImplicators() that returns an Implicator.Chain. See MacPlatform's API docs for details on this new mechanism.
THIS CHANGE AFFECTS BINARY COMPATIBILITY if you called any of the methods that were eliminated.- MacPlatform.selectFactoryName() will now emit an error message to stderr when the designated property's FileForker imp is unusable, and the default imp for the host platform is used instead. I made this change because too many people were being confused by this silent fallback behavior. To disable the error message, set the "glguerin.util.MacPlatform.selectFactoryName.quiet" property to "true".
- MacPlatform.isMRJ() has a different implementation. It now recognizes that Java 1.4.1 on Mac OS X is a version of MRJ, and returns true for it.
- FileForker.SetFactory() now has more informative messages in the IllegalArgumentExceptions it throws.
- MacBinarySequenceStream, which is returned by MacBinaryEncoder.getEncodedStream(), now has a usable implementation of skip() on JDK 1.1 platforms. The prior default method inherited from InputStream had bugs under JDK 1.1.
- MacBinaryEncoder.isEncodeable() has been replaced by getEncodeableInfo(), which throws an IOException. This new method also performs more extensive checks on the encodeability of the target before encoding begins.
THIS CHANGE MAY AFFECT BINARY COMPATIBILITY but only if MacBinaryEncoder was subclassed, and then only if isEncodeable() was overridden. The ultimate effect is that your method will never be called.
2003-February-19 -- Upgrade of MacBinary Toolkit 2
The principal improvements in this release center around aliases, change-signals, and new Mac OS and Mac OS X implementations. Highlights include:
- a new capability for creating alias-files and symlinks
- a new capability for distinguishing symlinks from other aliases
- a new platform-neutral imp that uses plain Java and reflection
- two new Mac OS X imps that use JNI for native code
- several new Mac OS imps that accept alias-files as leading directories in pathnames
- a new capability for signalling the Finder to update its folder display
- a new capability for receiving Finder-originated change signals
- RandomRWFile.setLength() uses reflection, so it now works under Java 2
- fixes for several bugs and suboptimal design choices
Backward Compatibility
This release is very nearly binary compatible with the prior release. One method was renamed for source-level compatibility with the Java assertion facility in JDK 1.4. This change may affect binary compatibility:
the method FileAccess.assert() was renamed to affirm().If you used FileAccess.assert(), you'll have to change your source and recompile in order to use this release. If you don't use FileAccess.assert(), then this release should be a drop-in replacement of the new JARs over the prior release's JARs, and no recompile should be necessary.
All other features, fixes, improvements, and implementations should be binary compatible with your classes already compiled against the public API of the prior release. All new features have default implementations. All fixes were made as compatible as possible, without attempting bug-for-bug compatibility. All improvements and implementation changes were done "behind the curtain" of the public API.
If you subclassed any of the concrete FileForker imps, especially the platform-neutral imps in glguerin.io.imp.gen, you may have to recompile. The superclass/subclass relationships of the concrete imps has changed slightly. The changes should not affect existing source, possibly only compiled class-files.
- About is a new command in the app.macbinary.cmd package. It displays the resolved Pathname, FileInfo, and FileAccess of pathnames on stdout.
- the Spy command uses the new FileInformer class, also used by About, to display the FileInfo of an encoded file.
- app.util.* classes have been refactored and updated. Some bugs and design mistakes have been fixed.
- ConverterFrame, which is the MB-Converter demo app, uses the new change-signal capability to tell the Finder when it has finished encoding or decoding a file.
- FileForker.Alias is a new nested class for creating symlinks and alias-files with the FileForker.createAliasFile() method. Availability and capability is implementation-dependent.
- FileForker.isSymlink() is for distinguishing symlinks.
- FileForker.resolveLeading() is for resolving all the directories leading up to a leaf, without resolving the leaf item itself.
- FileForker.signalChange() is for signalling the Finder (or other desktop display agent) that a change has occurred in the file-system, and any desktop display should be updated. Availability and capability is implementation-dependent.
- FileForker.Watcher is a new nested class for receiving the change-signals from signalChange() or from the Finder itself. Availability is implementation-dependent.
- FileForker.setPathReplica() now assigns null when passed null, rather than assigning a new empty Pathname. It is conceivable that this change might break some existing code.
- FileAccess.assert() was renamed to affirm().
- FileInfo.hasFinderFlags() returns a boolean representing the presence of Finder-flags under a bitmask. It is often more convenient to use than getFinderFlags().
- FileInfo.MASK_FINDER_X_HIDESUFFIX is a new name for the Finder-flags bit that Mac OS X uses to represent hidden file-extensions on a file.
- MacRoman.getOSTypeString() is now the method that converts 'int' OSType values to String form. The earlier method MacPlatform.getOSTypeString() simply calls the MacRoman method.
- Pathname.replica() is a factory method that returns a new replica of a Pathname.
- Pathname.part() accepts negative part-indexes and uses them to index from the last part of the Pathname. That is, -1 is the last part, -2 is the part before it, and so on.
- Pathname.hashCode() has a better algorithm, calculated from the hashcodes of its part Strings.
- RandomRWFile.setLength() now works on Java 2 (JDK 1.2+). It uses reflection to call RandomAccessFile.setLength(), whenever it finds that class having that method.
- FileHelper.WalkAction.doNode()'s doc-comment described its returned boolean as the reverse of its actual meaning. The correct meaning is "true to stop at current node".
- MacTime.javaMillisToMacUTCDateTime() now uses double-precision division instead of multiplication. This doesn't affect the calculation, but eliminates the need for a 2nd constant.
- PlainForker is a new platform-neutral implementation. It uses only plain ordinary Java. PlainForker is the new default implementation for all non-Mac platforms. This may affect existing code.
- NineForker now correctly follows symlinks under Classic.
- TenForker no longer refers to Apple-private classes in its implementation. The JDirect-3 usage adheres to the public API. This was an implementation mistake.
- TenForker will no longer present a UI if it becomes necessary to mount an unmounted volume to resolve an alias. If the volume can't be mounted without a UI, an IOException is thrown.
- TenForker fixes a symlink-following bug, and a bug that occasionally threw a NullPointerException when using a pathname of "/".
- ResolvingTenForker, ResolvingNineForker, ResolvingJD2Forker, and ResolvingJD1Forker are new implementations that accept alias-files as leading directories and resolve them on-the-fly.
- TenForker.isSymlink() distinguishes symlinks from other kinds of aliases.
- TenForker provides a nested Alias implementation that supports symlink creation. It does not support Finder-alias-file creation.
- TenForker.signalChange() signals the Finder that a change has occurred in the file-system. It does not provide a nested Watcher implementation.
- MacOSXForker is a new JNI-based implementation for Mac OS X 10.1 or higher. It will work in Cocoa-Java programs, where TenForker won't. It also works in any other Java program.
- MacOSXForker provides a nested Alias that supports both symlink and alias-file creation.
- MacOSXForker.signalChange() signals the Finder that a change has occurred in the file-system. It does not provide a nested Watcher implementation, but the subclass CarbonMacOSXForker does, with some restrictions.
2002-July-16 -- Upgrade of MacBinary Toolkit 2
- MBFileEncoder and MBFileDecoder are higher-level classes for encoding and decoding files. They are easier to work with than earlier classes.
- MacBinaryProducer was replaced by MacBinaryEncoder, which is easier to work with.
- MacBinaryOutputStream is a new OutputStream in the Adapter pattern that decodes bytes written to an OutputStream and restores a target file.
- Encode, Decode, and Resolve are new classes in app.macbinary.cmd that provide command-line interfaces to encoding, decoding, and alias-resolving.
- The MacBinary Spy utility can now calculate checksums over pieces.
- All the demos/utilities were revised to use the new classes, and their names changed a little (Greg Lerns to Spel Converter Rite).
- FileForker can now return its actual Pathname in use with getPathname(), not just a replica. Method-name changes here are:
useTarget() --> usePathname()
getTarget() --> getPathReplica()
setTarget() --> setPathReplica()- FileTools is replaced by FileHelper, and made more than just static methods.
- RandomRWArray can return its underlying byte-array, or a sized copy of it.
- RandomRWRange can optionally not close the underlying RandomRW container on close().
- RandomRWInputStream and RandomRWOutputStream can optionally not close the underlying RandomRW container on close().
2002-April-12 -- Minor Update of MacBinary Toolkit 2
This is a minor update release only. A few bugs were fixed in demos. A few classes were restructured, and one (MacEscaping) was eliminated. The new PathnameFormat is more easily separable.
- FileAccess gained equals() and hashCode() methods, to simplify comparing one FileAccess to another.
- refactored MacPlatform, moving some code to new class app.util.Fixes.
- refactored PathnameFormat to match Easy Posix Toolkit, so the two toolkits now share identical class source files.
- MacEscaping no longer exists; use new class PF_MacOS for static methods that do MRJ escaping.
- Fixed ReplicatorFrame and ReceiverFrame so the buttons work.
- Call Toolkit.getDefaultToolkit() in AppFrame.registerHandlers(), to ensure that AWT is loaded before registering handlers.
2001-July-09 -- Final release of MacBinary Toolkit 2
Highlights of the changes from the previous final MacBinary Toolkit release include:
- The MacBinary Convertor app now lets you select any of the three possible MacBinary encoding formats, and has a way to configure which format is selected by default.
- Mac OS X versions of the demo-apps are provided.
- Pathname now represents all pathnames. It works in conjunction with an automatically selected platform-specific PathnameFormat class.
- FileForker represents access to the file-system. It has additional capabilities over its MacFileForker predecessor, such as the ability to append to output files, make directories, list directory contents, etc. It now provides essentially every feature that java.io.File provides, so you can write programs using FileForker and almost never have to use a File again. FileForker also adds the capability to define a default file-type and creator-ID, a feature not otherwise available under Mac OS X.
- RandomRW is the base class for several sub-classes that represent random-access read/write data containers. This set of classes represent a file's contents or an underlying byte-array in a uniform I/O orientation. One sub-class is RandomRWBuffered, which does buffered I/O and can greatly speed up DataInput and DataOutput access as compared to an unbuffered RandomAccessFile.
- FileAccess represents Unix-style access privileges.
- TenForker is a FileForker implementation for Mac OS X. It provides long UniCode file-names, fork-length above 2 GB, and full Unix-style access privileges.
- NineForker is a FileForker implementation for Mac OS 9. It provides long UniCode file-names, fork-length above 2 GB, and limited Unix-style access privileges.
2001-May-27 -- Start beta releases of MacBinary Toolkit 2
- Lots of changes and bug fixes.
1999-Oct-29
- Bug-fixes to CommentAccessor's for Mac OS platform to be compatible with Mac OS 8.6 and with AppleShared files. The bug prevented file-comments from being read, hence from being put into the MacBinary-encoded output file. This had no effect on restoring comments when decoding a file, only encoding one. The bug only appeared on Mac OS 8.6 or when encoding a file shared from a remote machine. It did not appear when encoding local files that had comments.
- AppDemoFrame was added, which is a minor refactoring of AppFrame. The AWT-based demos now inherit from AppDemoFrame.
- SpyFrame will now tell whether an encoded file is locked or not, i.e. whether the original file had its file-lock set.
- SmallPoint now has a toString() method that displays the current X and Y coordinates.
- Perhaps other miscellaneous bug fixes or tweaks that I've forgotten to write down since the prior release.
- It happens that the executables and classes of this release are smaller than before. I used a newer compiler and it left out some spurious junk in the constant-pool of each class. So even though there's more code, the files are smaller.
1999-June-24
- Bug-fix to app.macbinary.droplet.Convertor so it closes its file-inputs after decoding them. The fix yields a minor refactoring, adding the decodeFork() method.
- MacCatalogInfo was revised, replacing the get/setFinderWindowing() methods with get/setFinderIconAt(), and adding a SmallPoint class. The documentation error regarding Finder auto-placement of icons was also corrected.
- MacCatalogInfo also received a new convenience method, getForkLength(boolean), to simplify certain programming idioms. You can see its use in app.macbinary.droplet.Convertor. MacBinaryAccessor adds a similar capability in its method getForkInput(boolean).
- MacBinaryHeader gained maskFinderFlags( int, int ) to mask off Finder-flags in a MacBinary encoding-aware way. This helps prevent garbage-flags from being "restored".
- JD2ForkAccessor now automatically closes still-open forks at exit. It uses the internal JDirect 2 class TerminationServices to do this. This feature is not possible in the JDirect 1 implementation. This capability required some internal refactoring of ForkAccessor.
- SpyFrame emits more info about the files it spies upon.
- UTF8 gained methods that operate on char-arrays.
1999-June-07
- MacBinaryHeader, MacBinaryProducer, and MacBinarySequenceStream were all enhanced to allow specifying the MacBinary-level under which the header should be encoded. You can now control whether MacBinary-1, 2, or 3 headers are produced. This feature was added because the earlier versions always encoded as MacBinary-3, and some translators from other vendors didn't accept this format, even though it's backwards-compatible with MacBinary-2.
- ConvertorFrame has a new Checkbox to force MacBinary-2 header encoding when checked. This allows production of MacBinary files that other translators will be able to decode, and gives finer control over encoding. This Checkbox has no effect on decoding -- all three defined MacBinary header-formats continue to be automatically identified and decoded.
- SpyFrame is the main application Frame of a new utility program that peeks into files and tells you about the MacBinary header it may find there. It can open any file and detect whether it's MacBinary or not, what MacBinary-format it is, and then tell you about what it finds in the header. This works on any platform, since it does no encoding and does not use a MacFileForker. I found this to be a very useful tool in making the above enhancements and other recent work involving MacBinary files.
- MacPlatform and MacTime were moved from the package 'glguerin.mac.util' to 'glguerin.util' since they are useful in more situations than just dealing with Mac-specifics. All the classes that referred to them in their old package now refer to their new package.
1999-May-11
- Bug-fix in RandomAccessInputRange where read-lengths were being incorrectly calculated. The effect on MacBinary decoding was that extra bytes were written at the end of file-forks, since read-lengths were wrong.
All users should download and use the fixed version.
1999-May-10
- MacBinaryReceiver is a new class that decodes MacBinary on-the-fly rather than from a random-access container as MacBinaryAccessor does. This class should be most useful in file-transfers where a temp-file would otherwise be needed. A simple AWT-based test-app for this new class is provided.
- MacFileForker gains a public convenience method -- replicateTo(MacFilePathname). With a single invocation, this method replicates (copies) the data and resource forks, the catalog-info, and the comment of a file to another location. The method does not resolve aliases, making it possible to replicate an alias-file. The method is implemented generically in MacFileForker using its other methods. This should simplify copying files, even on non-Mac platforms. A simple AWT-based test-app for this new method is provided.
- MacFileForker gains some public methods that act on the file-system -- delete(), renameLeaf(String), moveTo(MacFilePathname). None of these resolve aliases, so alias-file manipulations should now be possible where MRJ would otherwise alter the original instead of the alias.
- MacFileForker gains some attribute-checking public methods that neither throw exceptions nor resolve aliases -- exists(), isFile(), isDirectory(), canRead(), canWrite(), isAlias(). These should simplify some trivial tasks where before getCatalogInfo() was used or a new File() was instantiated.
- MacFilePathname gains public methods -- setFrom(MacFilePathname), appendFrom(MacFilePathname). It was an oversight not to provide these before. The new methods should make it easier to copy MacFilePathnames from one to another, and to use any particular MacFilePathname as a base for composing other references.
- RandomAccessInput gains public reading methods -- read(), read(byte[]), and read(byte[],int,int). These make reading a RandomAccessInput more like reading an InputStream, when you need that capability. Also, since RandomAccessIO extends RandomAccessInput, you can read(...) from it, too.
- MacFileForker now caches the factory Class, and clears the cached Class when you set a new factory-name.
- ForkInputStream now supports the mark/reset protocol. This class is the base for InputStreams returned from MacFileForker.makeInputStream() of the JDirect 1 and JDirect 2 implementations. That is, both Mac OS implementations now return an InputStream that supports mark() and reset().
- The JDirect 2 implementation now uses Toolbox.LOCK as described in:
Technote 1153: Thread-Safe Toolbox Access From MRJ.- Bug-fix of a latent bug in the CommentAccessor classes of JDirect 1 and JDirect 2 implementations. The bug arose when a target had no comment, you tried to set it to null (i.e. remove it), and an exception was thrown. Now, any target can have its comment set to null (removed) without an exception, even when it has no comment yet.
1999-April-27
- First release.
To Greg's Home Page
To Greg's Software Page