<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>From Zero To One &#187; Coding</title>
	<atom:link href="http://www.cromis.net/blog/category/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cromis.net/blog</link>
	<description>A blog about Delphi programming and all things technical</description>
	<lastBuildDate>Tue, 16 Mar 2010 12:11:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>TValue and other &#8220;Variants&#8221; like implementation tests</title>
		<link>http://www.cromis.net/blog/2010/03/tvalue-and-other-variable-like-implementation-tests/</link>
		<comments>http://www.cromis.net/blog/2010/03/tvalue-and-other-variable-like-implementation-tests/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 11:51:30 +0000</pubDate>
		<dc:creator>Iztok Kacin</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://www.cromis.net/blog/?p=710</guid>
		<description><![CDATA[The recent post from Mason Wheeler about TValue speed was very interesting. I always had the impression, that variants were slow, but never tested that. So this was a surprise to me. But how fast the variants really are? There are other &#8220;variants&#8221; like implementations out there, so I decided to test them in a [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">The recent <a title="TValue is very slow" href="http://www.delphifeeds.com/go/s/66399">post</a> from Mason Wheeler about TValue speed was very interesting. I always had the impression, that variants were slow, but never tested that. So this was a surprise to me. But how fast the variants really are? There are other &#8220;variants&#8221; like implementations out there, so I decided to test them in a common test. At least the ones I know that exist. The record implicit operator allows for some very flexible operations on different data types. So I tested 5 different approaches to &#8220;variant&#8221; implementation.</p>
<ul>
<li>Variants (build in Delphi as long as I can remember <img src='http://www.cromis.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</li>
<li>TValue (new in Delphi 2010)</li>
<li>TAnyValue (recently added to my <a title="http://www.cromis.net/blog/downloads/" href="http://www.cromis.net/blog/downloads/">library</a>)</li>
<li>TOmniValue (part of <a title="OmniThreadLibrary" href="http://otl.17slon.com/">OmniThreadLibrary</a>)</li>
<li>Bare-bone variant record implementation for comparison.</li>
</ul>
<p style="text-align: justify;">Here is the code I tested on. It is just a little changed version of Masons. It forces the compiler to include all lines (by calling Writeln on resulting values) and it averages over integers, strings and floating point values. Just integers seemed unfair to me. After all in real life we would use all possible combinations of data. The test also has range and overflow checks turned on.</p>
<p><span style="text-decoration: underline;"><strong>The results:</strong></span></p>
<p>Iterations: <span style="text-decoration: underline;">10000000</span></p>
<p>Times are in milliseconds</p>
<table style="border-collapse: collapse; border-spacing: 0px;" border="1" cellpadding="3px" width="700px">
<tbody>
<tr>
<td><span style="color: #0000ff;"><strong>Type</strong></span></td>
<td><span style="color: #0000ff;"><strong>Variants</strong></span></td>
<td><span style="color: #0000ff;"><strong>TValue</strong></span></td>
<td><span style="color: #0000ff;"><strong>TAnyValue</strong></span></td>
<td><span style="color: #0000ff;"><strong>TOmniValue</strong></span></td>
<td><span style="color: #0000ff;"><strong>TVariableRec</strong></span></td>
</tr>
<tr>
<td style="padding-left: 5px;"><span style="color: #0000ff;">j := I</span></td>
<td style="text-align: center;">255</td>
<td style="text-align: center;">4070</td>
<td style="text-align: center;">916</td>
<td style="text-align: center;">128</td>
<td style="text-align: center;">175</td>
</tr>
<tr>
<td style="padding-left: 5px;"><span style="color: #0000ff;">j := I/5</span></td>
<td style="text-align: center;">332</td>
<td style="text-align: center;">4081</td>
<td style="text-align: center;">1400</td>
<td style="text-align: center;">3265</td>
<td style="text-align: center;">313</td>
</tr>
<tr>
<td style="padding-left: 5px;"><span style="color: #0000ff;">j := IntToStr(I)</span></td>
<td style="text-align: center;">4548</td>
<td style="text-align: center;">11051</td>
<td style="text-align: center;">7873</td>
<td style="text-align: center;">6429</td>
<td style="text-align: center;">2795</td>
</tr>
<tr>
<td style="padding-left: 5px;"><span style="color: #0000ff;">ALL</span></td>
<td style="text-align: center;">4905</td>
<td style="text-align: center;">18847</td>
<td style="text-align: center;">9932</td>
<td style="text-align: center;">9654</td>
<td style="text-align: center;">3255</td>
</tr>
</tbody>
</table>
<p><span style="text-decoration: underline;"><strong>And here is the test code:</strong></span></p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">program</span> ValuesTest<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic;">{$APPTYPE CONSOLE}</span>
<span style="color: #000000; font-weight: bold;">uses</span>
  SysUtils<span style="color: #000066;">,</span>
  rtti<span style="color: #000066;">,</span>
  diagnostics<span style="color: #000066;">,</span>
  OtlCommon<span style="color: #000066;">,</span>
  Cromis<span style="color: #000066;">.</span><span style="color: #006600;">AnyValue</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">const</span>
  HUNDRED_MILLION <span style="color: #000066;">=</span> <span style="color: #0000ff;">10000000</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">type</span>
  TVariableRec <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
  <span style="color: #000000; font-weight: bold;">private</span>
    FFLoat<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
    FString<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
    FInteger<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">function</span> GetAsFloat<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> SetAsFloat<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">function</span> GetAsInteger<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> SetAsInteger<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">function</span> GetAsString<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> SetAsString<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span>
    <span style="color: #000000; font-weight: bold;">class</span> operator Implicit<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">class</span> operator Implicit<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">class</span> operator Implicit<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">class</span> operator Implicit<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">class</span> operator Implicit<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">class</span> operator Implicit<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">property</span> AsFloat<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span> <span style="color: #000066;">read</span> GetAsFloat <span style="color: #000066;">write</span> SetAsFloat<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">property</span> AsString<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span> <span style="color: #000066;">read</span> GetAsString <span style="color: #000066;">write</span> SetAsString<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">property</span> AsInteger<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span> <span style="color: #000066;">read</span> GetAsInteger <span style="color: #000066;">write</span> SetAsInteger<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> tryTValue<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  i<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
  j<span style="color: #000066;">:</span> TValue<span style="color: #000066;">;</span>
  value1<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  value2<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
  value3<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">to</span> HUNDRED_MILLION <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I<span style="color: #000066;">;</span>
    value1 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I <span style="color: #000066;">/</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">;</span>
    value2 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsExtended</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">IntToStr</span><span style="color: #000066;">&#40;</span>I<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    value3 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value1<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value2<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value3<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> tryAnyValue<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  i<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
  j<span style="color: #000066;">:</span> TAnyValue<span style="color: #000066;">;</span>
  value1<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  value2<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
  value3<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">to</span> HUNDRED_MILLION <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I<span style="color: #000066;">;</span>
    value1 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I <span style="color: #000066;">/</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">;</span>
    value2 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsFloat</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">IntToStr</span><span style="color: #000066;">&#40;</span>I<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    value3 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value1<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value2<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value3<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> tryOmniValue<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  i<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
  j<span style="color: #000066;">:</span> TOmniValue<span style="color: #000066;">;</span>
  value1<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  value2<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
  value3<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">to</span> HUNDRED_MILLION <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I<span style="color: #000066;">;</span>
    value1 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I <span style="color: #000066;">/</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">;</span>
    value2 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsExtended</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">IntToStr</span><span style="color: #000066;">&#40;</span>I<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    value3 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value1<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value2<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value3<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> tryVariants<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  i<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
  j<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">variant</span><span style="color: #000066;">;</span>
  value1<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  value2<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
  value3<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">to</span> HUNDRED_MILLION <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I<span style="color: #000066;">;</span>
    value1 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I <span style="color: #000066;">/</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">;</span>
    value2 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">IntToStr</span><span style="color: #000066;">&#40;</span>I<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    value3 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value1<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value2<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value3<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> tryVarRec<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  i<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
  j<span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">;</span>
  value1<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  value2<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
  value3<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">to</span> HUNDRED_MILLION <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I<span style="color: #000066;">;</span>
    value1 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> I <span style="color: #000066;">/</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">;</span>
    value2 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsFloat</span><span style="color: #000066;">;</span>
    j <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">IntToStr</span><span style="color: #000066;">&#40;</span>I<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    value3 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> j<span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value1<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value2<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>value3<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span>
  stopwatch<span style="color: #000066;">:</span> TStopWatch<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">{ TVariableRec }</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> operator TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">Implicit</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result<span style="color: #000066;">.</span><span style="color: #006600;">AsFloat</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">GetAsFloat</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> FFLoat<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">GetAsInteger</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> FInteger<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">GetAsString</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> FString<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> operator TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">Implicit</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result<span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> operator TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">Implicit</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> operator TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">Implicit</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">.</span><span style="color: #006600;">AsFloat</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> operator TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">Implicit</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result<span style="color: #000066;">.</span><span style="color: #006600;">AsString</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> operator TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">Implicit</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> TVariableRec<span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">SetAsFloat</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Extended</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  FFLoat <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">SetAsInteger</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  FInteger <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TVariableRec<span style="color: #000066;">.</span><span style="color: #006600;">SetAsString</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Value<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  FString <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Value<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">try</span>
    stopwatch <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStopWatch<span style="color: #000066;">.</span><span style="color: #006600;">StartNew</span><span style="color: #000066;">;</span>
    tryVariants<span style="color: #000066;">;</span>
    stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">Stop</span><span style="color: #000066;">;</span>
    <span style="color: #000066;">writeln</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Variants: '</span><span style="color: #000066;">,</span> stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">ElapsedMilliseconds</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    stopwatch <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStopWatch<span style="color: #000066;">.</span><span style="color: #006600;">StartNew</span><span style="color: #000066;">;</span>
    tryTValue<span style="color: #000066;">;</span>
    stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">Stop</span><span style="color: #000066;">;</span>
    <span style="color: #000066;">writeln</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'TValue: '</span><span style="color: #000066;">,</span> stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">ElapsedMilliseconds</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    stopwatch <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStopWatch<span style="color: #000066;">.</span><span style="color: #006600;">StartNew</span><span style="color: #000066;">;</span>
    tryAnyValue<span style="color: #000066;">;</span>
    stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">Stop</span><span style="color: #000066;">;</span>
    <span style="color: #000066;">writeln</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'TAnyValue: '</span><span style="color: #000066;">,</span> stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">ElapsedMilliseconds</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    stopwatch <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStopWatch<span style="color: #000066;">.</span><span style="color: #006600;">StartNew</span><span style="color: #000066;">;</span>
    tryOmniValue<span style="color: #000066;">;</span>
    stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">Stop</span><span style="color: #000066;">;</span>
    <span style="color: #000066;">writeln</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'TOmniValue: '</span><span style="color: #000066;">,</span> stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">ElapsedMilliseconds</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    stopwatch <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStopWatch<span style="color: #000066;">.</span><span style="color: #006600;">StartNew</span><span style="color: #000066;">;</span>
    tryVarRec<span style="color: #000066;">;</span>
    stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">Stop</span><span style="color: #000066;">;</span>
    <span style="color: #000066;">writeln</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'TVariableRec: '</span><span style="color: #000066;">,</span> stopwatch<span style="color: #000066;">.</span><span style="color: #006600;">ElapsedMilliseconds</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">except</span>
    <span style="color: #000000; font-weight: bold;">on</span> E<span style="color: #000066;">:</span> Exception <span style="color: #000000; font-weight: bold;">do</span>
      <span style="color: #000066;">Writeln</span><span style="color: #000066;">&#40;</span>E<span style="color: #000066;">.</span><span style="color: #006600;">ClassName</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">': '</span><span style="color: #000066;">,</span> E<span style="color: #000066;">.</span><span style="color: #006600;">Message</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000066;">readln</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">.</span></pre></div></div>

<p style="text-align: justify;">It is obvious and expected that bare-bone record is the fastest. But Variants are not far behind and in real world the difference is negligible. My TAnyValue and TOmniValue from Primož are on the same level. But in most cases his implementation is faster because I use an interface to store the data in a class (because of my other code that uses interface based IAnyValue) and he stores most of the data as numeric type (only some as interface based class). I could speed up my implementation but I find it fast enough in most cases. And I will take elegance over speed if the difference is small enough. But TValue is slow, to slow probably to be used a lot. They should work on it in the future. It is a shame to throw it away since it brings quite a lot of power with it. I wonder if it is necessary for internal data to be stored as generics array</p>
<p style="text-align: justify;">For those of you who don&#8217;t like to use variants or want so more flexibility you can look for TAnyValue (which was inspired upon looking at TOmniValue implementation) or TOmniValue. They both work under older version of Delphi as far as I know (Delphi 2005 and up).</p>
<p style="text-align: justify;">If I missed something or if you know of another &#8220;variant&#8221; like implementation, please let me know. The purpose of this post is to explore this area as well as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cromis.net/blog/2010/03/tvalue-and-other-variable-like-implementation-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build your XML the LinqToXML style in native code &#8211; Part I.</title>
		<link>http://www.cromis.net/blog/2010/03/build-your-xml-the-linqtoxml-style-in-native-code-part-i/</link>
		<comments>http://www.cromis.net/blog/2010/03/build-your-xml-the-linqtoxml-style-in-native-code-part-i/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 09:12:19 +0000</pubDate>
		<dc:creator>Iztok Kacin</dc:creator>
				<category><![CDATA[Coding]]></category>

		<guid isPermaLink="false">http://www.cromis.net/blog/?p=698</guid>
		<description><![CDATA[A lot of you probably already know SimpleStorage. For those who don&#8217;t: http://www.cromis.net/blog/2008/07/simple-xml-based-storage/ http://www.cromis.net/blog/2008/07/simple-xml-based-storage-part-ii/ http://www.cromis.net/blog/2009/07/simple-xml-based-storage-part-iii/ http://www.cromis.net/blog/2010/02/what-is-new-in-simplestorage/ I read a blog entry recently about LinqToXML and while I was exploring the possibilities that it has, I wondered. Can something like this be done with Delphi and native code? Now SimpleStorage already enables you to write XML [...]]]></description>
			<content:encoded><![CDATA[<p>A lot of you probably already know SimpleStorage. For those who don&#8217;t:</p>
<ul>
<li><a title="http://www.cromis.net/blog/2008/07/simple-xml-based-storage/" href="http://www.cromis.net/blog/2008/07/simple-xml-based-storage/">http://www.cromis.net/blog/2008/07/simple-xml-based-storage/</a></li>
<li><a title="http://www.cromis.net/blog/2008/07/simple-xml-based-storage-part-ii/" href="http://www.cromis.net/blog/2008/07/simple-xml-based-storage-part-ii/">http://www.cromis.net/blog/2008/07/simple-xml-based-storage-part-ii/</a></li>
<li><a title="http://www.cromis.net/blog/2009/07/simple-xml-based-storage-part-iii/" href="http://www.cromis.net/blog/2009/07/simple-xml-based-storage-part-iii/">http://www.cromis.net/blog/2009/07/simple-xml-based-storage-part-iii/</a></li>
<li><a title="http://www.cromis.net/blog/2010/02/what-is-new-in-simplestorage/" href="http://www.cromis.net/blog/2010/02/what-is-new-in-simplestorage/">http://www.cromis.net/blog/2010/02/what-is-new-in-simplestorage/</a></li>
</ul>
<p style="text-align: justify;">I read a blog entry recently about <a title="LinqToXML" href="http://www.delphifeeds.com/go/s/66053">LinqToXML</a> and while I was exploring the possibilities that it has, I wondered. Can something like this be done with Delphi and native code? Now SimpleStorage already enables you to write XML in a very compact and efficient way, but it still lacks some elegance on the more native XML building approach. Ok there is a question why would you even want to write XML code inside the IDE editor? But sometimes it is viable, maybe just a wrapper XML shell for something that gets dynamically injected into it. Nevertheless I was intrigued if it can be done. Primož Gabrijelčič  has done it and blogged about it:</p>
<ul>
<li><a title="http://17slon.com/blogs/gabr/2009/04/fluent-xml-1.html" href="http://17slon.com/blogs/gabr/2009/04/fluent-xml-1.html">http://17slon.com/blogs/gabr/2009/04/fluent-xml-1.html</a></li>
<li><a title="http://17slon.com/blogs/gabr/2009/04/fluent-xml-2.html" href="http://17slon.com/blogs/gabr/2009/04/fluent-xml-2.html">http://17slon.com/blogs/gabr/2009/04/fluent-xml-2.html</a></li>
</ul>
<p style="text-align: justify;">It was a nice display what fluent interfaces approach can do, but I was not happy completely. I was aiming at code that would get rid of the &#8220;Here, Back&#8230;&#8221; functions to navigate in the document, because you don&#8217;t need them. You always build your document in one swoop and maybe access single elements latter. I know why they were used in that approach and that is why I think with fluent interfaces alone it is hard to achieve the wanted result. SimpleStorage uses an approach similar to that, but not to full extent. The second reason was I wanted to implement it using SimpleStorage, because my aim is to evolve it to be a great and all around tool for XML and data manipulation.</p>
<p style="text-align: justify;">The goal I wanted to achieve was that the Delphi code written inside IDE would match the actual XML as closely as possible and with as little boilerplate code as possible. This way you get the benefit of seeing the resulting XML before it is even created. Without further delay let me show you the results.</p>
<p>First the XML we are trying to construct.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Demografija<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Males<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Janez<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Novak<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Janez<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Darko<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Gazvoda<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Darko<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Mitja<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Dežela<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Mitja<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Tilen<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Medved<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Tilen<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Males<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Females<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Marija&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Gorenjska<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Tanja&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Notranjska<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Maja&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Primorska<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Tadeja&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Pomurje<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Irma&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Posočje<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Person</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;Marija&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Notranjska<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Person<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Females<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Demografija<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>And now the code that does it</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TfMain<span style="color: #000066;">.</span><span style="color: #006600;">btnExample2Click</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  MyStorage<span style="color: #000066;">:</span> ISimpleStorage<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  MyStorage <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CreateStorage<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Demografija'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  CreateBuilder<span style="color: #000066;">&#40;</span>MyStorage<span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">Construct</span><span style="color: #000066;">&#40;</span>
  <span style="color: #000066;">&#91;</span>
    AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Males'</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#91;</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Janez'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Novak'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Darko'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Gazvoda'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Mitja'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Dežela'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Tilen'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Medved'</span><span style="color: #000066;">&#41;</span>
    <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
    AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Females'</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#91;</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Person'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Name'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Marija'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Gorenjska'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Person'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Name'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Tanja'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Notranjska'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Person'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Name'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Maja'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Primorska'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Person'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Name'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Tadeja'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Pomurje'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Person'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Name'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Irma'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Posočje'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Person'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Name'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Marija'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Notranjska'</span><span style="color: #000066;">&#41;</span>
    <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span>
  <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>And for the second example let me show how to inject the actual dynamically generated XML into the given builder template. The target XML is like this</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Books<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;English<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Science<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Mathematics</span> <span style="color: #000066;">Difficulty</span>=<span style="color: #ff0000;">&quot;High&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>5<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Mathematics<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Physics</span> <span style="color: #000066;">Difficulty</span>=<span style="color: #ff0000;">&quot;Low&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Physics<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Computers</span> <span style="color: #000066;">Difficulty</span>=<span style="color: #ff0000;">&quot;Medium&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>8<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Computers<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Engineering</span> <span style="color: #000066;">Difficulty</span>=<span style="color: #ff0000;">&quot;Low&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>4<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Engineering<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Electoronics</span> <span style="color: #000066;">Difficulty</span>=<span style="color: #ff0000;">&quot;High&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>8<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Electoronics<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Biology<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Microbiology</span> <span style="color: #000066;">Difficulty</span>=<span style="color: #ff0000;">&quot;High&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>4<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Microbiology<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Undefined</span> <span style="color: #000066;">Difficulty</span>=<span style="color: #ff0000;">&quot;Low&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Undefined<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Biology<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Science<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Musical<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Classic<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Classic<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Etno<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Etno<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Pop<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>8<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Pop<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Musical<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/English<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Books<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>And the code that does it looks like this</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TfMain<span style="color: #000066;">.</span><span style="color: #006600;">btnExample1Click</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  MyStorage<span style="color: #000066;">:</span> ISimpleStorage<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  MyStorage <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CreateStorage<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Books'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  CreateBuilder<span style="color: #000066;">&#40;</span>MyStorage<span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">Construct</span><span style="color: #000066;">&#40;</span>
  <span style="color: #000066;">&#91;</span>
    AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'English'</span><span style="color: #000066;">,</span>
    <span style="color: #000066;">&#91;</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Science'</span><span style="color: #000066;">,</span>
      <span style="color: #000066;">&#91;</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Mathematics'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Difficulty'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'High'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">5</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Physics'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Difficulty'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Low'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Computers'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Difficulty'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Medium'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">8</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Engineering'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Difficulty'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Low'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">4</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Electoronics'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Difficulty'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'High'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">8</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Biology'</span><span style="color: #000066;">,</span>
        <span style="color: #000066;">&#91;</span>
          AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Microbiology'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Difficulty'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'High'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">4</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
          AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Undefined'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'Difficulty'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Low'</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">3</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
          Add<span style="color: #000066;">&#40;</span>
            <span style="color: #000000; font-weight: bold;">procedure</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Element<span style="color: #000066;">:</span> IElement<span style="color: #000066;">&#41;</span>
            <span style="color: #000000; font-weight: bold;">begin</span>
              <span style="color: #808080; font-style: italic;">// add few elements here</span>
              Element<span style="color: #000066;">.</span><span style="color: #000066;">Append</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'InsertedNode'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span>
              Element<span style="color: #000066;">.</span><span style="color: #000066;">Append</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'InsertedNode'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">2</span><span style="color: #000066;">;</span>
              Element<span style="color: #000066;">.</span><span style="color: #000066;">Append</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'InsertedNode'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">3</span><span style="color: #000066;">;</span>
            <span style="color: #000000; font-weight: bold;">end</span>
          <span style="color: #000066;">&#41;</span>
        <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span>
      <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
      AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Musical'</span><span style="color: #000066;">,</span>
      <span style="color: #000066;">&#91;</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Classic'</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">2</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Etno'</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">2</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>
        AddElement<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Pop'</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">8</span><span style="color: #000066;">&#41;</span>
      <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span>
    <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span>
  <span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p style="text-align: justify;">The result is easily readable dont&#8217; you think? I would really like to hear your opinion on the code. Maybe you have a suggestion or idea, or you simply have a comment about how it all sucks <img src='http://www.cromis.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  The code can already be downloaded from my download page, but be warned, it is still in early development and it will change. It only works in Delphi 2010 (should in 2009) opposed to other parts of SimpleStorage that work in Delphi 2006 and up. Also I use Variants for values for now and that will change. I will replace them with records and implicit operator overloads.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cromis.net/blog/2010/03/build-your-xml-the-linqtoxml-style-in-native-code-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updated SimpleStorage demos and added IDocument</title>
		<link>http://www.cromis.net/blog/2010/02/updated-simplestorage-demos-and-added-idocument/</link>
		<comments>http://www.cromis.net/blog/2010/02/updated-simplestorage-demos-and-added-idocument/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 13:17:14 +0000</pubDate>
		<dc:creator>Iztok Kacin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Demos]]></category>
		<category><![CDATA[IDocument]]></category>
		<category><![CDATA[SimpleStorage]]></category>
		<category><![CDATA[update]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.cromis.net/blog/?p=680</guid>
		<description><![CDATA[As I promised, I updated the demos. I added two new demos. One showing how to manipulate collection of documents and the other to show how to Encrypt / Decrypt whole documents. I also made a change in the &#8220;Cromis.SimpleStorage.Collection.pas&#8221; unit. There is now a new &#8220;IDocument&#8221; interface which is very simple: IDocument = Interface&#40;IInterface&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>As I promised, I updated the demos. I added two new demos. One showing how to manipulate collection of documents and the other to show how to Encrypt / Decrypt whole documents.</p>
<p>I also made a change in the &#8220;Cromis.SimpleStorage.Collection.pas&#8221; unit. There is now a new &#8220;IDocument&#8221; interface which is very simple:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  IDocument <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">Interface</span><span style="color: #000066;">&#40;</span>IInterface<span style="color: #000066;">&#41;</span>
  <span style="color: #000066;">&#91;</span><span style="color: #ff0000;">'{0B2F03BD-9929-43A1-A7E8-62B372D2D96C}'</span><span style="color: #000066;">&#93;</span>
    <span style="color: #000000; font-weight: bold;">function</span> GetPath<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">function</span> GetData<span style="color: #000066;">:</span> ISimpleStorage<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">property</span> Data<span style="color: #000066;">:</span> ISimpleStorage <span style="color: #000066;">read</span> GetData<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">property</span> Path<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span> <span style="color: #000066;">read</span> GetPath<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p style="text-align: justify;">Now instead of the collection returning directly ISimpleStorage interface, it returns the IDocument. The interface holds the storage XML and the additional property, the path of the document. This can be important in certain situations. Here I would also like to clarify that for now the collection can only hold XML documents on file system. They cannot be held directly in memory. This is intentional, because in many cases the collections can be huge and there is no way that all those XML documents would fit into memory. It would also be very time consuming to parse and load all XML documents in advance, before even using them.</p>
<p style="text-align: justify;">You can get the new version and demos from the download page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cromis.net/blog/2010/02/updated-simplestorage-demos-and-added-idocument/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is new in SimpleStorage</title>
		<link>http://www.cromis.net/blog/2010/02/what-is-new-in-simplestorage/</link>
		<comments>http://www.cromis.net/blog/2010/02/what-is-new-in-simplestorage/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 13:37:18 +0000</pubDate>
		<dc:creator>Iztok Kacin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[OmniXML]]></category>
		<category><![CDATA[SimpleStorage]]></category>
		<category><![CDATA[storage]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[XML manipulation]]></category>

		<guid isPermaLink="false">http://www.cromis.net/blog/?p=648</guid>
		<description><![CDATA[As you probably know by now (or not) SimpleStorage is a set of interfaces to ease the manipulation of XML documents. It is based on OmniXML, a wonderful Delphi XML parser. Simple Storage aims to treat XML as a practical data storage and means of data serialization and transportation. I have written about its usage [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">As you probably know by now (or not) SimpleStorage is a set of interfaces to ease the manipulation of XML documents. It is based on <a title="OmniXML" href="http://www.omnixml.com/">OmniXML</a>, a wonderful Delphi XML parser. Simple Storage aims to treat XML as a practical data storage and means of data serialization and transportation. I have written about its usage in a series of articles, some time ago. Here are the articles:</p>
<ul>
<li><a title="SimpleStorage" href="http://www.cromis.net/blog/2008/07/simple-xml-based-storage/">Simple XML based storage &#8211; Part I.</a></li>
<li><a title="SimpleStorage" href="http://www.cromis.net/blog/2008/07/simple-xml-based-storage-part-ii/">Simple XML based storage &#8211; Part II.</a></li>
<li><a title="SimpleStorage" href="http://www.cromis.net/blog/2009/07/simple-xml-based-storage-part-iii/">Simple XML based storage &#8211; Part III.</a></li>
</ul>
<p style="text-align: justify;">From then, the framework has matured and I use it in a lot of my software. It has proven invaluable in terms of time savings and ease of XML manipulation. After all I have written it because I was tired of doing the same XML tasks over and over again. Recently, I upgraded it with two new important units . They cover two aspects of XML manipulation:</p>
<ul>
<li>Encryption on a document scale</li>
<li>Working with collection of documents</li>
</ul>
<p style="text-align: justify;">I also did an upgrade of the core IElement interface. The goal was easier node attributes manipulation. I will show examples of all three improvements here. The new version of SimpleStorage can be found on my <a title="SimpleStorage download" href="http://www.cromis.net/blog/downloads/simplestorage/">download</a> page as always.</p>
<h3><span style="color: #0000ff;">Encryption on a document scale</span></h3>
<p style="text-align: justify;"><span style="color: #0000ff;"><span style="color: #000000;">I recently had the need to encrypt whole XML documents. Since I already have SimpleStorage and <a title="XTEA download" href="http://www.cromis.net/blog/downloads/xtea-encryption/">XTEA</a> encryption algorithm in my library, this was a no brainer. Whole documents can now be encrypted with some very simple code:</span></span></p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  EncryptedStorage<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'MyVeryStrongKey'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">SaveToFile</span><span style="color: #000066;">&#40;</span>StorageFromFile<span style="color: #000066;">&#40;</span>OpenDialog<span style="color: #000066;">.</span><span style="color: #006600;">FileName</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> SaveDialog<span style="color: #000066;">.</span><span style="color: #006600;">FileName</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></div></div>

<p>And decrypted just as easily.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  EncryptedStorage<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'MyVeryStrongKey'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">LoadFromFile</span><span style="color: #000066;">&#40;</span>OpenDialog<span style="color: #000066;">.</span><span style="color: #006600;">FileName</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">SaveToFile</span><span style="color: #000066;">&#40;</span>SaveDialog<span style="color: #000066;">.</span><span style="color: #006600;">FileName</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></div></div>

<p style="text-align: justify;">I have intentionally wrote this in one line, because I always want to show how compact and powerfull the whole framework is. It tends to minimize tedious code and make your life easier. In real apps this should probably be two lines for easy redability.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  Storage <span style="color: #000066;">:</span><span style="color: #000066;">=</span> StorageFromFile<span style="color: #000066;">&#40;</span>OpenDialog<span style="color: #000066;">.</span><span style="color: #006600;">FileName</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  EncryptedStorage<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'MyVeryStrongKey'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">SaveToFile</span><span style="color: #000066;">&#40;</span>Storage <span style="color: #000066;">,</span> SaveDialog<span style="color: #000066;">.</span><span style="color: #006600;">FileName</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></div></div>

<p>You can also encrypt / decrypt directly but you can look for that yourself. The code is obvious.</p>
<h3><span style="color: #0000ff;">Easier node attributes manipulation</span></h3>
<p style="text-align: justify;"><span style="color: #0000ff;"><span style="color: #000000;">As I said, I strive to make the code compact and clear and attribute manipulation was one thing, that bugged me from the beginning of SimpleStorage. Everything else was very compact, but if you wanted to manipulate attribute &#8220;Language&#8221;</span> <span style="color: #000000;">of node &#8220;Book&#8221;</span>, <span style="color: #000000;">for instance,</span> <span style="color: #000000;">you had to write something like the following code. The first line is setting &#8220;Language&#8221; attribute of the &#8220;Book&#8221; node, by first getting the &#8220;Book&#8221; node and the second is setting the &#8220;Language&#8221; directly from &#8220;Book&#8221; node.<br />
</span></span></p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  CurrentNode<span style="color: #000066;">.</span><span style="color: #006600;">Get</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Book'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">Attributes</span><span style="color: #000066;">.</span><span style="color: #006600;">Ensure</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Language'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'English'</span><span style="color: #000066;">;</span>
  CurrentNode<span style="color: #000066;">.</span><span style="color: #006600;">Attributes</span><span style="color: #000066;">.</span><span style="color: #006600;">Ensure</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Language'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'English'</span><span style="color: #000066;">;</span></pre></div></div>

<p><span style="color: #0000ff;"><span style="color: #000000;">Which is ok, but it stand out from other SimpleStorage code. So I added &#8220;shortcuts&#8221; to the IElement interface. Now you can do the same like this:<br />
</span></span></p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;">  CurrentNode<span style="color: #000066;">.</span><span style="color: #006600;">EnsureAttr</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Book'</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Language'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'English'</span><span style="color: #000066;">;</span>
  CurrentNode<span style="color: #000066;">.</span><span style="color: #006600;">EnsureAttr</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'Language'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'English'</span><span style="color: #000066;">;</span></pre></div></div>

<p>It saves a lot of characters on the long run <img src='http://www.cromis.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3><span style="color: #0000ff;">Working with collection of documents</span></h3>
<p style="text-align: justify;"><span style="color: #0000ff;"><span style="color: #000000;">Until now, SimpleStorage was great if you wanted to manipulate a single XML document. But what if you have lots of those and you wanted to process all of them. You had to write your own code (which is easy of course, but again repetitive work)</span> <span style="color: #000000;">and work with each </span><span style="color: #000000;">document separately. Well no more. You now have &#8220;</span></span>IDocuments<span style="color: #0000ff;"><span style="color: #000000;">&#8220;</span> <span style="color: #000000;">interface that enables you to work over collections of XML documents. I will show this on a simple example. This was a real task, I had in front of me a few days ago. I had a bunch of XML documents looking like this:</span></span></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Devices<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694350026014400780050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;23632&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;13092&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694350026012900880050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;14728&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;41084&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359925017200280050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;22116&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;61808&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694350026013800980050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;15140&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;54612&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359725014400580050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;13460&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;34064&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359925013100880050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;16332&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;47120&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359625013600380050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;14860&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;47752&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359625014900680050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;6120&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;10852&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359925016600480050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;11724&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;46016&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694350026011900980050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;6404&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;13540&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359925013600780050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;7616&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;10376&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359525017200080050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;3060&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;9996&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359925012400380050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;460&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;34084&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694359725010700280050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;8228&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;35664&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Device</span> <span style="color: #000066;">ID</span>=<span style="color: #ff0000;">&quot;002694350026012000780050BF3F5173&quot;</span> <span style="color: #000066;">InBound</span>=<span style="color: #ff0000;">&quot;4076&quot;</span> <span style="color: #000066;">OutBound</span>=<span style="color: #ff0000;">&quot;26664&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Devices<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p style="text-align: justify;">This is a shortened version, but you get the idea. It is an XML that holds the &#8220;InBound&#8221; and &#8220;OutBound&#8221; traffic for mobile devices, over the HTTP protocol. In short, it enables me to see how much traffic my application generates for a single device. The shown XML, is a log for a single month of traffic. And in over two years, quite a few of these files accumulated. It would be easy to make a sum of   &#8220;InBound&#8221; and &#8220;OutBound&#8221; traffic and  report that for a single device over the complete time span in a traditional way. But lets see how we can do that with SimpleStorage. First let me show how to get all log entries for a single device. All XML logs were stored in &#8220;s:\bandwidth&#8221; directory.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">Button2Click</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  Documents<span style="color: #000066;">:</span> IDocuments<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  Documents <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CreateCollection<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'s:\bandwidth'</span><span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">False</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  Documents<span style="color: #000066;">.</span><span style="color: #006600;">Get</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'//Device[@ID=&quot;3FBF5000735108010E1212674B5D036A&quot;]'</span><span style="color: #000066;">,</span>
    <span style="color: #000000; font-weight: bold;">procedure</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Document<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">const</span> Element<span style="color: #000066;">:</span> IElement<span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">const</span> Data<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      ListBox1<span style="color: #000066;">.</span><span style="color: #006600;">Items</span><span style="color: #000066;">.</span><span style="color: #006600;">Add</span><span style="color: #000066;">&#40;</span>Document <span style="color: #000066;">+</span> <span style="color: #ff0000;">' - '</span> <span style="color: #000066;">+</span> Element<span style="color: #000066;">.</span><span style="color: #006600;">Attributes</span><span style="color: #000066;">.</span><span style="color: #006600;">Get</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'InBound'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span>
  <span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p style="text-align: justify;">Thats it. Simple isn&#8217;t it. Try to do the same with classic MS XML and compare the result.  Let me tell you again what I just did in these few lines of code. First I acuired all XML documents in a sinlge directory. Then I enumerated all the documents, but only processed the ones that have a distinct node (based on XPath) in them. Finally I printed some results for the selected nodes. If you dislike the anonymous approach you can also do it with classic callback functions. The interface supports both. the Get function / procedure is overloaded and it returns documents collection or it enumerates nodes over all documents based on XPath.</p>
<p style="text-align: justify;">If you want to filter the collection of documents you have at your disposal you can do it like I have shown in this next example. This is just an example to show you how, it has no real value. In the callback you decide if the document will be included in the result collection or not. Then the code enumerates all documents and prints out a single attribute.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">Button3Click</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  Documents<span style="color: #000066;">:</span> IDocuments<span style="color: #000066;">;</span>
  Document<span style="color: #000066;">:</span> ISimpleStorage<span style="color: #000066;">;</span>
  Element<span style="color: #000066;">:</span> IElement<span style="color: #000066;">;</span>
  Subset<span style="color: #000066;">:</span> IDocuments<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  ListBox1<span style="color: #000066;">.</span><span style="color: #006600;">Clear</span><span style="color: #000066;">;</span>
  <span style="color: #000066;">Randomize</span><span style="color: #000066;">;</span>
&nbsp;
  Documents <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CreateCollection<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'s:\bandwidth'</span><span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">False</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  Subset <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Documents<span style="color: #000066;">.</span><span style="color: #006600;">Get</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'//Device[@ID=&quot;3FBF5000735108010E1212674B5D036A&quot;]'</span><span style="color: #000066;">,</span>
    <span style="color: #000000; font-weight: bold;">procedure</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Document<span style="color: #000066;">:</span> ISimpleStorage<span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">const</span> FileName<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000066;">Include</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">const</span> Data<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      <span style="color: #000066;">Include</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Random</span><span style="color: #000066;">&#40;</span><span style="color: #0000ff;">10</span><span style="color: #000066;">&#41;</span> &gt; <span style="color: #0000ff;">5</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span>
  <span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> Document <span style="color: #000000; font-weight: bold;">in</span> Subset <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">begin</span>
    Element <span style="color: #000066;">:</span><span style="color: #000066;">=</span> Document<span style="color: #000066;">.</span><span style="color: #006600;">Get</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'//Device[@ID=&quot;3FBF5000735108010E1212674B5D036A&quot;]'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    ListBox1<span style="color: #000066;">.</span><span style="color: #006600;">Items</span><span style="color: #000066;">.</span><span style="color: #006600;">Add</span><span style="color: #000066;">&#40;</span>Element<span style="color: #000066;">.</span><span style="color: #006600;">GetAttr</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'InBound'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>Now finally let me show the real code that helped me sumarize the traffic report. I used a classic callback here for sake of redability.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">type</span>
  TDeviceObject <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">class</span>
    InBound<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Int64</span><span style="color: #000066;">;</span>
    OutBound<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Int64</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">OnDeviceCallback</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> Document<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">const</span> Element<span style="color: #000066;">:</span> IElement<span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">const</span> Data<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  DeviceIdx<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  HashTable<span style="color: #000066;">:</span> TStringList<span style="color: #000066;">;</span>
  DeviceObject<span style="color: #000066;">:</span> TDeviceObject<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  HashTable <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStringList<span style="color: #000066;">&#40;</span>Data<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  DeviceIdx <span style="color: #000066;">:</span><span style="color: #000066;">=</span> HashTable<span style="color: #000066;">.</span><span style="color: #006600;">IndexOf</span><span style="color: #000066;">&#40;</span>Element<span style="color: #000066;">.</span><span style="color: #006600;">GetAttr</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'ID'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">if</span> DeviceIdx <span style="color: #000066;">=</span> <span style="color: #000066;">-</span><span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">then</span>
    DeviceIdx <span style="color: #000066;">:</span><span style="color: #000066;">=</span> HashTable<span style="color: #000066;">.</span><span style="color: #006600;">AddObject</span><span style="color: #000066;">&#40;</span>Element<span style="color: #000066;">.</span><span style="color: #006600;">GetAttr</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'ID'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsString</span><span style="color: #000066;">,</span> TDeviceObject<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  DeviceObject <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TDeviceObject<span style="color: #000066;">&#40;</span>HashTable<span style="color: #000066;">.</span><span style="color: #006600;">Objects</span><span style="color: #000066;">&#91;</span>DeviceIdx<span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  DeviceObject<span style="color: #000066;">.</span><span style="color: #006600;">InBound</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> DeviceObject<span style="color: #000066;">.</span><span style="color: #006600;">InBound</span> <span style="color: #000066;">+</span> Element<span style="color: #000066;">.</span><span style="color: #006600;">GetAttr</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'InBound'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span><span style="color: #000066;">;</span>
  DeviceObject<span style="color: #000066;">.</span><span style="color: #006600;">OutBound</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> DeviceObject<span style="color: #000066;">.</span><span style="color: #006600;">OutBound</span> <span style="color: #000066;">+</span> Element<span style="color: #000066;">.</span><span style="color: #006600;">GetAttr</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'OutBound'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">.</span><span style="color: #006600;">AsInteger</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">Button1Click</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  I<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
  HashTable<span style="color: #000066;">:</span> TStringList<span style="color: #000066;">;</span>
  Documents<span style="color: #000066;">:</span> IDocuments<span style="color: #000066;">;</span>
  OutputData<span style="color: #000066;">:</span> TStringList<span style="color: #000066;">;</span>
  DeviceObject<span style="color: #000066;">:</span> TDeviceObject<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  HashTable <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStringList<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">try</span>
    Documents <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CreateCollection<span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'s:\bandwidth'</span><span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">False</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    Documents<span style="color: #000066;">.</span><span style="color: #006600;">Get</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'//Device'</span><span style="color: #000066;">,</span> OnDeviceCallback<span style="color: #000066;">,</span> HashTable<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
    OutputData <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TStringList<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">try</span>
      <span style="color: #000000; font-weight: bold;">for</span> I <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">to</span> HashTable<span style="color: #000066;">.</span><span style="color: #006600;">Count</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">do</span>
      <span style="color: #000000; font-weight: bold;">begin</span>
       DeviceObject <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TDeviceObject<span style="color: #000066;">&#40;</span>HashTable<span style="color: #000066;">.</span><span style="color: #006600;">Objects</span><span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
       OutputData<span style="color: #000066;">.</span><span style="color: #006600;">Add</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">Format</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'%s,%d,%d'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span>HashTable<span style="color: #000066;">&#91;</span>I<span style="color: #000066;">&#93;</span><span style="color: #000066;">,</span> DeviceObject<span style="color: #000066;">.</span><span style="color: #006600;">InBound</span><span style="color: #000066;">,</span> DeviceObject<span style="color: #000066;">.</span><span style="color: #006600;">OutBound</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
      OutputData<span style="color: #000066;">.</span><span style="color: #006600;">SaveToFile</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'S:\bandwidth\Bandwidth.txt'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">finally</span>
      OutputData<span style="color: #000066;">.</span><span style="color: #006600;">Free</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">finally</span>
    HashTable<span style="color: #000066;">.</span><span style="color: #006600;">Free</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>The result is a CSV file ready for excel.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cromis.net/blog/2010/02/what-is-new-in-simplestorage/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How to start a GUI process from service, under Windows Vista/7</title>
		<link>http://www.cromis.net/blog/2010/01/how-to-start-a-gui-process-from-service-under-windows-vista7/</link>
		<comments>http://www.cromis.net/blog/2010/01/how-to-start-a-gui-process-from-service-under-windows-vista7/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 22:14:12 +0000</pubDate>
		<dc:creator>Iztok Kacin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[CreateProcessAsUser]]></category>
		<category><![CDATA[elevate]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[LOCAL SYSTEM]]></category>
		<category><![CDATA[priveleges]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[Vista]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Windows 7]]></category>

		<guid isPermaLink="false">http://www.cromis.net/blog/?p=553</guid>
		<description><![CDATA[Today I had a interesting challenge in front of me. I had to start a GUI application under Windows Vista or 7 with elevated privileges. And I had to start it from a restricted account. Why? Because the process was meant to start from a USB drive and act as a data synchronization tool. So [...]]]></description>
			<content:encoded><![CDATA[<p>Today I had a interesting challenge in front of me. I had to start a GUI application under Windows Vista or 7 with elevated privileges. And I had to start it from a restricted account. Why? Because the process was meant to start from a USB drive and act as a data synchronization tool. So in order to do some more complicated things, it has to have enough privileges. But it has to be started from a restricted user account, as this will be the account that will synchronize the data via the USB.</p>
<p>After some debating, the decision was, to use a service that will start the GUI application. It goes like this:</p>
<ol>
<li>The USB is inserted.</li>
<li>The GUI application is auto-started, or the service detects that the USB was inserted.</li>
<li>The GUI application informs the service via IPC that it needs to be elevated and exits immediately.</li>
<li>The service (running under SYSTEM account) starts the process with SYSTEM account token.</li>
<li>The GUI application detects that is was started by the service.</li>
<li>The GUI application has all possible privileges and does its job.</li>
</ol>
<p>Let me say here, that I am aware of the security risks involved in such procedure. But with proper approach this can be made safe. OK the theory is looking fine. And it works with no problems under Windows 2000/XP. But under Vista/7 it is a different story altogether. Here is the Microsoft paper on the topic:</p>
<p><a title="Interactive Services " href="http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx">http://msdn.microsoft.com/en-us/library/ms683502%28VS.85%29.aspx</a></p>
<p>To make it short, the service running under SYSTEM account is running in an non-interactive <a title="window station" href="http://msdn.microsoft.com/en-us/library/ms687096%28VS.85%29.aspx">window station</a>. In other words, that means, that it cannot interact with the desktop. This was tightened in Windows Vista. You have to specify the &#8220;Interactive  service&#8221; flag which is discouraged and can even be nullified in the registry (no interactive services). So starting a process from service, makes the process invisible because it is not running in the correct (logged on user) session.</p>
<p>What if we could just get a session for the logged on user, or even the user token and start the new process in the correct session. But wait we can do that, let me show you how. I found a  good example at the code project:</p>
<p><a title="VistaSessions" href="http://www.codeproject.com/KB/vista-security/VistaSessions.aspx">http://www.codeproject.com/KB/vista-security/VistaSessions.aspx</a></p>
<p>I started there. I ported the code to Delphi, cleaned it and removed the parts that are not needed. Here is the result:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> LaunchAppIntoDifferentSession<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">const</span> FileName<span style="color: #000066;">,</span> Params<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span> <span style="color: #000000; font-weight: bold;">const</span> WaitFor<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Cardinal</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
  <span style="color: #000066;">PI</span><span style="color: #000066;">:</span> PROCESS_INFORMATION<span style="color: #000066;">;</span>
  SI<span style="color: #000066;">:</span> STARTUPINFO<span style="color: #000066;">;</span>
  bResult<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Boolean</span><span style="color: #000066;">;</span>
  LaucherApp<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
  dwSessionId<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">DWORD</span><span style="color: #000066;">;</span>
  hUserTokenDup<span style="color: #000066;">,</span> hPToken<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">THANDLE</span><span style="color: #000066;">;</span>
  dwCreationFlags<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">DWORD</span><span style="color: #000066;">;</span>
  CommandLine<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
  Directory<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
  tp<span style="color: #000066;">:</span> TOKEN_PRIVILEGES<span style="color: #000066;">;</span>
  pEnv<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Pointer</span><span style="color: #000066;">;</span>
  LD<span style="color: #000066;">:</span> LUID<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">try</span>
    LaucherApp <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">IncludeTrailingPathDelimiter</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">ExtractFilePath</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">ParamStr</span><span style="color: #000066;">&#40;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> cLauncherApp<span style="color: #000066;">;</span>
    dwCreationFlags <span style="color: #000066;">:</span><span style="color: #000066;">=</span> NORMAL_PRIORITY_CLASS <span style="color: #000000; font-weight: bold;">or</span> CREATE_NEW_CONSOLE<span style="color: #000066;">;</span>
    CommandLine <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Format</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'%s &quot;%s&quot; &quot;%s&quot;'</span><span style="color: #000066;">,</span> <span style="color: #000066;">&#91;</span>LaucherApp<span style="color: #000066;">,</span>
                                           FileName<span style="color: #000066;">,</span>
                                           Params<span style="color: #000066;">&#93;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    Directory <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">ExtractFilePath</span><span style="color: #000066;">&#40;</span>LaucherApp<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">// get the current active session and the token</span>
    dwSessionId <span style="color: #000066;">:</span><span style="color: #000066;">=</span> WtsGetActiveConsoleSessionID<span style="color: #000066;">;</span>
    <span style="color: #808080; font-style: italic;">//WTSQueryUserToken(dwSessionId, &amp;amp;hUserToken);</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">// initialize startup info</span>
    <span style="color: #000066;">FillChar</span><span style="color: #000066;">&#40;</span>SI<span style="color: #000066;">,</span> <span style="color: #000066;">SizeOf</span><span style="color: #000066;">&#40;</span>SI<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">#0</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    SI<span style="color: #000066;">.</span><span style="color: #006600;">cb</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">SizeOf</span><span style="color: #000066;">&#40;</span>STARTUPINFO<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    SI<span style="color: #000066;">.</span><span style="color: #006600;">lpDesktop</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066; font-weight: bold;">PChar</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'winsta0\Default'</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    SI<span style="color: #000066;">.</span><span style="color: #006600;">dwFlags</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> STARTF_USESHOWWINDOW<span style="color: #000066;">;</span>
    SI<span style="color: #000066;">.</span><span style="color: #006600;">wShowWindow</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> SW_SHOWNORMAL<span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> OpenProcessToken<span style="color: #000066;">&#40;</span>GetCurrentProcess<span style="color: #000066;">,</span> TOKEN_ADJUST_PRIVILEGES <span style="color: #000000; font-weight: bold;">or</span>
                                           TOKEN_QUERY <span style="color: #000000; font-weight: bold;">or</span>
                                           TOKEN_DUPLICATE <span style="color: #000000; font-weight: bold;">or</span>
                                           TOKEN_ASSIGN_PRIMARY <span style="color: #000000; font-weight: bold;">or</span>
                                           TOKEN_ADJUST_SESSIONID <span style="color: #000000; font-weight: bold;">or</span>
                                           TOKEN_READ <span style="color: #000000; font-weight: bold;">or</span>
                                           TOKEN_WRITE<span style="color: #000066;">,</span>
                                           &amp;hPToken<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      <span style="color: #000000; font-weight: bold;">if</span> LookupPrivilegeValue<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span> SE_DEBUG_NAME<span style="color: #000066;">,</span> LD<span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span>
      <span style="color: #000000; font-weight: bold;">begin</span>
        tp<span style="color: #000066;">.</span><span style="color: #006600;">PrivilegeCount</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span>
        tp<span style="color: #000066;">.</span><span style="color: #006600;">Privileges</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">Luid</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> LD<span style="color: #000066;">;</span>
        tp<span style="color: #000066;">.</span><span style="color: #006600;">Privileges</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">Attributes</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> SE_PRIVILEGE_ENABLED<span style="color: #000066;">;</span>
&nbsp;
        DuplicateTokenEx<span style="color: #000066;">&#40;</span>hPToken<span style="color: #000066;">,</span> MAXIMUM_ALLOWED<span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span> SecurityIdentification<span style="color: #000066;">,</span> TokenPrimary<span style="color: #000066;">,</span> &amp;amp<span style="color: #000066;">;</span>hUserTokenDup<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
        SetTokenInformation<span style="color: #000066;">&#40;</span>hUserTokenDup<span style="color: #000066;">,</span> TokenSessionId<span style="color: #000066;">,</span> <span style="color: #000066;">@</span>dwSessionId<span style="color: #000066;">,</span> <span style="color: #000066;">SizeOf</span><span style="color: #000066;">&#40;</span><span style="color: #000066; font-weight: bold;">DWORD</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> CreateEnvironmentBlock<span style="color: #000066;">&#40;</span>pEnv<span style="color: #000066;">,</span> hUserTokenDup<span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">True</span><span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">then</span>
          dwCreationFlags <span style="color: #000066;">:</span><span style="color: #000066;">=</span> dwCreationFlags <span style="color: #000000; font-weight: bold;">or</span> CREATE_UNICODE_ENVIRONMENT
        <span style="color: #000000; font-weight: bold;">else</span>
          pEnv <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">// Launch the process in the client's logon session.</span>
        bResult <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CreateProcessAsUser<span style="color: #000066;">&#40;</span>hUserTokenDup<span style="color: #000066;">,</span>      <span style="color: #808080; font-style: italic;">// client's access token</span>
                                       <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span>                <span style="color: #808080; font-style: italic;">// file to execute</span>
                                       <span style="color: #000066; font-weight: bold;">PChar</span><span style="color: #000066;">&#40;</span>CommandLine<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #808080; font-style: italic;">// command line</span>
                                       <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span>                <span style="color: #808080; font-style: italic;">// pointer to process SECURITY_ATTRIBUTES</span>
                                       <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span>                <span style="color: #808080; font-style: italic;">// pointer to thread SECURITY_ATTRIBUTES</span>
                                       <span style="color: #000000; font-weight: bold;">False</span><span style="color: #000066;">,</span>              <span style="color: #808080; font-style: italic;">// handles are not inheritable</span>
                                       dwCreationFlags<span style="color: #000066;">,</span>    <span style="color: #808080; font-style: italic;">// creation flags</span>
                                       pEnv<span style="color: #000066;">,</span>               <span style="color: #808080; font-style: italic;">// pointer to new environment block</span>
                                       <span style="color: #000066; font-weight: bold;">PChar</span><span style="color: #000066;">&#40;</span>Directory<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span>   <span style="color: #808080; font-style: italic;">// name of current directory</span>
                                       &amp;si<span style="color: #000066;">,</span>                <span style="color: #808080; font-style: italic;">// pointer to STARTUPINFO structure</span>
                                       &amp;pi<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>               <span style="color: #808080; font-style: italic;">// receives information about new process</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #000000; font-weight: bold;">not</span> bResult <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #000000; font-weight: bold;">begin</span>
          Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">GetLastError</span><span style="color: #000066;">;</span>
          <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">end</span>
      <span style="color: #000000; font-weight: bold;">else</span>
      <span style="color: #000000; font-weight: bold;">begin</span>
        Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">GetLastError</span><span style="color: #000066;">;</span>
        <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
      <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span>
    <span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      Result <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">GetLastError</span><span style="color: #000066;">;</span>
      <span style="color: #000066;">Exit</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> WaitFor <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">begin</span>
      WaitForSingleObject<span style="color: #000066;">&#40;</span><span style="color: #000066;">PI</span><span style="color: #000066;">.</span><span style="color: #006600;">hProcess</span><span style="color: #000066;">,</span> INFINITE<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
      GetExitCodeProcess<span style="color: #000066;">&#40;</span><span style="color: #000066;">PI</span><span style="color: #000066;">.</span><span style="color: #006600;">hProcess</span><span style="color: #000066;">,</span> Result<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">finally</span>
    <span style="color: #808080; font-style: italic;">// close all handles</span>
    CloseHandle<span style="color: #000066;">&#40;</span>hUserTokenDup<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    CloseHandle<span style="color: #000066;">&#40;</span><span style="color: #000066;">PI</span><span style="color: #000066;">.</span><span style="color: #006600;">hProcess</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    CloseHandle<span style="color: #000066;">&#40;</span><span style="color: #000066;">PI</span><span style="color: #000066;">.</span><span style="color: #006600;">hThread</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    CloseHandle<span style="color: #000066;">&#40;</span>hPToken<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span></pre></div></div>

<p>The code is still not properly cleaned up, especially the error conditions, but it gives you the idea how it is done. In short it does the following:</p>
<ol>
<li>It gets the session token for the currently logged on user with &#8220;<a title="WTSGetActiveConsoleSessionId" href="http://msdn.microsoft.com/en-us/library/aa383835%28VS.85%29.aspx">WtsGetActiveConsoleSessionID</a>&#8220;.</li>
<li>It gets the user token of the current process,  that is the token for the service under SYSTEM account.</li>
<li>It duplicates that user token.</li>
<li>It sets the session for the duplicated token to be the session of the logged on user.</li>
<li>It launches the process with CreateProcessAsUser passing the duplicated, adjusted user token.</li>
</ol>
<p>Quite simple, but really powerful. What we get is a process with SYSTEM account privileges, but running in the logged on user session. At first I could not get the new process to be shown on the top of the desktop. It was started, I could see it in the taskbar, but I had to manually click on it to restore it to the original (non minimized) state . This is probably the side effect of the &#8220;hack &#8220;, because of two different sessions. But I had an Idea. What if I first create a &#8220;launcher&#8221; process, just a simple pascal &#8220;program&#8221; that just gets some parameters and then starts the real GUI application. This way my process will be started by process that is already running in the correct session. It tried the approach and now it worked perfectly. I get a process with all the priveleges, but it behaves just as any other GUI process. The launcher process is very simple:</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">program</span> GetMeUpLauncher<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">uses</span>
  Windows<span style="color: #000066;">,</span>
  SysUtils<span style="color: #000066;">,</span>
  ShellAPI<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">begin</span>
  ShellExecute<span style="color: #000066;">&#40;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'Open'</span><span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">PChar</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">ParamStr</span><span style="color: #000066;">&#40;</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #ff0000;">'/ADMIN'</span><span style="color: #000066;">,</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span> SW_SHOWNORMAL<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">.</span></pre></div></div>

<p>The &#8220;ADMIN&#8221; parameter tells the GUI application that it was started by the service with elevated privileges. I just want to mention another interesting function which is commented in the above example. &#8220;<a title="WTSQueryUserToken" href="http://msdn.microsoft.com/en-us/library/aa383840%28VS.85%29.aspx">WTSQueryUserToken</a>&#8221; can get the user token of the currently logged on user. It is a really powerful function. It means we can get the token from a service for the current user and do things in his/her name. This only works if it is called from a process under SYSTEM account. As it is not needed in my example I commented it.</p>
<p>You can get the complete example with the service, launcher and demo client from my<a title="Downloads page" href="http://www.cromis.net/blog/downloads/"> downloads page</a>. But you will need my <a title="Cromis IPC" href="http://www.cromis.net/blog/downloads/cromis-ipc/">IPC</a> and <a title="JWA" href="http://blog.delphi-jedi.net/category/downloads/jwa-downloads/">Jedi JWA</a> in order to compile it. This is why I included precompiled binaries if you want to try it out.</p>
<p><strong>EDIT:</strong></p>
<p>One of the readers pointed out that  it would be better, if the service was doing the actual synchronization. I agree with him. It is always better to use standard and supported techniques than to use hacks or undocumented features. Troubles are always around the next corner in such cases. However, as it usually happenes, we were under severe time constraint and had and already working application, that all of a sudden had to do some more. The easiest and fastest way was to do what we did. But in the future we will probably redesign it to a more standard solution, where the service will do the actual synchronization and the app will only act as the progress monitor.</p>
<p>The &#8220;hack&#8221; is still worth blogging about through <img src='http://www.cromis.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.cromis.net/blog/2010/01/how-to-start-a-gui-process-from-service-under-windows-vista7/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->