NXClose;¬void NXClose(NXStream *stream)

	DESCRIPTION	This function closes the stream given as its argument.  If the stream had been opened for writing, it's flushed first.  (The NXStream structure is defined in the header file stream/streams.h.) 

If the stream had been a file stream, the storage used by the stream is freed, but the file descriptor isn't closed.  See the UNIX manual page on close() for information about closing a file descriptor.  If the stream had been on memory, the internal buffer is truncated to the size of the data in it.  (Calling NXClose() on a memory stream is equivalent to NXCloseMemory() with the constant NX_TRUNCATEBUFFER.)

	EXCEPTIONS	NXClose() raises an NX_illegalStream exception if the stream passed in is invalid.

	SEE ALSO	NXCloseMemory()

NXFlush;¬int NXFlush(NXStream *stream)

	DESCRIPTION	This function flushes the buffer associated with the stream passed in as an argument.  NXFlush() is called by NXClose(), so you don't have to flush the buffer before closing a stream with NXClose().  In some cases, you might not want to close the stream but you might want to ensure that data is actually written to the stream's destination rather than remaining in the buffer.

	RETURN	NXFlush() returns the number of characters flushed from the buffer and written to the stream.

	EXCEPTIONS	This function raises an NX_illegalStream exception if the stream passed in is invalid.  In addition, it raises an NX_illegalWrite exception if an error occurs while flushing the stream.

NXOpenFile;¬NXStream *NXOpenFile(int fd, int mode) 
NXStream *NXOpenPort(port_t port, int mode)

	DESCRIPTION	These functions connect a stream to a file or a Mach port.  (The NXStream structure is defined in the header file streams/streams.h.)

NXOpenFile() opens a stream on the file specified by the file descriptor argument, fd, which can refer to a pipe or a socket.  (If the file is stored on disk, use NXMapFile(); this function is described below under NXOpenMemory().)  The mode argument should be one of the three constants NX_READONLY, NX_WRITEONLY, or NX_READWRITE to specify how the stream will be used.  The mode should be the same as the one used when obtaining the file descriptor.  (The system call open(), which returns a file descriptor, takes 0_RDONLY, 0_WRONLY, or 0_RDWR to indicate whether the file will be used for reading, writing, or both.  For more information on this function, see its UNIX manual page.)

You can use NXOpenFile() to connect to stdin, stdout, and stderr by obtaining their file descriptors using the standard C library function fileno().  (For more information on this function, see its UNIX manual page.)

NXOpenPort() opens a stream associated with the Mach port specified by port.  The mode must be either NX_READONLY or NX_WRITEONLY.  The port must already be allocated using the Mach function port_allocate().  See the ªMach Functionsº section later in this chapter for more information about using this function.

Once the file or Mach port stream is open, you can read from or write to it.  See the descriptions of NXRead() and NXPutc() for more information about the functions available for reading or writing to a stream.  

When you're finished with the stream, close it with NXClose().  If you've written to the stream, the data will be automatically saved in the file.  After calling NXClose() on a file stream, you still need to close the file descriptor.  To do this, use the system call close(), giving it the file descriptor as an argument.  (For more information about close(), see its UNIX manual page.)

	RETURN	Both functions return a pointer to the stream they open or NULL if an error occurred while trying to open the stream.

	SEE ALSO	NXOpenMemory(), NXRead(), NXPutc(), NXClose()

NXOpenMemory;¬NXStream *NXOpenMemory(const char *address, int size, int mode) 
NXStream *NXMapFile(const char *pathName, int mode)
int NXSaveToFile(NXStream *stream, const char *name) 
void NXGetMemoryBuffer(NXStream *stream, char **streambuf, int *len, int *maxlen)
void NXCloseMemory(NXStream *stream, int option)

	DESCRIPTION	These functions open, save, and close streams on memory.  (The NXStream structure is defined in the header file streams/streams.h.)

NXOpenMemory() returns a pointer to the memory stream it opens.  Its argument mode specifies whether the stream will be used for reading or writing.  If NX_WRITEONLY is specified, the first two arguments should be NULL and 0 to allow the amount of memory available to be automatically adjusted as more data is written.  Any other value for address should be the starting address of memory allocated with vm_allocate().  If NX_READONLY is specified, a memory stream will be set up for reading the data beginning at the location specified by the first argument; the second argument indicates how much data will be read.  To use the stream for both writing and reading, you can either use NULL and 0 or specify the location and amount of data to be read; again, address should be the starting address of memory allocated with vm_allocate().

NXMapFile() maps a file into memory and then opens a memory stream.  A related function, NXOpenFile(), connects a stream to a file specified with a file descriptor.  (This function is described earlier in this chapter.)  Memory mapping allows efficient random and multiple access to the data in the file, so NXMapFile() should be used whenever the file is stored on disk.  When you call NXMapFile(), give it the pathname for the file and indicate whether you will be writing, reading, or both, by using one of the mode constants described above.  If you use the stream only for reading, just close the memory stream when you're finished.  If you write to the memory-mapped stream, you need to call NXSaveToFile(), as described below, to save the data.

Once the memory stream is open, you can read from or write to it.  See the descriptions of NXRead() and NXPutc() for more information about reading or writing to a stream.

Before you close a memory stream, you can save data written to the stream in a file.  To do this, call NXSaveToFile(), giving it the stream and a pathname as arguments.  NXSaveToFile() writes the contents of the memory stream into the file, creating it if necessary.  After saving the data, close the stream using NXCloseMemory().

NXGetMemoryBuffer() returns the memory buffer (streambuf) and its current and maximum lengths (len and maxlen).  

When you're finished with a memory stream, close it by calling NXCloseMemory().  Typically, NX_FREEBUFFER will be used as the second argument to free all memory used by the stream, but there are two other constants available.  If you've used the stream for writing, more memory may have been made available than was actually used; the constant NX_TRUNCATEBUFFER indicates that any unused pages of memory should be freed.  (Calling NXClose() with a memory stream is equivalent to calling NXCloseMemory() and specifying NX_TRUNCATEBUFFER.)  NX_SAVEBUFFER doesn't free the memory that had been made available.  

	RETURN	NXOpenMemory() and NXMapFile() return a pointer to the stream they open or NULL if the stream couldn't be opened.

NXSaveToFile() returns -1 if an error occurred while opening or writing to the file and 0 otherwise.

	EXCEPTIONS	The functions in this group that take a stream as an argument raise an NX_illegalStream exception if the stream is invalid.  This exception is also raised if these functions are used on a stream that isn't a memory stream.

	SEE ALSO	NXRead(), NXPutc(), NXOpenFile()

NXPutc;¬int NXPutc(NXStream *stream, char c)
int NXGetc(NXStream *stream)
void NXUngetc(NXStream *stream)
int NXScanf(NXStream *stream, const char *format, ...)
void NXPrintf(NXStream *stream, const char *format, ...)
int NXVScanf(NXStream *stream, const char *format, va_list argList)
void NXVPrintf(NXStream *stream, const char *format, va_list argList)

	DESCRIPTION	These functions and macros read and write data to and from a stream that has already been opened.  (See the descriptions of NXOpenMemory() and NXOpenFile() for more information about opening a stream.)  After writing to a stream, you may need to call NXFlush() to flush data from the buffer associated with the stream.  (See the description of NXFlush() earlier in this chapter.) 

The macros for writing and reading single characters at a time are similar to the corresponding standard C functions:  NXPutc() and NXGetc() work like putc() and getc().  NXPutc() appends a character to the stream.  Its second argument specifies the character to be written to the stream.  NXGetc() retrieves the next character from the stream.  To reread a character, call NXUngetc().  This function puts the last character read back onto the stream.  NXUngetc() doesn't take a character as an argument as ungetc() does.  NXUngetc() can only be called once between any two calls to NXGetc() (or any other reading function).  

The other four functions convert strings of data as they're written to or read from a stream.  NXPrintf() and NXScanf() take a character string that specifies the format of the data to be written or read as an argument.  NXPrintf() interprets its variables according to the format string and writes them to the stream.  Similarly, NXScanf() reads characters from the stream, interprets them as specified in the format string, and stores them in the variables indicated by the last set of arguments.  The conversion characters in the format string for both functions are the same as those used for the standard C library functions, printf() and scanf().  For detailed information on these characters and how conversions are performed, see the UNIX manual pages for printf() and scanf().  

Two related functions, NXVPrintf () and NXVScanf(), are exactly the same as NXPrintf() and NXScanf(), except that instead of being called with a variable number of arguments, they are called with a va_list argument list, which is defined in the header file stdarg.h.  This header file also defines a set of macros for advancing through a va_list.

	RETURN	NXPutc() and NXGetc() return the character written or read.  NXScanf() and NXVScanf() return EOF if all data was successfully read; otherwise, they return the number of successfully read data items.

	SEE ALSO	NXOpenMemory(), NXOpenFile(), NXFlush(), NXRead()

NXRead;¬int NXRead(NXStream *stream, void *buf, int count) 
int NXWrite(NXStream *stream, const void *buf, int count)

	DESCRIPTION	These functions read and write multiple bytes of data to a stream that has already been opened.  (See the descriptions of NXOpenMemory() and NXOpenFile() for more information about opening a stream.)  After writing to a stream, you may need to call NXFlush() to flush data from the buffer associated with the stream.  (See the description of NXFlush() earlier in this chapter.)

These functions write multiple bytes of data to and read them from a stream.  To read data from a stream, call NXRead():

NXRect        myRect;
NXRead(stream, &myRect, sizeof(NXRect));

NXRead() reads the number of bytes specified by its third argument from the given stream and places the data in the location specified by the second argument.  

In the following example, an NXRect structure is written to a stream.

NXRect  myRect;

NXSetRect(&myRect, 0.0, 0.0, 100.0, 200.0);
NXWrite(stream, &myRect, sizeof(NXRect));

The second and third arguments for NXWrite() give the location and amount of data (measured in bytes) to be written to the stream.

	RETURN	These functions return the number of bytes written or read.  If an error occurs while writing or reading, not all the data will be written or read.

	SEE ALSO	NXFlush()

NXRegisterPrintfProc;¬void NXRegisterPrintfProc(char formatChar, NXPrintfProc *proc, void *procData)

	DESCRIPTION	 NXRegisterPrintfProc registers formatChar, a format character that corresponds to *proc, which is a pointer to a function of type NXPrintfProc.  The type definition for an NXPrintfProc function is:

typedef   void   NXPrintfProc(NXStream *stream, void *item, 
                                void *prodCata)

formatChar can be any of the characters ªvVwWyYzZº; other characters are reserved for use by NeXT.  procData represents client data that will be blindly passed along to the function.

After calling NXRegisterPrintfProc(), formatChar can be used in a format string for the NXPrintf() or NXVPrintf() functions.  When these functions encounter formatChar in a format string, proc will be called to format the corresponding argument passed to NXPrintf().  For example:

tabOver(NXStream stream, void *item, void *data)
{
...
}

NXRegisterPrintfProc('v', &tabOver, NULL)
...
NXPrintf(myStream, "%v", itemOne)

This code registers ªvº as the formatting character for tabOver(); with the NULL argument, no client data will be passed to the tabOver() function.  NXPrintf() then passes the variable itemOne to tabOver for formatting, which formats the item and places it in myStream.

	SEE ALSO	NXPutc()

NXSeek;¬void NXSeek(NXStream *stream, long offset, int ptrName)
long NXTell(NXStream *stream)
BOOL NXAtEOS(NXStream *stream)

	DESCRIPTION	These functions set or report the current position in the stream given as an argument.  This position determines which data will be read next or where the next data will be written since the functions for reading and writing to a stream start from the current position.

NXSeek() sets the position offset number of bytes from the place indicated by ptrName, which can be NX_FROMSTART, NX_FROMCURRENT, or NX_FROMEND.

NXTell() returns the current position of the buffer.  This information can then be used in a call to NXSeek().

The macro NXAtEOS() evaluates to TRUE if the end of a stream has been reached.  Since streams opened for writing don't have an end, this macro should only be used with streams opened for reading.

Since position within a Mach port stream is undefined, NXSeek() and NXTell() shouldn't be called on a Mach port stream.  These functions also shouldn't be used on a typed stream.  The NX_CANSEEK flag (defined in the header file streams/streams.h) can be used to determine if a given stream is seekable.

	RETURN	NXTell() returns the current position of the buffer.

NXAtEOS() evaluates to TRUE if the end of the stream has been detected and to FALSE otherwise.

	EXCEPTIONS	NXSeek() and NXTell() raise an NX_illegalStream exception if the stream passed in is invalid.  

NXSeek() raises an NX_illegalSeek exception if offset is less than 0 or greater than the length of a reading stream.  This exception will also be raised if ptrName is anything other than the three constants listed above.

NXStreamCreateFromZone;¬NXStream *NXStreamCreateFromZone(int mode, int createBuf, NXZone *zone)
NXStream *NXStreamCreate(int mode, int createBuf)
void NXStreamDestroy(NXStream *stream)
int NXDefaultRead(NXStream *stream, void *buf, int count)
int NXDefaultWrite(NXStream *stream, const void *buf, int count)
int NXFill(NXStream *stream)
void NXChangeBuffer(NXStream *stream)

	DESCRIPTION	These functions need only be used if you implement your own version of a stream.  If you're using a memory stream, a stream on a file, a stream on a Mach port, or a typed stream, you don't need the functions described here.  Instead, you can just use the functions already defined for these types of streams; see the Technical Summaries manual for a list of these functions.  

The first argument to NXStreamCreateFromZone(), mode, indicates whether the stream to be created will be used for reading or writing or both.  It should be one of the following constants:  NX_READONLY, NX_WRITEONLY, or NX_READWRITE.  The argument createBuf specifies whether the stream should be buffered.  If it is TRUE, a buffer is created of size NX_DEFAULTBUFSIZE, as defined in the header file streams/streamsimpl.h.  The argument zone specifies the memory zone where you allocate memory for the new stream; see NXCreateZone() for more on allocating zones of memory.  When implementing your own version of a stream, you may want to provide a function to open such a stream; this function will probably call NXStreamCreateFromZone(), as NXOpenMemory(), NXOpenPort(), and NXOpenFile() do.

NXStreamCreate() calls NXStreamCreateFromZone() with the default zone as its zone argument.  

NXStreamDestroy() destroys the stream given as its argument, deallocating the space it had used.  If a buffer had been created for stream, its storage is also freed.  To avoid losing data, a stream should be flushed using NXFlush() before it's destroyed.  When implementing your own version of a stream, you may want to provide a function to close such a stream; this function will probably call NXStreamDestroy(), as NXClose()and NXCloseMemory() do.

NXDefaultRead() and NXDefaultWrite() read and write multiple bytes of data on a stream.  NXDefaultRead() reads the next count number of bytes from stream, starting at the position specified by the buffer pointer buf.  NXDefaultWrite() writes count number of bytes to stream, starting at the position specified by buf.  These functions return the number of bytes read or written.  When implementing your own version of a stream, you can use these functions with your stream unless you want to perform specialized buffer management.  If you implement your own versions of these functions for reading and writing bytes, they should return the number of bytes read or written.

When reading from a buffered stream, NXFill() can be called to fill the buffer with the next data to be read.  Check whether buf_left is equal to 0 to determine whether all the data currently in the buffer has been read.  (See the header file streams/streams.h for more information about buf_left, which is part of an NXStream structure.)

NXChangeBuffer() switches the mode of a stream between reading and writing.  If the argument stream had been defined for reading, this function changes it to a stream that can be written to; if stream had been defined for writing, it becomes a stream for reading.  In both cases, the pointer that points to either the next piece of data to be read from the buffer or the next location to which data will be written is realigned appropriately.  Also, NX_READFLAG and NX_WRITEFLAG are updated to reflect the new mode of the stream.

	RETURN	NXStreamCreate() returns a pointer to the stream it creates.

NXDefaultRead() and NXDefaultWrite() return the number of bytes read or written.

NXFill() returns the number of characters read into the buffer.

	EXCEPTIONS	All functions that take a stream as an argument raise an NX_illegalStream exception if the stream passed in is invalid.

NXFill() raises an NX_illegalRead exception if an error occurs while filling.

NXChangeBuffer() raises an NX_illegalStream exception if NX_READFLAG and NX_WRITEFLAG have not been set to match the NX_CANREAD and NX_CANWRITE flags.  

	SEE ALSO	NXOpenFile(), NXOpenMemory(), NXClose(), NXFlush(), NXRead()