mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-11 00:30:49 +00:00
Merged in 'dawn' CVS branch
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3827 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2c66a6581f
commit
fc772ee2e5
26 changed files with 1090 additions and 607 deletions
9
ANNOUNCE
9
ANNOUNCE
|
@ -1,7 +1,7 @@
|
||||||
Announcement
|
Announcement
|
||||||
************
|
************
|
||||||
|
|
||||||
The GNUstep Base Library, version 0.5.0, is now available.
|
The GNUstep Base Library, version 0.5.5, is now available.
|
||||||
|
|
||||||
What is the GNUstep Base Library?
|
What is the GNUstep Base Library?
|
||||||
=================================
|
=================================
|
||||||
|
@ -14,8 +14,7 @@ network ports, remote object messaging support (distributed objects),
|
||||||
event loops, and random number generators.
|
event loops, and random number generators.
|
||||||
|
|
||||||
It provides functionality that aims to implement the non-graphical
|
It provides functionality that aims to implement the non-graphical
|
||||||
portion of the OpenStep standard. In many cases, the `NS*' classes are
|
portion of the OpenStep standard (the Foundation library).
|
||||||
implemented as wrappers around more featureful GNU classes.
|
|
||||||
|
|
||||||
There is more information available at the GNUstep homepage at
|
There is more information available at the GNUstep homepage at
|
||||||
`http://www.gnustep.org'.
|
`http://www.gnustep.org'.
|
||||||
|
@ -23,8 +22,8 @@ implemented as wrappers around more featureful GNU classes.
|
||||||
Where can you get it? How can you compile it?
|
Where can you get it? How can you compile it?
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
The gstepbase-0.5.0.tar.gz distribution file has been placed on
|
The gstepbase-0.5.5.tar.gz distribution file has been placed on
|
||||||
`ftp.gnu.org' in `pub/gnu'.
|
`ftp.gnu.org' in `pub/gnu/gstep'.
|
||||||
|
|
||||||
The library requires gcc 2.8.0 or higher. Significant sections of
|
The library requires gcc 2.8.0 or higher. Significant sections of
|
||||||
the library do not work with the NeXT runtime, so we recommend using
|
the library do not work with the NeXT runtime, so we recommend using
|
||||||
|
|
34
AUTHORS
34
AUTHORS
|
@ -12,7 +12,6 @@ BinaryTreeNode.m
|
||||||
CircularArray.m
|
CircularArray.m
|
||||||
Collection.m
|
Collection.m
|
||||||
ConnectedCoder.m
|
ConnectedCoder.m
|
||||||
Connection.m
|
|
||||||
Coder.m
|
Coder.m
|
||||||
CStream.m
|
CStream.m
|
||||||
Decoder.m
|
Decoder.m
|
||||||
|
@ -25,22 +24,16 @@ Invocation.m
|
||||||
KeyedCollection.m
|
KeyedCollection.m
|
||||||
LinkedList.m
|
LinkedList.m
|
||||||
LinkedListNode.m
|
LinkedListNode.m
|
||||||
Lock.m
|
|
||||||
MachPort.m
|
MachPort.m
|
||||||
Magnitude.m
|
|
||||||
MallocAddress.m
|
|
||||||
MappedCollector.m
|
MappedCollector.m
|
||||||
MemoryStream.m
|
MemoryStream.m
|
||||||
Notification.m
|
|
||||||
NotificationDispatcher.m
|
NotificationDispatcher.m
|
||||||
OrderedCollection.m
|
OrderedCollection.m
|
||||||
Port.m
|
Port.m
|
||||||
Proxy.m
|
|
||||||
Queue.m
|
Queue.m
|
||||||
RawCStream.m
|
RawCStream.m
|
||||||
RBTree.m
|
RBTree.m
|
||||||
RBTreeNode.m
|
RBTreeNode.m
|
||||||
RNGAdditiveCongruential.m
|
|
||||||
Set.m
|
Set.m
|
||||||
SplayTree.m
|
SplayTree.m
|
||||||
Stack.m
|
Stack.m
|
||||||
|
@ -48,34 +41,23 @@ StdioStream.m
|
||||||
Stream.m
|
Stream.m
|
||||||
TcpPort.m
|
TcpPort.m
|
||||||
TextCStream.m
|
TextCStream.m
|
||||||
Time.m
|
|
||||||
UdpPort.m
|
UdpPort.m
|
||||||
behavior.m
|
behavior.m
|
||||||
preface.m
|
preface.m
|
||||||
mframe.m
|
mframe.m
|
||||||
HashTable.m
|
|
||||||
List.m
|
|
||||||
objc/HashTable.h
|
|
||||||
objc/List.h
|
|
||||||
NSAllocateObject.m
|
|
||||||
NSArchiver.m
|
|
||||||
NSArray.m
|
NSArray.m
|
||||||
NSAutoreleasePool.m
|
NSAutoreleasePool.m
|
||||||
NSCoder.m
|
NSCoder.m
|
||||||
NSCopyObject.m
|
NSCopyObject.m
|
||||||
NSCountedSet.m
|
NSCountedSet.m
|
||||||
NSData.m
|
NSData.m
|
||||||
NSDeallocateObject.m
|
|
||||||
NSDictionary.m
|
NSDictionary.m
|
||||||
NSEnumerator.m
|
NSEnumerator.m
|
||||||
NSGArchiver.m
|
NSGArchiver.m
|
||||||
NSGArray.m
|
NSGArray.m
|
||||||
NSGCountedSet.m
|
|
||||||
NSGCString.m
|
NSGCString.m
|
||||||
NSGDictionary.m
|
|
||||||
NSGSet.m
|
NSGSet.m
|
||||||
NSGString.m
|
NSGString.m
|
||||||
NSInvocation.m
|
|
||||||
NSMethodSignature.m
|
NSMethodSignature.m
|
||||||
NSNotification.m
|
NSNotification.m
|
||||||
NSNotificationCenter.m
|
NSNotificationCenter.m
|
||||||
|
@ -93,16 +75,10 @@ NSUser.m
|
||||||
Kresten Krab Thorup:
|
Kresten Krab Thorup:
|
||||||
GapArray.m
|
GapArray.m
|
||||||
objc-gnu2next.m
|
objc-gnu2next.m
|
||||||
Storage.m
|
|
||||||
objc/Storage.h
|
|
||||||
|
|
||||||
|
|
||||||
Adam Fedor:
|
Adam Fedor:
|
||||||
ostream.m
|
ostream.m
|
||||||
NXStringTable.m
|
|
||||||
NXStringTable_scan.c
|
|
||||||
objc/NXStringTable.h
|
|
||||||
NXStringTable_scan.l
|
|
||||||
NSAssertionHandler.m
|
NSAssertionHandler.m
|
||||||
NSBitmapCharSet.m
|
NSBitmapCharSet.m
|
||||||
NSBundle.m
|
NSBundle.m
|
||||||
|
@ -189,12 +165,17 @@ NSZone.m
|
||||||
Richard Frith-Macdonald:
|
Richard Frith-Macdonald:
|
||||||
UnixFileHandle.m
|
UnixFileHandle.m
|
||||||
NSData.m
|
NSData.m
|
||||||
|
NSDateFormatter.m
|
||||||
NSDebug.m
|
NSDebug.m
|
||||||
NSDistantObject.m
|
NSDistantObject.m
|
||||||
NSDistributedLock.m
|
NSDistributedLock.m
|
||||||
|
NSDistributedNotificationCenter.m
|
||||||
NSFileHandle.m
|
NSFileHandle.m
|
||||||
|
NSFormatter.m
|
||||||
|
NSGDictionary.m
|
||||||
NSPipe.m
|
NSPipe.m
|
||||||
NSPort.m
|
NSPort.m
|
||||||
|
NSPortNameServer.m
|
||||||
NSProxy.m
|
NSProxy.m
|
||||||
NSTask.m
|
NSTask.m
|
||||||
NSUndoManager.m
|
NSUndoManager.m
|
||||||
|
@ -209,3 +190,8 @@ NSGString.m
|
||||||
|
|
||||||
Mike Kienenberger:
|
Mike Kienenberger:
|
||||||
NSProtocolChecker.m
|
NSProtocolChecker.m
|
||||||
|
|
||||||
|
|
||||||
|
Manuel Guesdon:
|
||||||
|
NSURL.m
|
||||||
|
NSURLHandle.m
|
||||||
|
|
39
ChangeLog
39
ChangeLog
|
@ -1,3 +1,42 @@
|
||||||
|
Tue Mar 2 08:04:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* Merge in 'dawn' CVS branch.
|
||||||
|
|
||||||
|
1999-03-01 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
|
* Update documentation.
|
||||||
|
|
||||||
|
1999-02-28 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
|
* Source/Makefile.postamble: Don't install services if not
|
||||||
|
root. (patches submitted by Christopher Seawood
|
||||||
|
<cls@seawood.org>).
|
||||||
|
|
||||||
|
Tue Feb 23 12:03:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* Source/include/NSObject.h: Fixed bugin in ASSIGNCOPY() macro and added
|
||||||
|
CREATE_AUTORELEASE_POOL() macro for libFoundation compatibility.
|
||||||
|
* Source/include/NSRunLoop.h: Added GCFinalization protocol.
|
||||||
|
* Source/NSRunLoop.m: Tidied a little, added GC macro use, fixed minor
|
||||||
|
bug, and added slight performance improvement.
|
||||||
|
|
||||||
|
Mon Feb 22 5:40:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
Merged in alterations from main cvs branch made to wrong place 'cos
|
||||||
|
dawn branch was already created :-(
|
||||||
|
* Source/NSData.m: preserve file attributes when writing atomically
|
||||||
|
* Source/NSUser.m: Bugfixes for consistent naming of current user.
|
||||||
|
* Source/NSUserDefaults.m: Bugfixes so that running apps as root
|
||||||
|
doesn't mess up defaults database.
|
||||||
|
* Source/NSFileManager.m: Create files with correct ownership when
|
||||||
|
process is setuid to root - and provide facility for NSData to do same.
|
||||||
|
* Source/NSArray.m: Merged enumerator bugfix - missing @end
|
||||||
|
|
||||||
|
1999-02-22 Adam Fedor <fedor@gnu.org>
|
||||||
|
|
||||||
|
* Version: update version.
|
||||||
|
* Source/NSProcessInfo.m: Change missing main message.
|
||||||
|
|
||||||
Sun Feb 21 19:30:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
Sun Feb 21 19:30:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
* Source/NSFileManager.m: Attempt to fix problems with directory
|
* Source/NSFileManager.m: Attempt to fix problems with directory
|
||||||
|
|
|
@ -35,9 +35,9 @@ DOCUMENT_NAME = gnustep-base
|
||||||
|
|
||||||
# The text documents to be generated
|
# The text documents to be generated
|
||||||
DOCUMENT_TEXT_NAME = \
|
DOCUMENT_TEXT_NAME = \
|
||||||
TODO INSTALL NEWS CODING-STANDARDS README ANNOUNCE STATUS
|
INSTALL NEWS CODING-STANDARDS README ANNOUNCE
|
||||||
|
|
||||||
TOP_DOC_FILES = TODO INSTALL NEWS README ANNOUNCE STATUS
|
TOP_DOC_FILES = INSTALL NEWS README ANNOUNCE
|
||||||
|
|
||||||
gnustep-base_TEXI_FILES = \
|
gnustep-base_TEXI_FILES = \
|
||||||
version.tmpl.texi \
|
version.tmpl.texi \
|
||||||
|
@ -47,9 +47,7 @@ announce.tmpl.texi \
|
||||||
coding-standards.tmpl.texi \
|
coding-standards.tmpl.texi \
|
||||||
install.tmpl.texi \
|
install.tmpl.texi \
|
||||||
news.tmpl.texi \
|
news.tmpl.texi \
|
||||||
readme.tmpl.texi \
|
readme.tmpl.texi
|
||||||
status.tmpl.texi \
|
|
||||||
todo.tmpl.texi
|
|
||||||
|
|
||||||
TODO_TEXI_FILES = version.tmpl.texi
|
TODO_TEXI_FILES = version.tmpl.texi
|
||||||
TODO_TEXT_MAIN = todo.tmpl.texi
|
TODO_TEXT_MAIN = todo.tmpl.texi
|
||||||
|
|
|
@ -6,5 +6,4 @@ remote object messaging support (distributed objects), event loops, and
|
||||||
random number generators.
|
random number generators.
|
||||||
|
|
||||||
It provides functionality that aims to implement the non-graphical
|
It provides functionality that aims to implement the non-graphical
|
||||||
portion of the OpenStep standard. In many cases, the @samp{NS*} classes
|
portion of the OpenStep standard (the Foundation library).
|
||||||
are implemented as wrappers around more featureful GNU classes.
|
|
||||||
|
|
|
@ -90,12 +90,6 @@ into another language, under the above conditions for modified versions.
|
||||||
@c News
|
@c News
|
||||||
@include news.texi
|
@include news.texi
|
||||||
|
|
||||||
@c Status Report
|
|
||||||
@include status.texi
|
|
||||||
|
|
||||||
@c The ToDo
|
|
||||||
@include todo.texi
|
|
||||||
|
|
||||||
@c Generate Short Contents
|
@c Generate Short Contents
|
||||||
@shortcontents
|
@shortcontents
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,31 @@
|
||||||
The currently released version of the library is
|
The currently released version of the library is
|
||||||
@samp{@value{GNUSTEP-BASE-VERSION}}.
|
@samp{@value{GNUSTEP-BASE-VERSION}}.
|
||||||
|
|
||||||
|
@section Noteworthy changes in version @samp{0.5.5}
|
||||||
|
|
||||||
|
Too many changes to mention in detail, but here is a list of a few:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
|
||||||
|
@item
|
||||||
|
Many base classes have been rewritten with tonnes of performance
|
||||||
|
improvements that in many cases make it as fast as or faster than the
|
||||||
|
NeXT implementation.
|
||||||
|
|
||||||
|
@item
|
||||||
|
DO and archiving has received many improvements that help it work on a
|
||||||
|
variety of different platforms.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Configuration and compilation has been greatly improved and fool
|
||||||
|
proofed.
|
||||||
|
|
||||||
|
@item
|
||||||
|
There are several new tools for handling services, defaults, and
|
||||||
|
pasteboards.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
@section Noteworthy changes in version @samp{0.5.1}
|
@section Noteworthy changes in version @samp{0.5.1}
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
|
|
|
@ -21,107 +21,13 @@ will be forthcoming, but the library needs to settle first. For now I
|
||||||
recommend reading the header files.
|
recommend reading the header files.
|
||||||
The headers for the classes are in @file{./src/include}.
|
The headers for the classes are in @file{./src/include}.
|
||||||
|
|
||||||
The FAQ contains an outline of the class heirarchy, as well as a
|
|
||||||
list of the differences between GNUstep and NeXT's implementation of
|
|
||||||
OpenStep, and GNUstep's improvements over NeXT's implementation.
|
|
||||||
|
|
||||||
@section Overview of the classes
|
|
||||||
|
|
||||||
Here is partial list of non-OpenStep classes, grouped by functionality.
|
|
||||||
|
|
||||||
There are several GNU-specific protocols also. You can recognize the
|
|
||||||
protocols by their name: they all end with ``ing''.
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
|
|
||||||
@item The collection objects all conform to the @samp{Collecting}
|
|
||||||
protocol. Reading @samp{src/include/Collecting.h} is a good place to
|
|
||||||
start. Protocols for collections that store their contents with keys
|
|
||||||
and with indices can be found in @samp{src/incliude/KeyedCollecting.h} and
|
|
||||||
@samp{src/include/IndexedCollecting.h} respectively. Examples of generic
|
|
||||||
collections are @samp{Set} and @samp{Bag}. The keyed collections are
|
|
||||||
@samp{Dictionary} and @samp{MappedCollector}. The classes @samp{Array},
|
|
||||||
@samp{Queue}, @samp{GapArray}, @samp{LinkedList}, @samp{BinaryTree},
|
|
||||||
@samp{RBTree} and @samp{SplayTree} are all indexed collections.
|
|
||||||
|
|
||||||
@item The string objects conform to the @samp{String} protocol.
|
|
||||||
@samp{CString} provides an interface to strings based on ASCII bytes,
|
|
||||||
and is currently the only concrete subclass of String. The interface
|
|
||||||
between GNU @samp{String} and OpenStep's @samp{NSString} needs cleaning
|
|
||||||
up and will change. For now, I recommend using @samp{NSString}.
|
|
||||||
|
|
||||||
@item The public magnitude classes are @samp{Time} and @samp{Random}.
|
|
||||||
The @samp{Random} class works in conjunction with pseudo-random number
|
|
||||||
generators that conform to the @samp{RandomGenerating} protocol. The
|
|
||||||
conforming class @samp{RNGBerkeley} provides identical behavior to the
|
|
||||||
BSD random() function. The class @samp{RNGAdditiveCongruential} is an
|
|
||||||
implementation of the additive congruential method.
|
|
||||||
|
|
||||||
@item Stream objects provide a consistent interface for reading and
|
|
||||||
writing bytes. Read @samp{src/include/Stream.h} to get the general
|
|
||||||
idea. @samp{StdioStream} objects work with files, file descriptors,
|
|
||||||
FILE pointers and pipes to/from executables. @samp{MemoryStream}
|
|
||||||
objects work with memory buffers.
|
|
||||||
|
|
||||||
@item CStream objects provide a way to write C variables to Stream
|
|
||||||
objects. Read @file{src/include/CStream.h} to understand the interface
|
|
||||||
of the abstract superclass. @samp{TextCStream} writes C variables in a
|
|
||||||
human-readable ASCII format that can be manipulated with a text editor
|
|
||||||
or with your choice of text-processing programs, like @samp{awk} or
|
|
||||||
@samp{perl}. @samp{BinaryCStream} writes C variables in a compact,
|
|
||||||
illegible stream of bytes. @samp{TextCStream} and @samp{BinaryCStream}
|
|
||||||
each write in machine-independant formats---so you can write on one
|
|
||||||
machine architecture, and successfully read on another.
|
|
||||||
@samp{RawCStream} is like @samp{BinaryCStream} accept it is
|
|
||||||
machine-dependant; it useful for efficient Distributed Objects
|
|
||||||
connections on the same machine.
|
|
||||||
|
|
||||||
@item Coders provide a formatted way of writing Objective C objects to
|
|
||||||
CStream objects. After a coder is initialized with a stream, the coder
|
|
||||||
can encode/decode interconnected webs of Objective C objects and C types
|
|
||||||
and successfully keep track of complex interconnections between objects.
|
|
||||||
See @samp{src/include/Coder.h} for the abstract superclass interface;
|
|
||||||
see @samp{src/include/Coding.h} for the protocol adopted by objects that
|
|
||||||
read and write themselves using coders. @samp{Archiver} and
|
|
||||||
@samp{Unarchiver} are concrete subclasses that are used for
|
|
||||||
writing/reading with files.
|
|
||||||
|
|
||||||
@samp{Coder}s and @samp{CStream}s and @samp{Stream}s can be mixed and
|
|
||||||
matched so that programmers can choose the destination and the format
|
|
||||||
separately.
|
|
||||||
|
|
||||||
@ignore
|
|
||||||
@item @samp{Notification}
|
|
||||||
@samp{NotificationDispatcher}
|
|
||||||
@end ignore
|
|
||||||
|
|
||||||
@item The distributed object support classes are @samp{NSConnection},
|
|
||||||
@samp{NSProxy}, @samp{ConnectedCoder}, @samp{Port} and @samp{TcpPort}.
|
|
||||||
This version of the distributed objects only works with sockets. A Mach
|
|
||||||
port back-end should be on the way.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@section Test Programs
|
|
||||||
|
|
||||||
Some of the programs I've used to test the library are in
|
|
||||||
@samp{./checks}. Many of them are pretty messy, (desperately trying to
|
|
||||||
tickle that late night bug), but at least they show some code that works
|
|
||||||
when the library compiles correctly. I'm looking for a volunteer to
|
|
||||||
write some nicely organized test cases using @samp{dejagnu}. Any
|
|
||||||
takers?
|
|
||||||
|
|
||||||
@section How can you help?
|
@section How can you help?
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
|
|
||||||
@item Read the projects and questions in the @samp{TODO} file. If you
|
|
||||||
can volunteer for any of the projects, or if you have any useful
|
|
||||||
comments send me email!
|
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Give me feedback! Tell me what you like; tell me what you think
|
Give us feedback! Tell us what you like; tell us what you think
|
||||||
could be better. Send me bug reports.
|
could be better. Send bug reports to @email{bug-gnustep@@gnu.org}.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Donate classes. If you write classes that fit in the libgnustep-base
|
Donate classes. If you write classes that fit in the libgnustep-base
|
||||||
|
@ -131,9 +37,4 @@ framework, I'd be happy to include them.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
Happy hacking!
|
Happy hacking!
|
||||||
Andrew McCallum
|
|
||||||
mccallum@@gnu.org
|
|
||||||
|
|
||||||
Adam Fedor
|
|
||||||
fedor@@gnu.org
|
|
||||||
@end example
|
@end example
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
@include version.tmpl.texi
|
@include version.tmpl.texi
|
||||||
@end ifset
|
@end ifset
|
||||||
|
|
||||||
|
The gnustep-base library is nearly complete, although a few things could
|
||||||
|
be fixed here and there and it could be ported to more systems. This
|
||||||
|
list is probably out of date. In the future we will be primarily adding
|
||||||
|
features and performance tuning.
|
||||||
Please send corrections to @email{fedor@@gnu.org}.
|
Please send corrections to @email{fedor@@gnu.org}.
|
||||||
|
|
||||||
@emph{Key:}
|
@emph{Key:}
|
||||||
|
@ -31,80 +35,62 @@ Unknown status.
|
||||||
(Many classes do not raise the proper NSExceptions yet.)
|
(Many classes do not raise the proper NSExceptions yet.)
|
||||||
|
|
||||||
@table @strong
|
@table @strong
|
||||||
@item NSArchiver:: [8]
|
@item NSArchiver:: [9]
|
||||||
Doesn't yet call -awakeAfterUsingCoder:.
|
|
||||||
@item NSArray:: [9]
|
@item NSArray:: [9]
|
||||||
@item NSAssertionHandler:: [9]
|
@item NSAssertionHandler:: [9]
|
||||||
@item NSAttributedString:: [8]
|
@item NSAttributedString:: [9]
|
||||||
@item NSAutoreleasePool:: [9]
|
@item NSAutoreleasePool:: [9]
|
||||||
But not exception- safe
|
But not exception- safe
|
||||||
@item NSBundle:: [8]
|
@item NSBundle:: [9]
|
||||||
@item NSCalendarDate:: [7]
|
@item NSCalendarDate:: [8]
|
||||||
@item NSCharacterSet:: [8]
|
@item NSCharacterSet:: [9]
|
||||||
decomposableCharacterSet and illegalCharacter set missing
|
@item NSCoder:: [9]
|
||||||
@item NSCoder:: [8]
|
|
||||||
Missing class name substitution methods.
|
|
||||||
@item NSConditionLock:: [8]
|
@item NSConditionLock:: [8]
|
||||||
@item NSConnection:: [7]
|
@item NSConnection:: [9]
|
||||||
GNU Connection, however, needs:
|
@item NSCountedSet:: [9]
|
||||||
@itemize @bullet
|
@item NSData:: [9]
|
||||||
@item to handle retain/release/dealloc properly
|
@item NSDate:: [9]
|
||||||
@item to be integrated with NSInvocation
|
@item NSDeserializer:: [8]
|
||||||
@item to incorporate futzing with low-level TCP-backend for better speed
|
@item NSDictionary:: [9]
|
||||||
@item to have UDP-backend work
|
@item NSDistantObject:: [8]
|
||||||
@item to cache ConnectedCoder's for better speed
|
@item NSDistributedLock:: [9]
|
||||||
@item Thread-safety overhaul, this is major
|
|
||||||
@end itemize
|
|
||||||
@item NSCountedSet:: [8]
|
|
||||||
@item NSData:: [8]
|
|
||||||
@item NSDate:: [8]
|
|
||||||
@item NSDeserializer:: [7]
|
|
||||||
@item NSDictionary:: [8]
|
|
||||||
@item NSDistantObject:: [7]
|
|
||||||
@item NSDistributedLock:: [7]
|
|
||||||
@item NSEnumerator:: [9]
|
@item NSEnumerator:: [9]
|
||||||
@item NSException:: [9]
|
@item NSException:: [9]
|
||||||
But this needs integration with new, better
|
But this needs integration with new, better
|
||||||
@item NSFileHandle:: [9]
|
@item NSFileHandle:: [9]
|
||||||
@item NSFileManager:: [9]
|
@item NSFileManager:: [9]
|
||||||
@item NSHashTable:: [8]
|
@item NSHashTable:: [9]
|
||||||
@item NSHost:: [8]
|
@item NSHost:: [9]
|
||||||
@item NSInvocation:: [3]
|
@item NSInvocation:: [7]
|
||||||
@item NSLock:: [8]
|
@item NSLock:: [9]
|
||||||
@item NSMapTable:: [8]
|
@item NSMapTable:: [9]
|
||||||
@item NSMethodSignature:: [4]
|
@item NSMethodSignature:: [7]
|
||||||
@item NSMutableArray:: [8]
|
@item NSMutableArray:: [9]
|
||||||
@item NSMutableCharacterSet:: [7]
|
@item NSMutableCharacterSet:: [8]
|
||||||
@item NSMutableData:: [8]
|
@item NSMutableData:: [9]
|
||||||
@item NSMutableDictionary:: [8]
|
@item NSMutableDictionary:: [9]
|
||||||
@item NSMutableSet:: [8]
|
@item NSMutableSet:: [9]
|
||||||
@item NSMutableString:: [8]
|
@item NSMutableString:: [9]
|
||||||
@item NSNotification:: [9]
|
@item NSNotification:: [9]
|
||||||
@item NSNotificationCenter:: [9]
|
@item NSNotificationCenter:: [9]
|
||||||
@item NSNotificationQueue:: [6]
|
@item NSNotificationQueue:: [6]
|
||||||
Needs integration with NSRunLoop, and efficiency improvements
|
|
||||||
@item NSNumber:: [9]
|
@item NSNumber:: [9]
|
||||||
@item NSObject:: [10]
|
@item NSObject:: [10]
|
||||||
@item NSProcessInfo:: [9]
|
@item NSProcessInfo:: [9]
|
||||||
@item NSProxy:: [7]
|
@item NSProxy:: [8]
|
||||||
@item NSRecursiveLock:: [8]
|
@item NSRecursiveLock:: [9]
|
||||||
@item NSRunLoop:: [8]
|
@item NSRunLoop:: [9]
|
||||||
NSTimer's not yet working, but everything else should be
|
@item NSScanner:: [9]
|
||||||
@item NSScanner:: [8]
|
@item NSSerializer:: [8]
|
||||||
@item NSSerializer:: [7]
|
@item NSSet:: [9]
|
||||||
@item NSSet:: [8]
|
@item NSString:: [9]
|
||||||
@item NSString:: [8]
|
|
||||||
Careful, relationship with GNU String is tricky; this could
|
|
||||||
also use fixing.
|
|
||||||
@item NSTask:: [8]
|
@item NSTask:: [8]
|
||||||
@item NSThread:: [8]
|
@item NSThread:: [8]
|
||||||
@item NSTimeZone:: [8]
|
@item NSTimeZone:: [9]
|
||||||
@item NSTimeZoneDetail:: [8]
|
@item NSTimeZoneDetail:: [9]
|
||||||
@item NSTimer:: [6]
|
@item NSTimer:: [7]
|
||||||
Working out bugs with returning doubles.
|
@item NSUnarchiver:: [9]
|
||||||
@item NSUnarchiver:: [8]
|
@item NSUserDefaults:: [9]
|
||||||
See NSArchvier
|
|
||||||
@item NSUserDefaults:: [8]
|
|
||||||
@item NSValue:: [9]
|
@item NSValue:: [9]
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
|
@ -10,161 +10,5 @@
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
|
|
||||||
@item Implement Formatter classes (NSDateFormatter, etc) [5] (980722).
|
|
||||||
|
|
||||||
@item Implement NSDecimalNumber stuff [5] (981119).
|
|
||||||
|
|
||||||
@item Write tests for various classes using the testsuite built
|
|
||||||
by Richard Frith-Macdonald @email{richard@@brainstorm.co.uk}. Contact
|
|
||||||
him for details. [3, guile] (980629)
|
|
||||||
|
|
||||||
@item Check that every class implements coding (correctly). [2, NSCoder] (980721) - contribute to the testuite.
|
|
||||||
|
|
||||||
@item Check that every class implements copying (correctly) - i.e. non-mutable classes should just retain, etc. [1, NSCopying] (980721) - contribute to the testsuite.
|
|
||||||
|
|
||||||
@item Check that every class raises the NSExceptions it is supposed to.
|
|
||||||
Change many NSParameterAssert()'s into NSAssert()'s with
|
|
||||||
explanations. [2, exceptions] (970101) - contribute to the testsuite.
|
|
||||||
|
|
||||||
@item Improve initWithFormat related methods for NSString and find out how to implement the locale stuff [4 OPENSTEP/Rhapsody] (980712)
|
|
||||||
|
|
||||||
@item Make gstep-base 64bit clean [5, 64bit machine] (980629)
|
|
||||||
Donating internet access to a 64bit machine for someone else to do the
|
|
||||||
work on would also be helpful.
|
|
||||||
|
|
||||||
@item Make gstep-base smaller. Perhaps we can get rid of classes that
|
|
||||||
aren't strictly part of OpenStep and put them in an extensions-type
|
|
||||||
library. [5] (980629)
|
|
||||||
|
|
||||||
@item Fix NSLog so it conforms to specs. Need to check that write to
|
|
||||||
stderr went ok, and if not write to syslog. Also need to serialize
|
|
||||||
output (with threads). [3, OpenStep specs, threads] (980220)
|
|
||||||
|
|
||||||
@item Simplify NSException and NSAssertionHandler and make sure they
|
|
||||||
don't cause race conditions (if an exception is raised while processing
|
|
||||||
an exception. [4, exceptions, threads] (980220)
|
|
||||||
|
|
||||||
@item Fix all the places marked FIXME or xxx. [3-9] (980629)
|
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ignore
|
|
||||||
|
|
||||||
@c ==================================================================
|
|
||||||
@section Questions
|
|
||||||
|
|
||||||
I would greatly appreciate your feedback on the questions
|
|
||||||
below. Please email your thoughts to mccallum@@gnu.ai.mit.edu.
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
|
|
||||||
@item
|
|
||||||
I want to put method names in texinfo indices, but the colons in the
|
|
||||||
method names are interfering with info's notion of menu item names and
|
|
||||||
node names. Help. Any ideas? (Kresten?)
|
|
||||||
|
|
||||||
@item
|
|
||||||
HashTable.m (-initKeyDesc:valueDesc:capacity:) I tried to make it
|
|
||||||
portable, but I didn't try very hard. Anyone want to send in fixes?
|
|
||||||
|
|
||||||
@item
|
|
||||||
I fixed -emptyCopy in all the subclasses, but the -emptyCopy scheme
|
|
||||||
seems pretty fragile. How about calling -initFoo: inside -emptyCopy?
|
|
||||||
This way we avoid having yet another method in which instance vars
|
|
||||||
must be initialized to some consistent state. -allocCopy would never
|
|
||||||
even get called. <<ObjC insiders: This is a less well-expressed
|
|
||||||
version of what we've just been discussing in email.>>
|
|
||||||
|
|
||||||
@item
|
|
||||||
Does anyone really need the ability to set the collection element
|
|
||||||
comparison function independent of the -compare: method?
|
|
||||||
|
|
||||||
@item
|
|
||||||
How about adding flexibity in the method name that a LinkedList sends a
|
|
||||||
LinkedListNode to get/set the link ivars. This would enable us to add a
|
|
||||||
node to more than one linked list.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Something like this needed?
|
|
||||||
- elementDidChange: (elt*)elementPtr;
|
|
||||||
Currently you have to remove, change, add, for some classes.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
|
|
||||||
@section Albin's To Do List
|
|
||||||
|
|
||||||
I'm sure that there're other things to do, but these are the ones I know now:
|
|
||||||
|
|
||||||
@subsection General
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
@item Make thread-safe all of my code that should be.
|
|
||||||
@item Fully annotate all of my headers.
|
|
||||||
@item Document my work and the use of its fruit.
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@subsection Critical
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
@item Code:
|
|
||||||
@itemize +
|
|
||||||
@item (@file{src/array.m}) @samp{objects_array_check}
|
|
||||||
@item (@file{src/array.m}) @samp{objects_array_map_elements}
|
|
||||||
@item (@file{src/cbs-char-p.m}) @samp{objects_char_p_describe}
|
|
||||||
@item (@file{src/cbs-int-p.m}) @samp{objects_int_p_describe}
|
|
||||||
@item (@file{src/cbs-int.m}) @samp{objects_int_describe}
|
|
||||||
@item (@file{src/hash.m}) @samp{_objects_hash_hash}
|
|
||||||
@item (@file{src/hash.m}) @samp{objects_hash_check}
|
|
||||||
@item (@file{src/hash.m}) @samp{objects_hash_description}
|
|
||||||
@item (@file{src/list.m}) @samp{objects_list_is_equal_to_list}
|
|
||||||
@item (@file{src/map.m}) @samp{_objects_map_hash}
|
|
||||||
@item (@file{src/map.m}) @samp{objects_map_check}
|
|
||||||
@item (@file{src/map.m}) @samp{objects_map_description}
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@item Correct:
|
|
||||||
@itemize +
|
|
||||||
@item (@file{src/array.m}) @samp{objects_array_dealloc}
|
|
||||||
@item (@file{src/cbs-int.m}) @samp{_GNUSTEP_BASE_NOT_AN_INT_MARKER}
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@item Improve the error handling of:
|
|
||||||
@itemize +
|
|
||||||
@item (@file{src/array.m}) @samp{_objects_array_insert_bucket}
|
|
||||||
@item (@file{src/hash.m}) @samp{objects_hash_add_element_known_absent}
|
|
||||||
@item (@file{src/list.m}) @samp{objects_list_at_index_insert_element}
|
|
||||||
@item (@file{src/map.m}) @samp{objects_map_at_key_put_value_known_absent}
|
|
||||||
@end itemize
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@subsection Not So Critical
|
|
||||||
|
|
||||||
@itemize @bullet
|
|
||||||
@item Strengthen my resolve on the correctness of:
|
|
||||||
@itemize +
|
|
||||||
@item (@file{src/cbs-char-p.m}) @samp{_GNUSTEP_BASE_NOT_A_CHAR_P_MARKER}
|
|
||||||
@item (@file{src/cbs-id.m}) @samp{_GNUSTEP_BASE_NOT_AN_ID_MARKER}
|
|
||||||
@item (@file{src/cbs-int-p.m}) @samp{_GNUSTEP_BASE_NOT_AN_INT_P_MARKER}
|
|
||||||
@item (@file{src/cbs-int-p.m}) @samp{objects_int_p_is_equal}
|
|
||||||
@item (@file{src/cbs-void-p.m}) @samp{_GNUSTEP_BASE_NOT_A_VOID_P_MARKER}
|
|
||||||
@item (@file{src/hash.m}) @samp{objects_hash_rightsize}
|
|
||||||
@item (@file{src/hash.m}) @samp{objects_hash_all_elements}
|
|
||||||
@item (@file{src/map.m}) @samp{objects_map_rightsize}
|
|
||||||
@item (@file{src/map.m}) @samp{objects_map_all_keys}
|
|
||||||
@item (@file{src/map.m}) @samp{objects_map_all_values}
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@item Improve the efficiency of:
|
|
||||||
@itemize +
|
|
||||||
@item (@file{src/array.m}) @samp{_objects_array_insert_bucket}
|
|
||||||
@item (@file{src/hash.m}) @samp{objects_hash_minus_hash}
|
|
||||||
@item (@file{src/list.m}) @samp{objects_list_at_index_insert_list}
|
|
||||||
@end itemize
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@end ignore
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -231,8 +231,11 @@ extern NSRecursiveLock *gnustep_global_lock;
|
||||||
#define AUTORELEASE(object) ((id)object)
|
#define AUTORELEASE(object) ((id)object)
|
||||||
|
|
||||||
#define ASSIGN(object,value) (object = value)
|
#define ASSIGN(object,value) (object = value)
|
||||||
|
#define ASSIGNCOPY(object,value) (object = [value copy])
|
||||||
#define DESTROY(object) (object = nil)
|
#define DESTROY(object) (object = nil)
|
||||||
|
|
||||||
|
#define CREATE_AUTORELEASE_POOL(X)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define RETAIN(object) [object retain]
|
#define RETAIN(object) [object retain]
|
||||||
|
@ -269,7 +272,7 @@ if (__value != object) \
|
||||||
{ \
|
{ \
|
||||||
if (__value) \
|
if (__value) \
|
||||||
{ \
|
{ \
|
||||||
[__value copy]; \
|
__value = [__value copy]; \
|
||||||
} \
|
} \
|
||||||
if (object) \
|
if (object) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -285,6 +288,10 @@ if (__value != object) \
|
||||||
* object later.
|
* object later.
|
||||||
*/
|
*/
|
||||||
#define DESTROY(object) ([object release], object = nil)
|
#define DESTROY(object) ([object release], object = nil)
|
||||||
|
|
||||||
|
#define CREATE_AUTORELEASE_POOL(X) \
|
||||||
|
NSAutoreleasePool *(X) = [NSAutoreleasePool new]
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __NSObject_h_GNUSTEP_BASE_INCLUDE */
|
#endif /* __NSObject_h_GNUSTEP_BASE_INCLUDE */
|
||||||
|
|
|
@ -26,7 +26,11 @@
|
||||||
|
|
||||||
#include <Foundation/NSObject.h>
|
#include <Foundation/NSObject.h>
|
||||||
|
|
||||||
@class NSMutableSet;
|
@class NSArray;
|
||||||
|
@class NSConnection;
|
||||||
|
@class NSDate;
|
||||||
|
@class NSRunLoop;
|
||||||
|
@class NSString;
|
||||||
|
|
||||||
extern NSString *NSPortTimeoutException; /* OPENSTEP */
|
extern NSString *NSPortTimeoutException; /* OPENSTEP */
|
||||||
|
|
||||||
|
@ -39,16 +43,29 @@ extern NSString *NSPortTimeoutException; /* OPENSTEP */
|
||||||
+ (NSPort*) port;
|
+ (NSPort*) port;
|
||||||
+ (NSPort*) portWithMachPort: (int)machPort;
|
+ (NSPort*) portWithMachPort: (int)machPort;
|
||||||
|
|
||||||
- delegate;
|
- (id) delegate;
|
||||||
|
|
||||||
- init;
|
- (id) init;
|
||||||
- initWithMachPort: (int)machPort;
|
- (id) initWithMachPort: (int)machPort;
|
||||||
|
|
||||||
- (void) invalidate;
|
- (void) invalidate;
|
||||||
- (BOOL) isValid;
|
- (BOOL) isValid;
|
||||||
- machPort;
|
- (int) machPort;
|
||||||
- (void) setDelegate: anObject;
|
- (void) setDelegate: (id)anObject;
|
||||||
|
|
||||||
|
#ifndef STRICT_OPENSTEP
|
||||||
|
- (void) addConnection: (NSConnection*)aConnection
|
||||||
|
toRunLoop: (NSRunLoop*)aLoop
|
||||||
|
forMode: (NSString*)aMode;
|
||||||
|
- (void) removeConnection: (NSConnection*)aConnection
|
||||||
|
fromRunLoop: (NSRunLoop*)aLoop
|
||||||
|
forMode: (NSString*)aMode;
|
||||||
|
- (unsigned) reservedSpaceLength;
|
||||||
|
- (void) sendBeforeDate: (NSDate*)when
|
||||||
|
components: (NSArray*)components
|
||||||
|
from: (NSPort*)receivingPort
|
||||||
|
reserved: (unsigned) length;
|
||||||
|
#endif
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#ifndef NO_GNUSTEP
|
#ifndef NO_GNUSTEP
|
||||||
|
|
|
@ -42,6 +42,10 @@
|
||||||
- (NSPort*) receivePort;
|
- (NSPort*) receivePort;
|
||||||
- (void) setMsgid: (unsigned)anId;
|
- (void) setMsgid: (unsigned)anId;
|
||||||
- (unsigned) msgid;
|
- (unsigned) msgid;
|
||||||
|
|
||||||
|
#ifndef NO_GNUSTEP
|
||||||
|
- (void) addComponent: (id)aComponent;
|
||||||
|
#endif
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
/* Mode strings. */
|
/* Mode strings. */
|
||||||
extern id NSDefaultRunLoopMode;
|
extern id NSDefaultRunLoopMode;
|
||||||
|
|
||||||
@interface NSRunLoop : NSObject
|
@interface NSRunLoop : NSObject <GCFinalization>
|
||||||
{
|
{
|
||||||
@private id _current_mode;
|
@private id _current_mode;
|
||||||
@private NSMapTable *_mode_2_timers;
|
@private NSMapTable *_mode_2_timers;
|
||||||
|
|
|
@ -74,7 +74,6 @@ after-distclean::
|
||||||
|
|
||||||
configure: configure.in
|
configure: configure.in
|
||||||
autoconf
|
autoconf
|
||||||
autoheader
|
|
||||||
|
|
||||||
# Regenerate automatically generated files
|
# Regenerate automatically generated files
|
||||||
regenerate: stamp-regenerate
|
regenerate: stamp-regenerate
|
||||||
|
@ -84,36 +83,3 @@ stamp-regenerate: ChangeLog configure
|
||||||
(cd $$i; $(MAKE) $(MAKEDEFINES) regenerate); \
|
(cd $$i; $(MAKE) $(MAKEDEFINES) regenerate); \
|
||||||
done
|
done
|
||||||
touch stamp-regenerate
|
touch stamp-regenerate
|
||||||
|
|
||||||
snapshot:
|
|
||||||
@echo Making $(PACKAGE_NAME) snapshot
|
|
||||||
cvs export -r snapshot-`date +%y%m%d` $(PACKAGE_NAME)
|
|
||||||
rm -f .name
|
|
||||||
echo $(PACKAGE_NAME)-`date +%y%m%d` >.name
|
|
||||||
rm -rf `cat .name`
|
|
||||||
mv $(PACKAGE_NAME) `cat .name`
|
|
||||||
tar -chvf `cat .name`.tar `cat .name`
|
|
||||||
rm -f `cat .name`.tar.gz
|
|
||||||
gzip -9 `cat .name`.tar
|
|
||||||
rm -rf `cat .name`
|
|
||||||
|
|
||||||
dist:
|
|
||||||
@echo Making $(PACKAGE_NAME) release $(VERSION)
|
|
||||||
cvs export -r release-`echo $(VERSION) | tr . -` $(PACKAGE_NAME)
|
|
||||||
mv $(PACKAGE_NAME) $(PACKAGE_NAME)-$(VERSION)
|
|
||||||
tar -chvf $(PACKAGE_NAME)-$(VERSION).tar \
|
|
||||||
$(PACKAGE_NAME)-$(VERSION)
|
|
||||||
rm -f $(PACKAGE_NAME)-$(VERSION).tar.gz
|
|
||||||
gzip -9 $(PACKAGE_NAME)-$(VERSION).tar
|
|
||||||
rm -rf $(PACKAGE_NAME)-$(VERSION)
|
|
||||||
|
|
||||||
snapshot-rtag:
|
|
||||||
@echo Tagging current base HEAD for snapshot `date +%y%m%d`
|
|
||||||
cvs rtag snapshot-`date +%y%m%d` $(PACKAGE_NAME)
|
|
||||||
|
|
||||||
dist-rtag:
|
|
||||||
@echo Tagging current base HEAD for release $(VERSION)
|
|
||||||
cvs rtag release-`echo $(VERSION) | tr . -` $(PACKAGE_NAME)
|
|
||||||
|
|
||||||
rdiff:
|
|
||||||
cvs rdiff -u -r $(OLD) $(PACKAGE_NAME)
|
|
||||||
|
|
20
NEWS
20
NEWS
|
@ -1,7 +1,25 @@
|
||||||
News
|
News
|
||||||
****
|
****
|
||||||
|
|
||||||
The currently released version of the library is `0.5.0'.
|
The currently released version of the library is `0.5.5'.
|
||||||
|
|
||||||
|
Noteworthy changes in version `0.5.5'
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Too many changes to mention in detail, but here is a list of a few:
|
||||||
|
|
||||||
|
* Many base classes have been rewritten with tonnes of performance
|
||||||
|
improvements that in many cases make it as fast as or faster than
|
||||||
|
the NeXT implementation.
|
||||||
|
|
||||||
|
* DO and archiving has received many improvements that help it work
|
||||||
|
on a variety of different platforms.
|
||||||
|
|
||||||
|
* Configuration and compilation has been greatly improved and fool
|
||||||
|
proofed.
|
||||||
|
|
||||||
|
* There are several new tools for handling services, defaults, and
|
||||||
|
pasteboards.
|
||||||
|
|
||||||
Noteworthy changes in version `0.5.1'
|
Noteworthy changes in version `0.5.1'
|
||||||
=====================================
|
=====================================
|
||||||
|
|
99
README
99
README
|
@ -9,8 +9,7 @@ remote object messaging support (distributed objects), event loops, and
|
||||||
random number generators.
|
random number generators.
|
||||||
|
|
||||||
It provides functionality that aims to implement the non-graphical
|
It provides functionality that aims to implement the non-graphical
|
||||||
portion of the OpenStep standard. In many cases, the `NS*' classes are
|
portion of the OpenStep standard (the Foundation library).
|
||||||
implemented as wrappers around more featureful GNU classes.
|
|
||||||
|
|
||||||
Here is some introductory info to get you started:
|
Here is some introductory info to get you started:
|
||||||
|
|
||||||
|
@ -30,106 +29,14 @@ documentation will be forthcoming, but the library needs to settle
|
||||||
first. For now I recommend reading the header files. The headers for
|
first. For now I recommend reading the header files. The headers for
|
||||||
the classes are in `./src/include'.
|
the classes are in `./src/include'.
|
||||||
|
|
||||||
The FAQ contains an outline of the class heirarchy, as well as a
|
|
||||||
list of the differences between GNUstep and NeXT's implementation of
|
|
||||||
OpenStep, and GNUstep's improvements over NeXT's implementation.
|
|
||||||
|
|
||||||
Overview of the classes
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Here is partial list of non-OpenStep classes, grouped by
|
|
||||||
functionality.
|
|
||||||
|
|
||||||
There are several GNU-specific protocols also. You can recognize the
|
|
||||||
protocols by their name: they all end with "ing".
|
|
||||||
|
|
||||||
* The collection objects all conform to the `Collecting' protocol.
|
|
||||||
Reading `src/include/Collecting.h' is a good place to start.
|
|
||||||
Protocols for collections that store their contents with keys and
|
|
||||||
with indices can be found in `src/incliude/KeyedCollecting.h' and
|
|
||||||
`src/include/IndexedCollecting.h' respectively. Examples of
|
|
||||||
generic collections are `Set' and `Bag'. The keyed collections are
|
|
||||||
`Dictionary' and `MappedCollector'. The classes `Array', `Queue',
|
|
||||||
`GapArray', `LinkedList', `BinaryTree', `RBTree' and `SplayTree'
|
|
||||||
are all indexed collections.
|
|
||||||
|
|
||||||
* The string objects conform to the `String' protocol. `CString'
|
|
||||||
provides an interface to strings based on ASCII bytes, and is
|
|
||||||
currently the only concrete subclass of String. The interface
|
|
||||||
between GNU `String' and OpenStep's `NSString' needs cleaning up
|
|
||||||
and will change. For now, I recommend using `NSString'.
|
|
||||||
|
|
||||||
* The public magnitude classes are `Time' and `Random'. The
|
|
||||||
`Random' class works in conjunction with pseudo-random number
|
|
||||||
generators that conform to the `RandomGenerating' protocol. The
|
|
||||||
conforming class `RNGBerkeley' provides identical behavior to the
|
|
||||||
BSD random() function. The class `RNGAdditiveCongruential' is an
|
|
||||||
implementation of the additive congruential method.
|
|
||||||
|
|
||||||
* Stream objects provide a consistent interface for reading and
|
|
||||||
writing bytes. Read `src/include/Stream.h' to get the general
|
|
||||||
idea. `StdioStream' objects work with files, file descriptors,
|
|
||||||
FILE pointers and pipes to/from executables. `MemoryStream'
|
|
||||||
objects work with memory buffers.
|
|
||||||
|
|
||||||
* CStream objects provide a way to write C variables to Stream
|
|
||||||
objects. Read `src/include/CStream.h' to understand the interface
|
|
||||||
of the abstract superclass. `TextCStream' writes C variables in a
|
|
||||||
human-readable ASCII format that can be manipulated with a text
|
|
||||||
editor or with your choice of text-processing programs, like `awk'
|
|
||||||
or `perl'. `BinaryCStream' writes C variables in a compact,
|
|
||||||
illegible stream of bytes. `TextCStream' and `BinaryCStream' each
|
|
||||||
write in machine-independant formats--so you can write on one
|
|
||||||
machine architecture, and successfully read on another.
|
|
||||||
`RawCStream' is like `BinaryCStream' accept it is
|
|
||||||
machine-dependant; it useful for efficient Distributed Objects
|
|
||||||
connections on the same machine.
|
|
||||||
|
|
||||||
* Coders provide a formatted way of writing Objective C objects to
|
|
||||||
CStream objects. After a coder is initialized with a stream, the
|
|
||||||
coder can encode/decode interconnected webs of Objective C objects
|
|
||||||
and C types and successfully keep track of complex
|
|
||||||
interconnections between objects. See `src/include/Coder.h' for
|
|
||||||
the abstract superclass interface; see `src/include/Coding.h' for
|
|
||||||
the protocol adopted by objects that read and write themselves
|
|
||||||
using coders. `Archiver' and `Unarchiver' are concrete subclasses
|
|
||||||
that are used for writing/reading with files.
|
|
||||||
|
|
||||||
`Coder's and `CStream's and `Stream's can be mixed and matched so
|
|
||||||
that programmers can choose the destination and the format
|
|
||||||
separately.
|
|
||||||
|
|
||||||
* The distributed object support classes are `NSConnection',
|
|
||||||
`NSProxy', `ConnectedCoder', `Port' and `TcpPort'. This version
|
|
||||||
of the distributed objects only works with sockets. A Mach port
|
|
||||||
back-end should be on the way.
|
|
||||||
|
|
||||||
Test Programs
|
|
||||||
=============
|
|
||||||
|
|
||||||
Some of the programs I've used to test the library are in
|
|
||||||
`./checks'. Many of them are pretty messy, (desperately trying to
|
|
||||||
tickle that late night bug), but at least they show some code that works
|
|
||||||
when the library compiles correctly. I'm looking for a volunteer to
|
|
||||||
write some nicely organized test cases using `dejagnu'. Any takers?
|
|
||||||
|
|
||||||
How can you help?
|
How can you help?
|
||||||
=================
|
=================
|
||||||
|
|
||||||
* Read the projects and questions in the `TODO' file. If you can
|
* Give us feedback! Tell us what you like; tell us what you think
|
||||||
volunteer for any of the projects, or if you have any useful
|
could be better. Send bug reports to <bug-gnustep@gnu.org>.
|
||||||
comments send me email!
|
|
||||||
|
|
||||||
* Give me feedback! Tell me what you like; tell me what you think
|
|
||||||
could be better. Send me bug reports.
|
|
||||||
|
|
||||||
* Donate classes. If you write classes that fit in the
|
* Donate classes. If you write classes that fit in the
|
||||||
libgnustep-base framework, I'd be happy to include them.
|
libgnustep-base framework, I'd be happy to include them.
|
||||||
|
|
||||||
Happy hacking!
|
Happy hacking!
|
||||||
Andrew McCallum
|
|
||||||
mccallum@gnu.org
|
|
||||||
|
|
||||||
Adam Fedor
|
|
||||||
fedor@gnu.org
|
|
||||||
|
|
||||||
|
|
|
@ -58,19 +58,22 @@ after-install::
|
||||||
$(INSTALL_DATA) $(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS)/mframe.h \
|
$(INSTALL_DATA) $(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS)/mframe.h \
|
||||||
$(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS)
|
$(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS)
|
||||||
if [ "$(INSTALL_ROOT_DIR)" = "" ]; then \
|
if [ "$(INSTALL_ROOT_DIR)" = "" ]; then \
|
||||||
if [ "`whoami`" != root ]; then \
|
|
||||||
echo "WARNING: Please add the following lines yourself"; \
|
|
||||||
fi; \
|
|
||||||
services=/etc/services; \
|
services=/etc/services; \
|
||||||
else \
|
else \
|
||||||
mkdir -p $(INSTALL_ROOT_DIR)/etc; \
|
mkdir -p $(INSTALL_ROOT_DIR)/etc; \
|
||||||
services=$(INSTALL_ROOT_DIR)/etc/services.add; \
|
services=$(INSTALL_ROOT_DIR)/etc/services.add; \
|
||||||
echo "GNUstep addons for /etc/services written to $$services"; \
|
|
||||||
fi; \
|
fi; \
|
||||||
|
if [ "`whoami`" != root ]; then \
|
||||||
|
echo "WARNING: Please add the following lines to $$services"; \
|
||||||
|
echo "gdomap 538/tcp # GNUstep distrib objects"; \
|
||||||
|
echo "gdomap 538/udp # GNUstep distrib objects"; \
|
||||||
|
else \
|
||||||
if [ "`fgrep gdomap $$services 2>/dev/null`" = "" ]; then \
|
if [ "`fgrep gdomap $$services 2>/dev/null`" = "" ]; then \
|
||||||
|
echo "GNUstep addons for /etc/services written to $$services"; \
|
||||||
set -x; \
|
set -x; \
|
||||||
echo "gdomap 538/tcp # GNUstep distrib objects" >> $$services; \
|
echo "gdomap 538/tcp # GNUstep distrib objects" >> $$services; \
|
||||||
echo "gdomap 538/udp # GNUstep distrib objects" >> $$services; \
|
echo "gdomap 538/udp # GNUstep distrib objects" >> $$services; \
|
||||||
|
fi; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Things to do before uninstalling
|
# Things to do before uninstalling
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSLock.h>
|
#include <Foundation/NSLock.h>
|
||||||
#include <Foundation/NSThread.h>
|
#include <Foundation/NSThread.h>
|
||||||
|
#include <Foundation/NSPort.h>
|
||||||
|
#include <Foundation/NSPortMessage.h>
|
||||||
#include <Foundation/NSNotification.h>
|
#include <Foundation/NSNotification.h>
|
||||||
|
|
||||||
NSString* NSConnectionReplyMode = @"NSConnectionReplyMode";
|
NSString* NSConnectionReplyMode = @"NSConnectionReplyMode";
|
||||||
|
@ -184,6 +186,7 @@ static unsigned local_object_counter = 0;
|
||||||
|
|
||||||
@interface NSConnection (Private)
|
@interface NSConnection (Private)
|
||||||
- _superInit;
|
- _superInit;
|
||||||
|
- (void) handlePortMessage: (NSPortMessage*)msg;
|
||||||
+ setDebug: (int)val;
|
+ setDebug: (int)val;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -411,6 +414,11 @@ static int messages_received_count;
|
||||||
return delegate;
|
return delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) handlePortMessage: (NSPortMessage*)msg
|
||||||
|
{
|
||||||
|
[self notImplemented: _cmd];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL) independantConversationQueueing
|
- (BOOL) independantConversationQueueing
|
||||||
{
|
{
|
||||||
return independant_queueing;
|
return independant_queueing;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSString.h>
|
#include <Foundation/NSString.h>
|
||||||
#include <Foundation/NSNotificationQueue.h>
|
#include <Foundation/NSNotificationQueue.h>
|
||||||
#include <Foundation/NSPort.h>
|
#include <Foundation/NSPort.h>
|
||||||
|
@ -38,17 +39,17 @@ NSString *NSPortTimeoutException
|
||||||
|
|
||||||
+ (NSPort*) port
|
+ (NSPort*) port
|
||||||
{
|
{
|
||||||
return [[[NSPort alloc] init] autorelease];
|
return AUTORELEASE([NSPort new]);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSPort*) portWithMachPort: (int)machPort
|
+ (NSPort*) portWithMachPort: (int)machPort
|
||||||
{
|
{
|
||||||
return [[[NSPort alloc] initWithMachPort: machPort] autorelease];
|
return AUTORELEASE([[NSPort alloc] initWithMachPort: machPort]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) copyWithZone: (NSZone*)aZone
|
- (id) copyWithZone: (NSZone*)aZone
|
||||||
{
|
{
|
||||||
return [self retain];
|
return RETAIN(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) delegate
|
- (id) delegate
|
||||||
|
@ -75,7 +76,7 @@ NSString *NSPortTimeoutException
|
||||||
|
|
||||||
- (id) initWithMachPort: (int)machPort
|
- (id) initWithMachPort: (int)machPort
|
||||||
{
|
{
|
||||||
[self notImplemented: _cmd];
|
[self shouldNotImplement: _cmd];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,10 +97,10 @@ NSString *NSPortTimeoutException
|
||||||
return is_valid;
|
return is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) machPort
|
- (int) machPort
|
||||||
{
|
{
|
||||||
[self notImplemented: _cmd];
|
[self shouldNotImplement: _cmd];
|
||||||
return nil;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) release
|
- (void) release
|
||||||
|
@ -126,8 +127,38 @@ NSString *NSPortTimeoutException
|
||||||
|
|
||||||
- (void) setDelegate: anObject
|
- (void) setDelegate: anObject
|
||||||
{
|
{
|
||||||
|
NSAssert([anObject respondsToSelector: @selector(handlePortMessage:)],
|
||||||
|
NSInvalidArgumentException);
|
||||||
delegate = anObject;
|
delegate = anObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) addConnection: (NSConnection*)aConnection
|
||||||
|
toRunLoop: (NSRunLoop*)aLoop
|
||||||
|
forMode: (NSString*)aMode
|
||||||
|
{
|
||||||
|
[self subclassResponsibility: _cmd];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) removeConnection: (NSConnection*)aConnection
|
||||||
|
fromRunLoop: (NSRunLoop*)aLoop
|
||||||
|
forMode: (NSString*)aMode
|
||||||
|
{
|
||||||
|
[self subclassResponsibility: _cmd];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (unsigned) reservedSpaceLength
|
||||||
|
{
|
||||||
|
[self subclassResponsibility: _cmd];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) sendBeforeDate: (NSDate*)when
|
||||||
|
components: (NSArray*)components
|
||||||
|
from: (NSPort*)receivingPort
|
||||||
|
reserved: (unsigned) length
|
||||||
|
{
|
||||||
|
[self subclassResponsibility: _cmd];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -32,20 +32,20 @@
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[components release];
|
RELEASE(components);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PortMessages MUST be initialised with ports and data. */
|
/* PortMessages MUST be initialised with ports and data. */
|
||||||
- (id) init
|
- (id) init
|
||||||
{
|
{
|
||||||
[self notImplemented: _cmd];
|
[self shouldNotImplement: _cmd];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithMachMessage: (void*)buffer
|
- (id) initWithMachMessage: (void*)buffer
|
||||||
{
|
{
|
||||||
[self notImplemented: _cmd];
|
[self shouldNotImplement: _cmd];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,8 @@
|
||||||
components: (NSArray*)items
|
components: (NSArray*)items
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self)
|
||||||
|
{
|
||||||
components = [[NSMutableArray allocWithZone: [self zone]]
|
components = [[NSMutableArray allocWithZone: [self zone]]
|
||||||
initWithCapacity: [items count] + 2];
|
initWithCapacity: [items count] + 2];
|
||||||
[components addObject: aPort];
|
[components addObject: aPort];
|
||||||
|
@ -65,9 +66,12 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sendBeforeDate: (NSDate*)when
|
- (void) addComponent: (id)aComponent
|
||||||
{
|
{
|
||||||
[self notImplemented: _cmd];
|
NSAssert([aComponent isKindOfClass: [NSData class]]
|
||||||
|
|| [aComponent isKindOfClass: [NSPort class]],
|
||||||
|
NSInvalidArgumentException);
|
||||||
|
[components addObject: aComponent];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*) components
|
- (NSArray*) components
|
||||||
|
@ -77,9 +81,9 @@
|
||||||
return [components subarrayWithRange: r];
|
return [components subarrayWithRange: r];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSPort*) sendPort
|
- (unsigned) msgid
|
||||||
{
|
{
|
||||||
return [components objectAtIndex: 0];
|
return msgid;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSPort*) receivePort
|
- (NSPort*) receivePort
|
||||||
|
@ -87,14 +91,24 @@
|
||||||
return [components objectAtIndex: 1];
|
return [components objectAtIndex: 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) sendBeforeDate: (NSDate*)when
|
||||||
|
{
|
||||||
|
NSPort *port = [self sendPort];
|
||||||
|
|
||||||
|
[port sendBeforeDate: when
|
||||||
|
components: [self components]
|
||||||
|
from: [self receivePort]
|
||||||
|
reserved: [port reservedSpaceLength]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSPort*) sendPort
|
||||||
|
{
|
||||||
|
return [components objectAtIndex: 0];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setMsgid: (unsigned)anId
|
- (void) setMsgid: (unsigned)anId
|
||||||
{
|
{
|
||||||
msgid = anId;
|
msgid = anId;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) msgid
|
|
||||||
{
|
|
||||||
return msgid;
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -74,12 +74,11 @@
|
||||||
|
|
||||||
/* This error message should be called only if the private main function
|
/* This error message should be called only if the private main function
|
||||||
* was not executed successfully. This may heppen ONLY if onother library
|
* was not executed successfully. This may heppen ONLY if onother library
|
||||||
* or kit defines its own main function (as libobjects does).
|
* or kit defines its own main function (as gnustep-base does).
|
||||||
*/
|
*/
|
||||||
#define _GNU_MISSING_MAIN_FUNCTION_CALL @"Libobjects internal error: \
|
#define _GNU_MISSING_MAIN_FUNCTION_CALL @"GNUSTEP Internal Error: \
|
||||||
the private libobjects function to establish the argv and environment \
|
The private GNUstep function to establish the argv and environment \
|
||||||
variables was not called. Please contact Tuparev@EMBL-Heidelberg.de for \
|
variables was not called. Please report this error to bug-gnustep@gnu.org."
|
||||||
further information."
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
*** _NSConcreteProcessInfo
|
*** _NSConcreteProcessInfo
|
||||||
|
|
|
@ -107,10 +107,11 @@ static int debug_run_loop = 0;
|
||||||
* NB. This class is private to NSRunLoop and must not be subclassed.
|
* NB. This class is private to NSRunLoop and must not be subclassed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@interface RunLoopWatcher: NSObject
|
@interface RunLoopWatcher: NSObject <GCFinalization>
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
BOOL invalidated;
|
BOOL invalidated;
|
||||||
|
BOOL handleEvent; // New-style event handling
|
||||||
void *data;
|
void *data;
|
||||||
id receiver;
|
id receiver;
|
||||||
RunLoopEventType type;
|
RunLoopEventType type;
|
||||||
|
@ -130,9 +131,9 @@ static int debug_run_loop = 0;
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[self invalidate];
|
[self gcFinalize];
|
||||||
[limit release];
|
RELEASE(limit);
|
||||||
[receiver release];
|
RELEASE(receiver);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,8 +145,7 @@ static int debug_run_loop = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([receiver respondsToSelector:
|
if (handleEvent)
|
||||||
@selector(receivedEvent:type:extra:forMode:)])
|
|
||||||
{
|
{
|
||||||
[receiver receivedEvent: data type: type extra: info forMode: mode];
|
[receiver receivedEvent: data type: type extra: info forMode: mode];
|
||||||
}
|
}
|
||||||
|
@ -155,21 +155,27 @@ static int debug_run_loop = 0;
|
||||||
{
|
{
|
||||||
case ET_RDESC:
|
case ET_RDESC:
|
||||||
case ET_RPORT:
|
case ET_RPORT:
|
||||||
[receiver readyForReadingOnFileDescriptor: (int)info];
|
[receiver readyForReadingOnFileDescriptor: (int)(gsaddr)info];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ET_WDESC:
|
case ET_WDESC:
|
||||||
[receiver readyForWritingOnFileDescriptor: (int)info];
|
[receiver readyForWritingOnFileDescriptor: (int)(gsaddr)info];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithType: (RunLoopEventType)aType
|
- (void) gcFinalize
|
||||||
|
{
|
||||||
|
[self invalidate];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) initWithType: (RunLoopEventType)aType
|
||||||
receiver: (id)anObj
|
receiver: (id)anObj
|
||||||
data: (void*)item
|
data: (void*)item
|
||||||
{
|
{
|
||||||
invalidated = NO;
|
invalidated = NO;
|
||||||
|
|
||||||
switch (aType)
|
switch (aType)
|
||||||
{
|
{
|
||||||
case ET_RDESC: type = aType; break;
|
case ET_RDESC: type = aType; break;
|
||||||
|
@ -179,7 +185,12 @@ static int debug_run_loop = 0;
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
format: @"NSRunLoop - unknown event type"];
|
format: @"NSRunLoop - unknown event type"];
|
||||||
}
|
}
|
||||||
receiver = [anObj retain];
|
receiver = RETAIN(anObj);
|
||||||
|
if ([receiver respondsToSelector:
|
||||||
|
@selector(receivedEvent:type:extra:forMode:)])
|
||||||
|
handleEvent = YES;
|
||||||
|
else
|
||||||
|
handleEvent = NO;
|
||||||
data = item;
|
data = item;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +235,7 @@ static int debug_run_loop = 0;
|
||||||
* messages which are due to be sent to objects once a particular
|
* messages which are due to be sent to objects once a particular
|
||||||
* runloop iteration has passed.
|
* runloop iteration has passed.
|
||||||
*/
|
*/
|
||||||
@interface RunLoopPerformer: NSObject
|
@interface RunLoopPerformer: NSObject <GCFinalization>
|
||||||
{
|
{
|
||||||
SEL selector;
|
SEL selector;
|
||||||
id target;
|
id target;
|
||||||
|
@ -252,10 +263,10 @@ static int debug_run_loop = 0;
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[timer invalidate];
|
[self gcFinalize];
|
||||||
[target release];
|
RELEASE(target);
|
||||||
[argument release];
|
RELEASE(argument);
|
||||||
[modes release];
|
RELEASE(modes);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,13 +275,18 @@ static int debug_run_loop = 0;
|
||||||
if (timer != nil)
|
if (timer != nil)
|
||||||
{
|
{
|
||||||
timer = nil;
|
timer = nil;
|
||||||
[[self retain] autorelease];
|
AUTORELEASE(RETAIN(self));
|
||||||
[[[NSRunLoop currentInstance] _timedPerformers]
|
[[[NSRunLoop currentInstance] _timedPerformers]
|
||||||
removeObjectIdenticalTo: self];
|
removeObjectIdenticalTo: self];
|
||||||
}
|
}
|
||||||
[target performSelector: selector withObject: argument];
|
[target performSelector: selector withObject: argument];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) gcFinalize
|
||||||
|
{
|
||||||
|
[timer invalidate];
|
||||||
|
}
|
||||||
|
|
||||||
- initWithSelector: (SEL)aSelector
|
- initWithSelector: (SEL)aSelector
|
||||||
target: (id)aTarget
|
target: (id)aTarget
|
||||||
argument: (id)anArgument
|
argument: (id)anArgument
|
||||||
|
@ -281,8 +297,8 @@ static int debug_run_loop = 0;
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
selector = aSelector;
|
selector = aSelector;
|
||||||
target = [aTarget retain];
|
target = RETAIN(aTarget);
|
||||||
argument = [anArgument retain];
|
argument = RETAIN(anArgument);
|
||||||
order = theOrder;
|
order = theOrder;
|
||||||
modes = [theModes copy];
|
modes = [theModes copy];
|
||||||
}
|
}
|
||||||
|
@ -331,8 +347,8 @@ static int debug_run_loop = 0;
|
||||||
NSMutableArray *array;
|
NSMutableArray *array;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
[target retain];
|
RETAIN(target);
|
||||||
[arg retain];
|
RETAIN(arg);
|
||||||
array = [[NSRunLoop currentInstance] _timedPerformers];
|
array = [[NSRunLoop currentInstance] _timedPerformers];
|
||||||
for (i = [array count]; i > 0; i--)
|
for (i = [array count]; i > 0; i--)
|
||||||
{
|
{
|
||||||
|
@ -343,8 +359,8 @@ static int debug_run_loop = 0;
|
||||||
[array removeObjectAtIndex: i-1];
|
[array removeObjectAtIndex: i-1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[arg release];
|
RELEASE(arg);
|
||||||
[target release];
|
RELEASE(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) performSelector: (SEL)aSelector
|
- (void) performSelector: (SEL)aSelector
|
||||||
|
@ -366,7 +382,7 @@ static int debug_run_loop = 0;
|
||||||
selector: @selector(fire)
|
selector: @selector(fire)
|
||||||
userInfo: nil
|
userInfo: nil
|
||||||
repeats: NO]];
|
repeats: NO]];
|
||||||
[item release];
|
RELEASE(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) performSelector: (SEL)aSelector
|
- (void) performSelector: (SEL)aSelector
|
||||||
|
@ -398,7 +414,7 @@ static int debug_run_loop = 0;
|
||||||
userInfo: nil
|
userInfo: nil
|
||||||
repeats: NO];
|
repeats: NO];
|
||||||
[item setTimer: timer];
|
[item setTimer: timer];
|
||||||
[item release];
|
RELEASE(item);
|
||||||
for (i = 0; i < [modes count]; i++)
|
for (i = 0; i < [modes count]; i++)
|
||||||
{
|
{
|
||||||
[loop addTimer: timer forMode: [modes objectAtIndex: i]];
|
[loop addTimer: timer forMode: [modes objectAtIndex: i]];
|
||||||
|
@ -438,8 +454,8 @@ static int debug_run_loop = 0;
|
||||||
if (watchers == nil)
|
if (watchers == nil)
|
||||||
{
|
{
|
||||||
watchers = [NSMutableArray new];
|
watchers = [NSMutableArray new];
|
||||||
NSMapInsert (_mode_2_watchers, mode, watchers);
|
NSMapInsert(_mode_2_watchers, mode, watchers);
|
||||||
[watchers release];
|
RELEASE(watchers);
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -592,7 +608,7 @@ static int debug_run_loop = 0;
|
||||||
data: data];
|
data: data];
|
||||||
/* Add the object to the array for the mode. */
|
/* Add the object to the array for the mode. */
|
||||||
[self _addWatcher:info forMode:mode];
|
[self _addWatcher:info forMode:mode];
|
||||||
[info release]; /* Now held in array. */
|
RELEASE(info); /* Now held in array. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,11 +699,12 @@ static int debug_run_loop = 0;
|
||||||
/* Positive values are in the future. */
|
/* Positive values are in the future. */
|
||||||
while (ti > 0 && mayDoMore == YES)
|
while (ti > 0 && mayDoMore == YES)
|
||||||
{
|
{
|
||||||
id arp = [NSAutoreleasePool new];
|
CREATE_AUTORELEASE_POOL(arp);
|
||||||
|
|
||||||
if (debug_run_loop)
|
if (debug_run_loop)
|
||||||
printf ("\tNSRunLoop run until date %f seconds from now\n", ti);
|
printf ("\tNSRunLoop run until date %f seconds from now\n", ti);
|
||||||
mayDoMore = [self runMode: mode beforeDate: date];
|
mayDoMore = [self runMode: mode beforeDate: date];
|
||||||
[arp release];
|
RELEASE(arp);
|
||||||
ti = [date timeIntervalSinceNow];
|
ti = [date timeIntervalSinceNow];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -698,7 +715,7 @@ static int debug_run_loop = 0;
|
||||||
|
|
||||||
@implementation NSRunLoop
|
@implementation NSRunLoop
|
||||||
|
|
||||||
+ currentRunLoop
|
+ (NSRunLoop*) currentRunLoop
|
||||||
{
|
{
|
||||||
static NSString *key = @"NSRunLoopThreadKey";
|
static NSString *key = @"NSRunLoopThreadKey";
|
||||||
NSRunLoop* r;
|
NSRunLoop* r;
|
||||||
|
@ -710,7 +727,7 @@ static int debug_run_loop = 0;
|
||||||
{
|
{
|
||||||
r = [NSRunLoop new];
|
r = [NSRunLoop new];
|
||||||
[[t threadDictionary] setObject: r forKey: key];
|
[[t threadDictionary] setObject: r forKey: key];
|
||||||
[r release];
|
RELEASE(r);
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -722,7 +739,7 @@ static int debug_run_loop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the designated initializer. */
|
/* This is the designated initializer. */
|
||||||
- init
|
- (id) init
|
||||||
{
|
{
|
||||||
[super init];
|
[super init];
|
||||||
_current_mode = NSDefaultRunLoopMode;
|
_current_mode = NSDefaultRunLoopMode;
|
||||||
|
@ -736,12 +753,17 @@ static int debug_run_loop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
[self gcFinalize];
|
||||||
|
RELEASE(_performers);
|
||||||
|
RELEASE(_timedPerformers);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) gcFinalize
|
||||||
{
|
{
|
||||||
NSFreeMapTable(_mode_2_timers);
|
NSFreeMapTable(_mode_2_timers);
|
||||||
NSFreeMapTable(_mode_2_watchers);
|
NSFreeMapTable(_mode_2_watchers);
|
||||||
[_performers release];
|
|
||||||
[_timedPerformers release];
|
|
||||||
[super dealloc];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*) currentMode
|
- (NSString*) currentMode
|
||||||
|
@ -762,7 +784,7 @@ static int debug_run_loop = 0;
|
||||||
{
|
{
|
||||||
timers = [Heap new];
|
timers = [Heap new];
|
||||||
NSMapInsert (_mode_2_timers, mode, timers);
|
NSMapInsert (_mode_2_timers, mode, timers);
|
||||||
[timers release];
|
RELEASE(timers);
|
||||||
}
|
}
|
||||||
/* xxx Should we make sure it isn't already there? */
|
/* xxx Should we make sure it isn't already there? */
|
||||||
[timers addObject: timer];
|
[timers addObject: timer];
|
||||||
|
@ -801,7 +823,7 @@ static int debug_run_loop = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
[min_timer retain];
|
RETAIN(min_timer);
|
||||||
[timers removeFirstObject];
|
[timers removeFirstObject];
|
||||||
/* Firing will also increment its fireDate, if it is repeating. */
|
/* Firing will also increment its fireDate, if it is repeating. */
|
||||||
[min_timer fire];
|
[min_timer fire];
|
||||||
|
@ -809,7 +831,7 @@ static int debug_run_loop = 0;
|
||||||
{
|
{
|
||||||
[timers addObject: min_timer];
|
[timers addObject: min_timer];
|
||||||
}
|
}
|
||||||
[min_timer release];
|
RELEASE(min_timer);
|
||||||
min_timer = nil;
|
min_timer = nil;
|
||||||
[NSNotificationQueue runLoopASAP]; /* Post notifications. */
|
[NSNotificationQueue runLoopASAP]; /* Post notifications. */
|
||||||
}
|
}
|
||||||
|
@ -871,11 +893,11 @@ static int debug_run_loop = 0;
|
||||||
* If the watcher has been given a revised limit date -
|
* If the watcher has been given a revised limit date -
|
||||||
* re-insert it into the queue in the correct place.
|
* re-insert it into the queue in the correct place.
|
||||||
*/
|
*/
|
||||||
[min_watcher retain];
|
RETAIN(min_watcher);
|
||||||
ASSIGN(min_watcher->limit, nxt);
|
ASSIGN(min_watcher->limit, nxt);
|
||||||
[watchers removeObjectAtIndex: 0];
|
[watchers removeObjectAtIndex: 0];
|
||||||
[self _addWatcher: min_watcher forMode: mode];
|
[self _addWatcher: min_watcher forMode: mode];
|
||||||
[min_watcher release];
|
RELEASE(min_watcher);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1204,14 +1226,14 @@ static int debug_run_loop = 0;
|
||||||
{
|
{
|
||||||
id watcher = (id) NSMapGet (wfd_2_object, (void*)fd_index);
|
id watcher = (id) NSMapGet (wfd_2_object, (void*)fd_index);
|
||||||
NSAssert(watcher, NSInternalInconsistencyException);
|
NSAssert(watcher, NSInternalInconsistencyException);
|
||||||
[watcher eventFor:(void*)fd_index mode:_current_mode];
|
[watcher eventFor: (void*)(gsaddr)fd_index mode: _current_mode];
|
||||||
[NSNotificationQueue runLoopASAP];
|
[NSNotificationQueue runLoopASAP];
|
||||||
}
|
}
|
||||||
if (FD_ISSET (fd_index, &read_fds))
|
if (FD_ISSET (fd_index, &read_fds))
|
||||||
{
|
{
|
||||||
id watcher = (id) NSMapGet (rfd_2_object, (void*)fd_index);
|
id watcher = (id) NSMapGet (rfd_2_object, (void*)fd_index);
|
||||||
NSAssert(watcher, NSInternalInconsistencyException);
|
NSAssert(watcher, NSInternalInconsistencyException);
|
||||||
[watcher eventFor:(void*)fd_index mode:_current_mode];
|
[watcher eventFor: (void*)(gsaddr)fd_index mode: _current_mode];
|
||||||
[NSNotificationQueue runLoopASAP];
|
[NSNotificationQueue runLoopASAP];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1250,12 +1272,12 @@ static int debug_run_loop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the earlier of the two dates we have. */
|
/* Use the earlier of the two dates we have. */
|
||||||
d = [[d earlierDate:date] retain];
|
d = RETAIN([d earlierDate: date]);
|
||||||
|
|
||||||
/* Wait, listening to our input sources. */
|
/* Wait, listening to our input sources. */
|
||||||
[self acceptInputForMode: mode beforeDate: d];
|
[self acceptInputForMode: mode beforeDate: d];
|
||||||
|
|
||||||
[d release];
|
RELEASE(d);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1297,8 +1319,8 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
||||||
int count = [_performers count];
|
int count = [_performers count];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
[target retain];
|
RETAIN(target);
|
||||||
[argument retain];
|
RETAIN(argument);
|
||||||
for (i = count; i > 0; i--)
|
for (i = count; i > 0; i--)
|
||||||
{
|
{
|
||||||
item = (RunLoopPerformer*)[_performers objectAtIndex:(i-1)];
|
item = (RunLoopPerformer*)[_performers objectAtIndex:(i-1)];
|
||||||
|
@ -1308,8 +1330,8 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
||||||
[_performers removeObjectAtIndex:(i-1)];
|
[_performers removeObjectAtIndex:(i-1)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[argument release];
|
RELEASE(argument);
|
||||||
[target release];
|
RELEASE(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) configureAsServer
|
- (void) configureAsServer
|
||||||
|
@ -1353,7 +1375,7 @@ id NSDefaultRunLoopMode = @"NSDefaultRunLoopMode";
|
||||||
[_performers addObject:item];
|
[_performers addObject:item];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[item release];
|
RELEASE(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removePort: (NSPort*)port
|
- (void) removePort: (NSPort*)port
|
||||||
|
|
696
Source/TcpPort.m
696
Source/TcpPort.m
|
@ -44,6 +44,10 @@
|
||||||
#include <base/Invocation.h>
|
#include <base/Invocation.h>
|
||||||
#include <Foundation/NSData.h>
|
#include <Foundation/NSData.h>
|
||||||
#include <Foundation/NSDate.h>
|
#include <Foundation/NSDate.h>
|
||||||
|
#include <Foundation/NSHashTable.h>
|
||||||
|
#include <Foundation/NSHost.h>
|
||||||
|
#include <Foundation/NSMapTable.h>
|
||||||
|
#include <Foundation/NSPortMessage.h>
|
||||||
#include <Foundation/NSPortNameServer.h>
|
#include <Foundation/NSPortNameServer.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -108,6 +112,698 @@ static int debug_tcp_port = 0;
|
||||||
|
|
||||||
/* Private interfaces */
|
/* Private interfaces */
|
||||||
|
|
||||||
|
@class GSTcpPort;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gsu32 sendAddr;
|
||||||
|
gsu32 recvAddr;
|
||||||
|
gsu16 sendPort;
|
||||||
|
gsu16 recvPort;
|
||||||
|
gsu32 mesgId;
|
||||||
|
gsu32 mesgElems;
|
||||||
|
gsu32 remaining;
|
||||||
|
} GSTcpHeader;
|
||||||
|
|
||||||
|
@interface GSTcpHandle : NSObject <GCFinalization>
|
||||||
|
{
|
||||||
|
int desc; // Unix file descriptor.
|
||||||
|
NSLock *myLock; // Lock for This handle.
|
||||||
|
unsigned rLength; // Length of item read so far.
|
||||||
|
NSPortMessage *rMsg; // Message in progress.
|
||||||
|
unsigned rItem; // Index of current message item.
|
||||||
|
NSMutableData *rHeader; // Buffer for item data.
|
||||||
|
unsigned wLength;
|
||||||
|
NSPortMessage *wMsg;
|
||||||
|
unsigned wItem;
|
||||||
|
NSHashTable *ports;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (GSTcpHandle*) handleWithDescriptor: (int)descriptor;
|
||||||
|
- (void) addPort: (GSTcpPort*)p;
|
||||||
|
- (void) invalidate;
|
||||||
|
- (void) readData;
|
||||||
|
- (void) removePort: (GSTcpPort*)p;
|
||||||
|
- (void) writeData;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GSTcpHandle
|
||||||
|
|
||||||
|
static NSRecursiveLock *tcpHandleLock = nil;
|
||||||
|
static NSHashTable *tcpHandleTable = 0;
|
||||||
|
|
||||||
|
+ (id) allocWithZone: (NSZone*)zone
|
||||||
|
{
|
||||||
|
[NSException raise: NSGenericException
|
||||||
|
format: @"attempt to alloc a GSTcpHandle!"];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void) initialize
|
||||||
|
{
|
||||||
|
if (tcpHandleLock == nil)
|
||||||
|
{
|
||||||
|
[gnustep_global_lock lock];
|
||||||
|
if (tcpHandleLock == nil)
|
||||||
|
{
|
||||||
|
tcpHandleLock = [NSRecursiveLock new];
|
||||||
|
tcpHandleTable =
|
||||||
|
NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0);
|
||||||
|
}
|
||||||
|
[gnustep_global_lock unlock];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (GSTcpHandle*) handleWithDescriptor: (int)descriptor
|
||||||
|
{
|
||||||
|
static GSTcpHandle *dummy = nil;
|
||||||
|
GSTcpHandle *handle;
|
||||||
|
|
||||||
|
if (descriptor < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"illegal descriptor (%d) for Tcp Handle", descriptor);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
[tcpHandleLock lock];
|
||||||
|
if (dummy == nil)
|
||||||
|
dummy = (GSTcpHandle*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
||||||
|
|
||||||
|
dummy->desc = descriptor;
|
||||||
|
handle = (GSTcpHandle*)NSHashGet(tcpHandleTable, (void*)dummy);
|
||||||
|
|
||||||
|
if (handle == nil)
|
||||||
|
{
|
||||||
|
int e;
|
||||||
|
BOOL ok = YES;
|
||||||
|
|
||||||
|
if ((e = fcntl(descriptor, F_GETFL, 0)) >= 0)
|
||||||
|
{
|
||||||
|
e |= NBLK_OPT;
|
||||||
|
if (fcntl(descriptor, F_SETFL, e) < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to set non-blocking mode - %s", strerror(errno));
|
||||||
|
ok = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSLog(@"unable to get non-blocking mode - %s", strerror(errno));
|
||||||
|
ok = NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
handle = (GSTcpHandle*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||||
|
handle->desc = descriptor;
|
||||||
|
handle->ports =
|
||||||
|
NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0);
|
||||||
|
NSHashInsert(tcpHandleTable, (void*)handle);
|
||||||
|
AUTORELEASE(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[tcpHandleLock unlock];
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) addPort: (GSTcpPort*)p
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
NSHashInsert(ports, (void*)p);
|
||||||
|
[myLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) gcFinalize
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
|
||||||
|
[tcpHandleLock lock];
|
||||||
|
NSHashRemove(tcpHandleTable, (void*)self);
|
||||||
|
[tcpHandleLock unlock];
|
||||||
|
|
||||||
|
(void) close(desc);
|
||||||
|
desc = -1;
|
||||||
|
|
||||||
|
NSFreeHashTable(ports);
|
||||||
|
RELEASE(rHeader);
|
||||||
|
RELEASE(rMsg);
|
||||||
|
RELEASE(wMsg);
|
||||||
|
|
||||||
|
[myLock unlock];
|
||||||
|
RELEASE(myLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (unsigned) hash
|
||||||
|
{
|
||||||
|
return (unsigned)desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) invalidate
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
[myLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isEqual: (id)anObject
|
||||||
|
{
|
||||||
|
if (anObject == self)
|
||||||
|
return YES;
|
||||||
|
if ([anObject class] == [self class]
|
||||||
|
&& ((GSTcpHandle*)anObject)->desc == desc)
|
||||||
|
return YES;
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) readData
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
unsigned want;
|
||||||
|
void *bytes = 0;
|
||||||
|
|
||||||
|
[myLock lock];
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Get address and length of buffer for incoming data if we don't already
|
||||||
|
* have it from an earlier iteration of the loop. Create the buffer if
|
||||||
|
* necessary.
|
||||||
|
*/
|
||||||
|
if (bytes == 0)
|
||||||
|
{
|
||||||
|
if (rHeader == nil)
|
||||||
|
{
|
||||||
|
if (rItem == 0)
|
||||||
|
want = sizeof(GSTcpHeader);
|
||||||
|
else
|
||||||
|
want = 6;
|
||||||
|
|
||||||
|
rHeader = [[NSMutableData alloc] initWithLength: want];
|
||||||
|
bytes = [rHeader mutableBytes];
|
||||||
|
rLength = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
want = [rHeader length];
|
||||||
|
bytes = [rHeader mutableBytes];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we attempt to fill the buffer.
|
||||||
|
*/
|
||||||
|
result = read(desc, bytes + rLength, want - rLength);
|
||||||
|
if (result == 0)
|
||||||
|
{
|
||||||
|
NSLog(@"Unexpected EOF on descriptor %d", desc);
|
||||||
|
[self invalidate];
|
||||||
|
}
|
||||||
|
else if (result < 0)
|
||||||
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
{
|
||||||
|
NSLog(@"Error reading on descriptor %d - %s",
|
||||||
|
desc, strerror(errno));
|
||||||
|
[self invalidate];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rLength += result;
|
||||||
|
if (rLength == want)
|
||||||
|
{
|
||||||
|
if (rItem == 0)
|
||||||
|
{
|
||||||
|
if (want == sizeof(GSTcpHeader))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (result > 0);
|
||||||
|
|
||||||
|
[myLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) release
|
||||||
|
{
|
||||||
|
if ([self retainCount] == 1)
|
||||||
|
{
|
||||||
|
[super retain];
|
||||||
|
[self gcFinalize];
|
||||||
|
[super release];
|
||||||
|
}
|
||||||
|
[super release];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) removePort: (GSTcpPort*)p
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
NSHashRemove(ports, (void*)p);
|
||||||
|
[myLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) writeData
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
[myLock unlock];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@interface GSTcpPort : NSPort <GCFinalization>
|
||||||
|
{
|
||||||
|
NSRecursiveLock *myLock;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
int listener;
|
||||||
|
NSHashTable *handles;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (GSTcpPort*) portWithNumber: (gsu16)number
|
||||||
|
onHost: (NSHost*)host
|
||||||
|
beforeDate: (NSDate*)limit;
|
||||||
|
+ (GSTcpPort*) portWithAddress: (struct sockaddr_in*)address
|
||||||
|
andHandle: (GSTcpHandle*)handle
|
||||||
|
beforeDate: (NSDate*)limit;
|
||||||
|
|
||||||
|
- (void) addHandle: (GSTcpHandle*)h;
|
||||||
|
- (void) removeHandle: (GSTcpHandle*)h;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GSTcpPort
|
||||||
|
|
||||||
|
static NSRecursiveLock *tcpPortLock = nil;
|
||||||
|
static NSMapTable *tcpPortMap = 0;
|
||||||
|
static GSTcpPort *dummyPort = nil;
|
||||||
|
|
||||||
|
+ (void) initialize
|
||||||
|
{
|
||||||
|
if (tcpPortLock == nil)
|
||||||
|
{
|
||||||
|
[gnustep_global_lock lock];
|
||||||
|
if (tcpPortLock == nil)
|
||||||
|
{
|
||||||
|
tcpPortLock = [NSRecursiveLock new];
|
||||||
|
tcpPortMap = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
|
dummyPort = (GSTcpPort*)NSAllocateObject(self, 0,
|
||||||
|
NSDefaultMallocZone());
|
||||||
|
}
|
||||||
|
[gnustep_global_lock unlock];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (GSTcpPort*) portWithAddress: (struct sockaddr_in*)sockaddr
|
||||||
|
andHandle: (GSTcpHandle*)handle
|
||||||
|
beforeDate: (NSDate*)limit
|
||||||
|
{
|
||||||
|
GSTcpPort *port = nil;
|
||||||
|
NSMapTable *thePorts;
|
||||||
|
|
||||||
|
[tcpPortLock lock];
|
||||||
|
|
||||||
|
thePorts = (NSMapTable*)NSMapGet(tcpPortMap,
|
||||||
|
(void*)(gsaddr)sockaddr->sin_port);
|
||||||
|
|
||||||
|
if (thePorts == 0)
|
||||||
|
{
|
||||||
|
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
|
NSMapInsert(tcpPortMap,
|
||||||
|
(void*)(gsaddr)sockaddr->sin_port,
|
||||||
|
(void*)thePorts);
|
||||||
|
}
|
||||||
|
|
||||||
|
port = (GSTcpPort*)NSMapGet(tcpPortMap,
|
||||||
|
(void*)(gsaddr)sockaddr->sin_addr.s_addr);
|
||||||
|
|
||||||
|
if (port == nil)
|
||||||
|
{
|
||||||
|
port = (GSTcpPort*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||||
|
|
||||||
|
port->listener = -1;
|
||||||
|
memcpy(&port->addr, sockaddr, sizeof(port->addr));
|
||||||
|
port->myLock = [NSRecursiveLock new];
|
||||||
|
port->handles = NSCreateHashTable(NSObjectHashCallBacks, 0);
|
||||||
|
NSMapInsert(thePorts, (void*)(gsaddr)sockaddr->sin_addr.s_addr,
|
||||||
|
(void*)port);
|
||||||
|
AUTORELEASE(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port != nil && handle != nil)
|
||||||
|
{
|
||||||
|
NSHashInsert(port->handles, (void*)handle);
|
||||||
|
[handle addPort: port];
|
||||||
|
}
|
||||||
|
|
||||||
|
[tcpPortLock unlock];
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (GSTcpPort*) portWithNumber: (gsu16)number
|
||||||
|
onHost: (NSHost*)host
|
||||||
|
beforeDate: (NSDate*)limit
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
GSTcpPort *port = nil;
|
||||||
|
NSHost *thisHost = [NSHost currentHost];
|
||||||
|
NSArray *addresses;
|
||||||
|
NSMapTable *thePorts;
|
||||||
|
|
||||||
|
if (host == nil)
|
||||||
|
{
|
||||||
|
host = thisHost;
|
||||||
|
}
|
||||||
|
addresses = [host addresses];
|
||||||
|
if ([addresses count] == 0)
|
||||||
|
{
|
||||||
|
NSLog(@"attempt to get port on host with no IP address");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
[tcpPortLock lock];
|
||||||
|
|
||||||
|
memset(&dummyPort->addr, '\0', sizeof(dummyPort->addr));
|
||||||
|
dummyPort->addr.sin_family = AF_INET;
|
||||||
|
dummyPort->addr.sin_port = GSSwapHostI16ToBig(number);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the map table of ports with the specified number.
|
||||||
|
*/
|
||||||
|
thePorts = (NSMapTable*)NSMapGet(tcpPortMap,
|
||||||
|
(void*)(gsaddr)dummyPort->addr.sin_port);
|
||||||
|
|
||||||
|
if (thePorts)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Check to see if we have a port for any one of the hosts IP addresses.
|
||||||
|
*/
|
||||||
|
for (i = 0; port == nil && i < [addresses count]; i++)
|
||||||
|
{
|
||||||
|
const char *a = [[addresses objectAtIndex: i] cString];
|
||||||
|
|
||||||
|
#ifndef HAVE_INET_ATON
|
||||||
|
dummyPort->sin_addr.s_addr = inet_addr(a);
|
||||||
|
#else
|
||||||
|
if (inet_aton(a, &dummyPort->addr.sin_addr) == 0)
|
||||||
|
{
|
||||||
|
NSLog(@"attempt to get port on host with bad address - '%s'", a);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
port = (GSTcpPort*)NSMapGet(thePorts,
|
||||||
|
(void*)(gsaddr)dummyPort->addr.sin_addr.s_addr);
|
||||||
|
if (port != nil)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (port == nil)
|
||||||
|
{
|
||||||
|
if (host == thisHost)
|
||||||
|
{
|
||||||
|
int status = 1;
|
||||||
|
int desc;
|
||||||
|
|
||||||
|
port = (GSTcpPort*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||||
|
port->listener = -1;
|
||||||
|
port->handles =
|
||||||
|
NSCreateHashTable(NSObjectHashCallBacks, 0);
|
||||||
|
|
||||||
|
port->addr.sin_addr.s_addr = GSSwapHostI32ToBig(INADDR_ANY);
|
||||||
|
|
||||||
|
if ((desc = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to create socket - %s", strerror(errno));
|
||||||
|
DESTROY(port);
|
||||||
|
}
|
||||||
|
else if (setsockopt(desc, SOL_SOCKET, SO_REUSEADDR, (char *)&status,
|
||||||
|
sizeof(status)) < 0)
|
||||||
|
{
|
||||||
|
(void) close(desc);
|
||||||
|
NSLog(@"unable to set reuse on socket - %s", strerror(errno));
|
||||||
|
DESTROY(port);
|
||||||
|
}
|
||||||
|
else if (bind(desc, (struct sockaddr *)&port->addr,
|
||||||
|
sizeof(port->addr)) < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to bind to port %s:%d - %s",
|
||||||
|
inet_ntoa(port->addr.sin_addr), number, strerror(errno));
|
||||||
|
(void) close(desc);
|
||||||
|
DESTROY(port);
|
||||||
|
}
|
||||||
|
else if (listen(desc, 5) < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to listen on port - %s", strerror(errno));
|
||||||
|
(void) close(desc);
|
||||||
|
DESTROY(port);
|
||||||
|
}
|
||||||
|
else if (getsockname(desc, (struct sockaddr*)&port->addr, &i) < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to get socket name - %s", strerror(errno));
|
||||||
|
(void) close(desc);
|
||||||
|
DESTROY(port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port->listener = desc;
|
||||||
|
port->myLock = [NSRecursiveLock new];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ok - now add the port for all the IP addresses it listens on.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < [addresses count]; i++)
|
||||||
|
{
|
||||||
|
const char *a = [[addresses objectAtIndex: i] cString];
|
||||||
|
gsaddr val;
|
||||||
|
|
||||||
|
#ifndef HAVE_INET_ATON
|
||||||
|
dummyPort->addr.sin_addr.s_addr = inet_addr(a);
|
||||||
|
#else
|
||||||
|
if (inet_aton(a, &dummyPort->addr.sin_addr) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
val = (gsaddr)dummyPort->addr.sin_addr.s_addr;
|
||||||
|
|
||||||
|
if (thePorts == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No known ports within this port number -
|
||||||
|
* create the map table to add the new port to.
|
||||||
|
*/
|
||||||
|
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
|
NSMapInsert(tcpPortMap,
|
||||||
|
(void*)(gsaddr)port->addr.sin_port,
|
||||||
|
(void*)thePorts);
|
||||||
|
}
|
||||||
|
NSMapInsert(thePorts, (void*)val, (void*)port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (number != 0) /* Can't connect to port zero */
|
||||||
|
{
|
||||||
|
for (i = 0; port == nil && i < [addresses count]; i++)
|
||||||
|
{
|
||||||
|
int desc;
|
||||||
|
const char *a = [[addresses objectAtIndex: i] cString];
|
||||||
|
|
||||||
|
port = (GSTcpPort*)NSAllocateObject(self,0,NSDefaultMallocZone());
|
||||||
|
port->listener = -1;
|
||||||
|
|
||||||
|
#ifndef HAVE_INET_ATON
|
||||||
|
port->addr.sin_addr.s_addr = inet_addr(a);
|
||||||
|
#else
|
||||||
|
if (inet_aton(a, &port->addr.sin_addr) == 0)
|
||||||
|
{
|
||||||
|
NSLog(@"opening port on host with bad address - '%s'", a);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((desc = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to create socket - %s", strerror(errno));
|
||||||
|
DESTROY(port);
|
||||||
|
}
|
||||||
|
else if (connect(desc, (struct sockaddr*)&port->addr,
|
||||||
|
sizeof(port->addr)) < 0)
|
||||||
|
{
|
||||||
|
NSLog(@"unable to make connection to %s:%d - %s", a,
|
||||||
|
GSSwapBigI16ToHost(port->addr.sin_port), strerror(errno));
|
||||||
|
DESTROY(port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GSTcpHandle *handle;
|
||||||
|
|
||||||
|
port->myLock = [NSRecursiveLock new];
|
||||||
|
port->handles =
|
||||||
|
NSCreateHashTable(NSObjectHashCallBacks, 0);
|
||||||
|
handle = [GSTcpHandle handleWithDescriptor: desc];
|
||||||
|
NSHashInsert(port->handles, (void*)handle);
|
||||||
|
if (thePorts == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No known ports within this port number -
|
||||||
|
* create the map table to add the new port to.
|
||||||
|
*/
|
||||||
|
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
|
NSMapInsert(tcpPortMap,
|
||||||
|
(void*)(gsaddr)port->addr.sin_port,
|
||||||
|
(void*)thePorts);
|
||||||
|
}
|
||||||
|
NSMapInsert(thePorts,
|
||||||
|
(void*)(gsaddr)port->addr.sin_addr.s_addr, (void*)port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AUTORELEASE(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
[tcpPortLock unlock];
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) addHandle: (GSTcpHandle*)h
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
NSHashInsert(handles, (void*)h);
|
||||||
|
[myLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) copyWithZone: (NSZone*)zone
|
||||||
|
{
|
||||||
|
return RETAIN(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) gcFinalize
|
||||||
|
{
|
||||||
|
[self invalidate];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (unsigned) hash
|
||||||
|
{
|
||||||
|
return (unsigned)(addr.sin_addr.s_addr ^ addr.sin_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) invalidate
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
|
||||||
|
if ([self isValid])
|
||||||
|
{
|
||||||
|
NSMapTable *thePorts;
|
||||||
|
NSArray *handleArray;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
[tcpPortLock lock];
|
||||||
|
thePorts = NSMapGet(tcpPortMap, (void*)(gsaddr)addr.sin_port);
|
||||||
|
if (thePorts)
|
||||||
|
{
|
||||||
|
gsaddr val;
|
||||||
|
|
||||||
|
if (listener == -1)
|
||||||
|
{
|
||||||
|
val = (gsaddr)addr.sin_addr.s_addr;
|
||||||
|
NSMapRemove(thePorts, (void*)val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
NSArray *addresses = [[NSHost currentHost] addresses];
|
||||||
|
|
||||||
|
for (i = 0; i < [addresses count]; i++)
|
||||||
|
{
|
||||||
|
const char *a = [[addresses objectAtIndex: i] cString];
|
||||||
|
|
||||||
|
#ifndef HAVE_INET_ATON
|
||||||
|
addr,sin_addr.s_addr = inet_addr(a);
|
||||||
|
#else
|
||||||
|
if (inet_aton(a, &addr.sin_addr) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
val = (gsaddr)addr.sin_addr.s_addr;
|
||||||
|
NSMapRemove(thePorts, (void*)val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[tcpPortLock unlock];
|
||||||
|
|
||||||
|
if (listener >= 0)
|
||||||
|
{
|
||||||
|
(void)close(listener);
|
||||||
|
listener = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleArray = NSAllHashTableObjects(handles);
|
||||||
|
i = [handleArray count];
|
||||||
|
while (i > 0)
|
||||||
|
{
|
||||||
|
GSTcpHandle *handle = [handleArray objectAtIndex: i];
|
||||||
|
|
||||||
|
[handle removePort: self];
|
||||||
|
}
|
||||||
|
NSFreeHashTable(handles);
|
||||||
|
|
||||||
|
[super invalidate];
|
||||||
|
}
|
||||||
|
[myLock unlock];
|
||||||
|
RELEASE(myLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) isEqual: (id)anObject
|
||||||
|
{
|
||||||
|
if (anObject == self)
|
||||||
|
return YES;
|
||||||
|
if ([anObject class] == [self class])
|
||||||
|
{
|
||||||
|
GSTcpPort *o = (GSTcpPort*)anObject;
|
||||||
|
|
||||||
|
if (o->addr.sin_port == addr.sin_port &&
|
||||||
|
o->addr.sin_addr.s_addr == addr.sin_addr.s_addr)
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) release
|
||||||
|
{
|
||||||
|
if ([self retainCount] == 1)
|
||||||
|
{
|
||||||
|
[super retain];
|
||||||
|
[self gcFinalize];
|
||||||
|
[super release];
|
||||||
|
}
|
||||||
|
[super release];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) removeHandle: (GSTcpHandle*)h
|
||||||
|
{
|
||||||
|
[myLock lock];
|
||||||
|
NSHashRemove(handles, (void*)h);
|
||||||
|
[myLock unlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@interface TcpInPort (Private)
|
@interface TcpInPort (Private)
|
||||||
- (int) _port_socket;
|
- (int) _port_socket;
|
||||||
- (struct sockaddr_in*) _listeningSockaddr;
|
- (struct sockaddr_in*) _listeningSockaddr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <Foundation/NSObject.h>
|
||||||
#include <Foundation/NSConnection.h>
|
#include <Foundation/NSConnection.h>
|
||||||
#include <Foundation/NSDistantObject.h>
|
#include <Foundation/NSDistantObject.h>
|
||||||
#include <Foundation/NSDictionary.h>
|
#include <Foundation/NSDictionary.h>
|
||||||
|
@ -11,7 +12,10 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
@class TcpInPort;
|
||||||
|
@class PortDecoder;
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
id a;
|
id a;
|
||||||
id p;
|
id p;
|
||||||
|
@ -36,13 +40,18 @@ int main(int argc, char *argv[])
|
||||||
const char *type;
|
const char *type;
|
||||||
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||||
|
|
||||||
|
GSDebugAllocationActive(YES);
|
||||||
|
[NSConnection setDebug: 10];
|
||||||
|
[NSDistantObject setDebug: 10];
|
||||||
|
[TcpInPort setDebug: 10];
|
||||||
|
|
||||||
[Coder setDebugging:YES];
|
[Coder setDebugging:YES];
|
||||||
[BinaryCStream setDebugging:YES];
|
[BinaryCStream setDebugging:YES];
|
||||||
|
|
||||||
#if NeXT_runtime
|
#if NeXT_runtime
|
||||||
[NSDistantObject setProtocolForProxies:@protocol(AllProxies)];
|
[NSDistantObject setProtocolForProxies:@protocol(AllProxies)];
|
||||||
#endif
|
#endif
|
||||||
|
printf("oneway %d\n", _F_ONEWAY);
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
{
|
{
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
|
@ -60,12 +69,16 @@ int main(int argc, char *argv[])
|
||||||
[c setReplyTimeout:180.0];
|
[c setReplyTimeout:180.0];
|
||||||
localObj = [[NSObject alloc] init];
|
localObj = [[NSObject alloc] init];
|
||||||
[p outputStats:localObj];
|
[p outputStats:localObj];
|
||||||
|
fprintf(stderr, "XXXXXXXXXXXXXXXXA %d\n", GSDebugAllocationCount([PortDecoder class]));
|
||||||
|
[p getLong:&i];
|
||||||
|
fprintf(stderr,"XXXXXXXXXXXXXXXXB %d\n", GSDebugAllocationCount([PortDecoder class]));
|
||||||
[p getLong:&i];
|
[p getLong:&i];
|
||||||
[p outputStats:localObj];
|
[p outputStats:localObj];
|
||||||
|
fprintf(stderr,"XXXXXXXXXXXXXXXXC %d\n", GSDebugAllocationCount([PortDecoder class]));
|
||||||
type = [c typeForSelector:sel_get_any_uid("name")
|
type = [c typeForSelector:sel_get_any_uid("name")
|
||||||
remoteTarget:[p targetForProxy]];
|
remoteTarget:[p targetForProxy]];
|
||||||
|
printf("XXXXXXXXXXXXXXXXD %d\n", GSDebugAllocationCount([PortDecoder class]));
|
||||||
printf(">>type = %s\n", type);
|
printf(">>type = %s\n", type);
|
||||||
|
|
||||||
printf(">>list proxy's hash is 0x%x\n",
|
printf(">>list proxy's hash is 0x%x\n",
|
||||||
(unsigned)[p hash]);
|
(unsigned)[p hash]);
|
||||||
printf(">>list proxy's self is 0x%x = 0x%x\n",
|
printf(">>list proxy's self is 0x%x = 0x%x\n",
|
||||||
|
@ -149,9 +162,11 @@ int main(int argc, char *argv[])
|
||||||
id remote_peer_obj = [p objectAt:j];
|
id remote_peer_obj = [p objectAt:j];
|
||||||
printf("triangle %d object proxy's hash is 0x%x\n",
|
printf("triangle %d object proxy's hash is 0x%x\n",
|
||||||
j, (unsigned)[remote_peer_obj hash]);
|
j, (unsigned)[remote_peer_obj hash]);
|
||||||
|
#if 0
|
||||||
/* xxx look at this again after we use release/retain everywhere */
|
/* xxx look at this again after we use release/retain everywhere */
|
||||||
if ([remote_peer_obj isProxy])
|
if ([remote_peer_obj isProxy])
|
||||||
[remote_peer_obj release];
|
[remote_peer_obj release];
|
||||||
|
#endif
|
||||||
remote_peer_obj = [p objectAt:j];
|
remote_peer_obj = [p objectAt:j];
|
||||||
printf("repeated triangle %d object proxy's hash is 0x%x\n",
|
printf("repeated triangle %d object proxy's hash is 0x%x\n",
|
||||||
j, (unsigned)[remote_peer_obj hash]);
|
j, (unsigned)[remote_peer_obj hash]);
|
||||||
|
@ -170,9 +185,14 @@ int main(int argc, char *argv[])
|
||||||
printf("%s - %s\n", [k cString], [[v description] cString]);
|
printf("%s - %s\n", [k cString], [[v description] cString]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[arp release];
|
||||||
|
arp = [NSAutoreleasePool new];
|
||||||
|
printf("%d\n", [c retainCount]);
|
||||||
|
printf("%s\n", [[[c statistics] description] cString]);
|
||||||
|
// printf("%s\n", GSDebugAllocationList(YES));
|
||||||
|
|
||||||
[NSRunLoop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 20 * 60]];
|
[NSRunLoop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 20 * 60]];
|
||||||
[c invalidate];
|
[c invalidate];
|
||||||
|
|
||||||
[arp release];
|
[arp release];
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
4
Version
4
Version
|
@ -7,12 +7,12 @@ GCC_VERSION=2.8.0
|
||||||
# The version number of this release.
|
# The version number of this release.
|
||||||
MAJOR_VERSION=0
|
MAJOR_VERSION=0
|
||||||
MINOR_VERSION=5
|
MINOR_VERSION=5
|
||||||
SUBMINOR_VERSION=0
|
SUBMINOR_VERSION=5
|
||||||
GNUSTEP_BASE_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${SUBMINOR_VERSION}
|
GNUSTEP_BASE_VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${SUBMINOR_VERSION}
|
||||||
VERSION=${GNUSTEP_BASE_VERSION}
|
VERSION=${GNUSTEP_BASE_VERSION}
|
||||||
|
|
||||||
GNUSTEP_BASE_FTP_MACHINE=ftp.gnu.org
|
GNUSTEP_BASE_FTP_MACHINE=ftp.gnu.org
|
||||||
GNUSTEP_BASE_FTP_DIRECTORY=pub/gnu
|
GNUSTEP_BASE_FTP_DIRECTORY=pub/gnu/gstep
|
||||||
GNUSTEP_BASE_SNAP_FTP_MACHINE=alpha.gnu.org
|
GNUSTEP_BASE_SNAP_FTP_MACHINE=alpha.gnu.org
|
||||||
GNUSTEP_BASE_SNAP_FTP_DIRECTORY=gnu/gnustep
|
GNUSTEP_BASE_SNAP_FTP_DIRECTORY=gnu/gnustep
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue