Nov 252017

You might have noticed that I haven’t blogged as much as usual and that there have been no recent updates to GExperts either. The reason of course was that I was busy doing other things. Some of them were programming related and one of these was writing a caching class wrapper for TStream descendants (e.g. TFileStream, but it should work with any other streams as well).

It is simple to use and totally transparent to the calling code because the cache itself descends from TStream:

procedure TestCache;
  fs: TFileStream;
  cache: TdzStreamCache;
  i: integer;
  by: byte;
  cache := nil;
  fs := TFileStream.Create('C:\test.dat', fmOpenWrite);
    cache := TdzStreamCache.Create(fs);
    // now, do any operation you usually do on the stream, but use the
    // cache instead
    // e.g. write 50 megabytes of random bytes
    for i := 0 to 50*1024*1024 do begin
      by := Random(256);
      cache.WriteBuffer(by, SizeOf(by));
    // Writing a single byte to a TFileStream will result in very
    // bad performance, which is why we usually copy the bytes to a
    // larger buffer instead and then write this buffer to the stream.
    // Using the TdzStreamCache you won't see much of a difference between
    // these two approaches.

TdzStreamCache can also be used for read and read/write access to a stream. It supports linear and also random access. Performance is worst when reading a stream backwards a single byte at a time.

To get an idea how well it performs, I have benchmarked it against David Heffernan‘s excellent CachedFileStream and found that it compares very well. (I could not simply use David’s class because I needed caching for other types of streams, not just files.)

I have been using TdzStreamCache extensively in the last several weeks and I am pretty sure that I have weeded out most of the bugs. But of course, that does not mean that there aren’t any left, so there are no guarantees. If you use it, all problems are your own.

TdzStreamCache is released under the Mozilla Public License (MPL) 1.1 as part of my dzLib library, but the unit is pretty much stand alone. The only thing it requires is jedi.inc because Delphi 2007 declares NativeInt inconsistently to other Delphi versions. As with all my dzlib code, it is available from sourceforge as u_dzStreamCache.pas.

The code for the benchmarks I mentioned above is also available if you want to do the benchmarks yourself.

I would appreciate any feed back, especially if you find bugs or improve on it.

Nov 152017

So I don’t forget:

The following Linux command shows a list of all subdirectories that contain a least one *.xml file:

find . -type f -name '*.xml' | sed -r 's|/[^/]+$||' | sort | uniq

This is an adaptation of this answer on unix.stackexchange.com.

Nov 022017

There was a discussion about using the PE flag IMAGE_FILE_LARGE_ADDRESS_AWARE and whether this is equivalent to compiling a program to 64 bit Windows target (no it’s not) in the German Delphi Praxis forum. This prompted me to have a look at what kind of flags can be specified and how to do that for a Delphi program.

A quick Bing search for SETPEFLAGS and Delphi also found a blog post by Halvard Vassbotn from 2006 about the IMAGE_FILE_RELOCS_STRIPPED PE flag.

Since one of my programs has recently started to throw out of memory
exceptions (when displaying large(!) data files) and our executables tend to be rather large anyway, I decided to add these PE flags to it.

  • IMAGE_FILE_LARGE_ADDRESS_AWARE – App can handle >2gb addresses
  • IMAGE_FILE_RELOCS_STRIPPED – Relocation info stripped from file

With the flags it already used …

  • IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP – If Image is on removable media, copy and run from the swap file
  • IMAGE_FILE_NET_RUN_FROM_SWAP – If Image is on Net, copy and run from the swap file.

… this resulted in the following SETPEFLAGS compiler directive in the .dpr file:


The result was as I hoped: No out of memory error any more when displaying a file that always caused one before. The executable size also shrank, but not as significantly as I had hoped: 9698 KB where before it was 9987 KB, but every little helps.

But there is another side effect I found today: Setting IMAGE_FILE_NET_RUN_FROM_SWAP not only makes Windows load the executable into the swap file when executing it but apparently every time it accesses it. Simply selecting it in Windows Explorer resulted in the Explorer Window freezing for a short time (it feels like several seconds but probably is just about one), the same delay happens when opening the Properties dialog (e.g. to check the version info). That does not happen, when the flag isn’t set.

Oct 312017

Note to self: Delphi’s Advanced Records are also available in Lazarus / Free Pascal, but only if they have been explicitly enabled with the modeswitch compiler directive:

unit SomeUnit;

{$mode objfpc}{$H+}{$modeswitch advancedrecords}


  TSomeRecord = record
    FSomeField: integer;
    function SomeMethod: integer;


function TSomeRecord.SomeMethod: integer;
  Result := FSomeField;


If advancedrecords is not enabled this won’t compile:

Fatal: Syntax error: “END” expected but “FUNCTION” found.
Oct 212017

Flattr have changed their terms an conditions. Since I haven’t received a single cent via Flattr, I really can’t be bothered what exactly they have changed and whether that’s good or bad for me personally. So I have closed that account for good. That leaves only PayPal, if you want to make a donation to GExperts. Sorry, if that’s an inconvenience. And please remember that I’d prefer you to contribute to GExperts in one of the other means described on that page than money.

Oct 142017

Jeroen has submitted two enhancements to GExperts:


I am still working on the refactoring for the IDE form enhancements, but progress is slow, so the next release will probably take a while.

Sep 302017

A new test release of my dzDebugVisualizers for Delphi 2005, 2006 and 2007 is available. Apart from fixing an Access Violation when unloading the package I have added support for TDateTime and unquoted (multiline) strings to the Evaluate / Modify window:

In addition I have added a “Modifiers” button to the dialog which allows to add any of the supported display format specifiers to the expression.

Download that test release and tell me, what you think. What other data types would you like me to add? Are there any bugs?

Sep 272017

Wir suchen wieder einen Kollegen. Der Job ist inhaltlich definitiv interessant, auch die Kollegen aus der Hardwareentwicklung sind durchaus umgänglich.

Standort: Essen

Es geht nicht um die Prüfung von Kraftfahrzeugen, auch wenn wir zum TÜV Rheinland gehören.

Technischer Mitarbeiter im Bereich Elektrotechnik (w/m)

Ihre Aufgaben

  • Unterstützung des Fahrzeug Support-Teams bei
    Neuaufbau und Instandsetzung der Technik für unsere
    schnellfahrenden Messsysteme
  • Konstruktion, Aufbau und Test von elektronischen /
    elektromechanischen Prototypen für unsere
    Messfahrzeuge, Begleitung bis zur Serienreife
  • Organisation und Durchführung des Beschaffungswesens
    inkl. Lieferantenauswahl für den Bereich Systemtechnik
  • Betreuung der für Kunden entwickelten Mess- und

Nachteil: Man muss softwareseitig mit mir zusammenarbeiten 😉

Stellenangebot auf Stepstone

Sep 032017

I was made aware that dzPrepBuild no longer works with .dof files. Since I don’t use it with Delhi 6 or 7 any more, I didn’t realize that myself. The bugfix was easy, just pass the correct parameter.

The new version is available from SourceForge. Note that, for whatever reason, SoureForge still claims that the latest download is version 1.3.0. You’ll have to select version 1.3.2 yourself. I hope that it is just a matter of time for SourceForge to update that link.

%d bloggers like this: