<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Gerd Riesselmann</title>
 <link href="https://www.gerd-riesselmann.net/atom.xml" rel="self"/>
 <link href="https://www.gerd-riesselmann.net"/>
 <updated>2025-02-10T13:30:58+01:00</updated>
 <id>https://www.gerd-riesselmann.net</id>
 <author>
   <name>Gerd Riesselmann</name>
   <email>contact@gerd-riesselmann.net</email>
 </author>

 
 <entry>
   <title>Git Dubious Ownership on Remote Repository</title>
   <link href="https://www.gerd-riesselmann.net/development/git-dubious-ownership-on-remote-repository/"/>
   <updated>2024-05-31T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/git-dubios-ownership</id>
   <content type="html">&lt;p&gt;A couple of days ago I suddenly got the following error, when pulling from 
a remote Git repository using SSH:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;fatal: detected dubious ownership in repository at &apos;/some/repository&apos;
To add an exception for this directory, call:

        git config --global --add safe.directory /some/repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I did as advised, and added /some/repository as safe directory. But the error remained.&lt;/p&gt;

&lt;p&gt;Adding the repository to the list of safe directories did not work.&lt;/p&gt;

&lt;p&gt;Turns out: You had to change the Git config &lt;strong&gt;on the server hosting the repository&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For this, a server administrator needs to execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo git config --system --add safe.directory &apos;/some/directory&apos;&lt;/code&gt;
on the server.&lt;/p&gt;

&lt;p&gt;If the server hosts more than one repository she may also execute &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo git config --system --add safe.directory &apos;*&apos;&lt;/code&gt;.
This will mark all repositories on this server as safe.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Restart service if executable binary changes</title>
   <link href="https://www.gerd-riesselmann.net/admin/restart-service-if-executable-binary-changes/"/>
   <updated>2014-12-30T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/admin/restart-service-if-binary-changes</id>
   <content type="html">&lt;p&gt;This is a simple bash script to restart a service if the executable binary has been changed, for example
during deployment.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;SERVICE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{insert service_name}&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;FILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;{insert /path/to/service/binary}&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;FINGERPRINT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/root/watchers/&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SERVICE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.md5&quot;&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;fingerprint_expected&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;/usr/bin/md5sum &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FILE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FINGERPRINT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fingerprint_expected&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FINGERPRINT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;fingerprint_content&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;/bin/cat &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FINGERPRINT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fingerprint_expected&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fingerprint_content&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;# Service has new binary&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fingerprint_expected&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$FINGERPRINT&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Service &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SERVICE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; has changed, trying to restart&quot;&lt;/span&gt;
  /usr/sbin/service &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SERVICE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; restart
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This is tested on a Debian system. I call it as a cron job. It is also available on &lt;a href=&quot;https://gist.github.com/gerdriesselmann/d7c034c4156759da9c09&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Deploying an assembly jar file with sbt</title>
   <link href="https://www.gerd-riesselmann.net/development/deploying-assembly-jar-file-sbt/"/>
   <updated>2011-08-03T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/deploying-assembly-jar-file-sbt</id>
   <content type="html">&lt;p&gt;The &lt;a href=&quot;https://github.com/codahale/assembly-sbt&quot;&gt;assembly-sbt&lt;/a&gt; plugin for &lt;a href=&quot;http://code.google.com/p/simple-build-tool/wiki/DocumentationHome&quot;&gt;sbt 0.7&lt;/a&gt;, the (not so) simple build tool for scala, creates a nifty fat jar containing everything to run an application anywhere. You may want an additional task to automatically copy it to a server. Here’s how (Linux only, sorry).&lt;/p&gt;

&lt;p&gt;The following code copies the assembly jar to a linux computer using ssh. So you need an ssh account there, and you will also need access via a private key. Read &lt;a href=&quot;http://www.debuntu.org/ssh-key-based-authentication&quot;&gt;this tutorial&lt;/a&gt; on how to accomplish this. The key should be password-less, since it will not be possible to enter a password.&lt;/p&gt;

&lt;p&gt;Add this to your Project class in project/build/Project.scala. I assume the assembly-sbt plugin is enabled.&lt;/p&gt;

&lt;p&gt;Change the properties to match you settings.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Process._&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;deployAction&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;account&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;user@server&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;src&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;assemblyOutputPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;absolutePath&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/dir/on/server/&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;assemblyJarName&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;target_abs&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;:&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;keyfile&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user.home&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/keyfile&quot;&lt;/span&gt;

  &lt;span class=&quot;nv&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Copying &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;src&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; to &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_abs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;scp&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-i&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target_abs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Optional. Create symbolic link to last version&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;symlink&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/path/to/symlink&quot;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Symlinking it to  &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symlink&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;cmd&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ln -sf &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symlink&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ssh&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;-i&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyfile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;

  &lt;span class=&quot;nc&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;lazy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;deploy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deployAction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;incrementVersion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;dependsOn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assembly&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;describedAs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Builds assembly and moves it to server&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;What the code is to take the assembly created by assembly-sbt and copies it to the server using scp. It then will create a symbolic link to the copied file, which therefore always points to the most recent version. After that it automatically increments the application’s version.&lt;/p&gt;

&lt;p&gt;Run it using&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sbt deploy&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</content>
 </entry>
 
 <entry>
   <title>Authentication using Unfiltered for Scala</title>
   <link href="https://www.gerd-riesselmann.net/development/authentication-using-unfiltered-scala/"/>
   <updated>2011-07-11T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/authentication-using-unfiltered-scala</id>
   <content type="html">&lt;p&gt;Since it took me a while to figure this out (though it seems very obvious now), here’s how I do
HTTP authentication in &lt;a href=&quot;http://unfiltered.databinder.net/Unfiltered.html&quot;&gt;Unfiltered&lt;/a&gt; while
preserving the authenticated user for later access.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;user&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class=&quot;n&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;pwd&quot;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nc&quot;&gt;None&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AuthPlan&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Plan&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;AuthFail&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;Unauthorized&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WWWAuthenticate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Basic realm=&quot;/&quot;&quot;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;intent&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/na&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;ResponseString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;No Authentication needed&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BasicAuth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;req&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/a&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;ResponseString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

                    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(...)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;c1&quot;&gt;// Your other filters&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;nc&quot;&gt;NotFound&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AuthFail&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nc&quot;&gt;AuthFail&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</content>
 </entry>
 
 <entry>
   <title>Using /, ? and & in the path with Apache mod_rewrite and PHP</title>
   <link href="https://www.gerd-riesselmann.net/development/using-and-path-apache-modrewrite-and-php/"/>
   <updated>2011-06-06T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/using-and-path-apache-modrewrite-and-php</id>
   <content type="html">&lt;p&gt;I came upon a nasty problem the other day: The &lt;a href=&quot;http://microformats.org/wiki/rel-tag&quot;&gt;rel-tag microformat&lt;/a&gt;, poorly designed like so many of them, requires the URL to end on the tag name. Not a cleaned up, ANSI compatible version, no, a 1:1 representation. This on the one hand leads to some woes regarding encoding and non-ansi characters, think umlauts!, and on the other hand poses problems with caracters that usually are not allowed within an URL or have a special meaning. Think for example of a tag called “Q&amp;amp;A”.&lt;/p&gt;

&lt;p&gt;Unfortunately, as we will see, simple escaping is not enough.&lt;/p&gt;

&lt;p&gt;When it comes to routing requests to PHP code, a common approach is to use Apache’s mod_rewrite to redirect everything to a single file. The according code usually looks like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-f
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-d
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(.*)$ index.php?path=$1 [L,QSA]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This code turns the current path into a query parameter named ‘path’.&lt;/p&gt;

&lt;p&gt;However, the rewriting fails if the path contains either ? or &amp;amp;, even if they are url-escaped. For example&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;/q%26a&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;where %26 is the escaped ampersand,&lt;/p&gt;

&lt;p&gt;with be turned into&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;index.php?path=q&amp;amp;a=&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note that the escaped ampersand has been turned into a real ampersand, thus dividing query parameters. We can verify this in PHP:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;nb&quot;&gt;var_dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_GET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;returns&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;path =&amp;gt; q&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;a =&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Seems like Apache is ubersmart here.&lt;/p&gt;

&lt;p&gt;There are two solutions to this problem:&lt;/p&gt;

&lt;p&gt;1.) Use the &lt;a href=&quot;http://httpd.apache.org/docs/current/rewrite/flags.html#flag_b&quot;&gt;B rewrite flag&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-f
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-d
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^(.*)$ index.php?path=$1 [L,QSA,B]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Using the ‘B’ prevents Apache from peeking into the path and from unescaping the ampersand. The path is now correctly turned into:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;index.php?path=q%26a&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And in PHP we get&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;path =&amp;gt; q&amp;amp;a&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The ‘B’ rule has been added in Apache 2. But for some reasons it doesn’t work reliable across distributions. While there are no problems on my local Ubuntu 10.4, there’s no effect on my webhoster’s Gentoo machine.&lt;/p&gt;

&lt;p&gt;Luckily, there is a more generic solution&lt;/p&gt;

&lt;p&gt;2.) Use double escaping&lt;/p&gt;

&lt;p&gt;Escaping ?, &amp;amp; (and even /) twice allows safe usage of any of them. Escaping twice means to turn&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;? =&amp;gt; %3F =&amp;gt; %253F&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;&amp;amp; =&amp;gt; %26 =&amp;gt; %2526&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;/ =&amp;gt; %2F =&amp;gt; %252F&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if we invoke&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;/q%2526a&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;we get&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;index.php?path=q%26a&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And in PHP we get&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;path =&amp;gt; q&amp;amp;a&lt;/p&gt;
&lt;/blockquote&gt;

</content>
 </entry>
 
 <entry>
   <title>Splitting large Axis generated files into separate classes</title>
   <link href="https://www.gerd-riesselmann.net/scala/splitting-large-axis-generated-files-separate-classes/"/>
   <updated>2010-08-08T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/scala/splitting-large-axis-generated-files-separate-classes</id>
   <content type="html">&lt;p&gt;I recently had to struggle with a SOAP webservice class generated by Apache Axis2. The class file
was more than 13 MB in size, and contained more than 290.000 lines of code - much more than
Eclipse, IntelliJ IDEA or NetBeans could handle. After some rather unsuccessful attempts to work around
the problem, I finally decided to write a little tool to split the huge file into smaller pieces.&lt;/p&gt;

&lt;p&gt;Apache Axis generates a stub class with all required parameter classes placed as nested classes within the stub class. Therefore I decided to extract each nested class into its own class file, turning it into a standard Java class. This additionally requires to rewrite all references to this class that use the stub class’s name.&lt;/p&gt;

&lt;p&gt;Here’s the source. It’s also &lt;a href=&quot;https://github.com/gerdriesselmann/split-axis&quot;&gt;available on GitHub&lt;/a&gt;. It’s written in Scala, but should be easily transformable into any other language, since it just consists of a single method “main”.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.io._&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.io.FileWriter&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.io.File&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Main&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Directory where Axis generated files are, including slash at the end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;in_dir&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C:/your/directory/&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Directory where to put extracted class files, including slash at the end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;out_dir&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;extracted/&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Class name prefix fpr Stub And CallbackHandler classes&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;classname_prefix&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;ChangeThis&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Class name of Axis generated stub and callback handler class&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;classname_stub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Stub&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;classname_callback&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;CallbackHandler&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Namespace of Axis generated stub class&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;your.name.space&quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buffer_out&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;FileWriter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Everything that is not extracted is kept in stub file&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;buffer_main&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_stub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.java&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_stub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.java&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;namespace_stub&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_stub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.&quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextmatch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;c&apos;&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;fromPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;getLines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;n&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namespace_stub&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;nextmatch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Look for next static class declaration (This is the starting point of next snippet)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;c&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;public static class &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Factory&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
               &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ExtensionMapper&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;public static class&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;classname&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;classname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;trim&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;classname&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;classname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;classname&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;classname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;{&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;buffer_out&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.java&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;buffer_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;package &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;;nn&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;buffer_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;public static&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;public&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nextmatch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;f&apos;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Write to stub class file&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;buffer_main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Look for end of factory class. The curly bracket after this&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// is the end of class declaration&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;f&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;//end of factory class&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nextmatch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;b&apos;&lt;/span&gt;
          &lt;span class=&quot;c1&quot;&gt;// Just copy line&lt;/span&gt;
          &lt;span class=&quot;nv&quot;&gt;buffer_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;ExtensionMapper&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_stub&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.ExtensionMapper&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Look for closing curly bracket, ending extraction&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;b&apos;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nv&quot;&gt;buffer_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;nf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;buffer_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;flush&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;buffer_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;close&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Look for next class&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nextmatch&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos;c&apos;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nv&quot;&gt;buffer_main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;flush&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;buffer_main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;close&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Change namespaces in CallbackHandler class&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;callback_file&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_callback&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.java&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;callback_file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;callback_out&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileWriter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classname_callback&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;.java&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nf&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;fromFile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;callback_file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;getLines&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;n&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;callback_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namespace_stub&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;

      &lt;span class=&quot;nv&quot;&gt;callback_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;flush&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;callback_out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;close&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nf&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Finished&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To compile, place it a file, change the variables “in_dir”, “classname_prefix”, and “namespace”, and compile it using the Scala compiler or run it as a script. &lt;a href=&quot;http://www.scala-lang.org/node/166&quot;&gt;Here’s how to use the Scala compiler&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code is more or less straight forward: Look for class declaration. When a class is found, copy stuff until the end of the class. The end of a class declaration is simply the next closing bracket, after a the comment stating the end of the factory class declaration. The Axis developers really should be thanked for this comment, since else it would be more complicated to determine the end of a class declaration. One should count curly brackets, I guess.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Creating Java Classes from WSDL file using Apache Axis 2</title>
   <link href="https://www.gerd-riesselmann.net/scala/creating-java-classes-wsdl-file-using-apache-axis-2/"/>
   <updated>2010-08-06T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/scala/creating-java-classes-wsdl-file-using-apache-axis-2</id>
   <content type="html">&lt;p&gt;Since I didn’t found this on the internet (but some rather outdated or complicated tutorials) here’s how to create Java class as wrapper for a given SOAP webservice.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Download most recent Apache Axis 2: &lt;a href=&quot;http://ws.apache.org/axis2/download.cgi&quot;&gt;http://ws.apache.org/axis2/download.cgi&lt;/a&gt;. I used version 1.5.1&lt;/li&gt;
  &lt;li&gt;Extract it to a directory of your choice&lt;/li&gt;
  &lt;li&gt;On the command line, change to subdirectory &lt;code&gt;bin/&lt;/code&gt; and run &lt;code&gt;wsdl2java.bat -uri [URL of WSDL file]&lt;/code&gt; (on Windows) or &lt;code&gt;wsdl2java.sh -uri [URL of WSDL file]&lt;/code&gt; on Linux.&lt;/li&gt;
  &lt;li&gt;The Java classes are created in the &lt;code&gt;src/&lt;/code&gt; subdirectory. Copy them into your project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To effectivly use the classes generated you must add a bunch of jars to your project dependiencies. These are found in the &lt;code&gt;lib/&lt;/code&gt; directory of the extracted Apache Axis distribution. You need ([version] notes a version number):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;axis2-adb-[version].jar&lt;/li&gt;
  &lt;li&gt;axis2-kernel-[version].jar&lt;/li&gt;
  &lt;li&gt;axis2-transport-local-[version].jar&lt;/li&gt;
  &lt;li&gt;axis2-transport-http-[version].jar&lt;/li&gt;
  &lt;li&gt;axiom-api-[version].jar&lt;/li&gt;
  &lt;li&gt;axiom-dom-[version].jar&lt;/li&gt;
  &lt;li&gt;axiom-impl-[version].jar&lt;/li&gt;
  &lt;li&gt;commons-codec-[version].jar&lt;/li&gt;
  &lt;li&gt;commons-logging-[version].jar&lt;/li&gt;
  &lt;li&gt;commons-httpclient-[version].jar&lt;/li&gt;
  &lt;li&gt;httpcore-[version].jar&lt;/li&gt;
  &lt;li&gt;mail-[version].jar&lt;/li&gt;
  &lt;li&gt;neethi-[version].jar&lt;/li&gt;
  &lt;li&gt;wsdl4j-[version].jar&lt;/li&gt;
  &lt;li&gt;XmlSchema-[version].jar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apache Axis generated a class class [Name of Webservice]Stub, e.g. for a webservice TimeOfDay it would be &lt;code&gt;TimeOfDayStub&lt;/code&gt;. This class has all the webservice’s methods and nested classes for the method’s arguments. Everything is relatively straight forward and easy to use.&lt;/p&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;There is an Apache Axis Eclipse plugin for converting WSDL into Java classes, but the download URL seems broken. I also tried to use Eclipse’s WSD toolset, but this unnecessarily requires a local web server to be set up and running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; Corrected wsdl2java parameter from &lt;code&gt;-url&lt;/code&gt; to &lt;code&gt;-uri&lt;/code&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>PHP und UTF-8 - eine Anleitung, Exkurs: Wenn die DB durcheinander gerät</title>
   <link href="https://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-exkurs-wenn-die-db-durcheinander-geraet/"/>
   <updated>2010-06-09T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-exkurs-wenn-die-db-durcheinander-geraet</id>
   <content type="html">&lt;p&gt;Manchmal kommt es vor, dass der Import von Daten in die DB fehlschlägt, und man trotz korrektem UTF-8 wieder mit verhunzten Umlauten zu tun hat. In diesem Fall kann die CONVERT-Funktion von MySQL in Verbindung mit BLOB-Spalten hilfreich sein.&lt;/p&gt;

&lt;p&gt;Hier ist ein entsprechender Test-Case:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;CREATE TABLE test (
  id integer unsigned NOT NULL auto_increment,
  content varchar(45) NOT NULL,
  PRIMARY KEY  (`id`)
) DEFAULT CHARSET=utf8;

INSERT INTO test (content) VALUES (&apos;KÃ¶ln&apos;);&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Dies erzeugt eine Tabelle, in dessen UTF-8-Spalte “content” eine nach UTF-8 konvertierte ANSI-Version von “Köln” steht:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;SELECT * FROM test;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;pre&gt;
id  |   content
--------------------
1   |  KÃ¶ln
&lt;/pre&gt;

&lt;p&gt;Diese Spalte soll nun so konvertiert werden, sodass dort korrekt “Köln” steht.&lt;/p&gt;

&lt;p&gt;Dazu wird nun zunächst einmal eine temporäre Spalte erzeugt, die den konvertierten Inhalt aufnimmt. Diese Spalte ist zunächst Latin1!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;ALTER TABLE test
  ADD COLUMN c TEXT CHARACTER SET latin1;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Nun konvertieren wir den verhunzten UTF-8-Inhalt zunächst einmal nach Latin1:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;UPDATE test SET c = CONVERT(content USING latin1);

SELECT * FROM test;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;pre&gt;
id  |   content  |  c
------------------------------
1   |  KÃ¶ln     |  KÃ¶ln
&lt;/pre&gt;

&lt;p&gt;Die Spalte “c” enthält nun im Prinzip unser UTF-8 Ergebnis, wenn nur die einzelnen Bytes betrachtet werden. Es müsste nur der Zeichensatz geändert werden, ohne dabei eine Konvertierung durchzuführen.&lt;/p&gt;

&lt;p&gt;Dies geht über den Umweg eines BLOB-Feldes:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;ALTER TABLE test MODIFY COLUMN c BLOB;
ALTER TABLE test MODIFY COLUMN c TEXT CHARACTER SET utf8;

SELECT * FROM test;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;pre&gt;
id  |   content  |  c
------------------------------
1   |  KÃ¶ln     |  Köln
&lt;/pre&gt;

&lt;p&gt;Et voilá!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>PHP und UTF-8 - eine Anleitung, Teil 3: PHP String-Funktionen</title>
   <link href="https://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-3-php-string-funktionen/"/>
   <updated>2010-02-18T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-3-php-string-funktionen</id>
   <content type="html">&lt;p&gt;Es ist nun schon eine Weile her seit der letzten Folge, Zeit die unter anderem in den &lt;a href=&quot;http://www.gyro-php.org&quot;&gt;Gyro-PHP Application Framework&lt;/a&gt; geflossen ist. Dafür soll es in der &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-einleitung/&quot;&gt;Serie über PHP und UTF-8&lt;/a&gt; nun endlich um PHP selber gehen. Dabei wird in einem ersten Schritt über die String-Funktionen von PHP zu reden sein, während die Frage der Regular Expressions auf eine weitere Folge vertagt ist.&lt;/p&gt;

&lt;p&gt;Der grundlegende Unterschied zwischen Zeichensätzen wie Latin-1 aka ISO-8859-1 und UTF-8 ist, dass erstere pro Zeichen genau ein Byte brauchen, während ein Zeichen in UTF-8 beliebig viele Byte lang sein kann. Generell gilt die Regel, dass in UTF-8 die ASCII-Zeichen (das sind die Zeichen 1-128) ein Byte lang sind, die nächsten 1664 Unicode Zeichen (wozu auch das komplette Latin1 gehört) zwei Byte, und alle weiteren Zeichen (Kyrillisch, Indisch, Arabisch, etc.) drei Bytes.&lt;/p&gt;

&lt;p&gt;Folgende Tabelle soll das illustrieren. Dargestellt werden die hexadezimalen Bytecodes eines Zeichen in Latin1 und UTF-8:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Zeichen&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Code Latin1&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Code UTF-8&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Länge UTF-8&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;A&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x41&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0x41&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Ä&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0xC4&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0xC384&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;±&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0xB1&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;0xC2B1&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;2&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Zu den drei Byte langen Zeichen gibt es naturgemäß in Latin-1 keine Entsprechungen.&lt;/p&gt;

&lt;p&gt;Dass ein Zeichen in UTF-8 keine feste Länge mehr hat, stellt nun viele String-Funktionen in PHP vor ein großes Problem: Denn diese setzen vielfach voraus, dass ein Byte immer ein Zeichen ist. Augenfällig ist dies bei der &lt;code&gt;strlen()&lt;/code&gt; Funktion.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Ä&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// ergibt 2, wenn die Datei in UTF-8 ist&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Weitere Funktionen, die mit UTF-8 Probleme bekommen sind unter anderem &lt;code&gt;strtoupper()&lt;/code&gt; und &lt;code&gt;strtolower()&lt;/code&gt; sowie &lt;code&gt;strpos()&lt;/code&gt;. Erstere würden beispielsweise das große Ä nicht erkennen, da es aus zwei Bytes besteht. &lt;code&gt;strpos()&lt;/code&gt; leidet unter den gleichen Problemen wie &lt;code&gt;strlen()&lt;/code&gt;, denn es zählt zur Positionsermittlung einfach Bytes.&lt;/p&gt;

&lt;p&gt;Zum Glück ist die Abhilfe hier ziemlich einfach. Denn für jede Funktion, die mit UTF-8 nicht funktioniert, existiert ein Pendant in der &lt;a href=&quot;http://www.php.net/manual/de/book.mbstring.php&quot;&gt;PHP-Erweiterung Multibyte String&lt;/a&gt;. Die jeweilige Ersatz-Funktion ist namensgleich mit der originalen PHP-Funktion, hat aber ein “mb_” vorangestellt. So ist etwa &lt;code&gt;mb_strtolower()&lt;/code&gt; die Mutibyte-Variante zu &lt;code&gt;strtolower()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Die einzige Ausnahme ist die Funktion &lt;code&gt;lcfirst()&lt;/code&gt;, die erst mit PHP 5.3 eingeführt wurde. Diese ist nicht UTF-8-fähig, und es gibt keine Mutibyte-Ersetzung.&lt;/p&gt;

&lt;p&gt;Alle Multibyte-Funktionen, die PHP-Funktionen ersetzen, sind um einen Parameter erweitert, der die Zeichenkodierung aufnimmt.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mb_strtolower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Äh...&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Dieser Parameter ist optional, der Default-Wert kann über den Parameter &lt;code&gt;mbstring.internal_encoding&lt;/code&gt; in der php.ini oder über die Funktion &lt;code&gt;mb_internal_encoding()&lt;/code&gt; gesetzt werden.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;mb_internal_encoding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mb_strtolower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Äh...&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Es ist möglich, durch eine Einstellung in der php.ini alle relevanten PHP-String-Funktionen durch ihre Multibyte-Äquivalente zu ersetzten. &lt;a href=&quot;http://www.php.net/manual/de/mbstring.overload.php&quot;&gt;Hier die Dokumentation dazu&lt;/a&gt;. In diesem Fall ist &lt;code&gt;mb_internal_encoding()&lt;/code&gt; unbedingt aufzurufen, es sei denn, die Eigenschaft &lt;code&gt;mbstring.internal_encoding&lt;/code&gt; ist in der php.ini bereits entsprechend gesetzt.&lt;/p&gt;

&lt;p&gt;Das Überladen der originalen PHP-Funktionen sollte aber nur der letzte Ausweg sein, um bestehenden Code UTF-8 fähig zu machen, dessen Portierung zu umfangreich ist. Ansonsten sollten die mb-Funktionen immer vorgezogen werden, da damit auch für Dritte bereits im Code zu sehen ist, dass man sich Gedanken über UTF-8 gemacht hat.&lt;/p&gt;

&lt;p&gt;Die Multibyte-Erweiterung bringt auch Funktionen für das Arbeiten mit regulären Ausdrücken mit. Allerdings nur für die Gruppe der &lt;code&gt;ereg&lt;/code&gt;-Funktionen, die ab PHP 5.3 als “deprecated”, also veraltet, markiert sind und nicht mehr verwendet werden sollten. Die &lt;code&gt;preg&lt;/code&gt;-Varianten der Regular Expressions sind ebenfalls nicht ohne weiteres UTF-8-fähig, dafür existieren aber keine Überladungen. Dies wird Thema der nächsten Folge sein.&lt;/p&gt;

&lt;p&gt;Neben den klassischen String-Funktionen ist eine zweite Gruppe von Funktionen zu diskutieren, die für den Gebrauch mit UTF-8 angepasst werden müssen. Dies sind die Konvertierungsfunktionen, die Zeichen in ihre entsprechenden HTML-Entities umwandeln. Folgende Funktionen sind betroffen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;htmlentities()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;html_entity_decode()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;htmlspecialchars()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jede dieser Funktionen aktzeptiert, das wird gerne vergessen, einen dritten Parameter, der den Zeichensatz bestimmt. Mit UTF-8 müssen diese also so aufgerufen werden:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$safe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;htmlentities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$unsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENT_QUOTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$unsafe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;html_entity_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$safe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENT_QUOTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;$safe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;htmlspecialchars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$unsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENT_QUOTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// htmlspecialchars_decode() funktioniert immer, denn &amp;lt;, &amp;gt;, &amp;amp; sind immer ASCII&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$unsafe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;htmlspecialchars_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$unsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENT_QUOTES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Leider führt das unter PHP 4.3 zu einem Fehler, auch wenn UTF-8 als Parameter laut Dokumentation unterstützt werden sollte.&lt;/p&gt;

&lt;p&gt;Bei der Portierung existierenden Codes von Latin-1 zu UTF-8 ist es am einfachsten, für jede der drei Funktionen eine eigene Funktion zu schreiben, etwa indem man ein ‘utf8_’ davor schreibt:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;cd&quot;&gt;/**
 * UTF-8 aware version of htmlentities()
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8_htmlentities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$quote&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENT_COMPAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$charset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$double_encode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;TRUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;htmlentities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$quote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$charset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$double_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cd&quot;&gt;/**
 * UTF-8 aware version of html_entity_decode()
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8_html_entity_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$quote&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENT_COMPAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$charset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;html_entity_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$quote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$charset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;cd&quot;&gt;/**
 * UTF-8 aware version of htmlspecialchars()
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8_htmlspecialchars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$quote&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENT_COMPAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$charset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$double_encode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;TRUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;htmlspecialchars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$quote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$charset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$double_encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Jetzt können die alten Aufrufe einfach per Suchen und Ersetzen durch ihre UTF-8-Varianten ersetzt werden.&lt;/p&gt;

&lt;p&gt;An dieser Stelle sei gesagt, dass es generell eine gute Idee ist, Funktionen mit vielen konstanten Parametern, wie etwa hier der Quote-Style und der Charset, von vornherein in eine eigene Funktion zu wickeln. Dies macht es einfach, das Standardverhalten später zu ändern.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>PHP und UTF-8 - eine Anleitung, Teil 2: Webseiten als UTF-8 ausliefern</title>
   <link href="https://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-2-webseiten-als-utf-8-ausliefern/"/>
   <updated>2007-11-23T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-2-webseiten-als-utf-8-ausliefern</id>
   <content type="html">&lt;p&gt;Nachdem nun &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-1-mysql/&quot;&gt;die MySQL-Datenbankverbindung reibungslos mit UTF-8 funktioniert&lt;/a&gt;
und bevor wir uns im weiteren Verlauf der &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-einleitung/&quot;&gt;Serie über PHP und UTF-8&lt;/a&gt;
wirklich PHP selber zuwenden, sollen noch ein paar Worte über das korrekte ausliefern einer UTF-8 kodieren Webseite verloren werden.
Das Problem, das hier angegangen werden soll ist: Wie erkennt der Browser eigentlich, dass eine Webseite in UTF-8 ist?&lt;/p&gt;

&lt;p&gt;Die Antwort ist&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Am Content-Type-Feld im HTTP-Header&lt;/li&gt;
&lt;li&gt;Nur wenn der HTTP-Header fehlt: Am Content-Type Meta-Tag im HTML-Code&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Betrachten wir zunächst den HTTP-Header. HTTP kennt jeder von der Adresseingabe im Browser, und dahinter verbirgt sich ein Protokoll, das regelt, wie Daten vom Server zum Client (in diesem Fall der Browser) transportiert werden. Dazu werden vor dem eigentlichen Inhalt so genannte Header gepackt, die Informationen über den folgenden Inhalt wie auch etwaige Fähigkeiten des Clients liefern. Hier Auszüge des Headers für den Aufruf der Startseite von &lt;a href=&quot;https://www.gerd-riesselmann.net&quot;&gt;gerd-riesselmann.net&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot; data-lang=&quot;http&quot;&gt;&lt;span class=&quot;err&quot;&gt;HTTP/1.x 200 OK
Date: Thu, 22 Nov 2007 18:20:20 GMT
Last-Modified: Thu, 22 Nov 2007 18:20:20 GMT
Content-Type: text/html; charset=utf-8&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Interessant ist für uns lediglich das Feld Content-Type. Dieses legt fest, das im Folgenden Text– und zwar HTML – folgt, der in UTF-8 kodiert ist.
Dieses Feld – und erst mal nur dieses! – bringt den Browser dazu, die Seite als UTF-8 anzuzeigen. Wenn hier andere Sachen stehen etwa&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-http&quot; data-lang=&quot;http&quot;&gt;&lt;span class=&quot;err&quot;&gt;Content-Type: text/html; charset=iso-8859-1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;wird die Seite entsprechend als Latin1 angezeigt. Dagegen kann man dann auch nichts machen.&lt;/p&gt;

&lt;p&gt;Deshalb muss zunächst dafür gesorgt werden, dass der Content-Type-Header richtig gesetzt wird. Dies kann auf mehrere Arten geschehen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Aufseiten des Webservers&lt;/li&gt;
  &lt;li&gt;Durch PHP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um etwa im Apache-Webserver UTF-8 auszuliefern, benötigen wir die Direktive &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/core.html#adddefaultcharset&quot;&gt;AddDefaultCharset&lt;/a&gt;  . Diese kann bei der Definition des Virtual Host in der Apache-Config gesetzt oder mittels einer .htaccess-Datei überschrieben werden. Die Syntax ist einfach:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;AddDefaultCharset&lt;/span&gt; utf-8&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Sollte das Setzen oder Überschreiben mittels .htaccess nicht möglich sein, etwa weil der Provider entsprechende Restriktionen hat, kann der Header auch mittels PHP gesetzt werden:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Content-Type: text/html; charset=utf-8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Um einen Header mittels PHP senden zu können, darf allerdings noch keine Ausgabe erfolgt sein, also macht man das am besten noch während des Programmsstarts.&lt;/p&gt;

&lt;p&gt;Was passiert, wenn ein Content-Type-Eintrag im Header fehlt, etwa weil die Datei von der lokalen Festplatte geöffnet wurde? In diesem Fall greift der Browser auf den HTML-Code zurück, und hier auf einen Meta-Tag, das den Content-Type definiert:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;http-equiv=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;content=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/html; charset=utf-8&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
...
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Das Attribut “http-equiv” bedeutet eigentlich, dass der Webserver seinen eigenen Content-Type-Eintrag im Header durch den Wert des Meta-Tags ersetzten soll. Aus naheliegenden Gründen wird das allerdings von keinem Webserver umgesetzt: Jedes Schnipsel HTML zu interpretieren würde einfach zu viel Last bedeuten.
Daher greift nur der Browser hierauf zurück, und auch nur, wenn er keinen entsprechenden Header-Eintrag vorfindet.&lt;/p&gt;

&lt;p&gt;Erwähnt sei noch, dass für XHML-Seiten das Encoding auch in der XML-Deklaration gesetzt werden kann:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Allerdings kann der Internet Explorer 6 mit solchen XML-Deklarationen nicht umgehen, weshalb sie für gewöhnlich weggelassen werden.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>PHP und UTF-8 - eine Anleitung, Teil 1: MySQL</title>
   <link href="https://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-1-mysql/"/>
   <updated>2007-11-22T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-1-mysql</id>
   <content type="html">&lt;p&gt;Am Anfang der &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-einleitung/&quot;&gt;Serie über PHP und UTF-8&lt;/a&gt;
soll zunächst ein Abstecher zu MySQL stehen, schließlich ziehen die meisten PHP-Anwendungen ihre Daten aus einer
MySQL-Datenbank. Und anders als man vielleicht annehmen würde, ist die Verwendung von UTF-8 mit MySQL
alles andere als problemfrei - insbesondere reicht es nicht aus, Tabellen einfach als UTF-8 zu deklarieren!&lt;/p&gt;

&lt;p&gt;Das Gemeine an einer fehlerhaften Verwendung von UTF-8 im Zusammenspiel von PHP und MySQL ist, das diese nicht sofort auffällt. In der Tat gibt es nur einen wirklichen Testfall für eine richtige UTF-8-Integration, und das ist die Erkennung mit dem LIKE-Operator und dem Buchstaben „a“.&lt;/p&gt;

&lt;p&gt;Hier ist ein Testcase. Der Testcase wurde auf einem Linux-System ausgeführt, das UTF-8 als Systemzeichensatz benutzt. Auf System mit anderem Systemzeichensatz kann das Verhalten reproduziert werden, indem die SQL-Statements in eine Textdatei geschrieben werden, die als UTF-8 gespeichert und dann im MySQL-Client ausgeführt wird.&lt;/p&gt;

&lt;p&gt;Starten Sie den MySQL-Client aus der Kommandozeile (nein – PHPMyAdmin, MySQL Query Browser oder andere Tools zählen nicht!):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql &lt;span class=&quot;nt&quot;&gt;-uroot&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;rootpasswort] &lt;span class=&quot;nt&quot;&gt;--default-character-set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;LATIN1&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;und geben Sie folgende Zeilen ein:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;create database utf8test default character set &apos;UTF8&apos;;
use utf8test
create table sorttest (value varchar(15)) default character set &apos;UTF8&apos;;
insert into sorttest (value) values (&apos;aaa&apos;);
insert into sorttest (value) values (&apos;üüü&apos;);
select * from sorttest where value like &apos;a%&apos;;&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Das erwartete Ergebnis ist natürlich eine Zeile, nämlich „aaa“ – wir erhalten jedoch zwei: „aaa“ und „üüü“!&lt;/p&gt;

&lt;pre&gt;
+--------+
| value  |
+--------+
| aaa    |
| üüü    |
+--------+
&lt;/pre&gt;

&lt;p&gt;Wie kann das angehen?&lt;/p&gt;

&lt;p&gt;Der Grund liegt natürlich im Parameter –default-chararacter-set=LATIN1. Machen wir mal die Gegenprobe, indem wir explizit UTF-8 als Standard setzen. Dazu öffnen wir wieder die MySQL Kommandozeile:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysql &lt;span class=&quot;nt&quot;&gt;-uroot&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;rootpasswort] &lt;span class=&quot;nt&quot;&gt;--default-character-set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;UTF8&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;und geben zunächst folgendes ein:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;use utf8test
select * from sorttest where value like &apos;a%&apos;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Wir bekommen wieder zwei Ergebnisse, diesmal aber sehen wir etwas anderes:&lt;/p&gt;

&lt;pre&gt;
+--------------+
| value        |
+--------------+
| aaa          |
| Ã¼Ã¼Ã¼       |
+--------------+
&lt;/pre&gt;

&lt;p&gt;Hier wird zunächst klar, warum wir zwei Ergebnisse für die Abfrage „Beginnt mit A“ bekommen: „Ã“ wird auch unter „a“ eingeordnet. Gleichzeitig sehen wir, was wirklich in die Tabelle geschrieben wurde: Der UTF-8-Code für „Ã“ und der UTF-8-Code für „¼“, statt wie erwartet die ANSI-Zeichen-Kombination „Ã¼“, die den UTF-8-Code für „ü“ bildet.&lt;/p&gt;

&lt;p&gt;Wir haben damit die wunderbare Welt der MySQL-Zeichensatzkonvertierung betreten.
Machen wir aber zunächst weiter mit der Gegenprobe:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;create table sorttest2 (value varchar(15)) default character set &apos;UTF8&apos;;
insert into sorttest2 (value) values (&apos;aaa&apos;);
insert into sorttest2 (value) values (&apos;üüü&apos;);
select * from sorttest2 where value like &apos;a%&apos;;&amp;lt;/code&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Wir bekommen das korrekte Ergebnis:&lt;/p&gt;

&lt;pre&gt;+-------+
| value |
+-------+
| aaa   |
+-------+&lt;/pre&gt;

&lt;p&gt;Wir haben in obigen Beispielen die Zeichenkodierung des MySQL-Clients gesetzt. Lassen wir den Parameter –default-character-set“ weg, wird die Standard-Kodierung genutzt. Sofern diese nicht manuell angepasst worden ist (was selten passiert) ist das Latin1 mit der Sortierung „Schwedisch“!&lt;/p&gt;

&lt;p&gt;Dröseln wir jetzt mal auf, was da genau passiert ist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wir sind auf einem Linux-System mit UTF-8 als Zeichensatz. Die Eingabe „üüü“ wird daher in die ANSI-Zeichen „Ã¼Ã¼Ã¼“ umgesetzt.&lt;/li&gt;
&lt;li&gt;Der MySQL-Client erwartet Latin1, liest also nicht „üüü“, sondern eben „Ã¼Ã¼Ã¼“.&lt;/li&gt;
&lt;li&gt;Und dies schickt er auch an den Server, und zwar mit der Anmerkung, es handele sich hier um Daten im Format Latin1.&lt;/li&gt;
&lt;li&gt;Der Server wiederum weiß, dass die Tabelle UTF-8 benutzt und konvertiert entsprechend die ankommenden Daten von Latin1 nach UTF-8. Er speichert also nicht ein UTF-8-&quot;ü&quot;, sondern UTF-8-„Ã¼Ã¼Ã¼“&lt;/li&gt;
&lt;li&gt;Wir fragen die Tabelle ab und verlangen dabei das Format Latin1.&lt;/li&gt;
&lt;li&gt;Der Server gibt uns die Daten zurück, konvertiert aber vorher von UTF-8 nach Latin1, weil der Client das so wollte.&lt;/li&gt;
&lt;li&gt;Der Client  erhält „Ã¼Ã¼Ã¼“ als ANSI und druckt das aus.&lt;/li&gt;
&lt;li&gt;„Ã¼Ã¼Ã¼“ werden auf dem Bildschirm als „üüü“ angezeigt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Offensichtlich gibt es hier zwei Knackpunkte:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Die Zeichenkodierung der Eingabe&lt;/li&gt;
&lt;li&gt;Die Konvertierungen auf dem Weg vom Client zum Server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wenn wir eine PHP-Seite betreiben, die ihre Daten als UTF-8 ausgibt, werden auch die Eingaben aller Forms als UTF-8 vorliegen. Sobald wir diese in die Datenbank speichern wollen haben wir effektiv die gleiche Situation wie im obigen Testcase, da MySQL mit hoher Wahrscheinlichkeit „Latin1/Schwedisch“ erwartet.&lt;/p&gt;

&lt;p&gt;Wir müssen also MySQL aus PHP heraus irgendwie mitteilen, dass UTF-8-Daten kommen, und das geht über das &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html&quot;&gt;„SET NAMES“- bzw. das „SET CHARSET“-Kommando&lt;/a&gt;. Direkt nach der Verbindung zur Datenbank senden wir dazu folgendes SQL-Statement:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-mysql&quot; data-lang=&quot;mysql&quot;&gt;set names &apos;utf8&apos;;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Dies entspricht dem Parameter –default-character-set=“UTF8“ beim MySQL-Client.&lt;/p&gt;

&lt;p&gt;Das wars.&lt;/p&gt;

&lt;p&gt;Naja, nicht ganz. Wir können natürlich an der MySQL-Konfiguration herumschrauben und dort UTF-8 als Standard setzen. Hier der entsprechende Auszug aus meiner MySQL-Konfiguration :&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;nn&quot;&gt;[mysql]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;default-character-set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;utf8&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[mysqld]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;collation_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;utf8_unicode_ci&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;character_set_server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;utf8&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Allerdings kann das zu unangenehmen Überraschungen führen, wenn das System migriert wird. Und wenn erst einmal richtige UTF-8 und ANSI-UTF-8-Mischmasch-Daten in einer Tabelle stehen ist Spaß garantiert.&lt;/p&gt;

&lt;p&gt;Des Weiteren sollte man sich angewöhnen, alle MySQL-Clients mit dem Systemzeichensatz als Zeichensatz zu starten, im Fall eines UTF-8-basierten Linux also so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;mysqldump &lt;span class=&quot;nt&quot;&gt;--default-character-set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;UTF8&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt;... &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;...
mysql &lt;span class=&quot;nt&quot;&gt;--default-character-set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;UTF8&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt;... &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;...
mysqlimport &lt;span class=&quot;nt&quot;&gt;--default-character-set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;UTF8&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt;... &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt;...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</content>
 </entry>
 
 <entry>
   <title>PHP und UTF-8 – eine Anleitung, Einleitung</title>
   <link href="https://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-einleitung/"/>
   <updated>2007-11-22T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/softwareentwicklung/php-und-utf-8-eine-anleitung-einleitung</id>
   <content type="html">&lt;p&gt;Es ist kein Geheimnis, dass PHP und Multibyte-Zeichensätze wie etwa UTF-8 nicht gut zusammen gehen. Dies hat drei Gründer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Die meisten PHP-Funktionen setzen wie selbstverständlich ANSI-Strings voraus, etwa die meisten String-Funktionen&lt;/li&gt;
&lt;li&gt;Bei PHP-Funktionen, die Multibyte-Zeichensätze verarbeiten können, wie etwa htmlentities(), werden diese nicht benutzt.&lt;/li&gt;
&lt;li&gt;Und last not least ist der korrekte Einsatz von MySQL und UTF-8 auch nicht einfach.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ich werden diesen drei Problemfeldern nachspüren.&lt;/p&gt;

&lt;p&gt;Teil 1: &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-1-mysql/&quot;&gt;UTF-8 und MySQL&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Teil 2: &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-2-webseiten-als-utf-8-ausliefern/&quot;&gt;Webseiten als UTF-8 ausliefern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Teil 3: &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-teil-3-php-string-funktionen/&quot;&gt;PHP String Funktionen&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exkurs: &lt;a href=&quot;/softwareentwicklung/php-und-utf-8-eine-anleitung-exkurs-wenn-die-db-durcheinander-geraet/&quot;&gt;Exkurs: Falsche Daten in der DB fixen&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Apache Xerces' weird error message</title>
   <link href="https://www.gerd-riesselmann.net/development/apache-xerces-weird-error-message/"/>
   <updated>2007-04-04T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/apache-xerces-weird-error-message</id>
   <content type="html">&lt;p&gt;For one of my projects I’m using Apache’s &lt;a href=&quot;http://xml.apache.org/xerces-c/&quot;&gt;Xerces C++ XML Parser&lt;/a&gt; and run into this strange error:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The primary document entity could not be opened.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Took me a while to figure out that Xerces simply wants to say “File not found” here, because I was was calling parse() with the data to be parsed, while Xerces expects a file name here. Silly me.&lt;/p&gt;

&lt;p&gt;However: Here’s how to parse an XML string using Xerces SAX parser. You need to use a MemBufInputSource:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#define XNS XERCES_CPP_NAMESPACE_QUALIFIER 
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;xmldoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;first&amp;gt;&amp;lt;second&amp;gt;Some Text&amp;lt;/second&amp;gt;&amp;lt;/first&amp;gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  Create a SAX parser object.
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;XNS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SAX2XMLReader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
	&lt;span class=&quot;n&quot;&gt;XNS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLReaderFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;createXMLReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  Create the handler object and install it
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;YourContentHandler&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setContentHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setErrorHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;XNS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MemBufInputSource&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XMLByte&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xmldoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
	&lt;span class=&quot;n&quot;&gt;xmldoc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
	&lt;span class=&quot;s&quot;&gt;&quot;a name for the input source&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>When Internet Explorer displays a white page...</title>
   <link href="https://www.gerd-riesselmann.net/development/when-internet-explorer-displays-a-white-page/"/>
   <updated>2007-03-27T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/when-internet-explorer-displays-a-white-page</id>
   <content type="html">&lt;p&gt;.. this may be because of a wrong script tag. Actually, both Internet Explorer 6 and 7 will fail, if you use the script tag like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;blabla.js&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;IE instead requires an explicit closing tag, like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;type=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;text/javascript&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;blabla.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;PS: This is primary a note to myself, since I get trapped by this over and over again…&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>UTF-8, Latin1 aka ISO-8859-1 und das Euro-Zeichen</title>
   <link href="https://www.gerd-riesselmann.net/webentwicklung/utf-8-latin1-aka-iso-8859-1-und-das-euro-zeichen/"/>
   <updated>2006-11-18T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/webentwicklung/utf-8-latin1-aka-iso-8859-1-und-das-euro-zeichen</id>
   <content type="html">&lt;p&gt;Um mal gleich mit der Tür ins Haus zu fallen: Es gibt kein Euro-Zeichen im ISO-8859-1-Zeichensatz (aka Latin1) -
und folglich sind alle Versuche, einen Text mit dem niedlichen Kniddel-E von UTF-8 oder jedem anderen Zeichen-Encoding
nach Latin1 zu konvertieren zum Scheitern verurteilt. Mit etwas Glück kommt dabei ein Fragezeichen oder
immerhin noch Gekröse raus. Korinthenkacker wie iconv dagegen stellen einfach ganz die Arbeit ein und man endet in einem Fehler.&lt;/p&gt;

&lt;p&gt;Latin1 soll also kein Euro-Zeichen enthalten, hmm? Warum kann ich dann das “€” in Webseiten sehen, die ISO-8859-1 kodiert sind?&lt;/p&gt;

&lt;p&gt;Tja… Sagen wir mal so: Es ist heute ganz einfach, durch ganz Europa zu reisen und seine Euros fröhlich überall
auszugeben. Das heißt aber nicht, dass ein Grenzer einen nicht trotzdem stundenlang mit Formalitäten an der Grenze festhalten könnte.&lt;/p&gt;

&lt;p&gt;Das ist bei Computern nicht groß anders: Es gibt freundliche Programme, die versuchen, das Leben angenehm zu machen,
etwa indem sie Konventionen gelten lassen. Eine solche Konvention sagt, das man das Zeichen 128 im Latin1-Zeichensatz
durch das Euro-Symbol ersetzt hat.&lt;/p&gt;

&lt;p&gt;“Man” ist in diesem Fall eine große Koalition aus Software- und Hardware-Herstellern. Schließlich musste bei der
Einführung des Euros eine einfache und billige Lösung her. Die Vorteile liegen auf der Hand: die Programme
selber müssen nicht geändert werden, es braucht lediglich eine neue Schrift. Die Nachteile der Lösung kennt jeder,
der beim Drucken auf älteren Druckern auf die installierten Schriften des Druckers zurück greifen muss,
die das Euro-Zeichen leider nicht kennen.&lt;/p&gt;

&lt;p&gt;Auf der anderen Seite gibt es Programme, die penibel auf die Einhaltung der Regeln pochen: bürokratisch, humorlos.
Wie zum Beispiel die Programme, die Zeichenkodierungen konvertieren.&lt;/p&gt;

&lt;p&gt;Diese argumentieren, ISO-8859-1 enthalte ganz offensichtlich kein Euro-Zeichen (bei der Festlegung von ISO-8859-1
gab es noch keinen Euro) und gleich dreimal nicht an Position 128. Stattdessen gäbe es doch die Kodierung ISO-8859-15,
diese definiere ein Euro-Symbol und sei doch auch bereits seit 1999 gültig.&lt;/p&gt;

&lt;p&gt;Und das ist natürlich nicht verkehrt. ISO-8559-15 enthält einen Euro, und zwar an Position 164. Damit sind ISO-8859-15
und ISO-8859-1 (Euro-tauglich) euro-mäßig wiederum nicht kompatibel. Das wäre ja auch zu einfach, erklärt sich
aber vielleicht daraus, dass bei Latin1 an Position 164 noch dieses Zeichen steht: ¤. Das ist das internationale
Währungszeichen - süß, nicht wahr? Besser bekannt ist dieses Zeichen freilich als Tabellenzellen-Ende-Zeichen aus
Microsoft Word und anderen Textverarbeitungen. Genau so gut hätte man vorschlagen können, das Symbol ¶ durch den Euro zu ersetzen.&lt;/p&gt;

&lt;p&gt;ISO-8859-15 jedenfalls ist ein lustiger Geselle, von dem man noch nicht mal weiß, ob er nun Latin0 oder Latin9 heißt.
Man weiß jedoch, dass er eigentlich Latin1 hatte ersetzen sollen. Daraus ist allerdings nichts geworden, wenn wir
uns zum Beispiel &lt;a href=&quot;http://php.net/utf8-decode&quot;&gt;PHP&lt;/a&gt;,
&lt;a href=&quot;http://doc.trolltech.com/4.0/qstring.html#toLatin1&quot;&gt;QT&lt;/a&gt; oder andere Programmiersprachen und -frameworks ansehen. Latin1 ist immer noch omnipräsent.&lt;/p&gt;

&lt;p&gt;Wer sich aber Ärger ersparen will, der greift fortan auf ISO-8859-15 zurück.&lt;/p&gt;

&lt;p&gt;Aus all dem folgt also, dass Code wie der folgende - der einen UTF-8 Text annimmt und eine Latin1-Mail verschickt - in die Katastrophe führen, wenn der Text ein Euro-Zeichen enthält:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;send_mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$utf8_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//falsch!&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$latin_message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iconv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;ISO-8859-1&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$utf8_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// auch falsch!&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$latin_message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;utf_decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$utf_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$latin_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Hier ist die richtige Version. Da wir latin0-oder-9 verwenden, müssen wir das beim Verschicken der Mail irgendwie mitteilen, also auch einen entsprechenden Header dazupacken:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;send_mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$utf8_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$latin_message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iconv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;UTF-8&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;ISO-8859-15&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$utf8_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Content-Type: text/plain; charset=ISO-8859-15&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$latin_message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>The Holy Grail CSS Layout Fix for IE7</title>
   <link href="https://www.gerd-riesselmann.net/development/the-holy-grail-css-layout-fix-for-ie7/"/>
   <updated>2006-11-08T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/the-holy-grail-css-layout-fix-for-ie7</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://alistapart.com/article/holygrail/&quot;&gt;In Search of The Holy Grail&lt;/a&gt; describes an easy way to create a three-column, source-ordered, table-less layout with a fluid column in the middle. It is used by the &lt;a href=&quot;http://www.comicmarktplatz.de&quot;&gt;Comic Marktplatz&lt;/a&gt;, for example. However, there is an annoying bug with the shiny new Internet Explorer 7. IE7 has a problem in understanding the left column rule of&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Instead of considering the width of the surrounding div container, IE7 inserts the width of the body, which leads to the left column being moved out of sight to the far left. Here’s how to fix it.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;I experimented a little with overflow, position, and other attributes without any success. However, since IE supports JavaScript expressions in CSS, this can be used to apply a fix (The fix is a fix to &lt;a href=&quot;http://www.infocraft.com/articles/the_case_of_the_disappearing_column/&quot;&gt;this fix&lt;/a&gt;, actually):&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nf&quot;&gt;#left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;200px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;             &lt;span class=&quot;c&quot;&gt;/* LC width */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-100%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;150px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;              &lt;span class=&quot;c&quot;&gt;/* RC width for IE6 */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;#container&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-200px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;             &lt;span class=&quot;c&quot;&gt;/* -LC width for others */&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offsetWidth&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* Fix for IE7 */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In the case of the padded version, the left and right padding of the left and the left padding of the center column must be added to the margin like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-css&quot; data-lang=&quot;css&quot;&gt;&lt;span class=&quot;nf&quot;&gt;#container&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;nl&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-200px&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* -LC width for others */&lt;/span&gt;
   &lt;span class=&quot;nl&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;offsetWidth&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;-1&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;+&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;parseFloat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paddingLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;+&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;parseFloat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paddingLeft&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;+&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;parseFloat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;currentStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;paddingRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;/* Fix for IE7 */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;“left” in document.all.left is the id of the left column.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attention:&lt;/strong&gt; Note that “center” within the expression &lt;em&gt;document.all.center.offsetWidth&lt;/em&gt; refers to the column with the id “center”, as it was named in the original version. If you named the middle column differently, you must change this, too.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>And again: Is C++ really faster?</title>
   <link href="https://www.gerd-riesselmann.net/development/and-again-is-c-really-faster/"/>
   <updated>2006-11-04T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/and-again-is-c-really-faster</id>
   <content type="html">&lt;p&gt;I was pointing to articles about &lt;a href=&quot;/archives/2004/12/optimization-templates-and-the-rest/&quot;&gt;if low level optimization really makes sense&lt;/a&gt; and &lt;a href=&quot;/archives/2005/11/is-c-still-needed/&quot;&gt;if C++ is really faster than higher level languages&lt;/a&gt; several times. But of course this will be a never ending debate, and it &lt;a href=&quot;http://www.greythumb.org/blog/index.php?/archives/152-Programmers-rant-what-should-and-should-not-be-added-to-CC++.html&quot;&gt;still continues&lt;/a&gt;. This time C and C++ should be the best languages for higher level mathematics problems. Unfortunately this is not the case.&lt;/p&gt;

&lt;p&gt;The author argues that&lt;/p&gt;

&lt;blockquote&gt;
C and C++ just aren&apos;t productive languages. It takes 2-4 times as long to implement something in these languages than in a very high level language like Ruby. The resulting code is harder to read, harder to maintain, and harder to port.
&lt;/blockquote&gt;

&lt;p&gt;I totally agree with this, and like the author I think this is the reason why C++ looses popularity.&lt;/p&gt;

&lt;p&gt;I disagree however when the author opposes to high level language features like a garbage collection. He argues that this will have impact on speed, which is the last outstanding C and C++ have to offer:&lt;/p&gt;

&lt;blockquote&gt;C and C++ are never going to disappear. Why? Because there are classes of programming problems that are still and will always be CPU bound and there is still no language as fast as C or C++ for these problems. I highly doubt that there ever will be.

I&apos;m talking about things like: scientific number crunching, game/simulation physics, raytracing, real-time 3d graphics, audio processing, codec implementation, high-speed network packet routing, evolutionary computation (my personal favorite :), and of course implementing all these high-level languages&apos; runtimes. There are also problems like OS and hardware driver implementation where you need something &quot;close to the metal&quot; that can interact closely with and even embed assembly language. C is basically shorthand for assembler, which is why it&apos;s the preferred language for that kind of thing.
&lt;/blockquote&gt;

&lt;p&gt;While the second part of the argument may be true (I’m not that into C and Assembler since I sold my C64 back in 1985), this would be a rather - well - boring niche for the powerful language C++ is. For the first part, this is plain wrong, as it was already stated in the comments.&lt;/p&gt;

&lt;p&gt;A more detailed reply can be found at &lt;a href=&quot;http://scienceblogs.com/goodmath/2006/11/the_c_is_efficient_language_fa.php&quot;&gt;Good Math, Bad Math&lt;/a&gt; - and it is the same as for low level optimization: Compiles do a much better job than people can do. If they are provided with the necessary information, which due to their pointer based nature is a problem in C and C++:&lt;/p&gt;

&lt;blockquote&gt;
So for modern systems, writing an efficient program is sort of a partnership. The human needs to careful choose algorithms - the machine can&apos;t possibly do that. And the machine needs to carefully compute instruction ordering, pipeline constraints, memory fetch delays, etc. The two together can build really fast systems. But the two parts aren&apos;t independent: the human needs to express the algorithm in a way that allows the compiler to understand it well enough to be able to really optimize it.

And that&apos;s where C and C++ fall down. C and C++ are strongly pointer-based languages. The real semantics of almost anything interesting end up involving pretty much unrestricted pointers. In C and C++, there&apos;s no such thing as an array - there&apos;s just pointers, which you can subscript and a shorthand for pointer arithmetic and indirection(x[n] in C/C++ is the same thing as *(x+n).) 

That pointer based nature means that in a C or C++ program, it&apos;s &lt;em&gt;very&lt;/em&gt; hard for a compiler to figure out what things are independent. It comes down to a problem called &lt;em&gt;alias detection&lt;/em&gt;. Alias detection is identifying when two variables &lt;em&gt;might&lt;/em&gt; be referencing the same location. Alias detection becomes a horrific mess in the presence of unrestricted pointers.
&lt;/blockquote&gt;

</content>
 </entry>
 
 <entry>
   <title>General Comments on Drupal's Error "Unknown table 'n'"</title>
   <link href="https://www.gerd-riesselmann.net/drupal/general-comments-on-drupals-error-unknown-table-n/"/>
   <updated>2006-10-25T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/drupal/general-comments-on-drupals-error-unknown-table-n</id>
   <content type="html">&lt;p&gt;Maybe you already know the famous Drupal error “Unknown table ‘n’”. It looks like this:&lt;/p&gt;

&lt;blockquote&gt;
user warning: Unknown table &apos;n&apos; in where clause query: SELECT DISTINCT(node.nid), node.type AS node_type, node.title AS node_title, node.changed AS node_changed, users.name AS users_name, users.uid AS users_uid, node.created AS node_created, node_counter.daycount AS node_counter_daycount FROM node node LEFT JOIN users users ON node.uid = users.uid LEFT JOIN node_counter node_counter ON node.nid = node_counter.nid INNER JOIN node_access na ON na.nid = node.nid WHERE (na.grant_view &amp;gt;= 1 AND ((na.gid = -1 AND na.realm = &apos;all&apos;) OR (na.gid = 0 AND na.realm = &apos;og_public&apos;) OR (na.gid = 0 AND na.realm = &apos;og_all&apos;) OR (na.gid = 3 AND na.realm = &apos;og_subscriber&apos;) OR (na.gid = 4 AND na.realm = &apos;og_subscriber&apos;) OR (na.gid = 0 AND na.realm = &apos;cac_lite&apos;))) AND (n.moderate != 1) AND (node.status = &apos;1&apos;) ORDER BY node_counter.daycount DESC LIMIT 0, 5 in /home/orbit42/public_html/includes/database.mysql.inc on line 120.
&lt;/blockquote&gt;

&lt;p&gt;This error is caused by some module “rewriting” a query of some other module, each of them not aware of each other. This is a powerful Drupal feature, yet it also is highly error prone - as the lots of error alike show. Here’s how to deal with it.&lt;/p&gt;

&lt;p&gt;The process of rewriting a query works like this: A module builds a SQL query and passes it to the function &lt;a href=&quot;http://api.drupal.org/api/4.7/function/db_rewrite_sql&quot; title=&quot;db_rewrite_sql() API documentation&quot;&gt;db_rewrite_sql&lt;/a&gt;, together with the table name and some other information.&lt;/p&gt;

&lt;p&gt;In general there are two possible error sources:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;A module invokes db_rewrite_sql with wrong parameters&lt;/li&gt;
  &lt;li&gt;A module wrongly implements the actual rewriting&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of these errors will occur only if the query is rewritten, which actually may depend on a the module configuration, user state etc. That’s why there are so much different forms of the error.&lt;/p&gt;

&lt;p&gt;An example: Module 1 issues a query rewrite, but does it wrong. This will only be discovered when another module really rewrites something. There aren’t to many modules doing this, so it may take a time. The same holds, when a module wrongly implements the query rewriting. In this case, the error will occur within some other module, which is especially nasty.&lt;/p&gt;

&lt;p&gt;For this reasons, when dealing with “Unknown table ‘n’”, the list of modules installed is extremely important.&lt;/p&gt;

&lt;p&gt;Now let’s dive a little deeper into db_rewrite_sql(). The function is declared like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db_rewrite_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;n&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_field&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;nid&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The first 3 parameters are of interest. First it takes the SQL query as a string, followed by the name of the primary table and the primary id field. Table and id field are supposed to default to ‘n’ and ‘nid’.&lt;/p&gt;

&lt;p&gt;‘n’ - does that sound familiar?&lt;/p&gt;

&lt;p&gt;Indeed, this ‘n’ causes all the trouble. See, it is assumed that the table queried is called ‘n’ normally, however, this is not required.&lt;/p&gt;

&lt;p&gt;This can be an error source when invoking the function. This for example is wrong:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;db_rewrite_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Select nid, title from {node} as squirrel&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The primary table name (which correctly should be called the primary alias name) in this case is ‘squirrel’. I like squirrels. Due to the default values, the function is expanded to:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;db_rewrite_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Select nid, title from {node} as squirrel&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;n&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;nid&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;OK, there is a field ‘nid’, but no ‘n’ anywhere. This is bad.&lt;/p&gt;

&lt;p&gt;A correct way to invoke db_rewrite_sql() and keep the squirrel alias is to simply pass it:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;db_rewrite_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Select nid, title from {node} as squirrel&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;squirrel&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;nid&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This code should issue no problems - well, unless of course some squirrel hating module handles it wrong.&lt;/p&gt;

&lt;p&gt;If a module wants to rewrite queries of other modules, it has to provide a so-called hook. A hook is named [module-name]_[hook_name]. So if your module file is named squirrel_hater.module, the hook would be named squirrel_hater_db_rewrite_sql(). This function takes exactly the same arguments than the original db_rewrite_sql():&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;nf&quot;&gt;squirrel_hater_db_rewrite_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Let’s have a look at a real word example. Code like this (a patch taken from &lt;a href=&quot;http://drupal.org/node/53772&quot;&gt;here&lt;/a&gt;) is a true troublemaker:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cd&quot;&gt;/**
 * Implementation of hook_db_rewrite_sql
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content_db_rewrite_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$primary_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;nid&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;n.type &amp;lt;&amp;gt; &apos;&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;content_types&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;user_access&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;view &apos;&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos; content&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;n.type &amp;lt;&amp;gt; &apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;where&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos; AND &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note that this codes checks if the element queried is a node. Therefore it looks if the query deals with a node’s id (case “nid”). This is totally correct.&lt;/p&gt;

&lt;p&gt;But then the code assumes the table alias is “n” - for exampel in this line:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;n.type &amp;lt;&amp;gt; &apos;&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Notice “n.type”? No squirrels! This is what will be causing an error “unknown table ‘n’” error.&lt;/p&gt;

&lt;p&gt;Correct code would use the table alias $primary_table, like so:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt; 
&lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$primary_table&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.type &amp;lt;&amp;gt; &apos;&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here’s the whole snippet, corrected:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cd&quot;&gt;/**
 * Implementation of hook_db_rewrite_sql
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content_db_rewrite_sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$primary_field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;nid&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$primary_table&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.type &amp;lt;&amp;gt; &apos;&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;content_types&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;user_access&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;view &apos;&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos; content&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$primary_table&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.type &amp;lt;&amp;gt; &apos;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&apos;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;where&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos; AND &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This little error in the implementation of the db_rewrite_sql-hook is not noticed, as long as the primary table is “n”, which it is in about 95% of all cases. There are, however, some modules, who name the table differently. Not “squirrel”, of course, but for “node”, for example. Additionally, the rewriting is not done for administrators. This turns the code into a neat little time bomb.&lt;/p&gt;

&lt;p&gt;There are hundreds of modules, and any of them may contain a wrong implementation like the above one. Additionally there are hundreds of patches, which - like the example - may contain errors, too.&lt;/p&gt;

&lt;p&gt;So, my advise in case of trouble is to look for code fragments like above. Look for functions named “[modulename]_db_rewrite_sql” and see if there’s a hard coded “n.[fieldname]” in it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This article is based on what I wrote on &lt;a href=&quot;http://drupal.org/node/82513&quot;&gt;this bug report&lt;/a&gt;. I polished it a bit, tried to simplify it here and there, and added some squirrels.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Focus first Form field with jQuery</title>
   <link href="https://www.gerd-riesselmann.net/development/focus-first-form-field-with-jquery/"/>
   <updated>2006-10-19T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/focus-first-form-field-with-jquery</id>
   <content type="html">&lt;p&gt;I somehow like the &lt;a href=&quot;http://jquery.com&quot;&gt;jQuery JavaScript library&lt;/a&gt;. Have a look at the jQuery code for the &lt;a href=&quot;http://jquery.com/blog/2006/10/18/zebra-table-showdown/&quot;&gt;Zebra-Table-Showdown&lt;/a&gt;: Ain’t this a beauty?&lt;/p&gt;

&lt;p&gt;However, when it comes to focusing the first (visible) field on a form, things are not that elegant. I got it working, though. Here’s my current attempt:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Focus first element
&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;focus_first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;input:visible&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;select:visible&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;offsetTop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;offsetTop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;textarea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;textarea:visible&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textarea&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textarea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;offsetTop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;offsetTop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;textarea&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Use it like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nf&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;focus_first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I wonder, though, if there is a more comprehensive expression to find the first element of either type “input”, “select”, or “textarea”.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nf&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;input:visible,select:visible,textarea:visible&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;will not work, since it will always return the first “input”, regardless if there is a “select” or “textarea” before it.&lt;/p&gt;

&lt;p&gt;Any suggestions?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>std::clock(), threading, and Linux</title>
   <link href="https://www.gerd-riesselmann.net/development/std-clock-threading-and-linux/"/>
   <updated>2006-09-09T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/development/stdclock-threading-and-linux</id>
   <content type="html">&lt;p&gt;I had a strange experience with the &lt;a href=&quot;https://www.boost.org/doc/libs/1_83_0/libs/timer/doc/index.html&quot;&gt;boost::timer class&lt;/a&gt; the other day, since it never elapsed within a certain thread. As it turns out, this was because std::clock() itself doesn’t tick but returns the same value over and over again - a value that probably indicates the time the tread was started. The solution is rather simple: I implemented the boost::timer interface based upon &lt;a href=&quot;http://www.boost.org/doc/html/threads/reference.html#id2416096&quot;&gt;boost::xtime&lt;/a&gt; from the &lt;a href=&quot;http://www.boost.org/doc/html/threads.html&quot;&gt;boost threading library&lt;/a&gt; like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;XTimer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;XTimer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;xtime_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_start_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TIME_UTC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;XTimer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XTimer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_start_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_start_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;XTimer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elapsed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xtime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;xtime_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TIME_UTC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lexical_cast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sec&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_start_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xtime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_start_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>XMLRPC value types and C++</title>
   <link href="https://www.gerd-riesselmann.net/archives/2006/08/xmlrpc-value-types-and-c/"/>
   <updated>2006-08-05T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2006/08/xmlrpc-value-types-and-c</id>
   <content type="html">&lt;p&gt;A while ago, I was looking for a C/C++ XMLRPC client implementation. However, for some reason or another, I was unsatisfied with the recent implementations, which mostly seem utterly complex for my purposes. That’s why I decided to roll out my own. While the XML building and parsing is more or less straight forward (although there’s too much redundancy and unneccessary tags in the spec for my taste), implementing the possible value types made me scratch my head. The XMLRPC protocol &lt;a href=&quot;http://www.xmlrpc.com/spec&quot;&gt;supports a set of data types&lt;/a&gt;: integer, string, double etc., but also an array or a struct. Integer and double are native types, string is either a char pointer or a class. How this should be put within one class? My first sketch introduced a quite complex model with an impressing inheritence chain, but then &lt;a href=&quot;http://www.boost.org/doc/html/variant.html&quot;&gt;boost::variant&lt;/a&gt; came to the rescue:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*! \brief XmlRpcValue is defined as a variant that can
 *         take string, int, double, bool,
 *         and collections of itself, namely a vector and a map
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_recursive_variant&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recursive_variant_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recursive_variant_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*! \brief Key and value pairs form a struct
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcStruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/*! \brief A list forms an array 
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This defines a type called XmlRpcValue. This type can contain either a string, an int, a bool, a double, or a vector of XmlRpcValues or a string-based map of XmlRpcValues. Isn’t that cool?&lt;/p&gt;

&lt;p&gt;We can easily utilize this type like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*! \brief convert given parser value into xmlrpc value.
 *
 * \exception boost::lecial_cast_error
 *              Conversion wasn&apos;t successful
 * \exception std::invalid-argument
 *              Data type not recognized
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcValue&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_read_parser_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ParserValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Check all types
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;int&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;i4&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lexical_cast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;double&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;XmlRpcValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lexical_cast&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[...]&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Unrecognized data type
&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invalid_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Unknown data type detected&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;ParserValue in this case is a simple structure containing information about parsed data:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-c--&quot; data-lang=&quot;c++&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*! \brief A single value extracted from response
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ParsedValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;public:&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/*! \brief The name. Used only for struct members */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/*! \brief The value as string */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/*! \brief The type, value type tag name like
     *         &quot;int&quot;, &quot;struct&quot;, &quot;array&quot; etc. */&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>A triangle with rounded corners in C#</title>
   <link href="https://www.gerd-riesselmann.net/archives/2006/01/a-triangle-with-rounded-corners-in-c/"/>
   <updated>2006-01-29T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2006/01/a-triangle-with-rounded-corners-in-c</id>
   <content type="html">&lt;p&gt;For one of my projects I needed to draw triangles with rounded egdes, and since I didn’t found anything about this topic elsewhere, I had to figure it out by myself. Luckily no mathematics is needed, except the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pythagorean_theorem&quot;&gt;Pythagorean theorem&lt;/a&gt;. So here’S how I did it, complete with a sample implementation using C#.&lt;/p&gt;

&lt;p&gt;To make things easier, I started with a right-angled triangle where the two sides forming the right angle are vertical and horizontal. This makes applying a rounded corner for the right angle easy, since it is a common problem known from drawing rounded rectangles. You’ll find examples for this all over the net. I instead will discuss, how to round the two other edges, which both form an angle of 45 degrees.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/roundedtriangle.gif&quot; width=&quot;308&quot; height=&quot;254&quot; alt=&quot;A sketch demonstrating the problem&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here’s a sketch demonstrating the problem. A circle with radius r needs to be placed at point C for the two sides forming the triangle becoming its tangents. How do we calculate C? Well, we already know that the length of BC is r, so we just need to figure out the length of AB. AB itself has the same length then BD, whitch is the sum of BC and CD, where BC is r:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;AB = BD
AB = BC + CD
AB = r + CD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now the points C, D, and E form another right-angled triangle with CE = ED = r. So we can apply the Pythagorean theorem:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;AB = r + CD
AB = r + sqr(CE * CE + ED * ED)
AB = r + sqr(r * r + r * r)
AB = r + sqr(2 * r * r)
AB = r + sqr(2) * r
AB = (1 + sqr(2)) * r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For drawing circles or parts of it in C#, we need to provide the surrounding rectangle R, which obviously starts at Rx = Cx - r and Ry = Cy - r.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Rx = Cx - r = Ax
Ry = Cy - r = Ay + (1 + sqr(2)) * r - r
Ry = Ay + (1 - 1 + sqr(2)) * r
Ry = Ay + sqr(2) * r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here’s the C# code to contruct a rounded rectangle’s graphic path. The right angle is rounded with double radius, just because it looks better:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// Build it in default size, pointing to left bottom,
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// so 90° angle is left bottom.
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radius&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radius&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;GraphicsPath&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GraphicsPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// bottom left corner (90°)
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddArc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// left line
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// top corner
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddArc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;180&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;135&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// diagonal line
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// right corner
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddArc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;315&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;135&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Bottom line
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;AddLine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cornerDist&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthArcRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CloseFigure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now having the triangle, we can transform it, to point in any directions and to have any size. If for example we want to draw a triangle pointing to the right beeing 20 pixel in height, we apply the following transformation:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newHeight&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Matrix&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Rotate
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;PointF&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PointF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)/&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;RotateAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(-&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;135&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Rotated triangle is larger than the original
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;widthOriginal&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lengthHypotenuse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lengthHypotenuse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Scale to fit size
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newSize&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lengthHypotenuse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Scale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// Apply Matrix
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;What is happening here? After rotating, the triangle’s bounding rectangle is higher then the original, since the hypotenuse is now vertical. The length of the hypotenuse (Lh) is:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Lh = sqr(width * width + width * width)
Lh = sqr(2 * width * width)
Lh = sqr(2) * width;&amp;lt;/code&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We now have to move the triangle down a bit, so that its top corner is within the orignals path boundaries (This makes positioning much easier). The amount we have to move is the lengh of the hypotenuse minus the width divided by two. We also have to move the whole triangle to the left, since it was rotated at its bounding rectangle’s center, which now forms the left side of the triangle. Afterwards the triangle is scaled, since we want the hypotenuse to be 20 pixel in height.&lt;/p&gt;

&lt;p&gt;After the transformation, we have a right angled triangle with rounded edges, pointing to the right, and 20 pixel in height. We now can apply a last transformation to place it at the coordinates (5, 10), for example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-csharp&quot; data-lang=&quot;csharp&quot;&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Translate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>Microformats: Prefering machines over people</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/12/microformats-prefering-machines-over-people/"/>
   <updated>2006-01-17T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/12/microformats-prefering-machines-over-people</id>
   <content type="html">&lt;p&gt;Anybody ever took a look at the &lt;a href=&quot;http://microformats.org/wiki/datetime-design-pattern&quot;&gt;Datetime Design Pattern&lt;/a&gt; at &lt;a href=&quot;http://microformats.org&quot;&gt;Microformats.org&lt;/a&gt; (via &lt;a href=&quot;http://rfc1437.de/page/und-wir-machen-alle-fehler-erneut/&quot;&gt;Georg Bauer&lt;/a&gt; (German))? It goes like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;abbr&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;foo&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;title=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;YYYY-MM-DDTHH:MM:SS+ZZ:ZZ&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;Date Time&lt;span class=&quot;nt&quot;&gt;&amp;lt;/abbr&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I think this is a misuse of the abbreviation tag - and worse: it’s completely ignoring user experience.
Most nowadays browsers display the text of the title attribute when you hover over the abbreviation.
Now imaging a user browsing your microformatted page. When he hovers over a date like - say -
&lt;abbr class=&quot;birthdate&quot; title=&quot;1970-05-04T18:10:52+01:00&quot;&gt;May 4th 1970&lt;/abbr&gt;, which is my birthday,
he’ll see a tooltip stating “1970-05-04T18:10:52+01:00”. Doh!&lt;/p&gt;

&lt;p&gt;Not to tell that screen readers usually read the abbreviation’s title. So, a screen reader would read
“One Nine Seven Zero Minus Zero Five Minus Zero Four T One Eight Colon…” Really well done, you microformat people.&lt;/p&gt;

&lt;p&gt;Like &lt;a href=&quot;https://alistapart.com/article/hattrick/&quot;&gt;Colin Lieberman writes on A List Apart&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;The point of including expanded forms of abbreviations is to make sure that users
can access those forms if needed. The value of the abbr element lies in its ability to tell screen readers
what they should read (thus improving the flow of spoken text), while &lt;em&gt;also&lt;/em&gt; providing additional
useful information to visual users with learning or cognitive disabilities
(or those coping with language barriers). The assertion that abbr is structural is misguided, as the
point of the tag &lt;em&gt;is the content of its title attribute&lt;/em&gt;.&lt;/blockquote&gt;

&lt;p&gt;He’s right. Abbreviation is not structural. Even if it once was intended to be,
in real life it isn’t. It seems, this has been forgotten by
the &lt;a href=&quot;http://www.joelonsoftware.com/articles/fog0000000018.html&quot;&gt;microformat astronauts&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Don't trust PHP_SELF</title>
   <link href="https://www.gerd-riesselmann.net/archives/2006/01/dont-trust-php-self/"/>
   <updated>2006-01-11T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2006/01/dont-trust-php_self</id>
   <content type="html">&lt;p&gt;Sean Coates points out why &lt;a href=&quot;http://blog.phpdoc.info/archives/13-guid.html&quot;&gt;$_SERVER[“PHP_SELF”] must be considered unsafe&lt;/a&gt;. You should never use it without at least converting it to entities:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;htmlentities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;PHP_SELF&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This offers me the chance to again repeat one of my mantras: Create a function for everything, at least when reading values from somewhere, even for something simple like retrieving the value of PHP_SELF. The reason is maintenance: If you haven’t previously validated the value of PHP_SELF there will be only one place to change, instead of checking all your code.&lt;/p&gt;

&lt;p&gt;Here’s my implementation:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cd&quot;&gt;/**
 * Static returns the recent URL.
 *
 * @param Boolean Indicated if query string (?...) should be included or not
 * @returns String
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recentURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$includeParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$http&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$includeParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$http&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;REQUEST_URI&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$http&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$_SERVER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;PHP_SELF&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;      
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;toSafeURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$http&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;cd&quot;&gt;/**
 * Static. Processes an URL to strip of possible injection code 
 * 
 * @param String The URL to process 
 * @return String The cleaned URL
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toSafeURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;htmlentities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;strip_tags&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</content>
 </entry>
 
 <entry>
   <title>Large-Scale C++ Software Design</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/12/large-scale-c-software-design/"/>
   <updated>2005-12-03T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/12/large-scale-c-software-design</id>
   <content type="html">&lt;p&gt;Following up on a comment from Udi Dahan about &lt;a href=&quot;http://udidahan.weblogs.us/archives/033734.html&quot;&gt;physical design&lt;/a&gt; Len Holgate &lt;a href=&quot;http://www.lenholgate.com/archives/000585.html&quot;&gt;points out that&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
If you&apos;re working in C++ and you haven&apos;t read &lt;em&gt;Large-Scale C++ Software Design&lt;/em&gt; (APC) by John Lakos then you really should.
&lt;/blockquote&gt;

&lt;p&gt;This is definitly true. John Lakos’ book - beeing as far as I know the only one on the topic - is a must-read for each C++ developer.&lt;/p&gt;

&lt;p&gt;Len is using Lakos’ book as an argument against my post about &lt;a href=&quot;/archives/2005/11/is-c-still-needed/&quot;&gt;C++ still beeing needed?&lt;/a&gt; and further states:&lt;/p&gt;

&lt;blockquote&gt;
You have to actively manage your dependencies all the time, no matter what language you&apos;re working in. If you don&apos;t do it in C++ you can end up in a hell of slow compiles and horribly entwined code that all needs to be rebuilt if you ever change one class. If you do it right you rebuild just what needs to be built and you depend on just what you need, and no more.
&lt;/blockquote&gt;

&lt;p&gt;Again: true. However, each project contains some very fundamental libraries, nearly all other packages depend on. A custom string class comes to mind ;-), but there are other. Let me tell you a little bit about the application I’m developing at work to get things clear.&lt;/p&gt;

&lt;p&gt;We follow a model driven development approach. This is: One should be able to model what we call domains in any UML-capable CASE tool from which some basic code is generated so that the new domain can be used right away without further manual work. This allows easy prototyping of new business domains and it futher allows adjustments of the application’s class model at runtime.&lt;/p&gt;

&lt;p&gt;To achieve this, we needed to bring reflection to C++. Reflection - known from most modern languages like C#, Java, Ruby etc. - allows retrieving class level information from instances. .NET’s &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemobjectclassgettypetopic.asp&quot;&gt;GetType() function&lt;/a&gt; is an example of this. Our reflection model itself is an implementation of the &lt;a href=&quot;http://www.omg.org/cgi-bin/doc?formal/05-07-04&quot;&gt;UML 2.0 superstructure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We established three meta modelling levels M0 (instance level), M1 (reflection) and M2 (runtime modelling). For example, to participate from reflection, all business objects must be derived from a class called M0Instance.&lt;/p&gt;

&lt;p&gt;At this point, it should be quite clear, that nearly all of our code in some way or another depends on what we called the Kernel, containing the levels M0 and M1. We of course applied the guidelines of &lt;em&gt;Large Scale C++ Software Design&lt;/em&gt;, but still changes to any of the Kernel’s core interfaces lead to a massive recompile. Just to give you some numbers: 30 Minutes on Windows, 1 hour on Linux and 2 hours on HP-UX.&lt;/p&gt;

&lt;p&gt;I was arguing that development in C++ takes a significant higher amount of time compared to other high level languages, and that the long compile time is one factor among others. I think this still holds. Of course, changes in basic packages should occur rather seldom, however, our application is evolving, and so is the Kernel.&lt;/p&gt;

&lt;p&gt;As a side note, the massive compile time established a culture of “better don’t touch”. I was realizing this, when I found myself adding complicated, ugly, and similiar code (referenced further as “the shame”) in several application layers when extending the application’s user access control features. By just introducing one new function to the reflection level, all this code was made obsolete. I &lt;strong&gt;was&lt;/strong&gt; thinking about this function when I added the shame the first time, I also thought about it the second time. I finally did it in the middle of adding the shame the third time…&lt;/p&gt;

&lt;p&gt;Some last note: I was implementing the Kernel in C#, mainly to learn the language. This, including persistence, two simple domains and a basic generic UI framework, took me four to five days. The initial C++ Kernel development - without any UI stuff - took several man months.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Is C++ still needed?</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/11/is-c-still-needed/"/>
   <updated>2005-11-24T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/11/is-c-still-needed</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.baus.net&quot;&gt;Christopher Baus&lt;/a&gt; is &lt;a href=&quot;http://www.baus.net/pool-allocation&quot;&gt;reasoning about why C++ is falling out of favor&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;In domains where low level access is critical, developers are going for C. If developers can live with higher level abstractions, then they are skipping straight to Java or Python or Ruby or PHP, and by passing C++ altogether. C++ is getting squeezed out in the middle.&lt;/blockquote&gt;

&lt;p&gt;I think he’s right. If you’re doing large scale business applications, like I do on work, C++ definitely is not the language of choice. Some reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;C++ is slow. Amazing, but true. We evaluated both Java, C# and C++, and Java and C# were up to five times faster on usual use cases, like retrieving and instantiating objects from a database.  This is because creating a new instance in memory takes much more time in C++ compared to other, even interpreted, languages - unless you don&apos;t write your own memory management. But as Christoper explains, C++ is missing some low level feature in this area, too ;-).&lt;/li&gt;
&lt;li&gt;C++ takes more development time. Not only because you have to write your own memory management, there&apos;s much more to take care about in C++ than in other high level languages, mostly due to missing garbage collection. And a lot of time is consumed by compiling, which takes significantly longer than in any other language (talking about hours compared to minutes, actually).&lt;/li&gt;
&lt;li&gt;C++ isn&apos;t open to other languages. While you can bridge from say Python to Java or from Java to C, C++ binaries cannot be accessed (unless they publish core C-functions). This is because there is no standard on how C++ should publish its library entry points (don&apos;t know if this is the right term), so each compiler does it slighly different.&lt;/li&gt;
&lt;li&gt;C++ doesn&apos;t support module oriented development very well. For two reasons: First the interface definitions (the .h files) are cluttered with implementation stuff like private variables. If you work around this by holding your data in a separate structure, you pay with an additional memory allocation, which slows the application down. Second, C++ misses a concept like C# offers with &quot;internal&quot; (Java and VB offer same concepts): Code that is public within a module, but private from outside.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nevertheless, we chose C++ as our language. Why? Because it was the only language that (using the QT framework) ran on Windows, Linux, and several (already outdated) *nix platforms, like for example HP-UX 20. Platforms where Java is available in version 1.0 only, if available at all. Platforms where Mono will never run. This however rather is a niche and more and more of these platforms are replaced by Linux nowadays.&lt;/p&gt;

&lt;p&gt;Anyhow, there are cases were C++ comes in handy: All the high level languages and their libraries offer you about 90 percent of what you will need in everyday business programming. But if you want some advanced stuff like the most current juicy UI features or access to the systems network layer, you are left alone. There are reasons for this (for example the .NET framework must be compatible to Windows 98), of course and most languages will allow to use the system’s API, which is C.&lt;/p&gt;

&lt;p&gt;However, using for example the Windows API from C# is a pain in the ass, since you must redeclare each and every structure and function. You must deal with pointers or pointers to pointers etc. All of which is native to C++ and saves you a bunch of time (and results in much cleaner code), as &lt;a href=&quot;https://www.codeproject.com/Articles/11112/A-rational-attempt-to-substantiate-C-CLI-as-a-firs&quot;&gt;this comparison shows&lt;/a&gt;. In a recent project of mine I therefore happily mixed C++ and C#, the same as I did back when I was programming in Visual Basic 6.&lt;/p&gt;

&lt;p&gt;You may note however, that I’m doing this because I can. C++.NET managed code can be used by C# without any problems (Dude, I really love it). For Visual Basic I created COM objects in C++ using ATL. But what if Java was my main language or Python? I’d be stuck (unless I’m doing CORBRA, which - well - isn’t really made for this kind of thing).&lt;/p&gt;

&lt;p&gt;Conclusion? C++ sometimes is the best choice, sometimes not. If C++ is falling out of favor, then also because it didn’t care about the rest of the world - and still doesn’t care.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Sending spam through contact forms</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/09/sending-spam-through-contact-forms/"/>
   <updated>2005-09-15T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/09/sending-spam-through-contact-forms</id>
   <content type="html">&lt;p&gt;There’s a wave of contact form spamming going around and it hit the &lt;a href=&quot;http://comic-marktplatz.de&quot;&gt;Comic Marktplatz&lt;/a&gt;, too. The main purpose of this attack is to figure out websites providing forms that can be misused to send spam, effectivly turning them into open relays. This affects not only contact forms, but also blog comments.&lt;/p&gt;

&lt;p&gt;Anders Brownworth has &lt;a href=&quot;http://www.anders.com/projects/sysadmin/formPostHijacking/&quot;&gt;the details&lt;/a&gt; about all this (also see his &lt;a href=&quot;http://www.anders.com/cms/75/Crack.Attempt/Spam.Relay&quot;&gt;blog entry&lt;/a&gt;). However his solution for PHP has some syntax errors. These are corrected by &lt;a href=&quot;http://www.davidseah.com/archives/2005/09/01/wp-contact-form-spam-attack/&quot;&gt;David Seah&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Shortly said, you should remove line feeds from every user entered string that becomes part of a mail’s header. These usually are&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The sender (From:)&lt;/li&gt;
  &lt;li&gt;The subject (Subject:)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;David also suggests to remove common header tokens like “to:”, “subject:”, “mime-type:” etc. from this strings. I personally think, this is a good idea. I turned David’s code into a neat function, replacing the original preg_replace with str_replace, for &lt;a href=&quot;http://www.php.net/manual/en/function.str-replace.php&quot;&gt;performance purposes&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;cd&quot;&gt;/**
 * Clears header field to avoid injection
 * http://www.anders.com/projects/sysadmin/formPostHijacking/
 * http://www.davidseah.com/archives/2005/09/01/wp-contact-form-spam-attack/
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;preprocessHeaderField&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;//Remove line feeds
&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str_replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str_replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// Remove injected headers
&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$find&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/bcc\:/i&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;s2&quot;&gt;&quot;/Content\-Type\:/i&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;s2&quot;&gt;&quot;/Mime\-Type\:/i&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;s2&quot;&gt;&quot;/cc\:/i&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;s2&quot;&gt;&quot;/to\:/i&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;preg_replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                      &lt;span class=&quot;s2&quot;&gt;&quot;**bogus header removed**&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                      &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;David also suggest to do this with the message text itself, which I personally regard as not beeing necessary, since the message text usually can do no harm.&lt;/p&gt;

&lt;p&gt;It seems the robots are systematically scanning websites for input fields to provide an email, name and message. That’s why they also &lt;a href=&quot;http://www.google.com/search?hl=en&amp;amp;lr=&amp;amp;safe=off&amp;amp;q=jrubin3546%40aol.com+comments&amp;amp;btnG=Search&quot;&gt;try this out on comment forms&lt;/a&gt;. Since these forms usually also send a mail to the post author, they are also vunerable. So you better watch for updates of your blog software.&lt;/p&gt;

&lt;p&gt;Which finally brings me to one of my favourite topics: Architecture. Regarding the Comic Marktplatz, I needed to apply the fix to exactly one place, since all mailing is done through one single class representing a mail. No need to look up every possible vulnerable form throughout the application.&lt;/p&gt;

&lt;p&gt;Compare this - just for example and without any judging - to my blog software, Wordpress 1.2 (yes, still… upgrading takes too much time).  Do a search for “@mail” in the wordpress source files and you will find several occurances, all of whom potentially are vulnerable. There are even more including the plugins.&lt;/p&gt;

&lt;p&gt;In Wordpress 1.5, this hasn’t been quite corrected. Though there is central function called wp-mail(), it acts just as a very small wrapper around the PHP mail() function. Basically it only adds a content type and MIME version. It howevers still requires the caller to prepare a basic header including the sender (From:), which exactly is where the attack takes place. All this calling code must be identified and fixed to secure the application, which is error prone.&lt;/p&gt;

&lt;p&gt;Morale? Code duplication is bad, centralization is good. Think before you hack. Teach this, preach this!&lt;/p&gt;

&lt;p&gt;PS: I always wondered why PHP mail() doesn’t take the sender as a parameter -  this seems weird.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; There’s an article on Secure PHP &lt;a href=&quot;http://securephp.damonkohler.com/index.php/Email_Injection&quot;&gt;investigating the full story&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Safari first to pass ACID2 test</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/04/safari-first-to-pass-acid2-test/"/>
   <updated>2005-04-29T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/04/safari-first-to-pass-acid2-test</id>
   <content type="html">&lt;p&gt;Safari is the &lt;a href=&quot;http://www.sitepoint.com/blog-post-view.php?id=258586&quot;&gt;first browser to pass&lt;/a&gt; the &lt;a href=&quot;http://webstandards.org/act/acid2/&quot;&gt;ACID2 browser compliance test&lt;/a&gt;. Respect!
rm&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Tutorial XHTML2 and XForms</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/04/tutorial-xhtml2-and-xforms/"/>
   <updated>2005-04-20T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/04/tutorial-xhtml2-and-xforms</id>
   <content type="html">&lt;p&gt;Last event in my “Do as much in a couple of days as you would normally do in a year”-week: Together with &lt;a href=&quot;http://www.matente.de &quot;&gt;Natalia&lt;/a&gt; and &lt;a href=&quot;http://www.fade-in.de/&quot;&gt;Catarina&lt;/a&gt; I attended &lt;a href=&quot;http://homepages.cwi.nl/~steven/&quot;&gt;Steven Pemberton’s&lt;/a&gt; &lt;a href=&quot;http://www.w3.org/2005/Talks/04-19-steven-XHTML2-XForms/&quot;&gt;Tutorial on XHTML2 and XForms&lt;/a&gt;, organized by the &lt;a href=&quot;http://www.w3c.de&quot;&gt;German and Austrian section of W3C&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pemberton is a brilliant speaker, easy to follow for both unexperienced and experienced users, and entertaining, too. He covered the basics of &lt;a href=&quot;http://www.w3.org/TR/2004/WD-xhtml2-20040722/&quot;&gt;XHTML2&lt;/a&gt; and explained why things were decided the way they were. The recommendation looks quite promising. However, of course, it will be of pratical relevance in about five to six years from now - if at least.&lt;/p&gt;

&lt;p&gt;However, &lt;a href=&quot;http://www.w3.org/TR/2003/REC-xforms-20031014/&quot;&gt;XForms&lt;/a&gt; is already in use, as Pemberton explained. He demonstrated some XForms-applications, and it was really amazing what already can be done. This is something, I’ll have a deeper look at the other day. The people at Mozilla &lt;a href=&quot;http://www.mozilla.org/projects/xforms/&quot;&gt;are working on it&lt;/a&gt;, so maybe it will becoming wider spread soon.&lt;/p&gt;

&lt;p&gt;Finally, I’d like to thank the German and Austrian section of W3C for this event. You did a great job!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Beware of Apache's Multiviews</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/04/beware-of-apaches-multiviews/"/>
   <updated>2005-04-15T00:00:00+02:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/04/beware-of-apaches-multiviews</id>
   <content type="html">&lt;p&gt;Releasing a web project for the first time brings up something new every day. The lesson I learned yesterday was to never rely on Apache’s Multiview feature, since it doesn’t work with the most important browser on earth: Googlebot.&lt;/p&gt;

&lt;p&gt;As you may know, Google does deep indexing of new content onl once a month, which happened to be yesterday. But imagine my horror, when I discovered each of my content pages delivering an 406 error to Googlebot. Oh me, oh my! What has happened here?&lt;/p&gt;

&lt;p&gt;It turned out that this is a well-known problem of Apache’s multiview feature. Multiviews allow substitutions of file extensions, so you can call an URL like www.somehost.org/mypage.php using www.somehost.org/mypage. Apache will figure out there is only on file (mypage.php) matching the request and will serve this instead returning an error 404 - not found.&lt;/p&gt;

&lt;p&gt;So far, so good. And handy, indeed. &lt;strong&gt;But…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While doing this, Apache will check if the MIME-type of the file used for substitution matches the MIME types accepted by the client that does the request. This ain’t a problem for most browsers, since they usually accept any MIME type. However, Google decided to accept only (or mainly) text/html.&lt;/p&gt;

&lt;p&gt;Well, mypage.php creates text/html, doesn’t it? So where’s the problem?&lt;/p&gt;

&lt;p&gt;The problem is, that while it may create text/html, mypage.php itself is of MIME type application/x-httpd-php. This type is not accepted by Googlebot, hence the error 406 - Not accepted.&lt;/p&gt;

&lt;p&gt;Dooh!&lt;/p&gt;

&lt;p&gt;Unfortunately, there doesn’t seem to be a general solution for Apache 1.3.x (while &lt;a href=&quot;http://tranchant.plus.com/notes/multiviews&quot;&gt;there is one for Apache 2&lt;/a&gt;). And since I wasn’t feeling lucky enough to figure out by myself, I decided to rely on Apache’s rewriting capabilities. Which, to be honest, I recently tried to avoid, since regular expression usually give me headaches.&lt;/p&gt;

&lt;p&gt;My first hotfix was to simple hardcode every page:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; -Multiviews
&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;On&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; / 
&lt;span class=&quot;ss&quot;&gt;RewriteRule&lt;/span&gt; ^mypage/(.*) /mypage.php/$1
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^mypage$ /mypage.php&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This simply will rewrite /mypage/some/parameters to /mypage.php/some/parameters (the first rule) or /mypage to /mypage.php (the second one). Note that parameters like ?arg1=some&amp;amp;arg2=parameter are handled by Apache automatically. So something like /mypage?arg1=some&amp;amp;arg2=parameter will be handled by the second rule.&lt;/p&gt;

&lt;p&gt;This hotfix made Googlebot happy, and therefore me, too. However, I came up with a more general solution that covers all cases:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-apache&quot; data-lang=&quot;apache&quot;&gt;&lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; -Multiviews
&lt;span class=&quot;nc&quot;&gt;RewriteEngine&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;On&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RewriteBase&lt;/span&gt; /

&lt;span class=&quot;c&quot;&gt;# If there is no . before / rewrite to $1.php/$2
&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; $1 !images|downloads
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^([^&amp;amp;#92;./]+)/(.*) /$1.php/$2 [L]

&lt;span class=&quot;c&quot;&gt;# Find single files like mypage
&lt;/span&gt;
&lt;span class=&quot;nc&quot;&gt;RewriteCond&lt;/span&gt; $1 !images|downloads
&lt;span class=&quot;nc&quot;&gt;RewriteRule&lt;/span&gt; ^([^&amp;amp;#92;.]+)$ /$1.php [L]&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;First, all the rules should not apply to real directories, like for example images or downloads. Thats why I excluded them using a rewrite condition. This is far from good, and I hope to find a general (and performant) solution for this, too. But since regular expressions give me headaches, I won’t do too much at a time of them.&lt;/p&gt;

&lt;p&gt;The first rule now checks for a request that doesn’t contain a dot before the first slash, which means there is no file extension provided. It must have at least one char before the slash, though, else there will be a problem with the root directory “/”. The rule will simply append “.php” and exit.&lt;/p&gt;

&lt;p&gt;The second rule does nearly the same for requests like “/mypage”, where there is no trailing slash.&lt;/p&gt;

&lt;p&gt;I’m quite sure both cases can be put into one single rule, but as you may know, regular expressions give me headaches. So this is left up for another time.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Replacing Inheritance With Composition</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/01/replacing-inheritance-with-composition/"/>
   <updated>2005-01-31T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/01/replacing-inheritance-with-composition</id>
   <content type="html">&lt;p&gt;Ivan Moore briefly discusses &lt;a href=&quot;http://ivan.truemesh.com/archives/000490.html&quot;&gt;replacing inheritance with composition&lt;/a&gt; regarding the amout of testing code required. He concludes that with composition,&lt;/p&gt;
&lt;blockquote&gt;instead of having the tests duplicated (or using inheritance in the tests to remove the duplication) the tests can now be split into two parts. One test for the class with the code that is common, and separate tests for the code that is different.&lt;/blockquote&gt;

&lt;p&gt;This is quite similiar to what I wrote about &lt;a href=&quot;/archives/2005/01/applying-arbitrary-custom-filters-to-a-collection-chain-of-responsibility/&quot;&gt;applying filters to a collection&lt;/a&gt;. And as Ivan notes&lt;/p&gt;

&lt;blockquote&gt;There are other benefits in addition to the simplification of the tests, and the removal of duplication. Using composition also allows more flexibility in combining these classes together.&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Less PHP Database Code Using The Factory Design Pattern</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/01/encapsulating-database-access-in-php-using-the-factory-design-pattern/"/>
   <updated>2005-01-27T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/01/less-php-database-code-using-the-factory-design-pattern</id>
   <content type="html">&lt;p&gt;It’s PHP design pattern time again! Today I’ll show a simple way to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Encapsulate database access in a class&lt;/li&gt;
&lt;li&gt;Make queries return objects rather than records or arrays&lt;/li&gt;
&lt;li&gt;Reduce code to process database results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this is achieved by using the factory pattern. Read on!&lt;/p&gt;

&lt;p&gt;It usually is a good idea to encapsulate database access into a class. Not necessarily because you may change your database more easily (since for most PHP applications the database will be MySQL for still a long time, due to provider configurations), but to get rid of all this repeating database access code, which tends to be error prone.&lt;/p&gt;

&lt;p&gt;If you start to wrap db code fragments into a class, however, you’ll notice that having hidden MySQL inside a neat little class, you still have code like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mysql_fetch_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dbHandle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;doSomething&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;spread all over your application. And that’s the last thing you want, actually. So it’s time for another abstraction, a recordset, is it?&lt;/p&gt;

&lt;p&gt;Well, not necessarily. Try using the factory design pattern.&lt;/p&gt;

&lt;p&gt;The idea of the factory pattern is to use a function to create an instance of a class rather than calling the constructor using new. This is because a function can be overridden, while a constructor cannot. This makes quite a difference, since for using the new keyword, we must know the concrete type of the instance to create. Having a function, this is not required, since it is enough to know the function exists.&lt;/p&gt;

&lt;p&gt;Let’s start with a simple class like this one:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$firstName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lastName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$firstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$firstName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$lastName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we write a factory. It is really simple, since it contains just one function. We pass a record, which actually is an associative array. This is a brief abstraction in this case. Here we go:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonFactory&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;firstname&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;lastname&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;age&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Simple, isn’t it? This of course assumes the fields in the database are called accordingly.&lt;/p&gt;

&lt;p&gt;Now on to the database wrapper class. Having a factory class, a database query can return objects directly, rather then just records or a query handle:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DB&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// .. some other code to open connection etc.
&lt;/span&gt;
  
  &lt;span class=&quot;c1&quot;&gt;// returns an array of instances
&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;queryArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mysql_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mysql_fetch_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;nb&quot;&gt;mysql_free_result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$ret&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;c1&quot;&gt;// Returns a single instance	
&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;querySingle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$factory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mysql_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sql&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;		
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;mysql_fetch_array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;mysql_free_result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$queryID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$record&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I hope you get the idea. There is no magic in this code, everything is straight forward. Having the DB returning an array of instances makes it much easier to iterate through it, using a common foreach loop.&lt;/p&gt;

&lt;p&gt;What’s missing is a function to load objects from database. Here are two simple implementations:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonDB&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// returns one instance
&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;findByID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;querySingle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;&apos;Select * from Person where id = $id&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;c1&quot;&gt;// returns an array
&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;findByAge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;queryArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;s1&quot;&gt;&apos;Select * from Person where age = $age&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonFactory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And finally here’s the client code that uses it all:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;c1&quot;&gt;//print all persons that are 35 years old
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$arr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PersonDB&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;findByAge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arr&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foreName&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$person&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lastName&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&amp;amp;#92;n&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Neat, isn’t it? Notice that each of the functions and classes presented are simple and more or less self-explaining. Combined, however, they provide a great flexibility. Now compare this to the avarage PHP database code, you’ll find in oh so many PHP applications!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Applying Arbitrary Custom Filters To A Collection: Chain Of Responsibility</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/01/applying-arbitrary-custom-filters-to-a-collection-chain-of-responsibility/"/>
   <updated>2005-01-21T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/01/applying-arbitrary-custom-filters-to-a-collection-chain-of-responsibility</id>
   <content type="html">&lt;p&gt;I faced some annoyance of my Randomized Blogroll Plugin the last days: My own blogroll contains some subscriptions to ego searches that I don’t want to publicize on my webpage, since they are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;depressing, and&lt;/li&gt;
&lt;li&gt;not of any public interest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Getting tired of removing them by hand everytime I update my blogroll, I started to implement filtering. Here’s what I came up with. See my mind at work.&lt;/p&gt;

&lt;p&gt;My first sketch was to create a simple class called Filter, containing just one function that gets passed a collection, iterates through it and does what needs to be done. This is PHP 4.x code:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Iterate and apply filter 
&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;However, if I want to apply an additional filter (renaming root category “Subscriptions” to “General”, for example), the collection is stepped through a second time: ugly.&lt;/p&gt;

&lt;p&gt;So the next step was to extract the iteration from Filter and move it into the collection class:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Collection&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;myvalues&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// apply filter on $item
&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;However, this doesn’t solve the problem of applying more than one filter, since collection-&amp;gt;filter() still only takes one Filter instance. Maybe I should make it accepting an array, too?&lt;/p&gt;

&lt;p&gt;No. There is a nice little design pattern at hand that solves this problem: &lt;a href=&quot;http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern&quot; title=&quot;wikipedia about chain of responsibility&quot;&gt;chain of responsibility&lt;/a&gt;. This pattern can be applied if&lt;/p&gt;

&lt;blockquote&gt;the set of objects that can handle a request should be specified dynamically.&lt;/blockquote&gt;

&lt;p&gt;This is excatly what I want to do. Applying this pattern the collection can be left untouched, while I extend the Filter class:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FilterChain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;cd&quot;&gt;/**
   * The next chain mamber
   */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$nextInChain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  	
  &lt;span class=&quot;cd&quot;&gt;/**
   * Append new member to the end of the chain
   */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appendToChain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$member&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextInChain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextInChain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$member&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextInChain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;appendToChain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$member&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  	
  &lt;span class=&quot;cd&quot;&gt;/** 
   * Filter
   */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;doFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextInChain&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextInChain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  	
  &lt;span class=&quot;cd&quot;&gt;/**
   * Does filtering. Overridden in subclasses.
   * Returns TRUE if next filter can be applied, FALSE if not (the item has been removed)
   */&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// default. Override this.
&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  
&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Filter&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FilterChain&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$collection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// apply filter on $item 
&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// return FALSE if item was removed, otherwise TRUE
&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The code is simple. FilterChain delegates filtering to doFilter() which would be virtual protected in C++ or comparable languages. appendToChain() find the last member of the chain and sets its next element property.&lt;/p&gt;

&lt;p&gt;The usage is simple, too:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$filter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SomeFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$filter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;appendToChain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SomeOtherFilter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$someCollection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Reflecting the state of affairs for this plugin, I have customizable input, customizable output, customizable filtering and I’m starting on customizable sorting. Maybe it neds some renaming? What about &lt;strong&gt;The most customizable blogroll plugin ever&lt;/strong&gt;?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Building A Better C++ String Class?</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/01/building-a-better-c-string-class/"/>
   <updated>2005-01-18T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/01/building-a-better-c-string-class</id>
   <content type="html">&lt;p&gt;Preston L. Bannister tries to build &lt;a href=&quot;http://bannister.us/weblog/?p=186&quot;&gt;a better C++ string class&lt;/a&gt; than provided by the C++ standard libraries (found through &lt;a href=&quot;http://www.baus.net/optimizationsurprise&quot;&gt;Christopher Baus&lt;/a&gt;). However, I think he will fail, since he’s too much involved in low level things, rather then design.&lt;/p&gt;

&lt;!--break--&gt;

&lt;p&gt;Preston states that&lt;/p&gt;

&lt;blockquote&gt;I seldom use the C++ string classes supplied with the standard libraries, out of a belief that (for my purposes) that I can easily do better, building on bits of history and experience.  Considerations that go into building a simple and highly efficient C++ string class include the following.
&lt;ol&gt;&lt;li&gt;The standard &amp;lt;string .h&amp;gt; supplied C string functions are highly optimized (as described in a previous post).&lt;/li&gt;
&lt;li&gt;Heap operations are best avoided (where practical) in long running applications. Use of a free list is very effective when the application has a cyclic workload (as most do).&lt;/li&gt;
&lt;li&gt;Use of C++ inline class methods allows both readable code and most effective use of the optimizer.&lt;/li&gt;
&lt;/ol&gt;&lt;/blockquote&gt;

&lt;p&gt;I actually wonder why he’s so negative about the standard C++ string class, and what makes him belief the standard implementation isn’t highly efficient. Let’s take a look at the Visual C++ implementation, for example. Doesn’t it fullfill, what Preston considers?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It uses calls to the supplied C string functions, which turn out to perform very well on Windows machines, as &lt;a href=&quot;http://bannister.us/weblog/?p=189&quot;&gt;he himself figured out&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;It avoids unnecessary heap allocation by implementing copy-on-write, allocating in blocks and similiar tricks.&lt;/li&gt;
&lt;li&gt;Since it is a template class, all functions are inlined.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remarkably, the string class gains perfomance by changing the point of view from low level operations like memory copying to the actual usage. Take for example the copy-on-write strategy (Scott Meyers wrote about it in “More Effective C++”, Rule 29). This is a true performance boost, since you avoid memory beeing copied on each assignment or copy construction operation. And have in mind that each function returning a string class implicitly invokes the copy constructor. In other words: This is a very common use case for a string class.&lt;/p&gt;

&lt;p&gt;Figuring out the best way to copy an array of chars is simple. But designing a string class is much more than this: It is about avoiding  copying whereever possible, too. And I doubt if the string class Preston is to come up with, will be look too much different from the current standard implementation in the end.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>PHP Performance Also Is A Question Of Design</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/01/php-performance-also-is-a-question-of-design/"/>
   <updated>2005-01-14T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/01/php-performance-also-is-a-question-of-design</id>
   <content type="html">&lt;p&gt;Harry Fuecks, who runs the excelent &lt;a href=&quot;http://www.phppatterns.com/&quot;&gt;phpPatterns&lt;/a&gt; site talks about &lt;a href=&quot;http://www.sitepoint.com/blog-post-view.php?id=223760&quot;&gt;object oriented programming  and performance &lt;/a&gt;. He states that &lt;a href=&quot;http://www.sitepoint.com/blog-post-view.php?id=224444&quot;&gt;procedural PHP leads to slower apps&lt;/a&gt; and challenges everyone to prove the opposite.&lt;/p&gt;

&lt;p&gt;Harry argues, the argument of procedural code beeing faster&lt;/p&gt;

&lt;blockquote&gt;is based on benchmarking code. What it ignores though is the human aspect of writing code and that&apos;s where a side-effect of OOP can result in improved performance.&lt;/blockquote&gt;
&lt;blockquote&gt;Bearing in mind I&apos;m talking only in a general sense, I think the tendency with procedural code is to use &quot;brute force&quot; - the actual meaning and behaviour of the logic being masked by the spaghetti. If what the code was actually doing was transparent to the developer, they might see some of the &quot;blinding&quot; inefficiencies they&apos;ve introduced.&lt;/blockquote&gt;

&lt;p&gt;I totally agree. As I already argued regarding &lt;a href=&quot;/archives/2004/12/optimization-templates-and-the-rest/&quot;&gt;C++ optimization&lt;/a&gt;, performance is rather a question of design, not code.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>In Addition to C++ Optimization</title>
   <link href="https://www.gerd-riesselmann.net/archives/2005/01/in-addition-to-c-optimization/"/>
   <updated>2005-01-03T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2005/01/in-addition-to-c-optimization</id>
   <content type="html">&lt;p&gt;In addition to the recent discussion about &lt;a href=&quot;/archives/2004/12/optimization-templates-and-the-rest/&quot;&gt;C++ optimization&lt;/a&gt;: In &lt;a href=&quot;http://www.codeguru.com/forum/showthread.php?t=282272&quot;&gt;this CodeGuru Forums thread&lt;/a&gt; people talk about &lt;a href=&quot;http://www.codeguru.com/forum/showpost.php?p=893127&amp;amp;postcount=26&quot;&gt;optimizing conditional branches&lt;/a&gt; like&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Interesting, sure, though I still agree with &lt;a href=&quot;http://www.codeguru.com/forum/showpost.php?p=1071916&amp;amp;postcount=44&quot;&gt;this post&lt;/a&gt;, which argues that:&lt;/p&gt;

&lt;blockquote&gt;If there was a REAL performance benefit to be made, don&apos;t you think the compiler designers would have added this in their optimizer already? Compiler benchmarks are a big issue, and they add a LOT more complicated type optimisations than this.

Most of the time, if you want to get better performance, you have to rethink the program at a higher level. Put your brains at work to find a better design, and let the compiler twiddle the bits for you.&lt;/blockquote&gt;
</content>
 </entry>
 
 <entry>
   <title>Optimization, Templates And The Rest</title>
   <link href="https://www.gerd-riesselmann.net/archives/2004/12/optimization-templates-and-the-rest/"/>
   <updated>2004-12-18T00:00:00+01:00</updated>
   <id>hhttps://www.gerd-riesselmann.net/archives/2004/12/optimization-templates-and-the-rest</id>
   <content type="html">&lt;p&gt;Does low-level optimization really works? Do templates bring speed? Two articles by &lt;a href=&quot;http://weblogs.asp.net/oldnewthing/archive/2004/12/16/317157.aspx&quot;&gt;Raymond Chen&lt;/a&gt; and &lt;a href=&quot;http://www.baus.net/optimizationcounter.html&quot;&gt;Christopher Baus&lt;/a&gt; started a discussion, that I’m about to join. I’m arguing that in most cases, you do not want to do low-level optimization, since the speed you gain isn’t worth the effort, and you should rather concentrate on the design. At least if you are an application developer.&lt;/p&gt;

&lt;p&gt;Raymond Chen illustrates that &lt;a href=&quot;http://weblogs.asp.net/oldnewthing/archive/2004/12/16/317157.aspx&quot;&gt;optimization is often counter-intuitive&lt;/a&gt;. Well, with the right example, you can prove anything, and Raymond’s example seems rather bizarre to me. Maybe since I’m an application developer that couldn’t care less about low-level details.&lt;/p&gt;

&lt;p&gt;Now &lt;a href=&quot;http://www.baus.net/optimizationcounter.html&quot;&gt;Christopher Baus&lt;/a&gt; raises the question up to a level I’m familiar with. He starts with shortly discussing C++ function inlining and optimization and after that quickly jumps to talk about template meta programming and its impact on performance.  Christopher’s says that&lt;/p&gt;

&lt;blockquote&gt;It is extremely difficult to optimize for modern processors and results can vary even with in a product line; therefore most application developers should not spend their time trying to optimize the speed of a single operation such as a function call.&lt;/blockquote&gt;

&lt;p&gt;I agree with him, that it’s useless to do low level optimizations and spend your time thinking about inlining or not. However, I’d like to give another argument. Even if you can be sure that some optimization really speeds up things, it is still a waste of time in nearly all cases. Why? Because the amount of time your function is faster is way to small to be notable. Think of some inlined accessor and let’s say you safe 10 CPU instructions (I’m too lazy to look up the actual value). On a 1.5 MHz processor, 1.5 Millions instructions are executed a second. Let’s assume that one instruction takes one CPU cycle (indeed, AMD processors are able to execute even several instructions in one CPU cycle), these 10 instructions safe you 0.0666 milliseconds. You therefore need to call this accessor 15,000 times to make your application just one second faster. And you better do this in a loop.&lt;/p&gt;

&lt;p&gt;From my experience as an application developer, bottlenecks result far more often from wrong design decisions. For example when using a linked list where a hash table would be more appropriate. If you use a database, defining your indexes correctly is something to worry. However, optimization comes last, and you better let a profiler tell you where to look.&lt;/p&gt;

&lt;p&gt;Back to Christopher’s article: He continues arguing that&lt;/p&gt;

&lt;blockquote&gt;Recently a new version of the inline argument has re-surfaced. Many proponents of &quot;generic programming&quot; in C++ claim that by binding functions at compile time the resulting executable is faster (less code to execute to make a function call, sound familiar?). I am not convinced. What you do get is BIGGER object code. Bigger binaries are more difficult to cache, and performance on modern processors is all about effectively using the cache.&lt;/blockquote&gt;

&lt;p&gt;This may be or may not be, I actually know too little about processors to judge this statement. Nevertheless, I’d like to introduce another argument here: Design. Again, I speak as an application developer, and things may look different if you are programming devices or tricky algorithms.&lt;/p&gt;

&lt;p&gt;When you are doing applications, you should concentrate on the design rather then speed. There is a time to optimize and it is at the end, when you know where the bottlenecks are. Your design should be clear, flexible and understandable. It contains the logic of your application, and you will spend a lot of time changing and extending your code, because requirements will change and grow over time. You also will spend a lot of time compiling (I compile after each change, since compiling is the first test the code must pass), so you should consider compile time dependencies. Whether you use template meta programming (which is far more then just using templates here and there) or not, should be primary a design decision.&lt;/p&gt;

&lt;p&gt;Christopher ends up with some ranther ranty comment about template meta programming in generel (and is second by &lt;a href=&quot;http://www.lenholgate.com/archives/000406.html&quot;&gt;Len Holgate&lt;/a&gt;):&lt;/p&gt;

&lt;blockquote&gt;Template programming has become a mental game for those who want to be C++ giants. It is a proving ground. C++ templates are not a meta-programming language. Those that use templates for advanced meta programming are abusing a side effect of a language construct. The fact that the syntax is so obtuse (because it was never intend to be used in this way) provides a way to prove mental prowess.&lt;/blockquote&gt;

&lt;p&gt;Well, maybe. I tend to believe that we never will see large and complex business applications build entirely on templates. However, template meta programming can be useful sometimes, and you can do neat little things. Think of Andrei Alexandrescu’s &lt;a href=&quot;http://www.moderncppdesign.com/&quot;&gt;Modern C++ Design&lt;/a&gt;, for example.&lt;/p&gt;
</content>
 </entry>
 
 
</feed>