The decorator pattern would work well here, I think.

1
2
3
4
5
6
7
8
9
10
11
type TextWriterWithOffset(innerWriter : TextWriter) =
    inherit TextWriter()
    let mutable offset = 0
    member this.Offset = offset
    override this.Encoding = innerWriter.Encoding
    override this.Write (c : char) =
        offset <- offset + 1
        innerWriter.Write c
    override this.WriteLine () =
        offset <- 0
        innerWriter.WriteLine ()

Edit: Having said that, I doubt it would matter performance-wise if you just used sprintf, got the string's length and pushed it into the StreamWriter.

By on 5/30/2010 2:46 AM ()

Thank you for this Kha. I like the idea of using the decorator pattern but it still leaves the task of overriding all the other overloaded Write methods of TextWriter (for strings, numerics, objects, etc.) and calculating how much they write (i.e. will need offset <- offset + n, where I have to work out the value of n which I do not think is easy in all cases).

By on 5/30/2010 3:05 AM ()

but it still leaves the task of overriding all the other overloaded Write methods of TextWriter (for strings, numerics, objects, etc.)

fprintf will only call these two overloads. I checked that :) .
Even if it didn't,

1
Write(char)

ist the only method you must override for a working TextWriter, the default implementations of all the other methods will finally call it. For counting newlines

1
WriteLine()

and

1
WriteLine(string)

must additionally be overriden.

By on 5/31/2010 1:21 AM ()

You could:

1) Use the decorator, override just

1
Write(string), WriteLine(string)

and use

1
Write(string.Format("format", args))

to handle more complex patterns.

2) Write to a StringWriter and access the current length via

1
writer.ToString().Length

and periodically dump the contents into your real stream.

3) Write a very nice reusable wrapper of TextWriter that exposes events for each write, override all methods once and for all, and use it for you current problem.

I'd go for (1). Quick and easy :-)

By on 5/30/2010 3:41 AM ()

Thanks Mau. I'll take your first suggestion and let you know how it goes.

By on 5/30/2010 4:12 AM ()

A slightly different idea is to use the decorator, override only

1
Write(object obj)

and in the implementation use

1
Convert.ToString(obj)

.

You would need to be careful to always cast the argument to object though, to make sure overload resolution picks up your method.

By on 5/30/2010 4:21 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper