Friday, October 11, 2013

TStreamAdapter.Seek – Apology

Sometimes you write a blog post that you wish you wouldn’t. Maybe you don’t, but I certainly did. Yesterday I wrote about TStreamAdapter.Seek Broken For Large Files I completely incorrectly stated that “the bug was not fixed in XE4/XE5”.

The reason for my mistake was that although I verified the problem in the XE2, I didn’t write any test code for it (we already had a failing application so I didn’t have to – or so I thought) and I only checked the RTL for changes. I found out that the TStreamAdapter.Seek didn’t change from XE2 to XE4/5 and assumed the worst.

Well, the good guys at Embarcadero did fix the problem in the meantime – but in a different place. They have added a new Seek overload to the TStream class and this new Seek (which is implemented as an inline function) acts as an intermediary between the TStreamAdapter and the correct TStream.Seek method. This solution is much better than our quick fix as it also fixes all other code in the world which mistakenly calls the wrong Seek overload.

function Seek(Offset: Longint; Origin: Word): Longint; overload; virtual;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; virtual
function Seek(const Offset: Int64; Origin: Word): Int64; overload; deprecated; inline

function TStream.Seek(const Offset: Int64; Origin: Word):
Result := Seek(Offset,

Thanks to the Arioch’s prompt in the original post I did write a test code today and when I finally tested it on the XE5, it run just fine! Imagine my shame. :(

What have I learned today? That looking at the source code is not enough, especially if you want to complain. Always write a test case (and then run it!).

I deeply apology to Embarcadero programmers (especially to the guy who fixed the original error) and to you, my readers.

And now, if you’ll excuse me, I’ll pull a cover over my head and gently weep.


  1. The danger of speaking out is always that you will be mistaken at some point because no one is perfect. What you did with this post is show personal integrity, and in this day an age that is nothing to be ashamed about!

  2. Making an honest, well intentioned mistake isn't that big an issue. It's how you handle the mistake that's important.

    Thank you for both posts.

  3. Bah. Anyone could apologize. It would take blogging talent to turn this into a post about confusing RTL design and lack of commented code! ;-) Me, I'd have waited until there was an apology for FireMonkey 1.0 to issue a retraction. :-)

  4. I still call their fix strange at best.
    We have a saying "you'd better pull your pants on, or have your pectoral cross off"

    If they call that 3rd overload "deprecated" then they are deprecated from using it and should have aimed at its removal. That looks openly schizoid to volluntarily intreoduce deprecated function only to base your code on it.

  5. Good submit, thanks!