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_GetURLmethod 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_*Streamfunctions are called in the order you want and behave the way you expect, combineNPN_NewStream,NPN_Write, andNPN_Destroy_Streamin 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_ASFILEONLYmode 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