Page Numbers: Yes X: 527 Y: 10.2" First Page: 32 Margins: Top: 1.5" Bottom: 1" Heading:q(635) Mesa Pup Package Functional Specificationy734q\b Appendix A: Stream Packagee24jk80\b The Pup Package uses a stream interface different from the standard Alto/Mesa one. Pup's version includes, among other things, subsequences (a generalization of mark bytes) and an attention (break) facility. Note that this appendix describes the stream interface in a general (device and implementation independent) way; see the previous section on the Byte Stream Interface for Pup specifics.e18jk40 The stream package defined by the interface Stream provides a device and format independent interface for sequential access to a stream of data. In particular,e18jk40\44f6b6f0B It provides a vehicle by which processes or subsystems can communicate with each other, whether they reside on the same machine or on different machines.l4269e6jk40 It permits processes or subsystems to transmit arbitrary data to or from storage media in a device-independent way.l4269e6jk40 It defines a standard way for transforming the detailed interface for a device into a uniform, high level interface which can be used by other client software.l4269e6jk40 It provides an environment for implementing simple transformations to be performed on the data as it is being transmitted.l4269e6jk40 It provides optional access to and control over the mapping of data onto the physical format of the storage or transmission medium being used. l4269e6jk40 The stream package provides several facilities, not all of which may be important to an individual client. First, there is the stream interface, the set of procedures and data types by which a client actually controls the transmission of a stream of information. Each of the operations of the stream interface takes as a parameter a Stream.Handle which identifies the particular stream being accessed. Second, the stream package defines the concepts of transducer and filter. A transducer is a software entity (e.g. module or configuration) which implements a stream connected to a specific device or medium. A filter also implements a stream, but only for the purpose of transforming, buffering, or otherwise manipulating the data before passing it on to another stream. Transducers and filters may be provided either by the system or by clients. Third, the stream package provides a standard way of concatenating a sequence of filters (usually terminated with a transducer) to form a compound stream called a pipeline. A pipeline is accessed by means of the normal stream operations, and causes a sequence of separate transformations to be applied to data flowing between the client program at one end and the physical storage (or transmission) medium at the other.e12jk40\128i16I191f7b7f6 6f0B108i10I5i6I541i8I The use of pipelines permits clients to interpose new stream manipulation programs (filters and transducers) between clients (producers and consumers of data) without modifying the interfaces seen by the clients. For example, a data format conversion program can obtain its data either from a tape or from a disk, using the same stream interface, and hence the same program logic for both. Similarly, filters performing such functions as code conversion, buffering, data conversion, encryption, etc. may be inserted into a pipeline without affecting the way the client sends and receives data through the stream interface.e12jk40 The stream facility transmits arbitrary data, regardless of format and without prejudice to its type or characteristics. The data may comprise a sequence of bytes, words, or arbitrary Mesa data structures. The stream facility does not presume or require the encoding of information according to any particular protocol or convention. Instead, it permits clients to define their own protocols and standards according to their own needs.e12jk40 In this appendix, sections A.1, A.2, and A.3 will be of interest to all clients. Section A.4 will be of interest only to those clients wishing to control the physical record characteristics of a particular stream. Section A.5 will be of interest only to those clients wishing to implement their own filters or transducers. In addition, the clients of a particular stream type (e.g. disk, tape, etc.) will normally have to consult separate documentation regarding the details of that kind of stream.e12jk40\27i3I2i3I6i3I46i3I131i3I A.1 Semantics of Streamse24jk80\i The stream facility supports transmission of a sequence of eight-bit bytes. This sequence may be divided into identifiable subsequences, each of which has its own subsequence type.e12jk40\124i12I28i16I Stream.Byte: TYPE = [0..255];l5248d4268x4e12k40(988)\f7b7f6 6f7 7f6 8f7 1f6 Stream.SubSequenceType: TYPE = [0..255];l5248d4268x4e12k40\f7b7f6 17f7 7f6 8f7 1f6 A subsequence may be null; i.e., it may be of zero length and contain no bytes but still contain the SubSequenceType information. This information allows all subsequences to be easily identified and separated from each other while shielding clients from the bothersome problems of control-codes (i.e. embedding control-codes into the stream, making them transparent, and building a parser to implement such transparency).e12jk40(635)\101f6b15f0B Additionally, an attention flag may be inserted into a stream sequence. This is neither a byte nor a SubSequenceType, but simply an indication of an extraordinary situation. Attention flags are transmitted through the stream as quickly as possible, possibly bypassing bytes and changes in SubSequenceType which were transmitted earlier but which are still in transit. This provides a simple mechanism for implementing breaks (similar to the "attention-key" of many time-sharing systems).e12jk40\17i9I76f6b15f0B174f6b15f0B Streams per se have no notion of a byte number (i.e. an array index); they deal only with the sequential order of successive bytes comprising the arbitrary binary data being transmitted. The stream interface is thus unsuitable for applications requiring random access.e12jk40\8i7I Streams have no intrinsic notion of the bytes passing through them being grouped into physical records. The client program can completely ignore physical record structure and is thus relieved of the burden of dealing with the associated packing and unpacking problems. If, however, it becomes necessary to control or determine the underlying physical record structure, as determined by the particular storage (or transmission) medium, the interface provides extended facilities which allow this.e12jk40 All of the procedures described here are synchronous and none returns until the indicated operation is complete. That is, an input operation does not return until the data is actually available to the client, and an output operation does not return until the data has been accepted by the stream and client buffers may be reused. Note, however, that a stream component may do internal buffering and that the acceptance of data means only that the stream component itself has a correct copy and is in a position to proceed asynchronously to write or send it.e12jk40\371i3I Streams are inherently full-duplex -- i. e., separate processes may be transmitting and receiving simultaneously. The stream interface does not guarantee mutual exclusion among different processes attempting to access the same stream. However, individual transducers or filters may restrict themselves to half-duplex operation and/or may implement such mutual exclusion or more elaborate forms of synchronization as are appropriate. Documentation for such filters and transducers should be consulted on a case-by-case basis for details.e12jk40\141i3I A.2 Operations on Streamse24jk80\i The stream interface provides the following information transmission operations: GetBlock, GetByte, GetChar, GetWord, PutBlock, PutByte, PutChar, PutWord, SendNow, SetSST, SendAttention, and WaitForAttention.e12jk40\81f6b8f0B2f6b7f0B1f6b8f0B2f6b7f0B2f6b8f0B2f6b7f0B2f6b7f0B2f6b7f0B2f6b7f0B2f6b6f0B2f6b13f0B6f6b16f0B A client program identifies a particular instance of the stream interface by means of a Stream.Handle.e12jk40\88f7b7f6 6f0B Stream.Handle: TYPE = . . . ;l5248d4268x4e12k40(988)\f7b7f6 8f7 14f6 A Handle identifies an object (see :A.5.1) which embodies all of the information concerning the transfer of data to and/or from the client program via stream operations. It is passed as a parameter to each of the data transmission operations of the following sections to specify the stream to which the operations apply.e12jk40(635)\2f6b6f0B27f3 1f0i5I A.2.1 GetBlock and PutBlocke24jk80\i6f6bI8f0Bi5f6bI8f0Bi The principal operations for transferring blocks of data are Stream.GetBlock and Stream.PutBlock. Each of these takes a parameter specifying the block of virtual memory to or from which bytes are to be transmitted.e12jk40\61f7b7f6 8f0B5f7b7f6 8f0B Stream.Block: TYPE = RECORD [ blockPointer: LONG POINTER, startIndex, stopIndexPlusOne: CARDINAL];l5248d4268x4e12k40(988)\f7b7f6 7f7 14f6 16f7 15f6 10f7 2f6 18f7 8f6 A Block describes a section of memory which will be the source and/or sink of the bytes transmitted; the section of memory described is a sequence of bytes (not necessarily word aligned). The blockPointer may be regarded as a base of a packed array of bytes; it selects a word such that a startIndex of zero would select the left byte of that word (i.e., bits 0 - 7). The selected block consists of the bytes blockPointer^[i] for i in [startIndex..stopIndexPlusOne). Notice that a Block cannot describe more than 216-1 bytes or 215-1 words.e12jk40(635)\2f6b5f0B186f6b12f0B85f6b10f0B111f6b14f0Bi1f6bI1f0B5i1I4f6b30f0B17f6b5f0B28f1o4 2f0o0 13f1o4 2f0o0 Note: Some of the operations of this section and the next may cause signals to be generated. If such a signal is RESUMEd, transmission continues where it left off -- i.e., any changes made by the catch phrase to the Block record and/or to the input options (see below) are ignored. If, however, such a signal is RETRY'ed, the next byte of the stream sequence is transmitted to or from the byte specified by the current value of the Block record and/or input options, either of which might have been updated by the catch phrase. In no case is the stream sequence itself "backed up." That is, bytes previously received from input are not re-received, and bytes previously transmitted on output are not withdrawn.l4621d2999e12jk80(0,4608)\b5B109f7b6f0B97f6b5f0B92f7b5f0B115f6b5f0B275b The primary input operation is Stream.GetBlock.e12jk40(635)\31f7b7f6 8f0B Stream.GetBlock: PROCEDURE [sH: Stream.Handle, block: Stream.Block] RETURNS [bytesTransferred: CARDINAL, why: Stream.CompletionCode, sst: Stream.SubSequenceType];l5248d4268x4e12k40(988)\f7b7f6 10f7 10f6 5f7 7f6 15f7 7f6 7f7 8f6 19f7 8f6 7f7 7f6 21f7 7f6 Stream.CompletionCode: TYPE = {normal, endRecord, sstChange, endOfStream};l5248d4268x4e12k40\f7b7f6 16f7 4f6 The parameter block describes the memory area into which the bytes will be placed. GetBlock does not return until the input is terminated. Its exact behavior, however, is controlled by a set of input options which may be set by the client using the following operation:e12jk40(635)\14f6b5f0B65f6b8f0B Stream.SetInputOptions: PROCEDURE [sH: Stream.Handle, options: Stream.InputOptions];l5248d4268x4e12k40(988)\f7b7f6 17f7 10f6 5f7 7f6 17f7 7f6 14f7 Stream.InputOptions: TYPE = RECORD [ terminateOnEndPhysicalRecord, signalLongBlock, signalShortBlock, signalSSTChange, signalEndOfStream: BOOLEAN];l5248d4268x4e12k40\f7b7f6 14f7 4f6 3f7 7f6 103f7 7f6 Stream.defaultInputOptions: Stream.InputOptions = [FALSE, FALSE, FALSE, FALSE, FALSE];l5248d4268x4e12k40\f7b7f6 21f7 7f6 16f7 5f6 2f7 5f6 2f7 5f6 2f7 5f6 2f7 5f6 SetInputOptions controls exactly how GetBlock terminates and what signals it generates. Ordinarily (i.e., with the parameter options set to defaultInputOptions) the transmission will not terminate until the entire block of bytes is filled. However, under exceptional conditions described in :A.4, the transmission may terminate before the block is filled and may also result in a signal. In all cases the procedure will return the actual number of bytes transferred, a CompletionCode indicating the reason for termination, and the latest SubSequenceType encountered. The input operation may conveniently be restarted where it left off by first adding the result bytesTransferred to block.startIndex to update the record describing the block of bytes.e12jk40(635)\f6b15f0B22f6b8f0B81f6b7f0B8f6b19f0B133f3 1f0i3I44f6b5f0B126f6b14f0B55f6b15f0B110f6b16f0B4f6b16f0B Two circumstances which always suspend the transmission of data before the block is filled are (a) the detection of a change in SubSequenceType and (b) the endOfStream. If the input option signalSSTChange is FALSE (the default case), then the procedure GetBlock terminates immediately and returns the number of bytes transferred, with why = sstChange, and sst set to the new value of the SubSequenceType. If the input option signalSSTChange is TRUE, then the signale12jk40\24i6I45f6b5f0B48f6b16f0B12f6b11f0B23f6b15f0B4f7b5f0B40f6b8f0B74f6b3f0B3f6b9f0B6f6b3f0B29f6b15f0B23f6b15f0B4f7b4f0B Stream.SSTChange: SIGNAL [sst: Stream.SubSequenceType, nextIndex: CARDINAL];l5248d4268x4e12k40(988)\f7b7f6 11f7 7f6 6f7 7f6 28f7 8f6 is generated. The parameter sst specifies the new SubSequenceType, and the parameter nextIndex specifies the byte index within the block where the first byte of the new subsequence will be placed. This signal may be resumed, and the effect is to continue the data transmission as though the change in SubSequenceType had not occurred (i.e., in the same block of bytes).e12jk40(635)\29f6b3f0B19f6b15f0B20f6b9f0B37f6b5f0B166f6b15f0B Caution: A catch phrase for this signal must not attempt any other stream operations using the same Stream.Handle, for this will corrupt the internal state information maintained for the stream.l4621d2999e12jk80(0,4608)\b8B92f7b7f6 6f0B Implementation of the end-of-stream feature is strictly transducer and filter specific, and optional. All transducers and filters need not implement this feature. Transducer and filter implementors may implement an end-of-stream mechansim using any protocol they desire. Typically, this feature would be implemented by exchanging subsequence types in some specific order. If implementors use this mechansim, then they must document the subsequence types reserved for this, so that clients do not inadvertantly use the same ones for their own protocol. When putting together a pipeline from a transducer and filters, great care needs to be taken to preserve the end-of-stream feature through all the stream components. If the input option signalEndOfStream is TRUE and the stream component detects that the end-of-stream has occured, then the signale12jk40(635)\131i8I606f6b17f0B4f7b4f0B Stream.EndOfStream: SIGNAL [nextIndex: CARDINAL];l5248d4268x4e12k40(988)\f7b7f6 13f7 7f6 12f7 8f6 is generated. The parameter nextIndex specifies the byte index immediately following the last byte of the stream sequence filled into a client's block.l3008d2999e12jk80(0,4608)\29f6b9f0B Note: Stream component implementors may provide special procudure calls in order to actively cause a stream to be terminated.l4621d2999e12jk80\b5B The principal output operation is Stream.PutBlock.e12jk40(635)\34f7b7f6 8f0B Stream.PutBlock: PROCEDURE [sH: Stream.Handle, block: Stream.Block, endPhysicalRecord: BOOLEAN];l5248d4268x4e12k40(988)\f7b7f6 10f7 10f6 5f7 7f6 15f7 7f6 26f7 7f6 This operation is analogous to Stream.GetBlock. The parameter block describes the area of memory from which information is transmitted. This procedure returns only after the data has been accepted by the stream, at which time the client may reuse the block. If the client is ignoring physical record boundaries (the default case) then parameter endPhysicalRecord should be set to FALSE. Otherwise, see :A.4.e12jk40(635)\31f7b7f6 8f0B17f6b5f0B185f6b5f0B90f6b17f0B18f7b5f0B18f3 1f0i3I Note: Stream operations have the right to discard empty blocks, hence a PutBlock operation specifying a block of length zero may be a no-op.l4621d2999e12jk80(0,4608)\b5B67f6b8f0B24f6b5f0B A.2.2 Additional Data Transmission Operationse24jk80(635)\i In addition to GetBlock and PutBlock, the following operations are provided:e12jk40\15f6b8f0B5f6b8f0B Stream.GetByte: PROCEDURE [sH: Stream.Handle] RETURNS [byte: Stream.Byte];l5248d4268x4e12k40(988)\f7b7f6 9f7 10f6 5f7 7f6 8f7 8f6 7f7 7f6 Stream.GetChar: PROCEDURE [sH: Stream.Handle] RETURNS [char: CHARACTER];l5248d4268x4e12k40\f7b7f6 9f7 10f6 5f7 7f6 8f7 8f6 7f7 9f6 Stream.GetWord: PROCEDURE [sH: Stream.Handle] RETURNS [word: Stream.Word];l5248d4268x4e12k40\f7b7f6 9f7 10f6 5f7 7f6 7f7 9f6 7f7 7f6 Stream.Word: TYPE = [0..65535];l5248d4268x4e12k40\f7b7f6 6f7 5f6 GetByte and GetChar operations get the next Byte or CHARACTER from the stream sequence and return it. They are equivalent to a call upon Stream.GetBlock, specifying a Block containing one byte. The GetWord operation gets the next Word from the stream sequence and returns it. It is equivalent to a call upon Stream.GetBlock, specifying a Block containing AltoDefs.BytesPerWord bytes. Input options are assumed to be signalShortBlock, signalLongBlock, and endPhysicalRecord = FALSE, and signalEndOfStream and signalSSTChange = TRUE. Thus, these operations may result in signal SSTChange or EndOfStream.e12jk40(635)\f6b7f0B5f6b7f0B25f6b5f0B2f6b1f7 9f0B77f7b7f6 8f0B15f6b5f0B27f6b8f0B24f6b4f0B75f7b7f6 8f0B15f6b5f0B12f7b9f6 12f0B43f6b16f0B2f6b15f0B6f6b17f0B3f7b5f0B6f6b18f0B3f6b16f0B3f7b4f0B47f6b10f0B2f6b12f0B Note: When the SIGNALs SSTChange or EndOfStream are generated, nextIndex should be equal to 0. In the case of GetWord if nextIndex = 1, the caller is responsible for processing the "half-word".l4621d2999e12jk80(0,4608)\b5B10f7b6f0B2f6b10f0B2f6b12f0B16f6b9f0B39f6b7f0B4f6b9f0B Stream.PutByte: PROCEDURE [sH: Stream.Handle, byte: Stream.Byte];l5248d4268x4e12k40(988)\f7b7f6 9f7 10f6 5f7 7f6 14f7 7f6 Stream.PutChar: PROCEDURE [sH: Stream.Handle, char: CHARACTER];l5248d4268x4e12k40\f7b7f6 9f7 10f6 5f7 7f6 14f7 9f6 Stream.PutWord: PROCEDURE [sH: Stream.Handle, word: Stream.Word];l5248d4268x4e12k40\f7b7f6 9f7 10f6 5f7 7f6 14f7 7f6 The PutByte and PutChar operations transmit the next Byte or CHARACTER to the medium. They are equivalent to a call on Stream.PutBlock, specifying a Block containing one byte. The PutWord operation transmits the next Word to the medium. This procedure is equivalent to call on Stream.PutBlock, specifying a Block containing AltoDefs.BytesPerWord bytes. These output operations specify endPhysicalRecord = FALSE.e12jk40(635)\4f6b7f0B5f6b7f0B30f6b5f0B2f6b1f7 9f0B50f7b7f6 8f0B15f6b5f0B27f6b7f0B30f6b4f0B57f7b7f6 8f0B15f6b5f0B12f7b9f6 12f0B40f6b17f0B3f7b5f0B Stream.SendNow: PROCEDURE [sH: Stream.Handle];l5248d4268x4e12k40(988)\f7b7f6 9f7 10f6 5f7 7f6 This operation flushes the stream sequence; it guarantees that all information previously output (by means of PutBlock, PutByte, PutChar, PutWord or SetSST) will actually be transmitted to the medium (perhaps asynchronously). This procedure is equivalent to a call on Stream.PutBlock, specifying a Block containing no bytes and endPhysicalRecord = TRUE (see :A.4). Client programs which are not concerned with physical record boundaries should nevertheless call SendNow at appropriate times to ensure that the bytes and changes in SubSequenceType have actually been sent and are not buffered internally within the stream, awaiting additional output operations.e12jk40(635)\110f6b8f0B2f6b7f0B1f6b9f0B2f6b7f0B4f6b6f0B114f7b7f6 8f0B15f6b5f0B25f6b17f0B3f7b4f0B6f3 1f0i3I101f6b7f0B62f6b15f0B Stream.SetSST: PROCEDURE [ sH: Stream.Handle, sst: Stream.SubSequenceType];l5248d4268x4e12k40(988)\f7b7f6 8f7 10f6 6f7 7f6 13f7 7f6 This operation causes all subsequent bytes to have the indicated SubSequenceType. Even if the subsequent sequence of bytes is null (i.e., a call on SetSST is immediately followed by another), the SubSequenceType change demanded by this call will still be available to the receiver of the stream sequence.e12jk40(635)\65f6b15f0B69f6b6f0B42f6b15f0B Note: SubSequenceTypes are intended to be used to delineate different kinds of information flowing over the same stream (e.g. to identify control information, indicate end-of-file, etc.) The interpretation of a SubSequenceType value is a function of the particular stream.l4621d2999e12jk80(0,4608)\b5B1f6b15f0B191f6b15f0B Note: A SetSST operation specifying a SubSequenceType identical to the previous SubSequenceType is a no-op. Otherwise, SetSST always has the side effect of completing the current physical record, as explained in :A.4.l4621d2999e12jk80\b5B3f6b6f0B24f6b15f0B27f6b15f0B25f6b6f0B1i6I80f3 1f0i3I A.2.3 Attention Flagse24(635)\i The following operation causes an attention flag and an associated byte of data to be transmitted via the stream facility.e12j Stream.SendAttention: PROCEDURE [sH: Stream.Handle, byte:Stream.Byte];l5248d4268x4e12(988)\f7b6f6 16f7 10f6 5f7 6f6 14f7 7f6 Note that neither the attention flag nor the data byte occupy a byte in the stream sequence. They are out of band signals. Note also that an attention is not necessarily transmitted in sequence, but may bypass bytes and changes in SubSequenceType which were transmitted before it.e12j(635)\233f6b15f0B Note: This operation may have the side effect of completing the current physical record, as explained in :A.4. A client process will typically follow the SendAttention by a change in SubSequenceType or some recognizable pattern of bytes. This permits the recipient to identify where the SendAttention occurred.l4621d2999e12j(0,4608)\b5B100f3 1f0i3I46f6b13f0B16f6b15f0B90f6b13f0B Note: byte may be used by the client protocol to transmit other information regarding this attention.l4621d2999e12j\b5B1f6b4f0B The following operation awaits the arrival of an attention flag.e12j(635) Stream.WaitForAttention: PROCEDURE [sH: Stream.Handle] RETURNS [Stream.Byte];l5248d4268x4e12(988)\f7b6f6 19f7 10f6 5f7 6f6 9f7 8f6 1f7 6f6 When an attention is received on the stream sH, this procedure returns the byte of data associated with the attention. It is the responsibility of the client program to determine the appropriate action to take. If more than one attention flag has been sent, these will be queued by the stream. Each return from a call on WaitForAttention corresponds to precisely one attention sent by SendAttention.e12j(635)\44f6b2f0B278f6b16f0B48f6b13f0 1B Note: This operation is usually executed by a different process from that operating upon the stream. It returns as soon as the attention is received, whether or not all of the bytes preceding it in the stream have been transferred.l4621d2999e12j(0,4608)\b5B A.2.4 Timeoutse24jk80(635)\i Any of the operations of this section (except SendAttention and WaitForAttention) may fail to complete within a reasonable amount of time due to external conditions. For example, a stream operation on a Pup stream may fail because the process at the other end has terminated, aborted, or ceased to pay attention. In such a case the following signal is generated:e12jk40\46f6b13f0B5f6b16f0B Stream.TimeOut: SIGNAL [nextIndex: CARDINAL];l5248d4268x4e12k40(988)\f7b7f6 9f7 7f6 12f7 8f6 The parameter of this signal indicates the position within the block of bytes where the next byte would be placed. This signal may be resumed.e12jk40(635) Note: If this signal is RETRY'ed all previously received data may be lost. This is because it is likely that a stream component is performing internal bufferring (transferring data from its buffer into the client's block), and the action of RETRYing the SIGNAL may not tell the component that it must refill the client's block. Even if the component was informed of this fact, it may have discarded data already transferred into the client's block from its internal bufferl4621d2999e12jk80(0,4608)\b5B19f7b5f0B213f7b5f0B8f7b6f0B Caution: A catch phrase for this signal must not attempt any other stream operations using the same Stream.Handle, for this will corrupt the internal state information maintained for the stream.l4621d2999e12jk80\b8B92f7b7f6 6f0B A.3 Creating and Deleting Streamse24jk80(635)\i There are no general operations for creating streams. The reason for this is that the components of a stream -- i.e., pipelines, transducers, and filters -- must be able to take arbitrary parameters at the time they are created. It is not possible for the system to specify a general interface for their creation without either compromising the basic typesafeness of Mesa or constraining the flexibility and power of client-provided streams. Thus, the create function is implemented on a case-by-case basis, and clients must therefore refer to documentation for individual stream components for the correct interface for this operation. In this section, the general style is illustrated by means of a hypothetical example.e12jk40 For example, if a utility package implements a transducer to a particular device, it is obligated to provide a means by which other clients can create instances of that transducer, use them, and later delete them. Suppose the name of the interface module providing this function is DeviceStream. Then it would provide the following operation:e12jk40\283f6b12f0B DeviceStream.Create: PROCEDURE [ --optional parameters-- ] RETURNS [Stream.Handle, --optional other results--];l5248d4268x4e12k40(988)\f6b21f7 10f6 28f7 8f6 1f7 7f6 36f7 A client wishing to use the stream interface to access this device would thus call DeviceStream.Create, then use the Stream.Handle returned from it as a parameter to the stream operations of this chapter.e12jk40(635)\83f6b19f0B15f7b7f6 6f0B Similarly, a security package providing, say, an encryption facility might implement this by means of a filter for a stream. In this case, the interface might be called EncryptionFilter, and it would provide the following operation:e12jk40\170f6b16f0B EncryptionFilter.Create: PROCEDURE [Stream.Handle, --optional other parameters-- ] RETURNS [Stream.Handle, --optional other results--];l5248d4268x4e12k40(988)\f6b25f7 10f6 1f7 7f6 40f7 8f6 1f7 7f6 36f7 The client could easily couple an instance of this filter with the transducer above. This is done by calling EncryptionFilter.Create, passing as a parameter the Stream.Handle returned from DeviceStream.Create. Then the Stream.Handle returned from EncryptionFilter.Create would be the one used in GetBlock, PutBlock, and the other operations of :A.2. The net effect would be stream components which, on input, read bytes from the device, decrypt them, and pass them to the client and which, on output, encrypt the bytes supplied by the client and write them on the device.e12jk40(635)\110f6b23f0B29f7b7f6 6f0B15f6b19f0B12f7b7f6 6f0B15f6b23f0B26f6b8f0B2f6b8f0B30f3 1f0i3I In general, creating a filter accepts one Stream.Handle as a parameter and returns another as its result. Thus, several filters, each implementing a simple transformation, may be concatenated together to implement a more interesting transformation on the stream. The parameter passed to each one is the result returned from the adjacent one. Such a concatenation, called a pipeline, is illustrated in Figure A.1.e12jk40\42f7b7f6 6f0B321i8I <==