Hide this comment

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 ()Reply
Hide this comment

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 ()Reply
Hide this comment

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 ()Reply
Hide this comment

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 ()Reply
Hide this comment

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

By on 5/30/2010 4:12 AM ()Reply
Hide this comment

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 ()Reply
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

Logging in...