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

<channel>
	<title>W-Shadow.com &#187; Tutorials</title>
	<atom:link href="http://w-shadow.com/blog/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://w-shadow.com</link>
	<description>Slightly Advanced Computer Stuff (and some magic)</description>
	<lastBuildDate>Tue, 09 Mar 2010 16:38:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cool Things You Can Do With Unused Keyboard Keys</title>
		<link>http://w-shadow.com/blog/2010/01/14/cool-things-you-can-do-with-unused-keyboard-keys/</link>
		<comments>http://w-shadow.com/blog/2010/01/14/cool-things-you-can-do-with-unused-keyboard-keys/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 16:30:32 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[AutoHotkey]]></category>
		<category><![CDATA[CapsLock]]></category>
		<category><![CDATA[computer keyboard]]></category>
		<category><![CDATA[hotkeys]]></category>
		<category><![CDATA[macro utility]]></category>
		<category><![CDATA[Menu key]]></category>
		<category><![CDATA[ScrollLock]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1594</guid>
		<description><![CDATA[Most computer keyboards have one or more keys that see next to no use in day-to-day work. The standard 104-key Windows keyboard has a whole bunch of them &#8211; ScrollLock, Pause/Break, CapsLock, the Menu key. Depending on your typing style, even more keys &#8211; like the extra Alt and Ctrl keys to the right of [...]]]></description>
			<content:encoded><![CDATA[<p><img style=' float: left; padding: 4px; margin: 0 7px 2px 0;'  class="size-full wp-image-1607 alignleft" title="Computer keyboard" src="http://w-shadow.com/wp-content/uploads/2010/01/Keyboard-159917_1785-small.jpg" alt="Computer keyboard" width="200" height="133" />Most computer keyboards have one or more keys that see next to no use in day-to-day work. The <a href="http://en.wikipedia.org/wiki/IBM_PC_keyboard#104-key_.22Windows.22_keyboard">standard 104-key Windows keyboard</a> has a whole bunch of them &#8211; ScrollLock, Pause/Break, CapsLock, the Menu key. Depending on your typing style, even more keys &#8211; like the extra Alt and Ctrl keys to the right of the Space bar &#8211; might go unused.</p>
<p>Here&#8217;s a way to make them do something useful (and maybe even cool) : <a href="http://www.autohotkey.com/">AutoHotkey</a>. AutoHotkey is a free macro utility that lets you create scripted hotkeys for any key or key combination. With this utility, you can make the previously useless keys launch your favorite applications, control your media player, simplify copy/pasting, and more. I&#8217;ve included a small selection of handy hotkey scripts below, but you can find thousands more in the <a href="http://www.autohotkey.com/docs/scripts/index.htm">Script Showcase</a> and the <a href="http://www.autohotkey.com/forum/forum-2.html">AutoHotkey forums</a>.</p>
<p>Okay, lets move on to the actual scripts.</p>
<h3>Hot Hotkeys</h3>
<p><strong>Show desktop</strong></p>
<p>As you might know, you can hide/restore all open windows<strong> </strong>by pressing the Windows key and the D key together. With AutoHotkey, you can assign the same function to a single key &#8211; say, CapsLock. Here&#8217;s the AHK script :</p>
<pre>CapsLock::#d</pre>
<p><strong><strong>Open or focus the browser</strong></strong></p>
<p>If you&#8217;re like me, you probably tend Alt-Tab to the web browser every five minutes to run a Google search, read some online documentation or check for new emails. This can be simplified by creating a hotkey that, when pressed, brings the browser window to the front (or launches the browser if it isn&#8217;t already running). This <a href="http://superuser.com/questions/7271/most-useful-autohotkey-scripts/82800#82800">script by Niels Teglsbo</a> does just that :</p>
<pre>; Function to run a program or activate an already running instance
RunOrActivateProgram(Program, WorkingDir="", WindowSize=""){
    SplitPath Program, ExeFile
    Process, Exist, %ExeFile%
    PID = %ErrorLevel%
    if (PID = 0) {
        Run, %Program%, %WorkingDir%, %WindowSize%
    }else{
        WinActivate, ahk_pid %PID%
    }
}
; Make CapsLock run or activate Internet Explorer
CapsLock::RunOrActivateProgram("c:\Program Files\Internet Explorer\iexplore.exe")</pre>
<p>The example above uses Internet Explorer, but you can easily substitute it with your own favourite browser by editing the file path.</p>
<p><strong>Disable CapsLock</strong></p>
<p>Although CapsLock can be modified to become a useful hotkey, some people would rather just get rid of it because it&#8217;s too easy to press it accidentally. Well, all it takes is a single line script :</p>
<pre>SetCapsLockState, AlwaysOff</pre>
<p>Alternatively, you could remap CapsLock to act as Ctrl. This way it can both be useful and still remain harmless when accidentally pressed :</p>
<pre>CapsLock::Ctrl</pre>
<p><strong>Single-key Cut/Copy/Paste</strong></p>
<p>This script will make the right-side Alt, Windows and Menu keys function like Cut, Copy and Paste :</p>
<pre>RAlt::^x 	; Right Alt as Ctrl-X (Cut)
RWin::^c 	; Right Windows key as Ctrl-C (Copy)
AppsKey::^v	; Menu/Apps key as Ctrl-V (Paste)</pre>
<p>You can find an alternative setup that uses only the CapsLock key in <a href="http://stackoverflow.com/questions/1550019/how-to-hijack-the-caps-lock-key-for-cut-copy-paste-keyboard-operations">this StackOverflow thread</a>.</p>
<p><strong>Incrementally switch windows</strong></p>
<p><a href="http://www.autohotkey.com/forum/viewtopic.php?t=33353">iSwitchw</a> lets you incrementally switch between open windows using CapsLock (though you could easily modify it to use a different key).</p>
<blockquote><p>It&#8217;s a window switcher which shows the matching window titles as you type in your search string incrementally. If only one window is left it is activated immediately (configurable). Otherwise, you can type in more characters (or delete some with backspace) or select between the matching windows using cursor up/down/enter, or you can cancel the window with Esc.</p>
<p>You can use any substring of any window. For example, if you want to switch to word then you can type rd and there is a good chance word is selected immediately. Or type &#8220;notepad&#8221; and select quickly between the notepad windows with the cursor.</p></blockquote>
<p>The script itself is too long to be included here. You can find it in the <a href="http://www.autohotkey.com/forum/viewtopic.php?t=33353">iSwitchw forum thread</a>.</p>
<p><strong>Control your media player</strong></p>
<p>If your keyboard doesn&#8217;t have media keys, you can use AutoHotkey to remap some of your unused keys to act as passable substitutes. For example, I use the block of three keys to the right of the Space bar (on  a 104-key keyboard) to <a href="http://www.autohotkey.com/docs/misc/Winamp.htm">control Winamp</a> :</p>
<pre>RWin::
IfWinNotExist ahk_class Winamp v1.x
    return
ControlSend, ahk_parent, c  ; Pause/Unpause
return

RAlt::
IfWinNotExist ahk_class Winamp v1.x
    return
ControlSend, ahk_parent, z  ; Previous track
return

AppsKey::
IfWinNotExist ahk_class Winamp v1.x
	return
ControlSend, ahk_parent, b  ; Next track
return</pre>
<p><strong>Easy window dragging</strong></p>
<p>Normally, a window can only be dragged by clicking on its title bar. <a href="http://www.autohotkey.com/docs/scripts/EasyWindowDrag.htm">Easy Window Drag</a> extends that so that any point inside a window can be dragged. Just hold down CapsLock or the middle mouse button while clicking, then drag the window to a new position.</p>
<p>You can <a href="http://www.autohotkey.com/docs/scripts/EasyWindowDrag.htm">download the script here</a>.<strong></strong></p>
<h3>Other Uses For Unused Keys</h3>
<p>In addition to AutoHotkey, there are several other applications that can take advantage of typically unused keys.</p>
<p><strong><a href="http://humanized.com/enso/launcher/">Enso Launcher</a></strong></p>
<p>Enso Launcher is yet another cousin of Quicksilver/Launchy. It turns CapsLock into a multifunctional hotkey that lets you enter commands, launch applications, manipulate windows, access your bookmarks, quickly perform simple calculations, and more.</p>
<p><strong><a href="http://www.itsamples.com/network-lights.html">Network Lights</a></strong></p>
<p>Finally, here&#8217;s a little bonus for all who love to watch the <em>blinkenlights</em> : there&#8217;s a small freeware utility called <a href="http://www.itsamples.com/network-lights.html">Network Lights</a> that blinks the ScrollLock and NumLock LEDs indicating network traffic. It may not be very useful <em>per se</em>, but the thought of turning the keyboard into a network monitor of sorts certainly possesses a notable coolness factor.</p>
<p><em>Image credit : <a href="http://www.sxc.hu/photo/159917">staarpoint</a> @ sxc.hu </em></p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2010/01/14/cool-things-you-can-do-with-unused-keyboard-keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reliably Detecting The WordPress Version</title>
		<link>http://w-shadow.com/blog/2009/12/02/detect-wordpress-version/</link>
		<comments>http://w-shadow.com/blog/2009/12/02/detect-wordpress-version/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 17:56:26 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[footprinting]]></category>
		<category><![CDATA[footprints]]></category>
		<category><![CDATA[meta tag]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[wordpress version]]></category>
		<category><![CDATA[wp version]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1519</guid>
		<description><![CDATA[Sometimes you might want to find out if a website is built with WordPress, and which specific version of WP it&#8217;s running. In this post I&#8217;ll discuss a number of detection techniques, including ways to deal with sites that hide the fact that they&#8217;re running WordPress or spoof the version info.
For non-programmers : If you [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you might want to find out if a website is built with WordPress, and which specific version of WP it&#8217;s running. In this post I&#8217;ll discuss a number of detection techniques, including ways to deal with sites that hide the fact that they&#8217;re running WordPress or spoof the version info.</p>
<p><strong>For non-programmers</strong> : If you want something simple and don&#8217;t really care about detecting sites that hide their version info, check out the <a href="http://yoast.com/tools/seo/greasemonkey/show-wordpress-version/">Show WordPress Version</a> Greasemonkey script. Whenever you visit a WordPress blog, this simple userscsript will pop up  a small box showing the WP version.</p>
<h3>Introduction</h3>
<p>So how does one go about detecting the WordPress version? Simple &#8211; every WordPress site contains certain WordPress-specific footprints. A &#8220;footprint&#8221; can be anything from a unique piece of HTML code present on the front page to a specific subdirectory or file that&#8217;s only found on WordPress-based sites. Some sites try to <a href="http://www.bloganything.net/922/secure-your-wordpress-blog">hide the WordPress footprints</a>, but most still leave <em>something</em> visible. And more often than not, this <em>something</em> is enough to determine that the site is running WordPress, and even find out the version number.</p>
<p>Lets see what these footprints are, shall we?</p>
<h3>The generator META Tag</h3>
<p>This is probably the most well-known way to detect the WordPress version. By default, WP will add the following META tag to every page of the site :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;generator&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;WordPress 2.8.6&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>All you need to do is check for the presence of this tag and you&#8217;ll immediately know that the site is running WordPress. Even the version number is helpfully included. However, this is also the least reliable technique, as it&#8217;s very easy to <a href="http://www.seoegghead.com/software/wordpress-version-spoof.seo">replace the version number with a fake one</a> or remove the tag altogether.</p>
<h3>The RSS Feed generator Tag</h3>
<p>Even if the meta tag is gone, there&#8217;s still another place where the version number might be on display &#8211; the RSS feed. The WordPress generated feed is usually available at <code>example.com/?feed=rss2</code> and contains a tag that looks like this :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;generator<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://wordpress.org/?v=2.8.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/generator<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>As you can see, the version number is right there.</p>
<h3>CSS version data</h3>
<p>Another place where WP discloses version information is the <code>/wp-admin/upgrade.php</code> page. This page uses an external CSS stylesheet, and the stylesheet URL includes a &#8220;ver&#8221;/&#8221;version&#8221; parameter. Here&#8217;s an example from WP 2.8.6 :</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">'stylesheet'</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">'install-css'</span>  <span style="color: #000066;">href</span>=<span style="color: #ff0000;">'http://example.com/wp-admin/css/install.css?ver=20090514'</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">'text/css'</span> <span style="color: #000066;">media</span>=<span style="color: #ff0000;">'all'</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>This footprint is a (little) bit trickier to parse that the first two. Up to WordPress 2.5.1, the stylesheet URL contained the actual WordPress version in the &#8220;version&#8221; parameter. In later releases, it was replaced with a &#8220;ver&#8221; parameter containing some kind of a date; probably indicating the last time that CSS file was modified. I&#8217;ve found that the different date corresponds to each major WP release :</p>
<ul>
<li>20090514 &#8211; 2.8.*</li>
<li>20081210 &#8211; 2.7.*</li>
<li>20080708 &#8211; 2.6.*</li>
</ul>
<p>In some ways, this is actually <em>better</em> for our purposes than having the full version number in clear view. As I mentioned before, the version number can be easily spoofed. The date, however, can&#8217;t. I haven&#8217;t seen any plugins that would let you change or remove this footprint.</p>
<p>If <code>/wp-admin/upgrade.php</code> happens to be inaccessible on some sites, you can also find a similar footprint in <code>/wp-includes/js/tinymce/wp-mce-help.php</code>.</p>
<h3>Version-specific files</h3>
<p>Finally, almost every single new release of WordPress includes one or more files that weren&#8217;t there in the previous version. Many of these files &#8211; like images and JS scripts &#8211; are accessible to normal visitors. This means you can determine the WP version simply by checking for the presence of specific files. </p>
<p>I&#8217;ve compiled a small list of the last 6 major WP releases + a new web-accessible file that was added in each release :</p>
<ul>
<li>2.2 &#8211; <code>/wp-includes/images/rss.png</code></li>
<li>2.3 &#8211; <code>/wp-includes/js/scriptaculous/sound.js</code></li>
<li>2.5 &#8211; <code>/wp-includes/js/jquery/suggest.js</code></li>
<li>2.6 &#8211; <code>/wp-includes/images/blank.gif</code></li>
<li>2.7 &#8211; <code>/wp-includes/js/comment-reply.js</code></li>
<li>2.8 &#8211; <code>/wp-includes/js/codepress/codepress.js</code></li>
</ul>
<p>This list is by no means comprehensive, but you can easily make your own by downloading older versions of WP and comparing them.</p>
<p>Happy data mining <img src='http://w-shadow.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/12/02/detect-wordpress-version/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Detecting Parked Domains</title>
		<link>http://w-shadow.com/blog/2009/11/13/detecting-parked-domains/</link>
		<comments>http://w-shadow.com/blog/2009/11/13/detecting-parked-domains/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 20:12:19 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[detect parked domains]]></category>
		<category><![CDATA[domain parking]]></category>
		<category><![CDATA[identify parked domains]]></category>
		<category><![CDATA[parked domains]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1437</guid>
		<description><![CDATA[Some time ago, a commenter asked me if it was possible to make one of my WordPress plugins detect and report parked domains. I&#8217;ve done some research since then, and while it&#8217;s probably not practical to add such a feature to the plugin, I did come up with several ways to programmatically detect parked pages. [...]]]></description>
			<content:encoded><![CDATA[<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1444" title="WWW on the road (image credit : clix @ sxc.hu)" src="http://w-shadow.com/wp-content/uploads/2009/11/WWW-road.jpg" alt="WWW" width="200" height="149" />Some time ago, a commenter asked me if it was possible to make <a href="http://w-shadow.com/blog/2007/08/05/broken-link-checker-for-wordpress/">one of my WordPress plugins</a> detect and report parked domains. I&#8217;ve done some research since then, and while it&#8217;s probably not practical to add such a feature to the plugin, I did come up with several ways to programmatically detect parked pages. I&#8217;ve decided to summarize my findings in a blog post in case they&#8217;re useful to anyone else.</p>
<h3>What&#8217;s a Parked Domain?</h3>
<p>Broadly speaking, a parked domain is a website that contains no real content. Parked domains can have a benign purpose, like when someone puts a &#8220;Coming Soon&#8221; message on a domain reserved for an in-development site. However, much more commonly they are nothing but single-page &#8220;portals&#8221; stuffed with ads, bereft of any value to the unfortunate visitor. <a href="http://en.wikipedia.org/wiki/Typosquatting">Typosquatters</a> also frequently park their domains.</p>
<h3>How To Detect Parked Sites</h3>
<p>Let me state up-front that there is no single fool-proof method to detect parked domains. Each domain parking service has a lightly different page template and site structure, so even if you build a tool that can identify domains parked with SEDO.com with 100% accuracy it might still be clueless about sites parked with GoDaddy. The best approach is to use a combination of different detection algorithms.</p>
<p>Here&#8217;s a summary of techniques that I found promising.</p>
<p><strong>Check for subdomain wildcarding and ubiquitous redirects</strong></p>
<p>A lot of parked domains will gladly accept any HTTP request you throw at them, even if you try to access a non-existent subdomain or page. Instead of the typical &#8220;Not Found&#8221; error, a parked domain will either return a dynamically generated page full of ads or redirect you to the front page.  So you can check if a domain is parked is by requesting a bogus subdomain (e.g. <code>http://bogus.example.com/</code>) or page (e.g. <code>http://example.com/this-page-doesnt-exist.html</code>).</p>
<p>Another sign that a domain might be parked is that it redirects to a subdomain or a sub-directory on a different domain. For example, some domain parking services redirect parked domains to URLs like <code>http://domain-name.domainparking.com</code> or <code>http://domainparking.com/?domain=domain-name</code>.</p>
<p>There is sometimes a good reason to redirect a domain, like when the site has moved to a new address. How can we distinguish between legitimate redirects and parked sites? Legitimate redirects usually use (or <em>should</em> use) the <code>301</code> response code, while parked domains use the <code>302</code> code.</p>
<p>There are also lots of parked domains that don&#8217;t use redirects at all, so this method is unfortunately rather prone to false positives and negatives.</p>
<p><strong>Examine the WHOIS information</strong></p>
<p>The WHOIS info of a parked domain usually points to the domain parking service that owns/controls the domain. You can use this to build a database of known-suspicious WHOIS records that can be used to identify parked domains. Alternatively, if you have access to a big WHOIS database, you could probably catch a good portion of parked sites by flagging any domain registrant that owns a lot of domains (say, more than a hundred).</p>
<p><strong>Use an existing blacklist</strong></p>
<p>Surprise, surprise : there is actually a <a href="http://www.ivegotafang.com/">parked domain blacklist</a>. Run by the schizophrenically named company &#8220;I&#8217;ve Got a Fang&#8221;, the Parked Domains Project is an attempt to build and maintain an extensive database of parked domains. It even has a <a href="https://addons.mozilla.org/en-US/firefox/addon/10536">Firefox extension</a>.</p>
<p>As far as I can tell there is no documented public API, but you can probably reverse-engineer the FF add-on and see what it uses (or just screen-scrape the database if you&#8217;re feeling naughty).</p>
<p><strong>Analyse the content</strong></p>
<p>Personally, I think the most promising approach for detecting parked domains automatically is content analysis. Parked domains all have something in common &#8211; the ads. If you can come up with a reliable and automated way to detect if a page is devoted solely to advertising, you will be able to identify parked domains pretty accurately.</p>
<p>The paper <a href="http://www.ics.uci.edu/~malmisha/files/paper_tran.pdf">Content-Based Approach for Identifying Textual Ads-Portal Domains [PDF]</a> describes a very effective algorithm for detecting ads-only domains :</p>
<blockquote><p>In this paper, we develop a machine-learning-based classifier to identify ads-portal domains. The features of the classifier are extracted from the web content of the domain. In developing the classifier, we first create negative and positive samples set. Then, we identify set of features that are effective in distinguishing ads-portal domains. Finally, we combine these features along with other keyword-based features into a machine learning classifier. The resulting classifier has 97% accuracy in identifying ads-portal domains.</p></blockquote>
<p>On a related note, my <a href="http://w-shadow.com/blog/2008/01/25/extracting-the-main-content-from-a-webpage/">content extraction script</a> could also be used for detecting is a site is low on actual content. Its algorithm is much simpler than the one proposed in the above paper, but &#8211; unlike the paper &#8211; the source code of my PHP script is freely available <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><em>Illustration credit :  <a href="http://www.sxc.hu/photo/472760">clix @ sxc.hu</a></em></p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/11/13/detecting-parked-domains/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Extract HTML Tags And Their Attributes With PHP</title>
		<link>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/</link>
		<comments>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 14:35:03 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[extract attributes]]></category>
		<category><![CDATA[extract tags]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP script]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1375</guid>
		<description><![CDATA[There are several ways to extract specific tags from an HTML document. The one that most people will think of first is probably regular expressions. However, this is not always &#8211; or, as some would insist, ever &#8211; the best approach. Regular expressions can be handy for small hacks, but using a real HTML parser [...]]]></description>
			<content:encoded><![CDATA[<p>There are several ways to extract specific tags from an HTML document. The one that most people will think of first is probably regular expressions. However, this is not always &#8211; or, as some would insist, <em>ever</em> &#8211; the best approach. Regular expressions can be handy for small hacks, but using a real HTML parser will usually lead to simpler and more robust code. Complex queries, like &#8220;find all rows with the class .foo of the second table of this document and return all links contained in those rows&#8221;, can also be done much easier with a decent parser.</p>
<p>There are <em>some</em> (though very few they may be) edge case where regular expressions might work better, so I will discuss both approaches in this post.</p>
<h3>Extracting Tags With DOM</h3>
<p>PHP 5 comes with a usable <a href="http://php.net/manual/en/book.dom.php">DOM API</a> built-in that you can use to parse and manipulate (X)HTML documents. For example, here&#8217;s how you could use it to extract all link URLs from a HTML file :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Load the HTML page</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page.htm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Create a new DOM document</span>
<span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMDocument<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Parse the HTML. The @ is used to suppress any parsing errors</span>
<span style="color: #666666; font-style: italic;">//that will be thrown if the $html string isn't valid XHTML.</span>
<span style="color: #339933;">@</span><span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadHTML</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Get all links. You could also use any other tag name here,</span>
<span style="color: #666666; font-style: italic;">//like 'img' or 'table', to extract other tags.</span>
<span style="color: #000088;">$links</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dom</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'a'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Iterate over the extracted links and display their URLs</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$links</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//Extract and show the &quot;href&quot; attribute. </span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In addition to <code>getElementsByTagName()</code> you can also use <code>$dom-&gt;getElementById()</code> to find tags with a specific id. For more complex tasks, like extracting deeply nested tags, <a href="http://www.php.net/manual/en/class.domxpath.php">XPath</a> is probably the way to go. For example, to find all list items with the class &#8220;foo&#8221; containing links with the class &#8220;bar&#8221; and display the link URLs :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Load the HTML page</span>
<span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page.htm'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Parse it. Here we use loadHTML as a static method</span>
<span style="color: #666666; font-style: italic;">//to parse the HTML and create the DOM object in one go.</span>
<span style="color: #339933;">@</span><span style="color: #000088;">$dom</span> <span style="color: #339933;">=</span> DOMDocument<span style="color: #339933;">::</span><span style="color: #004000;">loadHTML</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$html</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Init the XPath object</span>
<span style="color: #000088;">$xpath</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> DOMXpath<span style="color: #009900;">&#40;</span><span style="color: #000088;">$dom</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Query the DOM</span>
<span style="color: #000088;">$links</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$xpath</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'//li[contains(@class, &quot;foo&quot;)]//a[@class = &quot;bar&quot;]'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Display the results as in the previous example</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$links</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>For more information about DOM and XPath see these resources : </p>
<ul>
<li><a href="http://www.php.net/manual/en/book.dom.php">DOM API documentation</a></li>
<li><a href="http://www.w3schools.com/Xpath/">W3Schools XPath tutorial</a></li>
<li><a href="http://www.w3.org/TR/xpath">XPath language specification</a></li>
</ul>
<p>Honourable mention : <a href="http://simplehtmldom.sourceforge.net/">Simple HTML DOM Parser</a> is a popular alternative HTML parser for PHP 5 that lets you manipulate HTML pages with jQuery-like ease. However, I personally wouldn&#8217;t recommend using it if you care about your script&#8217;s performance, as in my tests Simple HTML DOM was about 30 times slower than DOMDocument.</p>
<h3>Extracting Tags &#038; Attributes With Regular Expressions</h3>
<p>There are only two advantages to processing HTML with regular expressions &#8211; availability and edge-case performance. While most parsers require PHP 5 or later, regular expressions are available pretty much anywhere. Also, they are a little bit faster than real parsers when you need to extract something from a <em>very</em> large document (on the order of 400 KB or more). Still, in most cases you&#8217;re better off using the PHP DOM extension or even Simple HTML DOM, not messing with convoluted regexps.</p>
<p>That said, here&#8217;s a PHP function that can extract any HTML tags and their attributes from a given string :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * extract_tags()
 * Extract specific HTML tags and their attributes from a string.
 *
 * You can either specify one tag, an array of tag names, or a regular expression that matches the tag name(s). 
 * If multiple tags are specified you must also set the $selfclosing parameter and it must be the same for 
 * all specified tags (so you can't extract both normal and self-closing tags in one go).
 * 
 * The function returns a numerically indexed array of extracted tags. Each entry is an associative array
 * with these keys :
 * 	tag_name	- the name of the extracted tag, e.g. &quot;a&quot; or &quot;img&quot;.
 *	offset		- the numberic offset of the first character of the tag within the HTML source.
 *	contents	- the inner HTML of the tag. This is always empty for self-closing tags.
 *	attributes	- a name -&gt; value array of the tag's attributes, or an empty array if the tag has none.
 *	full_tag	- the entire matched tag, e.g. '&lt;a href=&quot;http://example.com&quot;&gt;example.com&lt;/a&gt;'. This key 
 *		          will only be present if you set $return_the_entire_tag to true.	   
 *
 * @param string $html The HTML code to search for tags.
 * @param string|array $tag The tag(s) to extract.							 
 * @param bool $selfclosing	Whether the tag is self-closing or not. Setting it to null will force the script to try and make an educated guess. 
 * @param bool $return_the_entire_tag Return the entire matched tag in 'full_tag' key of the results array.  
 * @param string $charset The character set of the HTML code. Defaults to ISO-8859-1.
 *
 * @return array An array of extracted tags, or an empty array if no matching tags were found. 
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">,</span> <span style="color: #000088;">$selfclosing</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span style="color: #000088;">$return_the_entire_tag</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #000088;">$charset</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ISO-8859-1'</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tag</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'|'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tag</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//If the user didn't specify if $tag is a self-closing tag we try to auto-detect it</span>
	<span style="color: #666666; font-style: italic;">//by checking against a list of known self-closing tags.</span>
	<span style="color: #000088;">$selfclosing_tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'area'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'base'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'basefont'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'br'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'hr'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'input'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'img'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'link'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'meta'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'col'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'param'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$selfclosing</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$selfclosing</span> <span style="color: #339933;">=</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">,</span> <span style="color: #000088;">$selfclosing_tags</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//The regexp is different for normal and self-closing tags because I can't figure out </span>
	<span style="color: #666666; font-style: italic;">//how to make a sufficiently robust unified one.</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$selfclosing</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag_pattern</span> <span style="color: #339933;">=</span> 
			<span style="color: #0000ff;">'@&lt;(?P&lt;tag&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$tag</span><span style="color: #339933;">.</span><span style="color: #0000ff;">')			# &lt;tag
			(?P&lt;attributes&gt;\s[^&gt;]+)?		# attributes, if any
			\s*/?&gt;					# /&gt; or just &gt;, being lenient here 
			@xsi'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$tag_pattern</span> <span style="color: #339933;">=</span> 
			<span style="color: #0000ff;">'@&lt;(?P&lt;tag&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$tag</span><span style="color: #339933;">.</span><span style="color: #0000ff;">')			# &lt;tag
			(?P&lt;attributes&gt;\s[^&gt;]+)?		# attributes, if any
			\s*&gt;					# &gt;
			(?P&lt;contents&gt;.*?)			# tag contents
			&lt;/(?P=tag)&gt;				# the closing &lt;/tag&gt;
			@xsi'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$attribute_pattern</span> <span style="color: #339933;">=</span> 
		<span style="color: #0000ff;">'@
		(?P&lt;name&gt;\w+)							# attribute name
		\s*=\s*
		(
			(?P&lt;quote&gt;[\&quot;\'])(?P&lt;value_quoted&gt;.*?)(?P=quote)	# a quoted value
			|							# or
			(?P&lt;value_unquoted&gt;[^\s&quot;\']+?)(?:\s+|$)			# an unquoted value (terminated by whitespace or EOF) 
		)
		@xsi'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//Find all tags </span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tag_pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #339933;">,</span> PREG_SET_ORDER <span style="color: #339933;">|</span> PREG_OFFSET_CAPTURE <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">//Return an empty array if we didn't find anything</span>
		<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$matches</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">//Parse tag attributes, if any</span>
		<span style="color: #000088;">$attributes</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> 
&nbsp;
			<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$attribute_pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$attribute_data</span><span style="color: #339933;">,</span> PREG_SET_ORDER <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
				<span style="color: #666666; font-style: italic;">//Turn the attribute data into a name-&gt;value array</span>
				<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attribute_data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
					<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_quoted'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_quoted'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_unquoted'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'value_unquoted'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
					<span style="color: #009900;">&#125;</span>
&nbsp;
					<span style="color: #666666; font-style: italic;">//Passing the value through html_entity_decode is handy when you want</span>
					<span style="color: #666666; font-style: italic;">//to extract link URLs or something like that. You might want to remove</span>
					<span style="color: #666666; font-style: italic;">//or modify this call if it doesn't fit your situation.</span>
					<span style="color: #000088;">$value</span> <span style="color: #339933;">=</span> <span style="color: #990000;">html_entity_decode</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$value</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #339933;">,</span> <span style="color: #000088;">$charset</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
					<span style="color: #000088;">$attributes</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$attr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$tag</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
			<span style="color: #0000ff;">'tag_name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tag'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
			<span style="color: #0000ff;">'offset'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> 
			<span style="color: #0000ff;">'contents'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">//empty for self-closing tags</span>
			<span style="color: #0000ff;">'attributes'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$attributes</span><span style="color: #339933;">,</span> 
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$return_the_entire_tag</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$tag</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'full_tag'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$match</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> 			
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$tags</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$tag</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$tags</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Usage examples</strong></p>
<p>Extract all links and output their URLs :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$html</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'example.html'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'a'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'attributes'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'href'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Extract all heading tags and output their text :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'h\d+'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #990000;">strip_tags</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Extract meta tags :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'meta'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Extract bold and italicised text fragments :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$nodes</span> <span style="color: #339933;">=</span> extract_tags<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$html</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'b'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'strong'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'em'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'i'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nodes</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #990000;">strip_tags</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$node</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'contents'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The function is pretty well documented, so check the source if anything is unclear. Of course, you can also leave a comment if you have any further questions or feedback.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/10/20/how-to-extract-html-tags-and-their-attributes-with-php/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How To Make a &#8220;Falling Sand&#8221; Style Water Simulation</title>
		<link>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/</link>
		<comments>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 14:14:43 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[falling sand game]]></category>
		<category><![CDATA[fluid simulation]]></category>
		<category><![CDATA[game design]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[water simulation]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1295</guid>
		<description><![CDATA[Have you ever wondered how all those &#8220;falling sand&#8221; games work under the hood? If so, read on. Today I will discuss one of the possible ways how you could implement the &#8220;falling&#8221; part of the game &#8211; sand particles falling under the effects of gravity, water (or other liquids) flowing down a hillside, and [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered how all those <a href="http://chir.ag/stuff/sand/">&#8220;falling sand&#8221; games</a> work under the hood? If so, read on. Today I will discuss one of the possible ways how you could implement the &#8220;falling&#8221; part of the game &#8211; sand particles falling under the effects of gravity, water (or other liquids) flowing down a hillside, and so on. <a href="http://w-shadow.com/files/FallingWater.zip">Source code</a> and a <a href="http://w-shadow.com/files/FallingSandWater/">live demo</a> are also available. This tutorial is along the same vein as my previous <a href="http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/">fluid simulation post</a> that dealt with pseudo-compressible fluids and pressure, but the specific algorithm is much simpler (and probably quite a bit faster, too).<em> </em></p>
<p><em>Side-note : No, I haven&#8217;t been completely consumed by an inexorable desire to build fun graphical toys instead of practically useful software, why do you ask? <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  In fact, there&#8217;ll be some WordPress-related announcements later this week&#8230;</em></p>
<h3>Learning To <del datetime="2009-09-28T14:15:43+00:00">Fly</del> Fall</h3>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1299" title="Falling water movement" src="http://w-shadow.com/wp-content/uploads/2009/09/gravity-simulation-rules.png" alt="Falling water movement" width="120" height="236" />While I can&#8217;t claim intimate familiarity with the algorithms the aforementioned games use to simulate fire or explosions, it&#8217;s pretty easy to come up with a way to implement falling sand/flowing water. First, you need to figure out under what conditions something can fall/flow downwards. For a basic simulation this could be just a small set of very simple rules :</p>
<ul>
<li>For each entity that is affected by gravity
<ul>
<li>If there&#8217;s an empty space <strong>below</strong> it, move it <strong>down</strong>.</li>
<li>If there&#8217;s an empty space <strong>down and to the left</strong>, move it <strong>down and to the left</strong>.</li>
<li>If there&#8217;s an empty space <strong>down and to the right</strong>, move it <strong>down and to the right</strong>.</li>
</ul>
</li>
</ul>
<p>Next, you need to decide how to represent the simulation world and all the objects (like immovable walls, moving water particles <em>et cetera</em>) that it contains. One of the most common solutions is to use a two-dimensional array where each array element is an numeric ID of the material contained in that map tile. For example, 0 = air (or an empty square), 1 = wall, 2 = water, and so on.</p>
<p style="text-align: center;"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="size-full wp-image-1300 aligncenter" title="Map array" src="http://w-shadow.com/wp-content/uploads/2009/09/map-representation.png" alt="Map array" width="481" height="306" /></p>
<p>In most falling sand games each array element would correspond to a single pixel on the game&#8217;s screen. However, in my example application I used 20&#215;20 pixel tiles instead to make the underlying simulation behaviour easier to see.</p>
<p>If possible, use <em>byte</em> or <em>char</em> as the array element datatype. Using <em>int&#8217;s</em> might seem more straightforward, but it would also take up at least four times more memory and hurt performance. It&#8217;s also a good idea to make the array just a bit bigger than the actual map dimensions and create a single-tile &#8220;buffer zone&#8221; around the map so that you can avoid checking for boundary conditions during the simulation.</p>
<p>Finally, during the simulation step we just loop over the entire array and apply the simple rules I mentioned above to each tile that contains material that should be affected by gravity.</p>
<h3>Getting It Right</h3>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright size-full wp-image-1301" title="Now that's just silly." src="http://w-shadow.com/wp-content/uploads/2009/09/whee.png" alt="Now that's just silly." width="78" height="211" />If you go ahead and implement the above algorithm as written, you will get a simulation that <em>kind-of</em> works, but quickly grinds to a halt on big maps and sometimes behaves in unexpected ways. For example, you might see sand tiles that seem to &#8220;teleport&#8221; to the bottom of the map instead of falling gradually and water that always flows <em>left</em> after hitting a free-standing ground tile (even though there&#8217;s a perfectly suitable channel available on the right side). Lets see what we can do about that.</p>
<p><strong>Keeping track of updated tiles</strong></p>
<p>The &#8220;teleportation&#8221; behaviour can happen if our simulation algorithm doesn&#8217;t keep track of which tiles it has already moved around during the current simulation step. For example, first it loops over the top row of the map, finds a water tile A and moves it downwards one row. Then it loops over the second row, finds the tile A, moves it again, goes to the third row, moves the same water tile <em>again</em>&#8230; and so on, until the water tile A hits a solid tile or falls off the map.</p>
<p>To prevent this bug we need to somehow remember which tiles have been updated already. Since I wanted to keep the memory use low, I used the most-significant bit of each map array element to indicate whether that tile was last updated on an even-numbered simulation step (0) or an odd-numbered step (1). Then, at the start of each step, the algorithm calculates what the flag should be for tiles updated in that step :</p>
<pre>update_mask = byte ( ( simulationFrameCount &amp; (long)1 ) &lt;&lt; 7 );
//this basically takes the modulo of frame-count / 2 and shifts the result 7 places to the left</pre>
<p>&#8230;then sets the msb of each tile it updates to that value and automatically skips tiles that have it already set to that value.</p>
<p><strong>Pseudo-random movement</strong></p>
<p>When a falling particle hits a free-standing fixed tile on a 2D map it has two choices &#8211; it can either move down and left, or down and right. In the naive algorithm I discussed above it will always try to move left first, leading to weirdness. Obviously we want it to choose at random, but on a big map generating a new random number for each tile would be slow. Instead, lets use the same approach as for the &#8220;teleportation&#8221; problem and move it either diagonally left if the current simulation step is even-numbered and or diagonally right if it&#8217;s odd-numbered. This can still introduce some artifacts in the simulation behaviour, but they&#8217;re rarer and and significantly less noticeable.</p>
<h3>Optimization</h3>
<p>Speaking of optimization, we don&#8217;t really need to update each gravity-enabled tile every time. Many of them will eventually end up in a situation where they can&#8217;t move anywhere (e.g. water at the bottom of a puddle or sand resting on a flat surface), so it would be nice if we could quickly skip them and not waste our time trying to apply the simulation rules to these static tiles. This would help performance quite a bit.</p>
<p>The way I implemented is with the help with another bit-flag. If the simulation algorithm discovers that it can&#8217;t move a tile in any direction, it will set the tile&#8217;s &#8220;static&#8221; bit-flag. It will also skip any tiles that have the &#8220;static&#8221; bit-flag set.</p>
<p>There&#8217;s some additional book-keeping we need to do to make this work as intended. When an empty space is created somewhere in the map (e.g. by a water tile moving down) we need to re-activate any gravity-enabled tiles that are directly above the newly created hole, so that they can fall/flow down into that space.</p>
<h3>Possible Improvements</h3>
<p>The result is a pretty basic and plain simulation that is useful to explain the basic principle, but it wouldn&#8217;t really qualify as a full game. Here are some ideas you could use to improve it :</p>
<ul>
<li>Make water flow horizontally if there&#8217;s another water tile on top of it. Consider adding a simple pressure model [link to my prev. article].</li>
<li>Implement fluid density. This one is easy &#8211; if the current tile is more dense than the tile below it, swap them.</li>
<li>Add tile generators, e.g. a faucet that creates a water tile below itself on each simulation step (included in my demo application).</li>
<li>To improve performance, use a <a href="http://en.wikipedia.org/wiki/Quadtree">quadtree</a> to keep track of which regions of the map have interacting tiles and quickly skip inactive regions.</li>
<li>Explore the source code of existing games and look for interesting ideas. Some open-source examples : <a href="http://www.piettes.com/fallingsandgame/download.html">wxSand</a>, <a href="http://sourceforge.net/projects/sdlsand/">SDL Sand</a>.</li>
</ul>
<h3>Live Demo &amp; Source</h3>
<p>Like my previous <a href="http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/">fluid simulation app</a>, this one was also written in <a href="http://processing.org/">Processing</a>. In addition to a working implementation of the algorithm discussed above it also lets you draw and erase water/ground/faucet tiles using your mouse, pan around the map with the WASD keys, zoom in/out with the mouse wheel and more. However, be warned that the map rendering code is not very optimized so the simulation <em>will</em> degenerate into a slideshow if you zoom all the way out, regardless of how fast your system is.</p>
<ul>
<li><a href="http://w-shadow.com/files/FallingSandWater/">Live demo  (requires Java)</a></li>
<li><a href="http://w-shadow.com/files/FallingWater.zip">Source code</a></li>
</ul>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/09/29/falling-sand-style-water-simulation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple Fluid Simulation With Cellular Automata</title>
		<link>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/</link>
		<comments>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 19:48:33 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[cellular automata]]></category>
		<category><![CDATA[fluid dynamics]]></category>
		<category><![CDATA[fluid simulation]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Processing]]></category>
		<category><![CDATA[water dynamics]]></category>
		<category><![CDATA[water simulation]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1285</guid>
		<description><![CDATA[Last week I couldn&#8217;t use my regular dev. machine (broken graphics card), so all my WordPress-related plans were on hold. To pass the time, I built a simple water simulation in Processing. Today I&#8217;m going to show you this little application and explain how it works. Online demo and source code are included.
Big Words, or [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I couldn&#8217;t use my regular dev. machine (broken graphics card), so all my WordPress-related plans were on hold. To pass the time, I built a simple water simulation in <a href="http://processing.org/">Processing</a>. Today I&#8217;m going to show you this little application and explain how it works. Online demo and source code are included.</p>
<h3>Big Words, or The Theoretical Part</h3>
<p>Fluid dynamics is a complex topic. If you so much as <a rel="nofollow" href="http://en.wikipedia.org/wiki/Computational_fluid_dynamics">look it up in Wikipedia</a>, you will be immediately assaulted by integrals, differentials  and other agents of mathematical insanity. To accurately model a fluid you would need a quite an in-depth understanding of physics and calculus. And while that&#8217;s certainly not something one couldn&#8217;t figure out given enough time, &#8220;proper&#8221; fluid simulation is still extremely rare in non-academic applications and games because it&#8217;s <strong>slow</strong>.</p>
<p>One way to create a faster (though less accurate) simulation is by using <a rel="nofollow" href="http://en.wikipedia.org/wiki/Cellular_automata">cellular automata</a> to represent the water. A cellular automaton is basically a grid where each cell can be in one of a finite number of states, plus a set of rules that determine how a cell can change from one state to another. The rules are typically local &#8211; that is, they consider only the current cell and it&#8217;s direct neighbours when determining the new state. During each step of the simulation, you simply loop through the entire grid and apply the rules to each cell.</p>
<p>When simulating water or other fluids it can more appropriate to store a continuous value (e.g. water mass) in each cell, instead of using discrete states.</p>
<h3>CA-Based Water Simulation</h3>
<p>Before we go into details, lets take a look at the promised online demo. It will give you a good idea about what you can achieve with this approach :</p>
<p><a href="http://w-shadow.com/files/water_sim/"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="aligncenter size-large wp-image-1291" title="Click to run the simulation" src="http://w-shadow.com/wp-content/uploads/2009/09/Water-Simulation1-490x513.png" alt="Click to run the simulation" width="490" height="513" /></a> <em>(klicken Sie auf das Bild; Java required)</em></p>
<p>Alright, on to the code stuff. Lets try simulating the most common fluid &#8211; water.</p>
<p><strong>The basic data structure</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Map dimensions</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> map_width <span style="color: #339933;">=</span> <span style="color: #cc66cc;">16</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> map_height <span style="color: #339933;">=</span> <span style="color: #cc66cc;">16</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Block types</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> AIR <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> GROUND <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> WATER <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Data structures</span>
<span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> blocks <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> mass <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span>,
          new_mass <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">float</span><span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I use two two-dimensional arrays to represent the simulation world. The <code>blocks</code> array defines a basic &#8220;map&#8221; where each cell can contain ground (solid, stops water flow), air (an empty cell, water can flow in) or water. Each water cell also has a corresponding entry in the <code>mass</code> array that defines how much water it contains. All water cells/blocks start out with one unit of water.</p>
<p>There&#8217;s also a third array &#8211; <code>new_mass</code> that is used to store intermediate mass values when running the simulation. Operating directly on the <code>mass</code> array is unadvisable because you would get various sideffects like water spreading at different speeds depending on the order in which you update the cells.</p>
<p><strong>Overall algorithm</strong></p>
<p>The main idea is to treat water as a slightly compressible liquid, as described in <a href="http://home.comcast.net/~tom_forsyth/papers/cellular_automata_for_physical_modelling.html">this article</a>. In terms of implementation, this means that if there are two or more water cells stacked vertically, the bottom cells will be able to hold slightly more water than normal. This way we don&#8217;t need to explicitly track pressure to make the water level equalize in communicating vessels &#8211; we can just look at how much excess water a cell has, and move it upwards if required.</p>
<p>Lets set up the exact fluid properties as constants :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Water properties</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MaxMass <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1.0</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//The normal, un-pressurized mass of a full water cell</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MaxCompress <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0.02</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//How much excess water a cell can store, compared to the cell above it</span>
<span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">float</span> MinMass <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0.0001</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">//Ignore cells that are almost dry</span></pre></div></div>

<p>For example, if one cell contains 1.0 units of water, the cell below it should contain up to 1.02 units, the cell below that one should contain 1.04, the next one 1.06, and so on. There is one however special case that we need to consider to get a plausible simulation &#8211; what if the if the top cell contains less than <code>MaxMass</code> units of water? In my implementation the bottom cell will contain a proportionally smaller excess amount, not the usual <code>mass_of_the_cell_above + MaxCompression</code> units.</p>
<p>Based on the above, we can simulate water movement by looping over the <code>mass</code> array and applying these cellular automaton rules to each cell :</p>
<ol>
<li>Take the mass of the current cell and the cell <strong>below</strong> it and figure out how much water the bottom cell should contain. If it has less than that, remove the corresponding amount from the current cell and add it to the bottom cell.</li>
<li>Check the cell to the <strong>left</strong> of this one. If it has less water, move over enough water to make both cells contain the same amount.</li>
<li>Do the same thing for the <strong>right</strong> neighbour.</li>
<li>Do the same thing as in step 1., but for the cell <strong>above</strong> the current one.</li>
</ol>
<p>While doing this you also need to keep track of how much water the current cell still has remaining, or you could end up with negative-mass water blocks.</p>
<p>After the new mass of each cell has been calculated, you can safely copy over the new values to the <code>mass</code> array. You also need to update the <code>blocks</code> array so that cells that are now dry get marked as empty and vice versa.</p>
<p>Here&#8217;s the simulation code :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">void</span> simulate_compression<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">float</span> Flow <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">float</span> remaining_mass<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Calculate and apply flow for each block</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;=</span> map_width<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;=</span> map_height<span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">//Skip inert ground blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Custom push-only flow</span>
       Flow <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
       remaining_mass <span style="color: #339933;">=</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//The block below this one</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span>blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         Flow <span style="color: #339933;">=</span> get_stable_state_b<span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">+</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
           Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//leads to smoother flow</span>
         <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span> Flow, <span style="color: #cc66cc;">0</span>, min<span style="color: #009900;">&#40;</span>MaxSpeed, remaining_mass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>   
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Left</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//Equalize the amount of water in this block and it's neighbour</span>
         Flow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span>Flow, <span style="color: #cc66cc;">0</span>, remaining_mass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Right</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//Equalize the amount of water in this block and it's neighbour</span>
         Flow <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span>Flow, <span style="color: #cc66cc;">0</span>, remaining_mass<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
&nbsp;
       <span style="color: #666666; font-style: italic;">//Up. Only compressed water flows upwards.</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> GROUND <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         Flow <span style="color: #339933;">=</span> remaining_mass <span style="color: #339933;">-</span> get_stable_state_b<span style="color: #009900;">&#40;</span> remaining_mass <span style="color: #339933;">+</span> mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> Flow <span style="color: #339933;">&gt;</span> MinFlow <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> Flow <span style="color: #339933;">*=</span> <span style="color: #cc66cc;">0.5</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
         Flow <span style="color: #339933;">=</span> constrain<span style="color: #009900;">&#40;</span> Flow, <span style="color: #cc66cc;">0</span>, min<span style="color: #009900;">&#40;</span>MaxSpeed, remaining_mass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
         new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+=</span> Flow<span style="color: #339933;">;</span>   
         remaining_mass <span style="color: #339933;">-=</span> Flow<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
     <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Copy the new mass values to the mass array</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;</span> map_width <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;</span> map_height <span style="color: #339933;">+</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> new_mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;=</span> map_width<span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
     <span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;=</span> map_height<span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
       <span style="color: #666666; font-style: italic;">//Skip ground blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> GROUND<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">continue</span><span style="color: #339933;">;</span>
       <span style="color: #666666; font-style: italic;">//Flag/unflag water blocks</span>
       <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&gt;</span> MinMass<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
         blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> WATER<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
         blocks<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> AIR<span style="color: #339933;">;</span>
       <span style="color: #009900;">&#125;</span>
     <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">//Remove any water that has left the map</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> x <span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> x <span style="color: #339933;">&lt;</span> map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> x<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    mass<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> y <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y <span style="color: #339933;">&lt;</span> map_height<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> y<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    mass<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    mass<span style="color: #009900;">&#91;</span>map_width<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>y<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And here&#8217;s the function that calculates how to distribute a given amount of water between two vertically adjacent cells :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Returns the amount of water that should be in the bottom cell.</span>
<span style="color: #000066; font-weight: bold;">float</span> get_stable_state_b <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">float</span> total_mass <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> total_mass <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> total_mass <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">*</span>MaxMass <span style="color: #339933;">+</span> MaxCompress <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>MaxMass<span style="color: #339933;">*</span>MaxMass <span style="color: #339933;">+</span> total_mass<span style="color: #339933;">*</span>MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #009900;">&#40;</span>MaxMass <span style="color: #339933;">+</span> MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>total_mass <span style="color: #339933;">+</span> MaxCompress<span style="color: #009900;">&#41;</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>Full source code</strong></p>
<ul>
<li><a href="http://w-shadow.com/files/water_sim.zip"><strong>Download the source</strong></a> (23 KB)</li>
<li>You will need the Java-based <a href="http://processing.org/">Processing programming language</a> to run the code.</li>
</ul>
<p>I didn&#8217;t discuss how to render the water, or how to handle user interaction, but the source code also includes a simplistic implementation of those things.</p>
<h3>Conclusion</h3>
<p>CA-based algorithms have both advantages and disadvantages. On the one hand, they&#8217;re relatively fast and the simulation quality is often good enough for games and software toys. On the other, they can produce behaviour that is very unrealistic &#8211; for example, water falling into a basin will form a little &#8220;hill&#8221; and spread out slowly, instead of near-instantly as real water would. Whether this is an acceptable downside depends on your application.</p>
<p>For a different take on simulating fluid dynamics with cellular automata, check out this <a href="http://www.gamasutra.com/view/feature/3549/interview_the_making_of_dwarf_.php?page=9">interview with the author of Dwarf Fortress</a>.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/09/01/simple-fluid-simulation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Make Any Application Remember Window Size</title>
		<link>http://w-shadow.com/blog/2009/06/23/remember-window-size/</link>
		<comments>http://w-shadow.com/blog/2009/06/23/remember-window-size/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 18:10:43 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[freeware]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[remember window size]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[save window size]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1188</guid>
		<description><![CDATA[Many applications have this convenient feature where they automatically save the current window state (like size and position) when they shut down and then restore it the next time you run them. For example, all modern web browsers will automatically remember their window size and most IM clients/media players/gadget apps will obediently stay put in [...]]]></description>
			<content:encoded><![CDATA[<p>Many applications have this convenient feature where they automatically save the current window state (like size and position) when they shut down and then restore it the next time you run them. For example, all modern web browsers will automatically remember their window size and most IM clients/media players/gadget apps will obediently stay put in whatever corner of the desktop you&#8217;ve allocated for them. But what about those that don&#8217;t?</p>
<p>If you want make an unruly application remember its window size, check out <a href="http://www.southbaypc.com/AutoSizer/">AutoSizer</a>. It&#8217;s a freeware tool that can keep any program at a specific size and/or position. In addition to the ability to set exact window dimensions and coordinates, you can also configure it to maximize or minimize the application, keep it on top of other windows, or even automatically center it on the desktop.</p>
<p style="text-align: center;"><a href="http://w-shadow.com/wp-content/uploads/2009/06/AutoSizer.png"><img style=' display: block; margin-right: auto; margin-left: auto;'  class="size-medium wp-image-1191 aligncenter" title="AutoSizer screenshot ( click for larger image )" src="http://w-shadow.com/wp-content/uploads/2009/06/AutoSizer-300x252.png" alt="AutoSizer screenshot ( click for larger image )" width="300" height="252" /></a></p>
<p><em>AutoSizer is also useful for dealing with extra-glitchy apps that crash every couple hours and lose their window settings as a result. I&#8217;m looking at you, TweetDeck 0.25.1b.</em></p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/06/23/remember-window-size/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Get Per-Core CPU Usage</title>
		<link>http://w-shadow.com/blog/2009/04/17/per-core-cpu-usage/</link>
		<comments>http://w-shadow.com/blog/2009/04/17/per-core-cpu-usage/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 17:22:48 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CPU usage]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[downloads]]></category>
		<category><![CDATA[how to]]></category>
		<category><![CDATA[multicore]]></category>
		<category><![CDATA[Windows API]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=1058</guid>
		<description><![CDATA[It&#8217;s pretty easy to get the average CPU usage, but how about calculating the per-code load on multicore systems? Turns out it&#8217;s also simple enough if you use performance counters. 
Windows API includes a subset of functions that provide various performance-related information, which includes data on how busy individual processors or cores are. In this [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s pretty easy to <a href="http://www.codeproject.com/KB/threads/Get_CPU_Usage.aspx">get the average CPU usage</a>, but how about calculating the per-code load on multicore systems? Turns out it&#8217;s also simple enough if you use <a href="http://msdn.microsoft.com/en-us/library/aa373083(VS.85).aspx">performance counters</a>. </p>
<p>Windows API includes a subset of functions that provide various performance-related information, which includes data on how busy individual processors or cores are. In this post I&#8217;ll show you how to retrieve and use this information. I&#8217;ve also included a simple example application that demonstrates the functionality (the download link is at the end of the post) :</p>
<div id="attachment_1061" class="wp-caption aligncenter" style="width: 342px;  border: 1px solid #dddddd; background-color: #f3f3f3; padding-top: 4px; margin: 10px; text-align:center; display: block; margin-right: auto; margin-left: auto;"><img src="http://w-shadow.com/wp-content/uploads/2009/04/per-core-cpu-usage-screenshot.png" alt="Screenshot of the example application" title="Screenshot of the example application" width="332" height="130" class="size-full wp-image-1061" /><p style=' padding: 0 4px 5px; margin: 0;'  class="wp-caption-text">Screenshot of the example application</p></div>
<p>The example app was written in Delphi, but the salient parts are almost purely Windows API so they should be easy to translate to other programming languages.</p>
<h3>Algorithm Overview</h3>
<p>Here&#8217;s a general overview of how to use the performance counter API to get the per-core usage numbers.</p>
<p><strong>Initialization</strong></p>
<ol>
<li>Create a performance query using <a href="http://msdn.microsoft.com/en-us/library/aa372652(VS.85).aspx">PdhOpenQuery</a>.</li>
<li>Generate a list of performance counter paths (one for each CPU or core) by feeding a wildcard path to PdhExpandWildCardPath. In this case, this is the path that we need :<br />
<code>\Processor(*/*#*)\% Processor Time</code><br />
You can read more about counter path syntax <a href="http://msdn.microsoft.com/en-us/library/aa373193(VS.85).aspx">here</a>.</p>
<p><em>Note : Unfortunately, the API makes no distinction between multiple physical processors and multiple cores, so you will get a &#8220;&#8230;\Processor(X)\&#8230;&#8221; entry for each core.</em></li>
<li>Add the generated counter paths to the query using <a href="http://msdn.microsoft.com/en-us/library/aa372204(VS.85).aspx">PdhAddCounter</a> and save the returned handle(s) for later.</li>
</ol>
<p><strong>Collecting &#038; Displaying Data</strong><br />
CPU usage is typically measured over an interval of time, so you will need to collect at least two data samples at different times to get a meaningful result. Depending on your needs, you could either : </p>
<ul>
<li>Collect one sample, sleep() for a second, collect another sample and calculate the result; <strong>OR</strong></li>
<li>Set up a timer or a loop to calculate &#038; displays the CPU usage periodically. That&#8217;s what I&#8217;ll do in this tutorial.</li>
</ul>
<p>Regardless of whether you only need a one-time measurement or periodic updates, the process is very similar API-wise. First, call <a href="http://msdn.microsoft.com/en-us/library/aa372563(VS.85).aspx">PdhCollectQueryData</a> to update all counters associated with the query. Then call <a href="http://msdn.microsoft.com/en-us/library/aa372637(VS.85).aspx">PdhGetFormattedCounterValue</a> with each counter handle to get the actual data. If you set the output format flag to PDH_FMT_DOUBLE the function will give you the CPU/core load percentage as a floating-point value in the range of [0..100]. </p>
<p>If you need periodic updates just call these two functions repeatedly.</p>
<p><strong>Cleanup</strong><br />
When you&#8217;re done, call <a href="http://msdn.microsoft.com/en-us/library/aa372558(VS.85).aspx">PdhCloseQuery</a> to close counters associated with the query and free up allocated system resources. You don&#8217;t need to explicitly remove individual counters.</p>
<h3>Source</h3>
<p>This is the source code of a simple Delphi 2009 application that displays the load percentage of each processor core in a progress bar. The output is updated every second by using a timer component.</p>

<div class="wp_syntax"><div class="code"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">unit</span> CoreUsage<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">interface</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">uses</span>
  Windows<span style="color: #000066;">,</span> Messages<span style="color: #000066;">,</span> SysUtils<span style="color: #000066;">,</span> Variants<span style="color: #000066;">,</span> Classes<span style="color: #000066;">,</span> Graphics<span style="color: #000066;">,</span> Controls<span style="color: #000066;">,</span> Forms<span style="color: #000066;">,</span>
  Dialogs<span style="color: #000066;">,</span> StdCtrls<span style="color: #000066;">,</span> JwaWindows<span style="color: #000066;">,</span> ExtCtrls<span style="color: #000066;">,</span> ComCtrls<span style="color: #000066;">,</span> Gauges<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">type</span>
  TForm1 <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">class</span><span style="color: #000066;">&#40;</span>TForm<span style="color: #000066;">&#41;</span>
    Timer1<span style="color: #000066;">:</span> TTimer<span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> FormCreate<span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> Timer1Timer<span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">procedure</span> FormDestroy<span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span>
    <span style="color: #808080; font-style: italic;">{ Private declarations }</span>
  <span style="color: #000000; font-weight: bold;">public</span>
    <span style="color: #808080; font-style: italic;">{ Public declarations }</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  TCounter <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
   Path <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
   Handle <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
   mLabel <span style="color: #000066;">:</span> TLabel<span style="color: #000066;">;</span>
   mGauge <span style="color: #000066;">:</span> TGauge<span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span>
  Form1<span style="color: #000066;">:</span> TForm1<span style="color: #000066;">;</span>
  Counters <span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span> <span style="color: #000000; font-weight: bold;">of</span> TCounter<span style="color: #000066;">;</span>
  Query <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Cardinal</span> <span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">implementation</span>
&nbsp;
<span style="color: #008000; font-style: italic;">{$R *.dfm}</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">FormCreate</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
 dwSize<span style="color: #000066;">,</span> h <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
 cnt<span style="color: #000066;">,</span> i <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">Integer</span><span style="color: #000066;">;</span>
 pPaths<span style="color: #000066;">:</span><span style="color: #000066; font-weight: bold;">PWideChar</span><span style="color: #000066;">;</span>
 pIterator<span style="color: #000066;">:</span><span style="color: #000066; font-weight: bold;">PwideChar</span><span style="color: #000066;">;</span>
 InstanceId<span style="color: #000066;">,</span> CounterPath <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">string</span><span style="color: #000066;">;</span>
 status <span style="color: #000066;">:</span> PDH_STATUS<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #808080; font-style: italic;">//Create a performance query</span>
  <span style="color: #000000; font-weight: bold;">if</span>  PdhOpenQuery<span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> Query<span style="color: #000066;">&#41;</span> <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Get all valid processor/core usage counter paths by expanding</span>
    <span style="color: #808080; font-style: italic;">//a wildcard path. To do this, we must first call PdhExpandWildCardPath</span>
    <span style="color: #808080; font-style: italic;">//with buffer size set to zero to get the actual required buffer size.</span>
    dwSize <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">;</span>
    pPaths <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">;</span>
&nbsp;
    status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhExpandWildCardPath<span style="color: #000066;">&#40;</span>
      <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span>                                  <span style="color: #808080; font-style: italic;">//search the local computer</span>
      <span style="color: #ff0000;">'\Processor(*/*#*)\% Processor Time'</span><span style="color: #000066;">,</span> <span style="color: #808080; font-style: italic;">//we want CPU usage counters for all CPUs/cores</span>
      pPaths<span style="color: #000066;">,</span>                               <span style="color: #808080; font-style: italic;">//user-allocated buffer; currently null</span>
      dwSize<span style="color: #000066;">,</span>                               <span style="color: #808080; font-style: italic;">//buffer size</span>
      <span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">;</span>                                  <span style="color: #808080; font-style: italic;">//no flags</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> PDH_MORE_DATA <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
      dwSize <span style="color: #000066;">:</span><span style="color: #000066;">=</span> dwSize <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span> <span style="color: #808080; font-style: italic;">//+1 byte required in XP and below.</span>
      pPaths <span style="color: #000066;">:</span><span style="color: #000066;">=</span> GetMemory<span style="color: #000066;">&#40;</span>dwSize<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span> <span style="color: #808080; font-style: italic;">//Allocate an output buffer.</span>
&nbsp;
      <span style="color: #808080; font-style: italic;">//Really get the counter paths.</span>
      status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhExpandWildCardPath<span style="color: #000066;">&#40;</span>
        <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">,</span>
        <span style="color: #ff0000;">'\Processor(*/*#*)\% Processor Time'</span><span style="color: #000066;">,</span>
        pPaths<span style="color: #000066;">,</span>
        dwSize<span style="color: #000066;">,</span>
        <span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">;</span>
&nbsp;
      <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
        cnt <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">;</span>
        <span style="color: #000066;">SetLength</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">,</span> <span style="color: #0000ff;">32</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">//PdhExpandWildCardPath returns the counter list (pPaths) as an array</span>
        <span style="color: #808080; font-style: italic;">//of null-terminated strings where the last item is a zero-length</span>
        <span style="color: #808080; font-style: italic;">//string (i.e. just #0). We'll now iterate over this list with some</span>
        <span style="color: #808080; font-style: italic;">//simple pointer math.</span>
        pIterator <span style="color: #000066;">:</span><span style="color: #000066;">=</span> pPaths<span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #000066;">&#40;</span><span style="color: #000066;">strlen</span><span style="color: #000066;">&#40;</span>pIterator<span style="color: #000066;">&#41;</span>&gt;<span style="color: #0000ff;">0</span><span style="color: #000066;">&#41;</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
          CounterPath <span style="color: #000066;">:</span><span style="color: #000066;">=</span> pIterator<span style="color: #000066;">;</span>
          pIterator <span style="color: #000066;">:</span><span style="color: #000066;">=</span> pIterator <span style="color: #000066;">+</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>pIterator<span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">;</span>
&nbsp;
          <span style="color: #808080; font-style: italic;">//Find the counter instance ID (the part in parentheses)</span>
          i <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Pos</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">'('</span><span style="color: #000066;">,</span> CounterPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
          InstanceId <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Copy</span><span style="color: #000066;">&#40;</span>CounterPath<span style="color: #000066;">,</span> i<span style="color: #000066;">+</span><span style="color: #0000ff;">1</span><span style="color: #000066;">,</span> <span style="color: #000066;">Pos</span><span style="color: #000066;">&#40;</span><span style="color: #ff0000;">')'</span><span style="color: #000066;">,</span> CounterPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span>i<span style="color: #000066;">-</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
          <span style="color: #808080; font-style: italic;">//Skip the counter if it indicates the overall CPU usage,</span>
          <span style="color: #808080; font-style: italic;">//we only want the per-core values.</span>
          <span style="color: #000000; font-weight: bold;">if</span> InstanceId <span style="color: #000066;">=</span> <span style="color: #ff0000;">'_Total'</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000066;">continue</span><span style="color: #000066;">;</span>
&nbsp;
          <span style="color: #808080; font-style: italic;">//Add the counter to the query</span>
          status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhAddCounter<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">,</span> <span style="color: #000066; font-weight: bold;">PWideChar</span><span style="color: #000066;">&#40;</span>CounterPath<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> h<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
          <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
            <span style="color: #808080; font-style: italic;">//Expand the internal counter array if necessary</span>
            <span style="color: #000000; font-weight: bold;">if</span> cnt &gt; <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">then</span>
              <span style="color: #000066;">SetLength</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">,</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">+</span><span style="color: #0000ff;">16</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
            <span style="color: #808080; font-style: italic;">//Save the counter data to the array</span>
            <span style="color: #000000; font-weight: bold;">with</span> Counters<span style="color: #000066;">&#91;</span>cnt<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
              Path <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CounterPath<span style="color: #000066;">;</span>
              Handle <span style="color: #000066;">:</span><span style="color: #000066;">=</span> h<span style="color: #000066;">;</span>
&nbsp;
              <span style="color: #808080; font-style: italic;">//Create a label for this core/CPU</span>
              mLabel <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TLabel<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Parent</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Caption</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #ff0000;">'Core '</span><span style="color: #000066;">+</span>InstanceId<span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Top</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">&#40;</span>mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Height</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">8</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">*</span> cnt <span style="color: #000066;">+</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Left</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">AutoSize</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #000066;">;</span>
              mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Width</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">80</span><span style="color: #000066;">;</span>
&nbsp;
              <span style="color: #808080; font-style: italic;">//Create a &quot;progress bar&quot; to show the core/CPU usage</span>
              mGauge <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TGauge<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">&#40;</span><span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Parent</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Top</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Top</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Left</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Width</span> <span style="color: #000066;">+</span> <span style="color: #0000ff;">20</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Height</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> mLabel<span style="color: #000066;">.</span><span style="color: #006600;">Height</span><span style="color: #000066;">+</span><span style="color: #0000ff;">2</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Width</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">.</span><span style="color: #006600;">ClientWidth</span> <span style="color: #000066;">-</span> mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Left</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">10</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">ForeColor</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #9ac;">$0031D329</span><span style="color: #000066;">;</span>
              mGauge<span style="color: #000066;">.</span><span style="color: #006600;">Anchors</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">&#91;</span>akRight<span style="color: #000066;">,</span> akTop<span style="color: #000066;">&#93;</span><span style="color: #000066;">;</span>
&nbsp;
            <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
            <span style="color: #000066;">inc</span><span style="color: #000066;">&#40;</span>cnt<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
          <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
        <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span><span style="color: #808080; font-style: italic;">//while</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">//Truncate the array to the actual number of discovered cores  </span>
        <span style="color: #000066;">SetLength</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">,</span> cnt<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">//Collect the first data sample</span>
        PdhCollectQueryData<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
      <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
    <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">//Did we get any valid counters?</span>
  <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span> <span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Nope. Show an unhelpful error message...</span>
    MessageBox<span style="color: #000066;">&#40;</span>Handle<span style="color: #000066;">,</span> <span style="color: #ff0000;">'Initialization was unsuccessful. The application will now exit.'</span><span style="color: #000066;">,</span>
      <span style="color: #ff0000;">'Error'</span><span style="color: #000066;">,</span> MB_OK <span style="color: #000000; font-weight: bold;">or</span> MB_ICONEXCLAMATION<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//...and quit.</span>
    Application<span style="color: #000066;">.</span><span style="color: #006600;">Terminate</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">end</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">begin</span>
    <span style="color: #808080; font-style: italic;">//Everything went well.</span>
    <span style="color: #808080; font-style: italic;">//Resize the form to make sure all progress bars are visible.</span>
    <span style="color: #000000; font-weight: bold;">Self</span><span style="color: #000066;">.</span><span style="color: #006600;">ClientHeight</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span>
      Counters<span style="color: #000066;">&#91;</span><span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mLabel</span><span style="color: #000066;">.</span><span style="color: #006600;">Top</span> <span style="color: #000066;">+</span>
      Counters<span style="color: #000066;">&#91;</span><span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span><span style="color: #000066;">-</span><span style="color: #0000ff;">1</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mLabel</span><span style="color: #000066;">.</span><span style="color: #006600;">Height</span> <span style="color: #000066;">+</span>
      Counters<span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mLabel</span><span style="color: #000066;">.</span><span style="color: #006600;">Top</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">Timer1Timer</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">var</span>
 i<span style="color: #000066;">:</span><span style="color: #000066; font-weight: bold;">integer</span><span style="color: #000066;">;</span>
 counterType<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">PDword</span><span style="color: #000066;">;</span>
 pValue<span style="color: #000066;">:</span>_PDH_FMT_COUNTERVALUE<span style="color: #000066;">;</span>
 status <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
  <span style="color: #000000; font-weight: bold;">if</span> Query <span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #000066;">exit</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">//Collect a data sample.</span>
  PdhCollectQueryData<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">//Iterate over all counters and update progress bars.</span>
  <span style="color: #000000; font-weight: bold;">for</span> i <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">to</span> <span style="color: #000066;">Length</span><span style="color: #000066;">&#40;</span>Counters<span style="color: #000066;">&#41;</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">1</span> <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">begin</span>
    counterType <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">nil</span><span style="color: #000066;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Get the current core/CPU usage</span>
    status <span style="color: #000066;">:</span><span style="color: #000066;">=</span> PdhGetFormattedCounterValue<span style="color: #000066;">&#40;</span>
      Counters<span style="color: #000066;">&#91;</span>i<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">Handle</span><span style="color: #000066;">,</span> <span style="color: #808080; font-style: italic;">//Counter handle as returned by PdhAddCounter.</span>
      PDH_FMT_DOUBLE<span style="color: #000066;">,</span>     <span style="color: #808080; font-style: italic;">//Get the counter value as a double-precision float.</span>
      CounterType<span style="color: #000066;">,</span>        <span style="color: #808080; font-style: italic;">//Counter type; unused.</span>
      pValue<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>            <span style="color: #808080; font-style: italic;">//Output buffer for the counter value.</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">//Update the progress bar.</span>
    <span style="color: #000000; font-weight: bold;">if</span> status <span style="color: #000066;">=</span> ERROR_SUCCESS <span style="color: #000000; font-weight: bold;">then</span>
      Counters<span style="color: #000066;">&#91;</span>i<span style="color: #000066;">&#93;</span><span style="color: #000066;">.</span><span style="color: #006600;">mGauge</span><span style="color: #000066;">.</span><span style="color: #006600;">Progress</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #000066;">Round</span><span style="color: #000066;">&#40;</span>pValue<span style="color: #000066;">.</span><span style="color: #006600;">doubleValue</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
  <span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">procedure</span> TForm1<span style="color: #000066;">.</span><span style="color: #006600;">FormDestroy</span><span style="color: #000066;">&#40;</span>Sender<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">TObject</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
 <span style="color: #808080; font-style: italic;">//Close the query when quitting.</span>
 <span style="color: #000000; font-weight: bold;">if</span> Query &lt;&gt; <span style="color: #0000ff;">0</span> <span style="color: #000000; font-weight: bold;">then</span> PdhCloseQuery<span style="color: #000066;">&#40;</span>Query<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">.</span></pre></div></div>

<h3>Download</h3>
<ul>
<li><strong><a href="http://w-shadow.com/files/CoreUsage.rar">Example source code</a></strong> (5 KB)<br />
This is a Delphi 2009 project. To compile it, you will also need to install the <a href="http://jedi-apilib.sourceforge.net/">Jedi API library</a> that contains PDH API headers for Delphi.</li>
<li><strong><a href="http://w-shadow.com/files/CpuCoreUsage.exe">Compiled example application</a></strong> (570 KB)</li>
</ul>
<p><em>P.S. </em><br />
Rumor has it that you may need administrative rights to use the performance counter API.</p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/04/17/per-core-cpu-usage/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>How To Open .MDF Files</title>
		<link>http://w-shadow.com/blog/2009/03/18/how-to-open-mdf-files/</link>
		<comments>http://w-shadow.com/blog/2009/03/18/how-to-open-mdf-files/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 11:57:00 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[file converters]]></category>
		<category><![CDATA[how to open a mdf file]]></category>
		<category><![CDATA[mdf file]]></category>
		<category><![CDATA[mdf file extension]]></category>
		<category><![CDATA[mdf to iso]]></category>
		<category><![CDATA[mds file]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=979</guid>
		<description><![CDATA[What is a .MDF file anyway?
The .MDF file extension usually designates a proprietary disk image format used by Alcohol 120%. Like ISO files, MDF files contain an exact copy a CD or DVD. This format is typically used for backing up discs and also for sharing the &#8220;backups&#8221; over BitTorrent or other P2P networks. 
There [...]]]></description>
			<content:encoded><![CDATA[<h3>What is a .MDF file anyway?</h3>
<p><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  src="http://w-shadow.com/wp-content/uploads/2009/03/mdf-file.jpg" alt="MDF Files" title="MDF Files" width="184" height="183" class="alignright size-full wp-image-992" />The .MDF file extension usually designates a proprietary disk image format used by Alcohol 120%. Like ISO files, MDF files contain an exact copy a CD or DVD. This format is typically used for backing up discs and also for sharing the &#8220;backups&#8221; over BitTorrent or other P2P networks. </p>
<p>There are several applications that can open .MDF files :</p>
<ul>
<li><a href="http://www.alcohol-soft.com/" rel="nofollow">Alcohol 120%</a> can mount .mdf files in a virtual CD/DVD drive. Commercial, free trial available.</li>
<li><a href="http://www.magiciso.com/download.htm" rel='nofollow'>MagicISO</a> can open or mount the files. Commercial, free trial available. Note : the trial version is limited to opening 300Mb files, so I don&#8217;t recommend using this one.</li>
<li><a href="http://www.daemon-tools.cc/eng/home">Daemon Tools</a> can also mount .mdf files using a virtual drive. Commercial, but the <a href="http://www.daemon-tools.cc/products/dtLite" rel='nofollow'>Lite edition</a> trial version has no functionality or time limitations. </li>
<li><a href="http://www.isobuster.com/">IsoBuster</a> can also open .mdf files. Commercial, has a free trial version with no time limit.</li>
</ul>
<p>Gah, so all the tools are commercial. Which one should you use? Personally, I would recommend IsoBuster &#8211; it&#8217;s pretty convenient and won&#8217;t nag you incessantly about upgrading to the Pro version. It can also convert a .mdf/.mds file to the ISO format which is handy if you want to use the disk image with other CD/DVD software.</p>
<h3>How To Open a .MDF File With IsoBuster</h3>
<ol>
<li><a href="http://www.isobuster.com/isobusterdownload.php">Download IsoBuster</a> &#038; install it.<br />
Note : You&#8217;ll probably want to uncheck the &#8220;Include the IsoBuster toolbar&#8221; option when installing IsoBuster. It&#8217;s probably not spyware, but there&#8217;s no point in polluting your computer with random applications. Just saying.</li>
<li><strong>Start up IsoBuster.</strong><br />
(The installer usually adds a QuickLaunch icon that you can use to run the program.)</li>
<li><strong>Open the .MDF or .MDS file by clicking on <em>File -&gt; Open Image File</em>.</strong><br />
It doesn&#8217;t matter whether you select the .mdf or the .mds file in the <em>Open..</em> dialog. IsoBuster will automatically load the appropriate disk image anyway. Alternatively, you can open a MDF file by dragging it into the left panel of the application window (it&#8217;s the box that contains the text &#8220;No media present&#8221; when you&#8217;ve just launched the program).</li>
<li><strong>Extract the files you need.</strong><br />
To extract a file or a folder, right-click it and select <em>Extract [file name]</em> from the pop-up menu. You can also drag files from the IsoBuster window and drop them into any folder on your computer to copy them there.</li>
</ol>
<h3>Additional Tip : How To Convert .MDF to .ISO</h3>
<p>This is not a widely advertised feature, but I&#8217;ve noticed that you can actually use IsoBuster to convert .MDF/.MDS files to ISO. First, open the .mdf file as described above. Then right-click on the &#8220;CD&#8221; or &#8220;DVD&#8221; entry on the left-side navigation panel and select <em>Extract CD/DVD &lt;Image&gt; -&gt; RAW (*.bin, *.iso)</em>. Choose where to save the converted file, make sure &#8220;Save as type&#8221; is set to &#8220;*.iso&#8221;, and hit <em>Save</em>. After a short conversion process you&#8217;ll get an .ISO file (+ <a href="http://en.wikipedia.org/wiki/Cue_sheet_(computing)">a .CUE file</a>) that you can use with any CD/DVD burning or emulation software.</p>
<p>Thanks for reading <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div style='font-size:smaller; clear:both;'><em>* CD stock image by <a href="http://www.sxc.hu/photo/1023847">bobmorley</a></em></div>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/03/18/how-to-open-mdf-files/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Text Classification With PHP</title>
		<link>http://w-shadow.com/blog/2009/03/07/text-classification-with-php/</link>
		<comments>http://w-shadow.com/blog/2009/03/07/text-classification-with-php/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 17:21:56 +0000</pubDate>
		<dc:creator>White Shadow</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[machine learning]]></category>
		<category><![CDATA[naive bayes]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[php classes]]></category>
		<category><![CDATA[spam filters]]></category>
		<category><![CDATA[text categorization]]></category>
		<category><![CDATA[text classifiers]]></category>

		<guid isPermaLink="false">http://w-shadow.com/?p=971</guid>
		<description><![CDATA[Text classification is probably the most popular real-world application of machine learning and other AI techniques. This is because the adaptive spam filters that guard our inboxes, comment forms and guestbooks are basically specialized text classifiers that only deal with two categories &#8211; &#8220;spam&#8221; and &#8220;not spam&#8221;. Text categorization can also be used to detect [...]]]></description>
			<content:encoded><![CDATA[<p>Text classification is probably the most popular real-world application of machine learning and other AI techniques. This is because the adaptive spam filters that guard our inboxes, comment forms and guestbooks are basically specialized text classifiers that only deal with two categories &#8211; &#8220;spam&#8221; and &#8220;not spam&#8221;. Text categorization can also be used to detect the language of a document, automatically suggest categories or tags for textual content, and more.</p>
<p>As with most AI algorithms, there are relatively few PHP classes/libraries available that deal with automated text classification. In this post I&#8217;ll review the classifier scripts I managed to find.</p>
<p><em>Note : All of these scripts use some form of the <a href="http://en.wikipedia.org/wiki/Naive_Bayes_classifier">naive Bayes classifier</a>. This algorithm is easy to implement and usually yields pretty good results, but it&#8217;s worth knowing that <a href="http://en.wikipedia.org/wiki/Document_classification#Techniques">other techniques</a> exist.</em></p>
<h3><a href="http://xhtml.net/php/PHPNaiveBayesianFilter">PHP Naive Bayesian Filter</a></h3>
<p>This is a simple text classifier backed by a MySQL database. You can train it to recognize any number of categories, and it will also allow you to &#8220;untrain&#8221; the classifier if you mistakenly assign the wrong category to a document. The downside is that most of the documentation is in French, but that shouldn&#8217;t be a huge problem &#8211; the code itself is easy enough to understand and commented in English. See also : <a href="http://www.hokstad.com/archives/2005/03/php_naive_bayes.html">an English translation of the project&#8217;s page</a>.</p>
<h3><a href="http://nasauber.de/opensource/b8/index.php.en">b8</a></h3>
<p>b8 is an actively developed spam filter implemented in PHP. This is a good choice if you need a document classifier specifically for the purpose of catching forum/comment spammers. However, with a bit of modification you could probably coerce it to do other kinds of classification.</p>
<p>The filter can be trained/untrained and supports several database backends &#8211; BerkleyDB (very fast), MySQL (ubiquitous, but slower when used this way) and SQLite (a file-based database). The whole thing has a fairly professional overall look and good documentation.</p>
<h3><a href="http://www.phpclasses.org/browse/package/5072.html">PHP Text Classifier</a></h3>
<p>I felt I had to include this class for completeness, but I personally wouldn&#8217;t use it for anything but the simplest projects. The good news is that this classifier supports an arbitrary number of categories and has a very simple implementation (the GPL headers probably take up more space than the code itself). The bad news is that there&#8217;s almost no documentation, the source comments are in whatever language they speak in Indonesia, and storing word frequency data as a serialized object isn&#8217;t very scalable.</p>
<h3>Roll Your Own</h3>
<p>If the above scripts don&#8217;t suit your needs you can always write your own. For example, the Wikipedia pages on <a href="http://en.wikipedia.org/wiki/Bayesian_spam_filtering">Bayesian spam filtering</a> and <a href="http://en.wikipedia.org/wiki/Naive_Bayes_classifier">naive Bayes classifiers</a> have a good (if a somewhat math-heavy) overview a simple classification algorithm and a list of useful resources and tutorials. Good luck <img src='http://w-shadow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<hr/>Copyright &copy; 2010 <strong><a href="http://w-shadow.com">W-Shadow.com</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@w-shadow.com so we can take legal action immediately.]]></content:encoded>
			<wfw:commentRss>http://w-shadow.com/blog/2009/03/07/text-classification-with-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
