* * *

Author Topic: Standard Input to stream  (Read 2126 times)

Kunstbanause

  • New member
  • *
  • Posts: 47
Standard Input to stream
« on: October 30, 2008, 09:21:58 am »
Hi,

I currently use the following code to get the standard input at the start of a console program:
Code: [Select]

var
  c: char;
  s: string;
  t: text;
begin
  s := '';
  AssignFile(t, '');
  Reset(t);

  while not eof(t) do
  begin
    Read(t, c);
    s := s + c;
  end;
end.


Is there a way to access standard input as a stream?

Zaher

  • Sr. Member
  • ****
  • Posts: 392
    • http://www.parmaja.com
RE: Standard Input to stream
« Reply #1 on: October 30, 2008, 02:54:24 pm »
Search for PIPE in FPC source.

Leledumbo

  • Hero Member
  • *****
  • Posts: 2997
RE: Standard Input to stream
« Reply #2 on: October 31, 2008, 04:03:21 am »
Can't you use TIOStream?

Kunstbanause

  • New member
  • *
  • Posts: 47
Re: RE: Standard Input to stream
« Reply #3 on: October 31, 2008, 11:57:57 am »
Quote from: "Leledumbo"
Can't you use TIOStream?


I tried TIOStream. But there's a problem.
I use the following code:

Code: [Select]
program project1;

{$mode objfpc}{$H+}

uses
  Classes, SysUtils, iostream;

var
  mem: TMemoryStream;
  ios: TIOStream;
begin
  ios := TIOStream.Create(iosInput);
  mem := TMemoryStream.Create;
  mem.CopyFrom(ios, 0);
  ios.Free;
  WriteLn(Format('Size of mem: %d', [mem.Size]));
  mem.Free;
end.


The output is:

Code: [Select]
$ ls | ./project1
Size of mem: 0
$ ls | wc -c
223

Chronos

  • Jr. Member
  • **
  • Posts: 76
    • PascalClassLibrary
Re: Standard Input to stream
« Reply #4 on: December 25, 2011, 11:39:20 pm »
Now I want to do same thing and problem is that standard input is rather queue/pipe than seekable stream and property InputStream.Size which use Seek to get size will fail. It is necessary to fetch available data using Read method which return actual read count. Stream CopyFrom method with Count = 0 will determine size using Size property.

Code for copy input to stream using buffer:

Code: [Select]
uses
  iostream, ...;
var
  Buffer: string;
  Count: Integer;
  MyStream: TMemoryStream;
  InputStream: TIOStream;
begin
  MyStream := TMemoryStream.Create;
  try
    InputStream := TIOStream.Create(iosInput);
    SetLength(Buffer, 10000);
    repeat
      Count := InputStream.Read(Buffer[1], Length(Buffer));
      if Count > 0 then MyStream.Write(Buffer[1], Count);
    until Count = 0;
  finally
    InputStream.Free;
  end;
  ...

felipemdc

  • Administrator
  • Hero Member
  • *
  • Posts: 3165
Re: Standard Input to stream
« Reply #5 on: December 26, 2011, 02:26:30 am »
Is there a way to access standard input as a stream?

There is one section in the Lazarus book in one of my chapters dedicated to that. But in short, you just need to do this:

Code: [Select]
MyStream := THandleStream.Create(StdInputHandle);

Chronos

  • Jr. Member
  • **
  • Posts: 76
    • PascalClassLibrary
Re: Standard Input to stream
« Reply #6 on: December 27, 2011, 01:45:14 am »
TIOStream is descendant of THandleStream and problem is how to get size of stream because TStream.Size method determine size using seek from end of stream which means change position in stream and standard input doesn't have start and end. All data readed from input stream is lost. Seeking from current position to end of stream means that all data are lost and this is probably reason why Kunstbanause example doesn't work. CopyFrom with zero count means "get count from size".

Standard input should be rather queue than seekable stream. Stream is good for positionable media as tape, disk or file. And stream may not have limited size and than it would be unlimited stream. Another situation is with buffered stream where one would want to read all currently buffered data at once. Not limited to size but somehow determine size of internal buffered data and read them all. And avoid repeated reading in small chunks or maybe one byte by one.

I am solving this problem for handling of CGI application where I need to read available data from input stream passed by apache web server. Another problem would be persistent connection with HTTP 1.1 and server more requests per connection.

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads