• Keine Ergebnisse gefunden

Device-Independent 1/0

Im Dokument Standards Programming (Seite 50-63)

CTOS provides both device-dependent and device-independent I/O.

Device-independent I/O is easiest to use and most portable, but it has limited capabilities. Device-dependent I/O gives greater control over a given device, but limits the application to communication with a particular type of device.

For the purposes of this manual, device dependence refers to dependence on a type of device (such as video). It does not refer to dependence on a particular subtype of device (such as a bit-mapped monitor).

The Sequential Access Method (SAM)

The Sequential Access Method (SAM) provides a generalized, device-independent method of performing I/O. SAM allows a program to read input and write output in the same way, no matter what device the program is actually communicating with.

This lets you use the same subroutines to perform I/O to different physical devices, reducing the amount of new code a program requires.

Because the SAM interface is consistent across device types, it also allows input and output to be redirected.

Compatibility comes at a price, however. SAM routines generally take more execution time than equivalent, device-dependent routines.

Therefore, if execution speed is at a premium the device-dependent Basic Input and Output 2-1

routines may be more appropriate. In addition, if the application communicates with only a single type of device, the SAM routines require more memory than a single device-dependent procedure does.

What Is a Byte Stream?

The generalized method SAM uses for I/O is called a byte stream. A byte stream is exactly what its name implies: a series of bytes which a program reads or writes in sequential order. Byte streams can be used for input, for output, or for both. A byte stream must be opened before it is used, and should be closed when it is no longer needed.

An input byte stream can be read either until the reader chooses to stop reading or until the reader receives a nonzero status code (such as "end of file") in response to a read request. An output byte stream can be written until the writer chooses to stop, or until some physical boundary (such as a full disk) is encountered.

While all byte streams share a set of common procedures, SAM also provides a few device-dependent procedures for each type of byte stream.

These procedures allow a small amount of device dependent control for different types of byte streams.

Each byte stream requires a 130-byte byte stream work area (BSWA).

Some types of byte streams require an additional buffer area. A program can have any number of byte streams open at a time, but it must have a separate BSW A for each one.

Supported Byte Streams

CTOS supports most commonly-used byte streams automatically. You can also add new types of byte stream to your program, by customizing SAM. Customizing SAM is discussed in Part II, Chapter 17, "Building a Customized SAM." The byte stream device types supported by the operating system are listed below.

• [Vid] or [Vid]n

The video byte stream. [Vid] specifies video frame

o.

[Vid]n allows the program to specify any defined video frame. Video frames are

2-2 eTOS/ Open Programming Practices and Standards - Part I

discussed below in "Yideo Management - YAM and YDM." Yideo byte streams are write-only.

The video byte stream is pre-opened by the operating system, and can be accessed using the external array variable bs Vid as the BSWA.

• [Kbd]

The keyboard. This byte stream includes input from submit files and batch files. The keyboard byte stream is read-only.

The keyboard byte stream is pre-opened by the operating system, and can be accessed using the external array variable bsKbd as the BSWA.

• {Node} [Vol]

<

Dir>jilename

Any file identified by a full or partial file specification.

• [LPT]&jilespec

A Centronics-compatible printer connected to the parallel printer port. &jilespec is optional, and specifies a configuration file for the printer.

• [PTR ]n&jilespec

A serial printer attached to serial port n. As with the [LPT] device,

&jilespec is optional, and specifies a configuration file for the printer.

• [COMM]n&jilespec

Serial communications port n. &jilespec is optional, and specifies a configuration file for the communications port.

• [QICm]n or [TAPEj]k

Quarter-inch cartridge (QIC) tape drive m, tape file n, or half-inch tape drive j, tape file k.

Basic Input and Output 2-3

• {Node}{QueueNameJreportname

Spooler queue name. QueueName is the name of the scheduling queue for the spooler. The default is [SPL]. Reportname is a text string by which the entry is identified.

• [NUL]

The system Null device .. All input operations return status code 1 ("End of file"). All output operations return status code 0, but the output is discarded.

• [X2S]n&jilespec

X.2S virtual circuit, where n is the network identifier. &jilespec is optional, and specifies a configuration file that defines the virtual circuit's characteristics.

Device and File Specification Parsing

To determine the type of byte stream you want, SAM parses the device or file specification as follows:

1. It scans from left to right for an open-bracket symbol ('[').

If SAM does not find an open-bracket, it assumes the string is a file name, and opens or creates a file with that name.

If SAM does find an open-bracket symbol, it continues parsing the specification.

2. After it finds an open-bracket symbol, SAM tries to match the bracketed string to each of the reserved strings for system devices (for example, KBD).

If SAM finds a match, it attempts to open the requested device.

If SAM does not find a match, it continues parsing the specification.

2-4 eTaS/Open Programming Practices and Standards - Part I

3. Next, SAM checks for a left angle-bracket ('<').

If SAM finds one, it assumes the string is a file specification, and opens a disk byte stream.

If SAM does not find an angle-bracket, it assumes the string identifies a Generic Print System byte stream or a Spooler byte stream.

Using a Generic Byte Stream

Before using a byte stream, a program must open it. To do so, the program passes SAM the following information:

• a device or file specification for the byte stream

• a password, if required

• the byte stream mode (read, write, or both)

• the address of the byte stream's BSWA

• the address and size of the additional buffer, if required

After it opens the byte stream, the program can use it at will. The program should explicitly close the byte stream before exiting, however.

If a byte stream remains open when a program exits, the operating system closes the byte stream, but does not check that all the program's data was written to it.

Listing 2-1 shows the body of a simple program that reads input from the keyboard, echoes it to the screen, then writes the input to a byte stream of the user's choice. It uses the procedure, GetByteStream, to open the byte stream. It then uses another procedure, GetString, to obtain a string of characters from an input device. It then writes the characters to the byte stream. Finally, if the byte stream is a file, the procedure ReplaceLineFeeds replaces all line feeds with page breaks. The GetString and ReplaceLineFeeds procedures are defined later in this chapter.

Listing 2-2 shows the variable declarations for the byte streams used in Listing 2-1. The entire program listing can be found in Appendix D.

Basic Input and Output 2-5

GetByteStream (char *BSWA)

cbString = GetString(bsKbd, rgbString, STRSIZE);

if (cbString

>

0) [

erc = OpenByteStream (BSWA, rgbString, cbString, NULL, 0, MODIFYMODE,

rgMyBuffer,sizeof(rgMyBuffer»;

if (erc == ERCNOTIMPLEMENTED)

[ /* Mode modify not applicable, check write */

erc = OpenByteStream (BSWA, rgbString,

cbString, NULL, 0, WRITEMODE, rgMyBuffer, sizeof(rgMyBuffer»;

if (erc == ERCNOTIMPLEMENTED)

}

[ /* Mode write not applicable */

CheckErc (WriteBsRecord (bsVid, rgblnvalidBs, strlen(rgblnvalidBs),&cbRet»;

CheckErc (WriteBsRecord (bsVid, rgbString, cbString, &cbRet»;

CheckErc (WriteBsRecord (bsVid, rgbPrompt,

sizeof(rgbPrompt), &cbRet»;

continued ...

2-6 eTaS/Open Programming Practices and Standards - Part I

cbString

=

GetString (bsKbd, rgbString, STRSIZE);

if (cbString > 0) [

CheckErc (WriteByte (MyBSWA, LINEFEED»;

CheckErc (WriteBsRecord (MyBSWA, rgbString, cbString, &cbRet»;

Listing 2-1. A Sample Program Using Byte Streams

/* file access constants */

/* define my global variables */

char rgbString[STRSIZE]i /* general purpose string */

char MyBSWA[130]i int cbStringi

Word rgMyBuffer[S12]i char rgbBsPrompt[] =

"\nType a device or file spec for the Byte Stream you want."

"\nPress CANCEL if you make a mistake: "i

char rgbExit[]

=

"\n\nPress GO to confirm FINISH, or CANCEL to continue."i

char rgbInvalidBs[]

=

"\n\nBytestream is invalid for output: "i

char rgbPrompt[]

"\n\nType a character string, then press RETURN:

Listing 2-2. Variable Declarations for Byte Streams

Using Byte Streams for File Access

"

I

.

Byte streams are commonly used to read and write sequential data files.

The program in Listing 2-1 could be used for that purpose.

Byte streams which access files also have two device dependent procedures available to them: GetBsLfa, and SetBsLfa. These procedures let a program determine and change the current Logical File Address (LF A) of a byte stream in a file. The Logical File Address is simply the offset, in bytes, of the current file position from the beginning of the file. The first byte in the file has an LF A of zero.

Listing 2-3 shows a procedure from the generic byte stream program.

This procedure converts all line feeds in a file byte stream to form feeds.

2-8 eTaS/Open Programming Practices and Standards - Part I

ReplaceLineFeeds (char *BSWA) ( char bIni

ErcType erCi long Lfai

/* flush my buffers */

CheckErc (CheckPointBs (BSWA»i erc

=

GetBsLfa (BSWA, &Lfa)i

if (erc

==

ERCOK) { /* i t ' s a file */

CheckErc (SetBsLfa (BSWA, O»i erc

=

ReadByte (BSWA, &bIn)i while (erc

==

ERCOK) {

if (bIn

==

LINEFEED) {

/* change this to a form feed just for fun */

CheckErc (GetBsLfa (BSWA, &Lfa»i CheckErc (SetBsLfa (BSWA, (Lfa - l»)i CheckErc (WriteByte (BSWA, FORMFEED»i

)

/* get the next character */

erc = ReadByte (BSWA, &bln)i )

else if (erc != ERCINVALIDBSWA)

ErrorExit (erc)i /* something is wrong */

/* flush the buffer and close the file */

CheckErc (CloseByteStream(BSWA»i )

Listing 2-3. Positioning a Byte Stream in a File

Using Byte Streams for Video Access

Video byte streams have one device dependent procedure, QueryVidBs, which returns information about the current state of the video byte stream. However, video byte streams can also use escape codes to modify the state of the byte stream. Escape codes allow the program to perform the following functions:

• control screen display attributes

• control character display attributes

• control scrolling and cursor position

Basic Input and Output 2-9

• control cursor visibility

• redirect the video byte stream to a different video frame

• enable or suppress a pause between screen-fulls of text

See Appendix D in the CTOS/Open Application Programming Interface Specification for a detailed description of the available byte stream escape sequences.

In addition, for simple byte stream video 110, eTOS provides the OutputToVidO procedure. This procedure outputs a text string to the current cursor position in video frame 0 (the default text frame), and is useful for displaying simple text messages.

Listing 2-4 shows a procedure that lets a user type an escape code, then sends that escape code to the video device. If the first character typed is an 'E', the rest of the string is interpreted as an escape code, otherwise the string is displayed as typed by the user.

PrintEscape (char *rgbEscape, char cbEscape) { char i, nCol, nFrame, nLinei

ErcType erCi

Word cbReti

/* save the current cursor location */

CheckErc (QueryVidBs (bsVid, &strVidStatus»i nFrame

=

strVidStatus.nFramei

nCo I

=

strVidStatus.nColi nLine = strVidStatus.nLinei

/* change to frame 0 (working frame) */

CheckErc (WriteBsRecord (bsVid, escToFrameO,

sizeof(escToFrameO), &cbRet»i /* now print out the user entered escape sequence */

CheckErc (WriteByte (bsVid, ESCAPE»i for (i

=

Oi i

<

cbEscapei i++) [

erc

=

WriteByte (bsVid, *(rgbEscape+i»i if (erc

==

ERCINVALIDVIDESCAPE) [

/* change to frame I (title frame) */

CheckErc (WriteBsRecord (bsVid, escToFrame1,

sizeof(escToFramel), &cbRet»i /* print out error message */

CheckErc (WriteBsRecord (bsVid, rgblnvEscape,

strlen(rgblnvEscape) , &cbRet»i return (-l)i

)

continued ...

2-10 CTOS/Open Programming Practices and Standards - Part I

/* output the sample string */

CheckErc (WriteBsRecord (bsVid, rgbTest, strlen(rgbTest),

&cbRet) ) ;

CheckErc (WriteBsRecord (bsVid, rgbEscape, 3, &cbRet»;

/* reset the cursor post ion */

rgbEscape[l]

=

COLSET;

rgbEscape[2] = nCol;

rgbEscape[3] = nLine;

CheckErc (WriteBsRecord (bsVid, rgbEscape, 4, &cbRet»;

return (0);

CheckErc (WriteBsRecord (bsVid, rgbPrompt,

sizeof(rgbPrompt), &cbRet»;

cbString

=

GetString(bsKbd, rgbString, STRSIZE);

if (cbString

>

0)

rgbEscape[j] = atoi (pString);

j++;

while (isdigit (rgbString[i]) != FALSE) i++;

) else i++;

) /* end while rgbString[i] */

rgbEscape[j] = 0; /* null-terminate i t */

PrintEscape(rgbEscape, j);

) /* end if i t starts with E */

else CheckErc (Beep (»;

) /* end if strsize

>

0 */

while (cbString != 0);

return(O);

)

Listing 2-4. Sending Escape Codes to Video

Using Byte Streams for Keyboard Access

There are no device-dependent procedures for keyboard byte streams, but keyboard byte streams return the following status codes when the Finish and Cancel keys are pressed .

• Finish (ASCII value 04) returns status code 1 ("End of file").

• Cancel (ASCII value 07) returns status code 4 ("Operator intervention").

Listing 2-5 shows a simple procedure that gets a string from the keyboard using a keyboard byte stream. Notice that the CheckErc procedure is not used when reading from a byte stream, because CheckErc causes the program to exit if it receives any status code other than zero.

2-12 eTOS/Open Programming Practices and Standards - Part I

GetString(char *BSWA, char *rgb, Word cbMax) {

CheckErc (NlsClass (NULL, bIn, &class»i if (class <= 2)

[ /* valid character, echo i t out */

CheckErc (WriteByte (bsVid, bIn»i rgb[i] = bIni

Other Uses for Byte Streams

Byte streams can be used for almost any type of I/O. Other common types of byte streams that this chapter does not discuss are printer I/O and communication port I/O.

In addition, you can create new instances of the standard byte stream procedure calls for special devices. For example, you could write byte stream procedures to communicate with a magnetic card reader, then link them with your program. The program could then use the standard byte stream interface for I/O, but use a device called [CardRdr], or something similar.

For more information on defining new byte streams, see Part II, Chapter 17, "Building a Customized SAM."

Im Dokument Standards Programming (Seite 50-63)