• Keine Ergebnisse gefunden

Device-Specific 1/0

Im Dokument Standards Programming (Seite 63-74)

When the Sequential Access Method procedures are not able to perform the functions you need, you can use a second layer of I/O procedures.

These procedures are more specific to the I/O device, and are therefore less portable.

File Management

CTOS provides a direct interface to the file system, as do almost all operating systems. Most programs use the byte stream interface unless they use a structured file format. In some cases, however, using the direct file system calls may be more efficient.

Listing 2-6 shows a procedure that opens a file using the direct file calls.

The procedure first assumes the file exists and tries to open it. If the file does not exist, the procedure creates it. Listing 2-7 shows a procedure that writes to a previously opened file using the direct file calls. A listing for the program that contains both procedures can be found in Appendix D.

Note that the procedure in Listing 2-7 assumes the existing End-of-File pointer is divisible by 512. If it is not, the procedure will fail. Normally, as in the example, a program saves entire files at a time when it uses the direct file calls. Therefore, only the last call to the procedure results in 2-14 eTOS/Open Programming Practices and Standards - Part I

an End-of-File pointer that may not be divisible by 512: the true end of the file.

Word GetFile () ( ErcType erc;

Word fh, cbRet;

DWord qZero = 0;

do (

CheckErc (WriteBsRecord (bsVid, rgbBsPrompt,

sizeof(rgbBsPrompt),&cbRet»;

cbString

=

GetString(bsKbd, rgbString, STRSIZE);

if (cbString

>

0) (

erc

=

OpenFile(&fh, rgbString, strlen(rgbString) , NULL, 0, MODIFYMODE);

if{erc == ERCNOSUCHFILE) ( /* create the file */

CheckErc(CreateFile(rgbString,

strlen(rgbString),NULL,O,O»;

continued ...

CheckErc(OpenFile(&fh, rgbString,

strlen(rgbString), NULL, 0, MODIFYMODE) );

else (

CheckErc(erc);

/* reset file size and EOF pointer */

CheckErc( SetFileStatus(fh, 6, &qZero, sizeof (qZero» );

CheckErc( ChangeFileLength(fh, qZero) );

)

else ( /* empty string, go get another one */

CheckErc (WriteByte (bsVid,LINEFEED»;

erc

=

ERCBOGUS;~ /* set error so we can loop back */

) )

while (erc != 0); /* if they make a mistake, ask again */

return ( fh) ; )

Listing 2-6. Opening a File

Basic Input and Output 2-15

void StoreData(Word fhMyHandle, Word cBytes) { DWord qEOFPtri

DWord Ifai Word sDataReti

/* get current Ifa and EOF pointer */

CheckErc( GetFileStatus(fhMyHandle,O,&lfa,sizeof(lfa» )i CheckErc( GetFileStatus(fhMyHandle, 6, &qEOFPtr,

sizeof(qEOFPtr» )i

/* increase file size */

Ifa += 512i

CheckErc( ChangeFileLength(fhMyHandle, Ifa ) )i CheckErc( Write(fhMyHandle, rgbMyBuffer, SMYBUFFER,

qEOFPtr, &sDataRet) )i

/* reset EOF pointer */

qEOFPtr += cBytesi

CheckErc( SetFileStatus(fhMyHandle, 6, &qEOFPtr, sizeof(qEOFPtr» )i

Listing 2-7. Writing to a File

Wild Cards

CTOS provides two procedures to ease wildcard processing. CTOS defines two wildcard characters: ,*, and '?'. The asterisk ('*') indicates that any string of 0 or more characters can be inserted at that position in the string and considered a match. The question mark ('?') indicates that any single character can be inserted at that Iposition in the string and considered a match.

The Executive normally expands wildcards on a command form automatically, but if a program needs to read a file specification from another source, it should be prepared to handle wildcards. Listing 2-8 shows a simple routine that displays a list of files that match an entered file specification.

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

ErcType ListMatches (char *pFs) { EreType ere

=

0;

sdType sdFs;

Word *pBuffer;

Word ebRet;

sdFs.pb

=

NULL;

sdFs.eb

=

0;

if «pBuffer = malloe (MEMSIZE»

ErrorExit(ERCINSUFFMEM);

NULL)

/* initialize the wild card expansion environment */

CheekEre (WildCardlnit (pFs, strlen(pFs), pBuffer, MEMSIZE) );

while (ere

==

ERCOK) {

/*get next file matching the wild card speeifieation*/

ere

=

WildCardNext (pBuffer, &sdFs);

if (ere

==

ERCOK) [

CheekEre (WriteBsReeord (&bsVid, sdFs.pb, sdFs.eb,

&ebRet) ) ; CheekEre (WriteByte (&bsVid, RETURN»;

}

else if (ere

==

ERCEOF) return(O);

else return (ere);

}

Listing 2-8. Building a List of File Names from a Wildcard

Temporary Files

When a program makes use of temporary files, it should create them in the current volume's <$> directory. This directory is reserved by the operating system for temporary files. The operating system also performs a file name translation to prevent multiple instances of the same program from trying to use the same temporary file name.

When a program opens a file <$> Foo.tmp, the operating system expands the file specification to <$OOO>nnnnn> Foo.tmp, where nnnnn is the user number for that partition. This expansion is invisible to the program, so the program can always use the same temporary file name.

Basic Input and Output 2-17

Because the user numbers at a cluster workstation are reassigned whenever the workstation is booted, you should never use the <$>

directory for permanent files.

Keyboard Management

Using byte streams to read the keyboard is a relatively inefficient process.

A program incurs all the byte stream overhead, but usually ends up reading one keystroke at a time. Using the keyboard-specific operations is more efficient and more flexible.

An application can read from the keyboard in either of two modes. The first, encoded mode, is the simpler one. In encoded mode, the application simply receives an ASCII character code whenever the user types one. The operating system makes the state of any special keys, such as Code or Shift, transparent to the application.

In un en coded mode, however, the application receives a keyboard code whenever a key is pressed or released. It is the application's responsibility to track and account for the states of any special keys. For example, the keyboard events that would return the character 'A' in encoded mode could return the following keyboard codes in unencoded mode:

• Left shift key depressed.

• 'A' key depressed.

• 'A' key released.

• Left shift key released.

Reading the keyboard in encoded mode is easier, but somewhat less flexible, than unencoded mode.

Listing 2-9 shows a modified version of the GetString procedure used in earlier listings. This procedure reads directly from the keyboard, in encoded mode. The procedure no longer uses byte streams, and now uses the TextEdit procedure to evaluate the entered character. TextEdit is a preferred method of processing keyboard input, since it handles most special keys for its client application.

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

/* read a string from the keyboard, echo i t to a video

CheckErc (PosFrameCursor (iFrame, iCurCol, iCurLine»;

/* get the chars */

CheckErc (PosFrameCursor (iFrame, ESCAPE, ESCAPE»;

return(textBlock.cchMac);

case HELP:

/* turn off cursor */

CheckErc (PosFrameCursor(iFrame, ESCAPE, ESCAPE»;

DisplayHelp ();

case FlO:

/* tell them they pressed a function key */

PrintMsg (rgbFuncKeyMsg)i CheckErc (ReadKbd (&bIn) )i

PrintMsg (NULL)i breaki

default:

/* add the char to the string if i t ' s a valid char */

ere

=

TextEdit (bIn, tbPtr)i /* beep if i t isn't */

if (ere != 0) [

CheckErc (Beep ( ) ) i

breaki }

/* display the modified TextEdit buffer, and move the cursor */

CheckErc (PutFrameChars (iFrame, iCurCol, iCurLine, textBlock.prgch, textBlock.cchMax))i CheckErc (PosFrameCursor (iFrame, (iCurCol +

textBlock.ichCursor), iCurLine))i breaki

} /* end of switch */

} /* end of while */

return(O)i }

Listing 2-9. Procedure to Read a String from the Keyboard

Video Management - VAM and VDM

Video byte streams are the simplest video interface to use, but they allow little more than line-oriented output. The Video Access Method (V AM) and Video Display Management (VDM) allow a program to use multiple display frames, and to control how those frames appear on the screen.

Before a program can use V AM and VDM, it must set up its screen. To do so, the application must perform the following steps in the order shown below:

1. Call QueryVidHdw to determine the workstation's video capabilities.

2. (Optional) Call LoadFontRam to load a customized screen font.

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

3. Call ResetVideo to initialize the video control structures.

4. Call InitVidFrame to initialize each display frame the application will use.

5. (Optional) Call SetScreenVidAttr to set reverse video or half-bright video.

6. Call InitCharMap to initialize the character map.

7. Call SetScreen VidAttr to set the screen refresh attribute.

Listing 2-10 shows the standard setup procedures used for V AM and VDM. The program first resets the screen, then establishes its own screen display, consisting of several display frames. A program that uses this procedure can be found in Appendix D.

Note that the procedure uses the values returned by QueryVidHdw to set global values for the number of rows and columns on the screen. Note also that the procedure computes the number of lines in a frame based on those returned values. Because different hardware may support different numbers of rows or columns on the screen, these values should always be considered variable.

void Initvideo ()

Word cb, sMapi /* counter, char map */

Byte rgbVidHdw[3]i

/* find out the screen size */

CheckErc (QueryVidHdw (&rgbVidHdw, sizeof(rgbVidHdw»)i nLines rgbVidHdw[l]i

nCols rgbVidHdw[2]i /* reset the screen */

CheckErc (ResetVideo (nCols, nLines, TRUE, Ox20, &SMap»i /* set the size of frame

°

*/

sFrameO

=

nLines - 6i

/* Initialize the frames */

CheckErc (InitVidFrame (MAINFRAME,O,3,nCols,sFrameO,O, THINBORDERCHAR,O,O,O»i

CheckErc (InitVidFrame (TITLEFRAME,O,O,nCols,3,O, THICKBORDERCHAR,O,O,O»i

continued ...

Basic Input and Output 2-21

CheckErc (InitVidFrame (MSGFRAME,0,nLines-2,nCols,1,0,0, 0,0,0»;

CheckErc (InitVidFrame (FKEYFRAME,0,nLines-3,nCols,3,0,0, 0,0,0) );

CheckErc (InitVidFrame (HELPFRAME,0,nLines-6 ,nCols, 3,0, 0,0,0,0»;

CheckErc (InitCharMap (0, sMap»;

CheckErc (SetScreenVidAttr (REFRESH, TRUE»;

/* reset the frames */

CheckErc (PutFrameChars (TITLEFRAME, «nCols-cb)/2), 0, rgbTitle, cb»;

/* display the frame border */

cb = sizeof (rgbOut);

memset (&rgbOut, THINBORDERCHAR, cb);

CheckErc (PutFrameChars (TITLEFRAME, 0, 2, rgbOut, cb»;

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

case 71:

rgbOut[i] VERTICALBAR;

break;

default:

rgbOut[i]

=

rgbFkeys[i];

}

/* display the function keys */

cbOut = sizeof (rgbOut);

CheckErc (PutFrameChars (FKEYFRAME, 0, 2, rgbOut, cbOut) ) ;

/* display the frame border */

memset (&rgbOut, THICKBORDERCHAR, cbOut);

CheckErc (PutFrameChars (FKEYFRAME, 0, 0, rgbOut, cbOut) ) ;

for (i = 0; i <= 2; i++)

CheckErc (PutFrameAttrs (FKEYFRAME,

rgCol[i] .FKeyStart, 2, HALFBRITEREVERSE, rgCol[i] .FKeyCount»;

Listing 2-10. VAM and VDM Setup Procedure

Basic Input and Output 2 - 23

3

Im Dokument Standards Programming (Seite 63-74)