This chapter describes using Plug-in API functions to receive and send streams.NPP_NewStream
,
NPP_WriteReady
,
NPP_Write
, and
NPP_DestroyStream
to, respectively, create a stream, find out how much data the plug-in can handle, push data into the stream, and delete it.
NPP_Write
NPN_RequestRead
NPP_StreamAsFile
NPP_NewStream
,
NPP_Write
, and
NPP_DestroyStream
to create a stream, push data into it, and delete it. For a detailed description of the methods discussed in this chapter, see "Stream Methods" in the API reference.
[Top]
NPP_NewStream
method. This method also determine which mode it should use to send data to the plug-in. Communicator can create a stream for several different types of data: The
NPP_NewStream
method has the following syntax:
NPError NPP_NewStream(NPP instance, NPMIMEType type,
The
NPStream *stream, NPBool seekable, uint16* stype);instance
parameter refers to the plug-in instance receiving the stream; the type
parameter represents the stream's MIME type.
The stream
parameter is a pointer to the new stream, which is valid until the stream is destroyed.
The seekable
parameter specifies whether the stream is seekable (true
) or not (false
). Seekable streams support random access (for example, local files or HTTP servers that support byte-range requests).
The plug-in can set the output parameter stype
to one of these transmission modes:
NP_NORMAL
(Default): The plug-in can process the data progressively as it arrives from the network or file system through series of calls to NPP_WriteReady
and NPP_Write
NP_ASFILEONLY
: New in Netscape Navigator 3.0. This plug-in gets full random access to the data using platform-specific file operations. Communicator saves stream data to a local file, and, when the stream is complete, delivers the path of the file through a call to NPP_StreamAsFile
.
NP_SEEK
: The plug-in instance can randomly access stream data as needed, through calls to NPN_RequestRead
. If the stream is not seekable, these requests are fulfilled only when all the data has been read and stored in the cache.
NPP_DestroyStream
or the plug-in can call NPN_DestroyStream
. This applies to all plug-in modes except NP_SEEK
.
NOTE: A plug-in can also use the[Top] [Receiving a Stream]NPN_GetURL
method to request a stream for an arbitrary URL. §
NPP_DestroyStream
method when it completes the stream sent to the plug-in, either successfully or abnormally. Once the plug-in returns from this method, Communicator deletes the NPStream
object. The plug-in can terminate the stream itself by calling NPN_DestroyStream
.
You should delete any private data allocated in the plug-in's stream->pdata
field when you destroy a stream. The plug-in can store private data associated with the stream in stream->pdata
. Communicator stores private data in stream->ndata
; this value should not be changed by the plug-in.
NPError NPP_DestroyStream(NPP instance,
The
NPStream *stream, NPError reason);instance
parameter is the current plug-in instance; the stream
parameter specifies the stream to be deleted.
The reason
parameter specifies why the stream was destroyed. It can have one of these values:
NPP_NewStream
and before writing data to the plug-in, Communicator calls NPP_WriteReady
to determine the maximum number of bytes that the plug-in can consume. This function allows Communicator to send only as much data to the instance as it can handle at one time, and it helps both Communicator and the plug-in to use their resources efficiently.
After a call to NPP_NewStream
, in which the plug-in requested a normal-mode stream, Communicator delivers the data in the stream progressively in a series of calls to NPP_WriteReady
and NPP_Write
. Communicator calls NPP_WriteReady
before each call to NPP_Write
.
The value returned by NPP_WriteReady
indicates how many bytes the plug-in instance can accept for this stream. If the plug-in allocates memory for the entire stream at once, it can return a large number. This number tells Communicator that it can pass as much data to the instance as possible in a single call to NPP_Write
. Communicator can write a smaller amount of data if desired or necessary (for example, if only 8K of data is available in a network buffer).
For instance, suppose the plug-in allocates, in NPP_NewStream
, an 8K buffer to hold the data written from that stream. In the first call, NPP_WriteReady
could return 8192, resulting in a call to NPP_Write
with a buffer of up to 8K bytes. After this data is copied from Communicator's buffer to the plug-in's buffer, the plug-in begins to process the data asynchronously. At the next NPP_WriteReady
call, only half of the data has been processed. To avoid allocating additional buffers, the plug-in could return 4096, resulting in a call to NPP_Write
with a buffer of up to 4K bytes.
The buffer passed to NPP_Write
may accommodate more bytes than the maximum number returned from NPP_WriteReady
. This maximum is only a promise to consume a certain amount of data from the buffer, not an upper limit on the buffer size. In the example above, suppose that the plug-in allocates an 8K buffer and returns 8192 from NPP_WriteReady
. If the plug-in gets 10000 bytes from Communicator in a subsequent call to NPP_Write
, the plug-in should copy the first 8192 bytes from Communicator's buffer into its own buffer and return 8192 (the number of bytes actually consumed) from NPP_Write
.
int32 NPP_WriteReady(NPP instance, NPStream *stream);
The instance
parameter is the current plug-in instance; the stream
parameter specifies the current stream.
[Top] [Receiving a Stream]
, in which the plug-in requested a normal-mode stream, Communicator delivers the data in the stream progressively in a series of calls to NPP_WriteReady
and
NPP_Write
.
The NPP_Write
function should return the number of bytes consumed by the instance. If this is a negative number, Communicator calls NPP_DestroyStream
to destroy the stream. If the number returned is smaller than the size of the buffer, Communicator sends the remaining data in the buffer to the plug-in through repeated calls to NPP_WriteReady
and NPP_Write
.
int32 NPP_Write(NPP instance, NPStream *stream,
The
int32 offset, int32 len, void *buf);instance
parameter is the current plug-in instance; the stream
parameter specifies the current stream. The offset
parameter specifies the offset, in bytes, of buf
from the beginning of the data in the stream. The len
parameter specifies the length, in bytes, of buf
, the buffer of data (delivered by the stream). The buffer allocated by Communicator is deleted after returning from the function, so the plug-in must make a copy of the data it needs to keep.
As an example, suppose that a plug-in (and the HTTP server) supports byte-range requests, and that Communicator is in the process of pushing data to the plug-in. If the user now requests a specific page of the document, the plug-in calls NPN_RequestRead
with a list of byte ranges. The open stream is converted from normal mode to seek mode in an effort to pass the plug-in the data that was already on the way, rather than just discarding it. All NPP_Write
calls for streaming data eventually stop, and NPP_Write
calls will be completed only for data requested with NPN_RequestRead
.
Communicator does not create a new stream for each byte range it requests. Instead, additional NPP_WriteReady
and NPP_Write
calls occur on the same stream. An individual call to NPN_RequestRead
can request discontiguous ranges, and you can have many outstanding NPN_RequestRead
calls. There is no guarantee that NPP_Write
will receive requests for ranges in the same order as you requested (although this typically is the case; the server controls the order). So, you'll need to pay attention to the offsets as data is being written.
The stream processes all byte-range requests, and then is placed in seek mode (either explicitly in NPP_NewStream
, or implicitly by a call to NPN_RequestRead
). It remains open until the plug-in closes it by calling NPN_DestroyStream
, or until the instance is destroyed.
NOTE: If you want to be sure that the[Top] [Receiving a Stream]NPN_*Stream
functions are called in the order you want and behave the way you expect, combineNPN_NewStream
,NPN_Write
, andNPN_Destroy_Stream
in the same callback. §
NPN_RequestRead
method. Communicator must download the entire stream to a temporary file before it can be used, unless the stream comes from a local file or an HTTP server that supports the proposed byte-range extension to HTTP. This mode consumes more resources than the others.
Random-access mode is determined in NPP_NewStream
by setting the mode NP_SEEK
. This mode gives the plug-in instance random access to stream data as needed, through calls to NPN_RequestRead
. If the stream is not seekable, these requests are fulfilled only when all the data has been read and stored in the cache.
The NPN_RequestRead
method requests a range of bytes from a seekable stream. Typically, the only streams that are seekable are from data that is in memory or on the disk, or from HTTP servers that support byte-range requests.
NPN_RequestRead
method has the following syntax:
NPError NPN_RequestRead(NPStream *stream, NPByteRange *rangeList);The
stream
parameter is the stream from which to read bytes; the rangeList
parameter specifies the range of bytes in the form of a linked list of NPByteRange
objects, which the plug-in must allocate. Because these objects are copied by Communicator, and so the plug-in can delete them as soon as the call to NPN_RequestRead
returns.
The plug-in can request multiple ranges, either through a list of NPByteRange
objects in a single call to NPN_RequestRead
or through multiple calls to NPN_RequestRead
. In this case, Communicator can write individual ranges in any order, with any number of NPP_WriteReady
and NPP_Write
calls.
[Top] [Receiving a Stream]
NPP_StreamAsFile
method. Use this feature only as a last resort; plug-ins should implement an incremental stream-based interface whenever possible.
File mode is determined in NPP_NewStream
by setting the mode NP_ASFILEONLY
. This mode gives the plug-in full random access to the data with platform-specific file operations. Communicator saves stream data to a local file, and, when the stream is complete, delivers the path of the file through a call to NPP_StreamAsFile
.
NOTE: Most plug-ins that need the stream saved to a file should useNP_ASFILEONLY
mode rather than the olderNP_ASFILE
; this mode is less efficient because it uses successive calls toNPP_Write
. §
NPP_StreamAsFile
provides the plug-in with a full path to a local file for the stream. It is a good idea to check that the file exists in the directory at the start of this method. If an error occurs during data retrieval or writing to the file, Communicator passes null
for the filename. If the file is created from a stream from the network, the file is locked in the Communicator disk cache until the stream or its instance is destroyed.
void(NPP instance, NPStream *stream,NPP_StreamAsFile
instance
parameter is the current plug-in; the stream
parameter specifies the current stream. The fname
parameter specifies the full path to a local file (or null
if an error occurs during data retrieval or writing to the file).
[Top] [Receiving a Stream]
NPN_NewStream
,
NPN_Write
, and
NPN_DestroyStream
to create a stream, push data into it, and delete it. Streams produced by a plug-in have a specific MIME type and can be sent to a particular Communicator window or frame for display. For an example that demonstrates these processes, see "Example of Sending a Stream."
NPN_NewStream
to send a new data stream to Communicator. Communicator creates a new NPStream
object and returns it to the plug-in as an output parameter.
The plug-in can use this stream object in subsequent NPN_Write
calls to Communicator. When all the plug-in data is written into the stream, the plug-in must terminate the stream and deallocate the NPStream
object by calling the NPN_DestroyStream
function.
NPError NPN_NewStream(NPP instance,The
NPMIMEType type,
const char* target,
NPStream** stream);
instance
parameter is the plug-in instance that is creating the stream; the type
specifies the MIME type of the stream.
The target
parameter specifies the window or frame. For the possible values for named targets, see the reference entry for
NPN_NewStream
. The target should not be the same window.
The stream
parameter represents the stream that Communicator creates.
For an example that demonstrates using this function with NPN_Write
and NPN_DestroyStream
, see "Example of Sending a Stream."
NPN_NewStream
, the plug-in can call NPN_Write
to deliver a buffer of data from the plug-in to Communicator. This function returns the number of bytes written or a negative integer in case of an error during processing.
NPN_Write
should send as much data as is available. Unlike NPP_Write
, NPN_Write
has no corresponding NPN_WriteReady
function.
int32 NPN_Write(NPP instance, NPStream *stream,
The plug-in should terminate the stream by calling
int32 len, void *buf);NPN_DestroyStream
, when all data has been written to the stream, or in the event of an error.
The instance
parameter is the current plug-in; the stream
parameter is a pointer to the stream being written to. The len
parameter specifies the length, in bytes, of data written to the stream. The buf
parameter is a pointer to the buffer holding the data to write to the stream.
For an example that demonstrates using this function with NPN_NewStream
and NPN_DestroyStream
, see "Example of Sending a Stream."
NPN_DestroyStream
to close and delete it. This applies to streams the plug-in creates with NPN_NewStream
or streams created by Communicator with NPP_NewStream
.
NPError NPN_DestroyStream(NPP instance, NPStream* stream,
The
NPError reason);instance
parameter is the current plug-in; the stream
parameter specifies the stream, created by either Communicator or the plug-in. The reason
parameter represents the reason the stream was stopped, as follows:
NPRES_DONE
(most common): The stream completed normally; the plug-in sent all data to Communicator.
NPRES_USER_BREAK
: The plug-in terminated the stream because of a user request.
NPRES_NETWORK_ERR
: The stream failed because of network problems.
For an example that demonstrates using this function with NPN_NewStream
and NPN_Write
, see "Example of Sending a Stream."
NPStream* stream;
char* myData = "<HTML><B>This is a message from my plug-in!</B></HTML>";
int32 myLength = strlen(myData) + 1;
/* Create the stream. */
err = NPN_NewStream(instance, "text/html", "_blank", &stream);
/* Push data into the stream. */
err = NPN_Write(instance, stream, myLength, myData);
/* Delete the stream. */Your plug-in can create another instance of itself by specifying its own MIME type and a new target name in a call to
err = NPN_DestroyStream(instance, stream, NPRES_DONE);
NPN_NewStream
.Last Updated: 01/15/97 16:36:52