*/
Love this site? Hate it? Leave us some comments.
*/

View \TEXTIO.PAS

Demonstration of useful text I/O features with turbo pascal:

Submitted By: WEBMASTER
Rating: (Not rated) (Rate It)


unit TextIO;

{  useful text i/o features with turbo pascal:

     1. large text buffers for speedier handling when needed
     2. complete seek function for text files
     3. write formatted output to a string variable
     4. read contents of a string variable as formatted input
     5. backup to the previous line of a file (if possible)

   language:  turbo pascal macintosh "(*MAC-  -MAC*)" comments
         or:  turbo pascal 4.0 ibm.  "(*IBM-  -IBM*)" comments

   by d.g.gilbert
   dogStar software
   po box 302, bloomington, in 47402
   compuserve  71450,1570

   Translated to a unit by Mike Babulic,  (Jan.25,1989)
                           3827 Charleswood Dr. N.W.
                           Calgary, Alberta, CANADA
                           T2L 2C7
                           compuserve: 72307,314

        NOTE:  1) This unit has been created and tested on MS/DOS only.
        -----     Porting to the Macintosh will involve some modification,
                  especially for new additions like "BackLn".

               2) Obviously if you do "interesting" things in your programs
                  you can expect some side-effects the authors couldn't
                  possibly forsee. Be careful!


   MODIFICATION LOG
   ----------------

     88/01/25 - Turned demo program into a unit. (Babulic)

     88/01/27 - BackLn procedure added. (Babulic)
}



interface

{$R-}   { Turn off range checking       }
{$I-}   { Turn off I/O error checking   }

(*IBM-*)
   USES  DOS;

   TYPE
        chars   = PACKED ARRAY [0..maxint] OF char;
        bufferPtr = ^chars;
        procPtr   = pointer;

        tpFileRec = RECORD            {turbo pascal ibm text file record}
          handle   : word;
          mode     : word;
          fBufSize : word;
          private  : word;
          fBufPos  : word;
          fBufEnd  : word;
          fBuffer  : bufferPtr;
          openFunc : procptr;
          inOutFunc: procptr;
          flushFunc: procptr;
          closeFunc: procptr;
          userdata : PACKED ARRAY[1..16] OF byte;
          name     : PACKED ARRAY [0..79] OF char;
          tbuffer  : PACKED ARRAY [0..127] OF char; { default buffer}
          END;
(*-IBM*)
(*MAC-
   USES  memTypes, quickDraw, osIntf, toolIntf;

   TYPE
      chars   = PACKED ARRAY [0..maxint] OF char;
      bufferPtr = ^chars;
      pointer = ^integer;

      tpFileRec   = RECORD            {turbo pascal mac file record }
          fInpFlag: boolean;
          fOutFlag: boolean;
          fRefNum : integer;
          fVrefNum: integer;
          fBufSize: integer;
          fBufPos : integer;
          fBufEnd : integer;
          fBuffer : bufferPtr;
          fInOutProc: procPtr;
          END;
-MAC*)


CONST
      forOutput = true; forInput = false;



FUNCTION openText( VAR f: text;
         fname : STRING;
         output: boolean{true if want a rewrite }
         bufsize: integer
         ): boolean;     { true if opened successfully }

PROCEDURE closeText( VAR f: text);

FUNCTION PosText(VAR f:text):LongInt;


TYPE seekType = (seek_set, seek_cur, seek_end);

PROCEDURE seekText( VAR f: text; offset: longInt; seekFrom : seektype);
  { seek for textfiles }


procedure BackLn(var f:Text);


PROCEDURE openStrIO( VAR f: text; VAR s: STRING; out: boolean);
  { assign file input/output to string. }

PROCEDURE closeStrIO( VAR f: text; VAR s: STRING);
  { close stringiO: get length }


{==========================================================================}

implementation


(*IBM-*)
FUNCTION msDosSeek( fh:integer; index:longint; fromwhere:seekType):LongInt;
{ move file pointer to byte index (hiIndx,lowIndx), respective to fromWhere }
TYPE  long = record lo,hi:word end;
VAR  reg : registers;
     l   : long;
BEGIN WITH REG DO BEGIN
  ah:= $42; { move f^ }
  al:= ord(fromwhere);
  cx:= long(index).hi; {hiindex}
  dx:= long(index).lo; {lowIndex}
  bx := fh;
  msdos(reg);
  IF 0 = (reg.flags AND $01) THEN
    msdosSeek:= 0
  ELSE BEGIN
    l.hi:= dx;
    l.lo:= ax;
    msdosSeek := longint(l);
  END;
END  END; { msDosSeek }
(*-IBM*)

{--------------------------------------------------------------------------}

FUNCTION openText( VAR f: text;
         fname : STRING;
         output: boolean{true if want a rewrite }
         bufsize: integer
         ): boolean;     { true if opened successfully }

VAR  abuf: pointer;
     err: integer;
BEGIN

(*IBM-*)
    assign( f, fname);
   { now change buf to the size we want}
    WITH tpfilerec(f) DO BEGIN
      getmem( abuf, bufsize);
      fBuffer:= abuf;
      fBufSize:= bufsize;
      END;
    IF output THEN rewrite( f) ELSE reset(f);
    err:= ioresult;
    IF err <> 0 THEN dispose(abuf); {forget it}
    openText:= err = 0;
(*-IBM*)
(*MAC-
    IF output THEN rewrite( f, fname, bufsize)
    ELSE reset( f, fname, bufsize);
    openText:= ioresult = 0;
-MAC*)

END; {openText}

PROCEDURE closeText( VAR f: text);
VAR  abuf: pointer;
BEGIN
(*IBM-*)
       abuf:= tpfilerec(f).fBuffer;
       close(f);
       dispose(abuf);
(*-IBM*)
END;


FUNCTION PosText(VAR f:text):LongInt;
  TYPE  long = record lo,hi:word end;
  VAR  reg : registers;
       p   : longint;
       l   : long  ABSOLUTE p;
  BEGIN
    WITH REG DO BEGIN
      ah:= $42; { move f^ }
      al:= ord(seek_cur);
      cx:= 0;
      dx:= 0;
      bx := tpfilerec(f).handle;
      msdos(reg);
      l.hi:= dx;
      l.lo:= ax;
    END;
    WITH tpfilerec(f) DO BEGIN
      IF mode=fmOutput THEN
        PosText := p + fBufPos
      ELSE
        PosText := p - fBufEnd + fBufPos;
    END
  END;


(*IBM-*)
CONST strFileName = '$%#temp.tmp';
CONST needStrFile: boolean = true; {1st time open tempFile }
VAR   strFile    : text; {.ibm -- save file i/o information for strIO}
(*-IBM*)

PROCEDURE openStrIO( VAR f: text; VAR s: STRING; out: boolean);
{ assign file input/output to string. }
BEGIN

(*IBM-*)
   IF needStrFile THEN BEGIN
     assign(strFile, strFileName);
     rewrite(strFile); {<< need this to fill in valid turbo proc ptrs}
     tpfilerec(f):= tpfilerec(strFile);
     close(strFile); erase(strFile);
     tpfilerec(strfile):= tpfilerec(f);
     needStrFile:= false;
     END;
   tpfilerec(f):= tpfilerec(strFile);
   WITH tpFileRec(f) DO BEGIN
     IF out THEN mode:= fmOutput ELSE mode:= fmInput;
     END;
(*-IBM*)
(*MAC-
   WITH tpfilerec(f) DO BEGIN
     fInpFlag:= NOT out;
     fOutFlag:= out;
     fRefNum:= 1; {dummy}
     fVrefNum:= 1;
     fInOutProc:= NIL;
     END;
-MAC*)

   WITH tpFileRec(f) DO BEGIN
     fBuffer:= @s[1];
     fBufSize:= 255; {assume it is full string}
     IF out THEN fBufEnd:= fBufSize
     ELSE fBufEnd:= length(s);
     fBufPos:= 0;
     END;
END; {openStrIO}

PROCEDURE closeStrIO( VAR f: text; VAR s: STRING);
{ close stringiO: get length }
VAR  err: integer;
BEGIN
   s[0]:= chr( tpFileRec(f).fBufPos);
END; {closeStrIO}




PROCEDURE seekText( VAR f: text; offset: longInt;
            seekFrom : seektype);
{ seek for textfiles }
VAR
   count: longint;
   iseek: integer;
   err  : integer;
(*IBM-*)
   uf   : FILE;
BEGIN
  WITH tpFileRec(f) DO BEGIN
   offset := offset + fBufPos;
   IF handle<0 THEN {nada - not a disk file}
   ELSE IF (seekFrom=seek_cur) and (offset>=0)
           and (  (mode=fmInput) and (offset<fBufEnd)
               or (mode=fmOutput) and (offset<=fBufPos)) THEN
     fBufPos := offset
   ELSE BEGIN
    offset := offset - fBufPos;
    IF mode = fmOutput THEN BEGIN
     { flush buffer to disk if seek on output file}
      move(f, uf, sizeof(uf));    { need right file type for blockwrite}
      fileRec(uf).recsize:= 1;
      blockwrite( uf, fBuffer^, fBufPos, err);
      fBufPos:= 0;
      END;
    IF seekFrom = seek_cur THEN
      offset:= offset - fBufEnd + fBufPos;
    IF 0 = msdosSeek( handle, offset, seekFrom) THEN BEGIN
      fBufPos:= 0; fBufEnd:= 0; {next read/write will fill buffer as needed}
      END;
   END;
  END; {with}
(*-IBM*)
(*MAC-
BEGIN
  CASE seekFrom OF
    seek_set : iseek:= fsFromStart; {offset from 0}
    seek_cur : iseek:= fsFromMark;
    seek_end : iseek:= fsFromLEOF;
    END;
  WITH tpFileRec(f) DO
   IF fRefNum=0 THEN {not a disk file}
   ELSE BEGIN
    IF fOutFlag THEN BEGIN { flush buffer to disk if seek on output file}
      count:= fBufPos;
      err:= fsWrite( fRefNum, count, ptr(fBuffer));
      fBufPos:= 0;
      END
    ELSE IF seekFrom = seek_cur THEN
      offset:= offset - fBufEnd + fBufPos;
    IF 0 = setFpos( fRefNum, iseek, offset) THEN BEGIN
      fBufEnd:= 0; fBufPos:= 0;
      END;
   END;
-MAC*)

END; {seekText}



procedure BackCh(var f:Text);
  var  p,q: longint;
       ch: char;
  begin with tpFileRec(f) do begin
    if fBufPos>0 then
      SeekText(f,-1,seek_cur)
    else
    {
      if mode=fmOutput then begin
        SeekText(f,-1,seek_cur);
       end
      else }
begin
        p := PosText(f) - 1;
        q := p - fBufSize;
        if q<0 then q := 0;
        SeekText(f,q,seek_set);
        read(f,ch);
        SeekText(f,p-1,seek_cur);
      end;
  end  end;

procedure BackLn(var f:Text);
  var ch: char;
      p:  longint;
      uf: File;
  begin
    BackCh(f); {Skip LF}
    BackCh(f); {Skip CR}
    if tpFileRec(f).mode=fmInput then begin
      REPEAT
        BackCh(f);
      UNTIL eoln(f);
      if eof(f) then
        SeekText(f,0,seek_set)
      else
        ReadLn(f);
     end
    else with tpFileRec(f) do begin
      reset(f);
      SeekText(f,0,seek_end);
      p := PosText(f);
      BackLn(f);
      p := PosText(f);
      close(f);
      append(f);
      IF 0 = msdosSeek( handle,p,seek_set) THEN BEGIN
        fBufPos := 0; fBufEnd := 0;
        END;
    end;
  end;


END.

corner
© 1996-2008 CommunityHeaven LLC. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
North American business development: Nicolai Wadstrom. Publisher: Lars Hagelin.