View previous topic :: View next topic |
Author |
Message |
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sat Aug 21, 2004 11:56 am Post subject: Reader/Writer change for char[]. byte[], ubyte[] ... |
|
|
In reviewing these methods, they don't provide the functionality wished for. For example, you can't read data into a client provided array. In addition, Writer.put() will write the length of the array first, which is not always what you want. I think the thing to do is as follows:
1) change the existing signatures from get(out char[]) to get(char[]). This will allow a client to specify the destination of the content, rather than just a reference to the content. The nice thing is that the client can use slicing to provide both an offset and an item count.
2) change put(char []) such that is does not write the length. This means that clients of (the binary format) Reader/Writer will have to read/write their own length values, if that's what they want to do.
3) I'll extend the array support to other scalar types, including int, float etc.
4) I'd like to retain the behavior that we have today in terms of returning a slice of the buffer (because it's fast). To do so, I'll have to change the method signature from get(out char[]) to get(out char[], uint size, bool slice=false)
Unfortunately, the compiler does not distinguish between char[] and char[100] when matching against a get(char[]) signature, although one is a array reference and the other is an array instance (which may be the source of bugs in the future). The compiler does distinguish between the two for the get (out char[]) signature, but that doesn't help us with migrating the existing code.
Any ideas about how to deal with this? I'd like to retain the get/put symmetry, but it's tricky. Perhaps we should drop get ([]) altogether, by changing the signatures to getArray([]) and getSlice(out []) ? Then, which version would the <</>> operators select?
- Kris |
|
Back to top |
|
|
pragma
Joined: 28 May 2004 Posts: 607 Location: Washington, DC
|
Posted: Sat Aug 21, 2004 9:35 pm Post subject: Changing a contract is never easy. |
|
|
Hrm.. that's quite a wrinkle in the design. Here's how I look at it.
I think that you may want to keep get() as it is, and then provide some more explict methods that provide more exact behavior for slices. That way you can get the behavior you need when you need it. Otherwise, you're looking at making use of 'get' a little too confounding as it will do very different things depending on the state of the passed array (empty or not empty).
Why not define a family of getBuffer() routines (or just one really good one) for writing to slices and buffers and such, while keeping the good-old-fashioned behavior for ">>" and get().
Also, your essay leaves out one point: writing to a slice or buffer is more complicated than get(). You'll need to go back to a more C-style of I/O if you're using buffers since knowing how many bytes were actually read is critical to using that buffer.
Here's where my thoughts went with this:
Code: |
int getBuffer(type[] buf); // C-style, return num entriesread.
void getBuffer(type[] buf,out uint num); // More of the same, just a little different
void getBuffer(type[] buf,out uint remain); // hrm....
void getBuffer(type[] buf,type[] remain); // now we're getting somewhere
|
That last one seems to do the job:
Code: |
type[100] buffer;
type[] remainder = buffer;
// looks wierd, but it works.
while(remainder.length > 0){
reader.getBuffer(remainder,remainder);
}
|
Now this method signature can be reduced to something else if it suits the Mango style of doing things:
Code: |
Reader get(type[] bufout, inout type[] remain);
|
So you provide a slice to write to and get a slice back for what's leftover, plus it returns "this" so you can chain your calls like get().
Another thing you can do to make ">>" do some similar magic is return a shim rather than the formal instance from the first call.
Warning: this is huge hack, but I thought it was worth menitoning here.
Code: |
class Reader{ // just the new methods
static Reader slice(){
return(new SliceShim(this));
}
// specialized ">>" operator that takes a delegate "operation"
Reader op_shr(Reader delegate() readerOp){
return(readerOp());
}
}
class SliceShim{
Reader original;
public this(Reader o){ original = o; }
public override Reader op_shr(type[] style){
uint count;
// perform slice style operation here
// return another shim to capture the count
return(new CountShim(original,count));
}
}
class CountShim{
Reader original;
uint count;
public this(Reader o,uint c){ original = o; count =c;}
public override Reader op_shr(out uint count){
count = this.count;
return(original); // pass back the original reader
}
}
// so we can do this:
type[] empty;
type[100] buf;
int count;
// now we stream the 'operation' along with the rest.
reader >> Reader.slice >> buf >> count >> empty;
|
Hope this helps. _________________ -- !Eric.t.Anderton at gmail |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Fri Aug 27, 2004 11:59 am Post subject: |
|
|
Thanks Eric;
Been distracted for a week ... the issue is not as bad as might initially appear. In fact, it'll work out nicely; without any changes to the existing API.
Appreciate your input, as always. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Oct 24, 2004 11:47 pm Post subject: |
|
|
All changes regarding this issue are finally checked-in. There is no alteration to the IReader/IWriter interfaces (in terms of prior functionality), so everything will hopefully be okay.
All of the Reader/Writer framework has been replaced, underneath the public interfaces ~ goes to show just how handy interfaces can be |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|