Wednesday, October 28, 2009

GpHugeFile v6 and other updates

Today I finally published all my updated open source units. Some were recently modified and for others the update was long overdue. Some were only slightly modified, in others the changes were bigger. Read through the list below and you’ll see.

In future posts I intend to write some more about changes in GpHugeFile, GpStuff, and GpLists. If you want to know more about changes in other units, drop a comment.

GpHugeFile 6.01

  • Implemented read prefetch, activated by setting hfoPrefetch option flag.
  • Number of buffers to prefetch can be set with a ResetEx parameter.

Unfortunately for some, this option is only available in Delphi 2007 and newer because the worker object is implemented using OmniThreadLibrary.

GpVersion 2.04

  • Updated for Delphi 2009.
  • Extended IVersion interface with IsNotHigherThan, IsNotLowerThan and IsEqualTo.

GpTextFile 4.02

  • Compatible with Delphi 2009.

GpSync 1.22

  • Implemented TGpSWMR.AttachToThread.
  • Added internal check to ensure that TGpSWMR.WaitToRead/WaitToWrite/Done are called from one thread only.

GpStuff 1.19

  • Added EnumPairs string array enumerator.
  • Added EnumList string enumerator.
  • Added EnumStrings enumerator.
  • InterlockedIncrement/InterlockedDecrement deal with integers, therefore TGp4AlignedInt.Increment/Decrement must return integers. All other functions in TGp4AlignedInt also changed to work with integers.
  • Implemented function CAS (compare and swap) in TGp4AlignedInt and TGp8AlignedInt64 records.
  • TGp8AlignedInt renamed to TGp8AlignedInt64.
  • TGp8AlignedInt.Addr must be PInt64, not PCardinal.
  • Implemented IGpTraceable interface.

GpStructuredStorage 2.0a

  • [Erik Berry] Definition of fmCreate in Delphi 2010 has changed and code had to be adjusted.

GpStreams 1.25b

  • Safer TGpFixedMemoryStream.Read.
  • Added setter for TGpFixedMemoryStream.Position so that invalid positions raise exception.

GpSharedMemory 4.12

  • Compatible with Delphi 2009.

GpLists 1.43

  • Added parameter 'step' to various Slice(), Walk() and WalkKV() enumerators.
  • Added method FreeObjects to the TStringList helper.

Tuesday, October 27, 2009

And the award goes to …

image Daniel R. Wolf of the Delphi PRAXiS.

Not the official Spirit of Delphi award, but the Delphi Legends Community Award in the organization of Wings of Wind (who are those people???).

Anyway, somehow I got nominated and even scrapped together the fifth place, which is definitely more than I deserve, but still – thanks for the recognition, folks!

Such things make one work harder and publish more so you can definitely expect plenty of articles on this blog in the near future …

Sunday, October 25, 2009

TDM Rerun #14: A Portable XML

The code unit, OmniXML.pas, which contains the XML representation interfaces, parser and writer, was written by a single programmer, Miha Remec (he is also the guy behind the website). He started writing it in 2000, because he was missing a native Delphi DOM parser, one that would represent the DOM the same way as it was designed. The best Delphi parser around at that time was OpenXML, but it used classes to represent XML elements, not interfaces. OmniXML uses interfaces, derived from the IXMLNode (as specified by the DOM). That also makes it almost completely compatible with the MSXML parser, which uses the same approach.

- A Portable XML, The Delphi Magazine 105, May 2004

In the 2004 May issue I wrote about OmniXML, a native Delphi XML parser. I described the OmniXML approach and wrote few short pieces of code that demonstrated its use.

Today, five years later, OmniXML is still strong and I’m still using it, as you can see in my Fluent XML series.

Links: article (PDF, 45 KB), source code (ZIP, 795 KB).

Thursday, October 22, 2009

DSiWin32 1.51

It’s been some time since I’ve last updated my open source units… For example, DSiWin32, a collection of Win32 API helpers, was last updated in August 2008! Bad me!

Time to do some housecleaning, then. Let’s see what’s new in DSiWin32 1.51.

There are new dynamic forwarders: DSiWow64DisableWow64FsRedirection, DSiWow64RevertWow64FsRedirection, DSiGetTickCount64 and DSiGlobalMemoryStatusEx. They call appropriate API functions if they are available and return error on older Windows systems. [Click on the function name to see the API specification on the MSDN.]

Function DSiGetGlobalMemoryStatus is not much more than a wrapper to the GlobalMemoryStatusEx API and returns information about global memory status (paging, virtual memory etc). Information is returned in a TMemoryStatusEx record, which is also defined in the DSiWin32 unit.

We implemented six new function in the files section. DSiGetNetworkResource converts drive letter (created by mapping network location) back to the network path. DSiDisconnectFromNetworkResource disconnects drive letter from a network resource. [DSiConnectToNetworkResource was included in the previous public version 1.41.] DSiGetSubstDrive maps drive letter (created by using Subst command) to the associated folder and DSiGetSubstPath does similar for a file path that starts with a subst’ed letter. DSiDisableWow64FsRedirection disables file system redirection (mapping from \Windows\System32 to \Windows\SysWOW64 for 32-bit applications on 64-bit systems) for the current thread and DSiRevertWow64FsRedirection reverts this change.

There are also two new install functions. DSiAddApplicationToFirewallExceptionList adds application to the firewall exception list and DSiAddPortToFirewallExceptionList does the same for a TCP/IP port.

DSiGetCurrentThreadHandle and DSiGetCurrentProcessHandle return (true) handles for the current thread and process. [In contrast to GetCurrentThread and GetCurrentProcess APIs which return pseudo handle which cannot be used outside of the current thread/process context.]

DSiGetWindowsVersion was extended to detect Windows Server 2008, Windows 7 and Windows Server 2008 R2. DSiGetTrueWindowsVersion was also upgraded to return “Windows Server 2008 or Vista SP1” and “Windows 7 or Server 2008 R2”. It looks like it is not possible to discriminate between those operating systems on the API level :( Record TOSVersionInfoEx was also defined as it was used in the DSiGetWindowsVersion.

'Access' parameter was added to the DSiWriteRegistry methods so that user can request writing to the non-virtualized key when running on 64-bit system (KEY_WOW64_64KEY).

DSiExecuteAndCapture got much deserved workover. Now the caller can be informed of each line outputted by the child process.

Delphi 2009/2010 compatibility was fixed for DSiGetFolderLocation, DSiGetNetworkResource, DSiGetComputerName, DSiGetWindowsFolder, DSiExecuteAndCapture and bugs were fixed in DSiGetTempFileName and DSiGetUserName.

All in all, lots of things were changed and improved. If you’re already using DSiWin32 then this is a good time to upgrade. [And if not, start using it!]

Saturday, October 17, 2009

Open source Computer Vision library

Memo to self: When you play with computer vision next time, check the OpenCV library.

From the OpenCV www:

“OpenCV (Open Source Computer Vision) is a library of programming functions for real time computer vision. Example applications of the OpenCV library are Human-Computer Interaction (HCI); Object Identification, Segmentation and Recognition; Face Recognition; Gesture Recognition; Camera and Motion Tracking, Ego Motion, Motion Understanding; Structure From Motion (SFM); Stereo and Multi-Camera Calibration and Depth Computation; Mobile Robotics.”

Found via IPhone Sudoku Grab via Julian M Bucknall.

Apparently there is no Delphi interface (yet) but as the DLL has simple C interface, such interface could easily (or “easily”?) be implemented.

Tuesday, October 06, 2009

Fluent XML [3]

Few days ago I was answering some OmniXML related question on Slovenian Delphi forum and I tried using GpFluentXML to provide the answer. The emphasis is on “tried” – my unit was just not powerful enough to be useful in this case.

So what else could I do besides improving GpFluentXML?

Modifications were very small. I added two overloads (AddChild and AddSibling) which allow setting node value. Implementation is equally trivial as everything else inside the fluent XML unit.

function TGpFluentXmlBuilder.AddChild(const name: XmlString;
value: Variant): IGpFluentXmlBuilder;
Result := AddChild(name);
SetTextChild(fxbActiveNode, XMLVariantToStr(value));
end; { TGpFluentXmlBuilder.AddChild }

(And similar for AddSibling.)

Now I (and you and everybody else) can write such code:

data : TData;
xmlBuilder: IGpFluentXmlBuilder;
xmlBuilder := CreateFluentXml
.AddProcessingInstruction('xml', 'version="1.0" encoding="UTF-8"')
['xsi:noNamespaceSchemaLocation', 'http://www.tempuri/schema.xsd']
['xmlns:xsi', '']
for data in GetData do begin
.AddChild('ID', data.ID)
.AddChild('GeneratedBy', data.Originator)
.AddSibling('Title', data.Title)

A non-obvious trick – .Mark and .Return are used inside the loop to store/restore proper level at which the child nodes must be inserted.

Full GpFluentXML source is available at