June 25, 2004
In article <cbh3le$1o0j$1@digitaldaemon.com>, Ben Hinkle says...

>> 3) FileMode.In and FileMode.Out should be renamed Filemode.IN and Filemode.OUT respectively.
>
>why not FileMode?

Sorry, that was a typo. I meant FileMode.IN and FileMode.OUT.

It was the IN and OUT that I wanted to suggest changing, not FileMode. (Although in hindsight, perhaps it should be Stream.IN and Stream.OUT anyway).

Jill


June 25, 2004
Regan Heath wrote:
> Lets assume for the sake of it that we're talking about a FileStream.. so.. you open it, then you call available() it returns 0 as there is nothing in the buffer.. yet.. you (return immediately) and do something else.. at which point does the stream actually read something into it's buffer?
When you tell it to :-P
The point is that available() is simply a request for information about the stream, _without_ telling it to do any work.
Sam
June 25, 2004
Ben Hinkle wrote:

>>2) File should in any case be renamed FileStream
> 
> 
> but what else would a File be? ;-)
> Personally I like the analogy with stdio's FILE.

Well, Java uses File to represent a path. I like the idea of
File f=new File("C:\\something.txt");
Tests:
f.exists()
f.isFile() // exists and is regular file
f.isDirectory() // exists and is directory
f.isDevice() // unix devices, (windows COM1 etc?)
f.canRead()
f.canWrite()
and then
f.open("r+") // returns a FileStream
f.open("a",false)	 // returns a RawFileStream,
			//optional arguments win again
Sam
June 25, 2004
In article <opr95c05pg5a2sq9@digitalmars.com>, Regan Heath says...
>
>>> What do you think of my filters idea, as long as you can snap any number
>>> of filters to streams and each other your data will be transcoded etc
>>> from
>>> one end to the other, and back again in the other direction.

The concept of an arbitrary byte-sequence to byte-sequence filter is staggeringly useful, no questions. Such a filter could zip, unzip, transcode from one eight-byte standard to another, and so on, just as you say.

But such a filter *IS ITSELF A STREAM*. In Java, you would make one by inheriting from FilterStream. Presumably, we'll be able to do that in D, too, fairly soon. But even without that, it suffices to inherit from std.stream.Stream, and simply override either readBlock() or writeBlock() (or both) as appropriate, and bingo - one arbitrary byte-sequence filter. In response to such a stream's readBlock() function being called, you get bytes as required from the underlying stream by calling /its/ readBlock() function, perform whatever filtering/buffering was required, and then return as many bytes as were requested (or fewer), buffering the rest.

Similarly, a Writer could derive from Stream, as it is a special case of an OutputStream, in that it delivers a stream of bytes. It is not a FilterStream, however, as its source is not a Stream.

It kind of stops there though. A Reader is not an InputStream, because it doesn't return a sequence of bytes. (It returns a sequence of dchars). However, it could use an InputStream as it's SOURCE, since it need a sequence of bytes as its input.

dchar-sequence to dchar-sequence are another kettle of fish altogether.



It would seem that the most general solution would be that Stream should be an
alias for a template class TStream!(ubyte). Such a template could provide
interfaces TStream!(ubyte).InputStream and TStream!(ubyte).OutputStream.

In this context, a Stream would implement TStream!(ubyte).InputStream and
TStream!(ubyte).OutputStream; a Reader would implement
TStream!(ubyte).InputStream and TStream!(dchar).OutputStream; a Writer would
implement TStream!(dchar).InputStream and TStream!(ubyte).OutputStream; and a
dchar-to-dchar filter would implement TStream!(dchar).InputStream and
TStream!(dchar).OutputStream.

Now THAT's how I'd LIKE to see it done.

Arcane Jill


June 25, 2004
In article <cbheg0$280c$1@digitaldaemon.com>, Arcane Jill says...
>
>It would seem that the most general solution would be that Stream should be an
>alias for a template class TStream!(ubyte). Such a template could provide
>interfaces TStream!(ubyte).InputStream and TStream!(ubyte).OutputStream.

You beat me to the punch--I was going to bring this up once we got back into talk about formatting :)  I had been trying to avoid templates for char type, but it caused too many problems with formatted i/o.  I'm not going to do anything with this for now, but I do think that this general idea is a good one.

Sean


June 25, 2004
Go-Go Templates

Arcane Jill wrote:
> In article <opr95c05pg5a2sq9@digitalmars.com>, Regan Heath says...
> 
>>>>What do you think of my filters idea, as long as you can snap any number
>>>>of filters to streams and each other your data will be transcoded etc from
>>>>one end to the other, and back again in the other direction.
> 
> 
> The concept of an arbitrary byte-sequence to byte-sequence filter is
> staggeringly useful, no questions. Such a filter could zip, unzip, transcode
> from one eight-byte standard to another, and so on, just as you say.
> 
> But such a filter *IS ITSELF A STREAM*. In Java, you would make one by
> inheriting from FilterStream. Presumably, we'll be able to do that in D, too,
> fairly soon. But even without that, it suffices to inherit from
> std.stream.Stream, and simply override either readBlock() or writeBlock() (or
> both) as appropriate, and bingo - one arbitrary byte-sequence filter. In
> response to such a stream's readBlock() function being called, you get bytes as
> required from the underlying stream by calling /its/ readBlock() function,
> perform whatever filtering/buffering was required, and then return as many bytes
> as were requested (or fewer), buffering the rest. 
> 
> Similarly, a Writer could derive from Stream, as it is a special case of an
> OutputStream, in that it delivers a stream of bytes. It is not a FilterStream,
> however, as its source is not a Stream.
> 
> It kind of stops there though. A Reader is not an InputStream, because it
> doesn't return a sequence of bytes. (It returns a sequence of dchars). However,
> it could use an InputStream as it's SOURCE, since it need a sequence of bytes as
> its input.
> 
> dchar-sequence to dchar-sequence are another kettle of fish altogether.
> 
> 
> 
> It would seem that the most general solution would be that Stream should be an
> alias for a template class TStream!(ubyte). Such a template could provide
> interfaces TStream!(ubyte).InputStream and TStream!(ubyte).OutputStream.
> 
> In this context, a Stream would implement TStream!(ubyte).InputStream and
> TStream!(ubyte).OutputStream; a Reader would implement
> TStream!(ubyte).InputStream and TStream!(dchar).OutputStream; a Writer would
> implement TStream!(dchar).InputStream and TStream!(ubyte).OutputStream; and a
> dchar-to-dchar filter would implement TStream!(dchar).InputStream and
> TStream!(dchar).OutputStream.
> 
> Now THAT's how I'd LIKE to see it done.
> 
> Arcane Jill
> 
> 
June 25, 2004
On Fri, 25 Jun 2004 14:57:04 +0000 (UTC), Arcane Jill <Arcane_member@pathlink.com> wrote:

> In article <opr95c05pg5a2sq9@digitalmars.com>, Regan Heath says...
>>
>>>> What do you think of my filters idea, as long as you can snap any number
>>>> of filters to streams and each other your data will be transcoded etc
>>>> from
>>>> one end to the other, and back again in the other direction.
>
> The concept of an arbitrary byte-sequence to byte-sequence filter is
> staggeringly useful, no questions. Such a filter could zip, unzip, transcode
> from one eight-byte standard to another, and so on, just as you say.
>
> But such a filter *IS ITSELF A STREAM*. In Java, you would make one by
> inheriting from FilterStream. Presumably, we'll be able to do that in D, too,
> fairly soon. But even without that, it suffices to inherit from
> std.stream.Stream, and simply override either readBlock() or writeBlock() (or
> both) as appropriate, and bingo - one arbitrary byte-sequence filter. In
> response to such a stream's readBlock() function being called, you get bytes as
> required from the underlying stream by calling /its/ readBlock() function,
> perform whatever filtering/buffering was required, and then return as many bytes
> as were requested (or fewer), buffering the rest.

Sure.. I was just calling them filters cos they did something to a data.
Once we agree on terminology I think we'll find we all agree on how it should be done.

> Similarly, a Writer could derive from Stream, as it is a special case of an
> OutputStream, in that it delivers a stream of bytes. It is not a FilterStream,
> however, as its source is not a Stream.
>
> It kind of stops there though. A Reader is not an InputStream, because it
> doesn't return a sequence of bytes. (It returns a sequence of dchars). However,
> it could use an InputStream as it's SOURCE, since it need a sequence of bytes as
> its input.

I dont think I understand what a Writer and a Reader are exactly..

AFAICS you have a Source i.e. a file and a Sink i.e. a socket. The source and sink are not streams themselves, but you could and probably would wrap a stream interface around them. In fact designing the stream as a template would allow you to wrap it around anything that provided the requisite methods i.e. read() write() etc.

Filters are, as you say, streams, doing this allows you to plug them into any other stream.

Where does the Reader/Writer enter the picture? Are they simply filters (and thus streams) that convert from one data format to another? Or...

> dchar-sequence to dchar-sequence are another kettle of fish altogether.

By the same rationale as ubyte-sequence to ubyte-sequence aren't they a STREAM also?

> It would seem that the most general solution would be that Stream should be an
> alias for a template class TStream!(ubyte). Such a template could provide
> interfaces TStream!(ubyte).InputStream and TStream!(ubyte).OutputStream.
>
> In this context, a Stream would implement TStream!(ubyte).InputStream and
> TStream!(ubyte).OutputStream; a Reader would implement
> TStream!(ubyte).InputStream and TStream!(dchar).OutputStream; a Writer would
> implement TStream!(dchar).InputStream and TStream!(ubyte).OutputStream; and a
> dchar-to-dchar filter would implement TStream!(dchar).InputStream and
> TStream!(dchar).OutputStream.
>
> Now THAT's how I'd LIKE to see it done.

It sounds pretty solid to me.

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
June 25, 2004
On Sat, 26 Jun 2004 02:45:45 +1200, Sam McCall <tunah.d@tunah.net> wrote:

> Regan Heath wrote:
>> Lets assume for the sake of it that we're talking about a FileStream.. so.. you open it, then you call available() it returns 0 as there is nothing in the buffer.. yet.. you (return immediately) and do something else.. at which point does the stream actually read something into it's buffer?
> When you tell it to :-P
> The point is that available() is simply a request for information about the stream, _without_ telling it to do any work.
> Sam

And my point was, if you only call available, you never tell it to do any work, so there will never *be* anything 'available' :)

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
June 25, 2004
On Fri, 25 Jun 2004 11:31:12 +0000 (UTC), Arcane Jill <Arcane_member@pathlink.com> wrote:

> In article <opr95cp4td5a2sq9@digitalmars.com>, Regan Heath says...
>>
>>> A File /IS/ a stream. How could it not be? Sorry, I just didn't
>>> understand you
>>> here.
>>
>> That's my point. I dont think it should be a stream. fopen etc is not a
>> stream. We want something as a drop in replacement for that, then, we
>> write a stream class, one that will take any class that support read()
>> write() etc.
>
> That's what most of us mean by "stream". A stream is simply something that does
> read() and write().

Ahh.. ok. If I revise my internal definition I think I'll get what you all mean.

>> Perhaps my idea of streams is different to the norm?
>
> Could be.

Seems likely.

>> ahh.. ok this would be part of the BufferedStream class. And it would
>> simply return the # in the buffer. Simple, easy, fast, efficient. :)
>
> Actually, it should return the number in the buffer PLUS the value returned by
> the underlying stream's available() function - because the buffered stream can
> get at least that many bytes from the underlying stream without blocking, and
> use those bytes to refill its own buffer. (That's assuming that the buffered
> stream is happy to get less than a bufferful at a time from the underlying
> stream).

Unless the underlying stream (new word/concept) i.e. the file cannot give it the data without possibly blocking i.e. disk IO right?

> And, the function should be present in unbuffered streams too, and in these
> cases it should return zero.

Which is sensible as there is 0 in it's buffer, because there is no buffer.

> But yes - simple, easy, fast and efficient. And useful.

I think things like File, Socket etc should be unbuffered. Then we write a BufferedStream template/class which takes any Stream i.e. File or Socket and buffers for them. After all buffering is the same for all, so why write it 10 times, why not just once.

If you like you write RawFile and BufferedStream then typedef BufferedStream!(RawFile) File

Yes?

Regan

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
June 25, 2004
"Arcane Jill" <Arcane_member@pathlink.com> escribió en el mensaje
news:cbgi0c$sp7$1@digitaldaemon.com
|
| ...
|
| Oh - one other thing I forgot. I think we need functions like basename(),
| dirname(), pathinfo(), realpath() and so on, (stolen from PHP), and some
| function to append a pathname-component to a pathname. Of course, these
things
| are dead easy to do with ordinary string manipulation ... IF you assume
that the
| file separator is "/". But that won't work on a Mac. Such functions would
let us
| manipulate pathnames in a platform independent way. (These should go in
| std.file, not std.stream, obviously).
|
| Arcane Jill

std.path

-----------------------
Carlos Santander Bernal