[Back to STRINGS SWAG index] [Back to Main SWAG index] [Original]

    {
    this unit implements a text-device that links to a PChar string. When you
    want to use a Pascal string, you can patch it, or convert your string to
    PChar before using it. An example is included.
    From: master@alterdial.uu.net (Nick Vermeulen)
    }
    Unit StrDev;
    (*
        This unit allows string manipulation with standard Read/Write proc's,
        using dataconversion and variable parameter-count as implemented by
        Read/Write proc's.

        example:

        Uses Strings, StrDev;

        Var  f: Text;
             s: Array[0..30] of Char;
             i: Integer;

        Begin
          AssignStrDevice(f, s, SizeOf(s));  { link s to f }
          Rewrite(f);                        { s will be overwritten }
          i := 12;
          Write(f, 'testing', i:12);         { write string + integer to s }
          Close(f);                          { NEEDED! buffer flushes to s }
          WriteLn(s);                        { show result }
          Append(f);                         { demonstrate appending }
          Write(f, 'appending!');            { try to make s smaller! }
          Close(f);
          WriteLn(s);
          StrCopy(s, '1 2 3');               { fill s with data }
          Reset(f);                          { open for reading }
          While not Eof(f) Do
          Begin
            Read(f, i);                      { read integers from s }
            WriteLn(i);
          End;
          Close(f);
        End.
    *)

    Interface

    Uses Strings, Dos;

    Procedure AssignStrDevice(var T: Text; aStr: PChar; aSize: Word);

    Implementation

    Type
      UData = Record          { typecasted over device's UserData (16 bytes) }
                Str  : PChar; { 4 bytes, string to use }
                Size : Word;  { 2 bytes, size of the string }
                p    : PChar; { 4 bytes, current pos in string }
                fill : array[1..6] of byte;
              End;

    Function WindowRead(var F: TextRec): Integer; far;
    {}
    Begin
      With F, UData(UserData) Do
      Begin
        BufEnd := StrEnd(Str)-p;
        If (BufEnd > BufSize) Then
          BufEnd := BufSize;
        BufPos := 0;
        StrLCopy(PChar(BufPtr), p, BufEnd);
        Inc(p, BufEnd);
        WindowRead := 0;
      End;
    End;

    Function WindowWrite(var F: TextRec): Integer; far;
    {}
    Begin
      With F, UData(UserData) do
      Begin
        StrLCopy(p, PChar(BufPtr), Size-(p-Str)-1);
        Inc(p, Size-(p-Str)-1);
        BufPos := 0;
      End;
      WindowWrite := 0;
    End;

    Function WindowOpen(var F: TextRec): Integer; far;
    {}
    Begin
      WindowOpen := 0;
      With F, UData(UserData) do
      Begin
        Case Mode of
          fmInput:
            Begin
              InOutFunc := @WindowRead;
              FlushFunc := nil;
              p         := Str;
            End;
          fmInOut:
            Begin
              InOutFunc := @WindowWrite;
              FlushFunc := nil;
              Mode      := fmOutput;
              p         := StrEnd(Str);
            End;
          fmOutput:
            Begin
              InOutFunc  := @WindowWrite;
              FlushFunc  := nil;
              p          := Str;
            End;
        End;
      End;
    End;

    Function WindowClose(var F: TextRec): Integer; far;
    {}
    Begin
      WindowClose := 0;
    End;

    Procedure AssignStrDevice(var T: Text; aStr: PChar; aSize: Word);
    {}
    Begin
      With TextRec(T), UData(UserData) do
      Begin
        Handle := $FFFF;
        Mode := fmClosed;
        BufSize := SizeOf(Buffer);
        BufPtr := @Buffer;
        Str := aStr;
        Size := aSize;
        OpenFunc := @WindowOpen;
        CloseFunc := @WindowClose;
      End;
    End;

    End.

[Back to STRINGS SWAG index] [Back to Main SWAG index] [Original]