Initial implementation of NSFileWrapper

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@6377 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
jagapen 2000-03-25 02:09:31 +00:00
parent 7e98311de1
commit 61d8f5e1c4
3 changed files with 373 additions and 91 deletions

View file

@ -1,3 +1,7 @@
2000-03-24 Jonathan Gapen <jagapen@whitewater.chem.wisc.edu>
* Source/NSFileWrapper.m: First implementation of NSFileWrapper
* Headers/gnustep/gui/NSFileWrapper.h: Added ivars and enum
2000-03-21 22:00 Fred Kiefer <FredKiefer@gmx.de> 2000-03-21 22:00 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSText.m: Changed to use a text storage instead of an * Source/NSText.m: Changed to use a text storage instead of an
attributed string. attributed string.

View file

@ -29,49 +29,62 @@
#ifndef _GNUstep_H_NSFileWrapper #ifndef _GNUstep_H_NSFileWrapper
#define _GNUstep_H_NSFileWrapper #define _GNUstep_H_NSFileWrapper
#include <Foundation/NSDictionary.h>
#include <AppKit/NSImage.h>
@class NSImage; @class NSImage;
@class NSFont;
@class NSString; @class NSString;
typedef enum
{
GSFileWrapperDirectoryType,
GSFileWrapperRegularFileType,
GSFileWrapperSymbolicLinkType
} GSFileWrapperType;
@interface NSFileWrapper : NSObject @interface NSFileWrapper : NSObject
{ {
NSString *_filename;
NSString *_preferredFilename;
NSMutableDictionary *_fileAttributes;
GSFileWrapperType _wrapperType;
id _wrapperData;
NSImage *_iconImage;
} }
// //
// Initialization // Initialization
// //
// Init instance of directory type
// Init instance of directory type
- (id)initDirectoryWithFileWrappers:(NSDictionary *)docs; - (id)initDirectoryWithFileWrappers:(NSDictionary *)docs;
// Init instance of regular file type // Init instance of regular file type
- (id)initRegularFileWithContents:(NSData *)data; - (id)initRegularFileWithContents:(NSData *)data;
// Init instance of symbolic link type // Init instance of symbolic link type
- (id)initSymbolicLinkWithDestination:(NSString *)path; - (id)initSymbolicLinkWithDestination:(NSString *)path;
// Init an instance from the file, // Init an instance from the file, directory, or symbolic link at path.
// directory, or symbolic link at path. // This can create a tree of instances
// This can create a tree of instances
- (id)initWithPath:(NSString *)path; // with a directory instance at the top - (id)initWithPath:(NSString *)path; // with a directory instance at the top
// Init an instance from data in std // Init an instance from data in standard serial format. Serial format
// serial format. Serial format is the // is the same as that used by NSText's RTFDFromRange: method. This can
// same as that used by NSText's // create a tree of instances with a directory instance at the top
// RTFDFromRange: method. This can
// create a tree of instances with a
// directory instance at the top
- (id)initWithSerializedRepresentation:(NSData *)data; - (id)initWithSerializedRepresentation:(NSData *)data;
// //
// General methods // General methods
// // write instace to disk //
- (BOOL)writeToFile:(NSString *)path // at path. if directory
atomically:(BOOL)atomicFlag // type this method is // write instace to disk at path. if directory type, this method is recursive
updateFilenames:(BOOL)updateFilenamesFlag; // recursive, if flag is // if flag is YES, the wrapper will be updated with the name used in writing
// YES the wrapper will be // the file
// updated with the name - (BOOL)writeToFile:(NSString *)path
// used in writing the file atomically:(BOOL)atomicFlag
updateFilenames:(BOOL)updateFilenamesFlag;
- (NSData *)serializedRepresentation; - (NSData *)serializedRepresentation;
- (void)setFilename:(NSString *)filename; - (void)setFilename:(NSString *)filename;
@ -95,25 +108,29 @@
// //
// Directory type methods // Directory type methods
// //
- (NSString *)addFileWrapper:(NSFileWrapper *)doc; // methods for use
- (void)removeFileWrapper:(NSFileWrapper *)doc; // with directory
- (NSDictionary *)fileWrappers; // type instances
- (NSString *)keyForFileWrapper:(NSFileWrapper *)doc; // types they raise
- (NSString *)addFileWithPath:(NSString *)path; // an exception.
- (NSString *)addRegularFileWithContents:(NSData *)data
preferredFilename:(NSString *)filename;
- (NSString *)addSymbolicLinkWithDestination:(NSString *)path
preferredFilename:(NSString *)filename;
// // these messages raise an exception when sent to non-directory type wrappers!
- (NSString *)addFileWrapper:(NSFileWrapper *)doc;
- (void)removeFileWrapper:(NSFileWrapper *)doc;
- (NSDictionary *)fileWrappers;
- (NSString *)keyForFileWrapper:(NSFileWrapper *)doc;
- (NSString *)addFileWithPath:(NSString *)path;
- (NSString *)addRegularFileWithContents:(NSData *)data
preferredFilename:(NSString *)filename;
- (NSString *)addSymbolicLinkWithDestination:(NSString *)path
preferredFilename:(NSString *)filename;
//
// Regular file type methods // Regular file type methods
// //
- (NSData *)regularFileContents; - (NSData *)regularFileContents;
// //
// Symbolic link type methods // Symbolic link type methods
// //
- (NSString *)symbolicLinkDestination; - (NSString *)symbolicLinkDestination;
@end @end

View file

@ -7,6 +7,8 @@
Author: Felipe A. Rodriguez <far@ix.netcom.com> Author: Felipe A. Rodriguez <far@ix.netcom.com>
Date: Sept 1998 Date: Sept 1998
Author: Jonathan Gapen <jagapen@whitewater.chem.wisc.edu>
Date: Dec 1999
This file is part of the GNUstep GUI Library. This file is part of the GNUstep GUI Library.
@ -30,6 +32,11 @@
#include <AppKit/NSFileWrapper.h> #include <AppKit/NSFileWrapper.h>
#include <AppKit/NSFont.h> #include <AppKit/NSFont.h>
#include <AppKit/NSWorkspace.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSData.h>
#include <Foundation/NSException.h>
#include <Foundation/NSFileManager.h>
@implementation NSFileWrapper @implementation NSFileWrapper
@ -37,150 +44,388 @@
// //
// Initialization // Initialization
// //
- (id)initDirectoryWithFileWrappers:(NSDictionary *)docs // Init instance of
{ // directory type // Init instance of directory type
return nil; - (id)initDirectoryWithFileWrappers:(NSDictionary *)docs
{
NSEnumerator *enumerator;
id key;
NSFileWrapper *wrapper;
[super init];
_wrapperType = GSFileWrapperDirectoryType;
_wrapperData = [NSMutableDictionary dictionaryWithCapacity: [docs count]];
enumerator = [docs keyEnumerator];
while ((key = [enumerator nextObject]))
{
wrapper = (NSFileWrapper *)[docs objectForKey: key];
if (![wrapper preferredFilename])
[wrapper setPreferredFilename: key];
[_wrapperData setObject: wrapper forKey: key];
}
return self;
} }
- (id)initRegularFileWithContents:(NSData *)data // Init instance of // Init instance of regular file type
{ // regular file type - (id)initRegularFileWithContents:(NSData *)data
return nil; {
[super init];
_wrapperData = [data copyWithZone: [self zone]];
_wrapperType = GSFileWrapperRegularFileType;
return self;
} }
- (id)initSymbolicLinkWithDestination:(NSString *)path // Init instance of // Init instance of symbolic link type
{ // symbolic link type - (id)initSymbolicLinkWithDestination:(NSString *)path
return nil; {
[super init];
_wrapperData = path;
_wrapperType = GSFileWrapperSymbolicLinkType;
return self;
} }
// Init an instance from the file, // Init an instance from the file,
// directory, or symbolic link at path. // directory, or symbolic link at path.
- (id)initWithPath:(NSString *)path // This can create a tree of instances // This can create a tree of instances
{ // with a directory instance at the top // with a directory instance at the top
return nil;
- (id)initWithPath:(NSString *)path
{
NSFileManager *fm = [NSFileManager defaultManager];
NSString *fileType;
NSDebugLLog(@"NSFileWrapper", @"initWithPath: %@", path);
[self setFilename: path];
[self setPreferredFilename: [path lastPathComponent]];
[self setFileAttributes: [fm fileAttributesAtPath: path traverseLink: NO]];
fileType = [[self fileAttributes] fileType];
if ([fileType isEqualToString: @"NSFileTypeDirectory"])
{
NSString *filename;
NSMutableArray *fileWrappers = [NSMutableArray new];
NSArray *filenames = [fm directoryContentsAtPath: path];
NSEnumerator *enumerator = [filenames objectEnumerator];
while ((filename = [enumerator nextObject]))
{
[fileWrappers addObject:
[[NSFileWrapper alloc] initWithPath:
[path stringByAppendingPathComponent: filename]]];
}
self = [self initDirectoryWithFileWrappers:
[NSDictionary dictionaryWithObjects: fileWrappers forKeys: filenames]];
}
else if ([fileType isEqualToString: @"NSFileTypeRegular"])
{
self = [self initRegularFileWithContents:
[[NSData alloc] initWithContentsOfFile: path]];
}
else if ([fileType isEqualToString: @"NSFileTypeSymbolicLink"])
{
self = [self initSymbolicLinkWithDestination:
[fm pathContentOfSymbolicLinkAtPath: path]];
}
return self;
} }
// Init an instance from data in std // Init an instance from data in std
// serial format. Serial format is the // serial format. Serial format is the
// same as that used by NSText's // same as that used by NSText's
// RTFDFromRange: method. This can // RTFDFromRange: method. This can
// create a tree of instances with a // create a tree of instances with a
// directory instance at the top // directory instance at the top
// FIXME - implement
- (id)initWithSerializedRepresentation:(NSData *)data - (id)initWithSerializedRepresentation:(NSData *)data
{ {
return nil; return nil;
}
- (void)dealloc
{
if (_filename)
[_filename release];
if (_preferredFilename)
[_preferredFilename release];
if (_wrapperData)
[_wrapperData release];
if (_iconImage)
[_iconImage release];
} }
// //
// General methods // General methods
// // write instance to disk //
- (BOOL)writeToFile:(NSString *)path // at path. if directory
atomically:(BOOL)atomicFlag // type, this method is // write instance to disk at path; if directory type, this
updateFilenames:(BOOL)updateFilenamesFlag // recursive, if flag is // method is recursive; if updateFilenamesFlag is YES, the wrapper
{ // YES the wrapper will be // will be updated with the name used in writing the file
return NO; // updated with the name
} // used in writing the file - (BOOL)writeToFile:(NSString *)path
atomically:(BOOL)atomicFlag
updateFilenames:(BOOL)updateFilenamesFlag
{
NSFileManager *fm = [NSFileManager defaultManager];
BOOL pathExists = [fm fileExistsAtPath: path];
NSDebugLLog(@"NSFileWrapper",
@"writeToFile: %@ atomically: updateFilenames:", path);
// don't overwrite existing paths
if (pathExists && atomicFlag)
return NO;
if (updateFilenamesFlag == YES)
[self setFilename: [path lastPathComponent]];
switch (_wrapperType)
{
case GSFileWrapperDirectoryType:
{
// FIXME - more robust save proceedure when atomicFlag set
NSEnumerator *enumerator = [_wrapperData keyEnumerator];
NSString *key;
[fm createDirectoryAtPath: path attributes: _fileAttributes];
while ((key = (NSString *)[enumerator nextObject]))
{
NSString *newPath =
[path stringByAppendingPathComponent: key];
[[_wrapperData objectForKey: key] writeToFile: newPath
atomically: atomicFlag
updateFilenames: updateFilenamesFlag];
}
return YES;
}
case GSFileWrapperRegularFileType:
{
return [_wrapperData writeToFile: path atomically: atomicFlag];
}
case GSFileWrapperSymbolicLinkType:
{
return [fm createSymbolicLinkAtPath: path pathContent: _wrapperData];
}
}
return NO;
}
// FIXME - implement
- (NSData *)serializedRepresentation - (NSData *)serializedRepresentation
{ {
return nil; return nil;
} }
- (void)setFilename:(NSString *)filename - (void)setFilename:(NSString *)filename
{ {
if (filename == nil || [filename isEqualToString: @""])
[NSException raise: NSInternalInconsistencyException
format: @"Empty or nil argument to setFilename:"];
else
ASSIGN(_filename, filename);
} }
- (NSString *)filename - (NSString *)filename
{ {
return nil; return _filename;
} }
- (void)setPreferredFilename:(NSString *)filename - (void)setPreferredFilename:(NSString *)filename
{ {
if (filename == nil || [filename isEqualToString: @""])
[NSException raise: NSInternalInconsistencyException
format: @"Empty or nil argument to setPreferredFilename:"];
else
ASSIGN(_preferredFilename, filename);
} }
- (NSString *)preferredFilename; - (NSString *)preferredFilename;
{ {
return nil; return _preferredFilename;
} }
- (void)setFileAttributes:(NSDictionary *)attributes - (void)setFileAttributes:(NSDictionary *)attributes
{ {
if (_fileAttributes == nil)
_fileAttributes = [NSMutableDictionary new];
[_fileAttributes addEntriesFromDictionary: attributes];
} }
- (NSDictionary *)fileAttributes - (NSDictionary *)fileAttributes
{ {
return nil; return _fileAttributes;
} }
- (BOOL)isRegularFile - (BOOL)isRegularFile
{ {
return NO; if (_wrapperType == GSFileWrapperRegularFileType)
return YES;
else
return NO;
} }
- (BOOL)isDirectory - (BOOL)isDirectory
{ {
return NO; if (_wrapperType == GSFileWrapperDirectoryType)
return YES;
else
return NO;
} }
- (BOOL)isSymbolicLink - (BOOL)isSymbolicLink
{ {
return NO; if (_wrapperType == GSFileWrapperSymbolicLinkType)
return YES;
else
return NO;
} }
- (void)setIcon:(NSImage *)icon - (void)setIcon:(NSImage *)icon
{ {
ASSIGN(_iconImage, icon);
} }
- (NSImage *)icon; - (NSImage *)icon;
{ {
return nil; if (!_iconImage)
return [[NSWorkspace sharedWorkspace] iconForFile: [self filename]];
else
return _iconImage;
} }
// FIXME - for directory wrappers
- (BOOL)needsToBeUpdatedFromPath:(NSString *)path - (BOOL)needsToBeUpdatedFromPath:(NSString *)path
{ {
return NO; NSFileManager *fm = [NSFileManager defaultManager];
switch (_wrapperType)
{
case GSFileWrapperRegularFileType:
if ([[self fileAttributes]
isEqualToDictionary: [fm fileAttributesAtPath: path
traverseLink: NO]])
return NO;
break;
case GSFileWrapperSymbolicLinkType:
if ([_wrapperData isEqualToString:
[fm pathContentOfSymbolicLinkAtPath: path]])
return NO;
break;
case GSFileWrapperDirectoryType:
break;
}
return YES;
} }
// FIXME - implement
- (BOOL)updateFromPath:(NSString *)path - (BOOL)updateFromPath:(NSString *)path
{ {
return NO; return NO;
} }
// //
// Directory type methods // Directory type methods
// //
#define GSFileWrapperDirectoryTypeCheck() \
if (_wrapperType != GSFileWrapperDirectoryType) \
[NSException raise: NSInternalInconsistencyException \
format: @"Can't invoke %@ on a file wrapper that" \
@" does not wrap a directory!", _cmd];
// FIXME - handle duplicate names
- (NSString *)addFileWrapper:(NSFileWrapper *)doc - (NSString *)addFileWrapper:(NSFileWrapper *)doc
{ {
return nil; NSString *key;
GSFileWrapperDirectoryTypeCheck();
key = [doc preferredFilename];
if (key == nil || [key isEqualToString: @""])
{
[NSException raise: NSInvalidArgumentException
format: @"Adding file wrapper with no preferred filename."];
return nil;
}
[_wrapperData setObject: doc forKey: key];
return key;
} }
- (void)removeFileWrapper:(NSFileWrapper *)doc - (void)removeFileWrapper:(NSFileWrapper *)doc
{ {
GSFileWrapperDirectoryTypeCheck();
[_wrapperData removeObjectsForKeys: [_wrapperData allKeysForObject: doc]];
} }
- (NSDictionary *)fileWrappers; - (NSDictionary *)fileWrappers
{ {
return nil; GSFileWrapperDirectoryTypeCheck();
return _wrapperData;
} }
- (NSString *)keyForFileWrapper:(NSFileWrapper *)doc - (NSString *)keyForFileWrapper:(NSFileWrapper *)doc
{ {
return nil; GSFileWrapperDirectoryTypeCheck();
return [[_wrapperData allKeysForObject: doc] objectAtIndex: 0];
} }
- (NSString *)addFileWithPath:(NSString *)path - (NSString *)addFileWithPath:(NSString *)path
{ {
return nil; NSFileWrapper *wrapper;
GSFileWrapperDirectoryTypeCheck();
wrapper = [[NSFileWrapper alloc] initWithPath: path];
if (wrapper != nil)
return [self addFileWrapper: wrapper];
else
return nil;
} }
- (NSString *)addRegularFileWithContents:(NSData *)data - (NSString *)addRegularFileWithContents:(NSData *)data
preferredFilename:(NSString *)filename preferredFilename:(NSString *)filename
{ {
return nil; NSFileWrapper *wrapper;
GSFileWrapperDirectoryTypeCheck();
wrapper = [[NSFileWrapper alloc] initRegularFileWithContents: data];
if (wrapper != nil)
{
[wrapper setPreferredFilename: filename];
return [self addFileWrapper: wrapper];
}
else
return nil;
} }
- (NSString *)addSymbolicLinkWithDestination:(NSString *)path - (NSString *)addSymbolicLinkWithDestination:(NSString *)path
preferredFilename:(NSString *)filename preferredFilename:(NSString *)filename
{ {
return nil; NSFileWrapper *wrapper;
GSFileWrapperDirectoryTypeCheck();
wrapper = [[NSFileWrapper alloc] initSymbolicLinkWithDestination: path];
if (wrapper != nil)
{
[wrapper setPreferredFilename: filename];
return [self addFileWrapper: wrapper];
}
else
return nil;
} }
// //
@ -188,7 +433,13 @@
// //
- (NSData *)regularFileContents - (NSData *)regularFileContents
{ {
return nil; if (_wrapperType == GSFileWrapperRegularFileType)
return _wrapperData;
else
[NSException raise: NSInternalInconsistencyException
format: @"File wrapper does not wrap regular file."];
return nil;
} }
// //
@ -196,12 +447,22 @@
// //
- (NSString *)symbolicLinkDestination - (NSString *)symbolicLinkDestination
{ {
return nil; if (_wrapperType == GSFileWrapperSymbolicLinkType)
return _wrapperData;
else
[NSException raise: NSInternalInconsistencyException
format: @"File wrapper does not wrap symbolic link."];
return nil;
} }
// //
// Archiving // Archiving
// //
// The MacOS X docs do not say that NSFileWrapper conforms to the
// NSCoding protocol. Should it nonetheless?
- (void) encodeWithCoder: (NSCoder*)aCoder - (void) encodeWithCoder: (NSCoder*)aCoder
{ {
[super encodeWithCoder: aCoder]; [super encodeWithCoder: aCoder];