<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Magp.ie</title>
	<atom:link href="http://magp.ie/feed/" rel="self" type="application/rss+xml" />
	<link>http://magp.ie</link>
	<description>A nest for the random, shiny, online tidbits I stumple across...</description>
	<lastBuildDate>Wed, 16 Jun 2010 17:15:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='magp.ie' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/061e340c5da13b5a41ae8016bee03aa8?s=96&#038;d=http://s2.wp.com/i/buttonw-com.png</url>
		<title>Magp.ie</title>
		<link>http://magp.ie</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://magp.ie/osd.xml" title="Magp.ie" />
	<atom:link rel='hub' href='http://magp.ie/?pushpress=hub'/>
		<item>
		<title>Textwrangler Tips &#8211; Compare files, keyboard shortcuts</title>
		<link>http://magp.ie/2010/06/16/textwrangler-tips-compare-files-keyboard-shortcuts/</link>
		<comments>http://magp.ie/2010/06/16/textwrangler-tips-compare-files-keyboard-shortcuts/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 17:10:30 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[shortcuts]]></category>
		<category><![CDATA[text editor]]></category>
		<category><![CDATA[textwrangler]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://magp.ie/?p=195</guid>
		<description><![CDATA[A few quick TextWrangler tips. I never knew until recently that you can compare files in TextWrangler&#8230; and its easy. Simply highlight the 2 files you want to compare in the Documents drawer, right click on them and select the option &#8216;Compare Selected Documents&#8216;. Now the 2 files will open into 2 windows with a <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=195&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>A few quick TextWrangler tips.</p>
<p>I never knew until recently that you can compare files in <a href="http://www.barebones.com/products/textwrangler/" target="_blank">TextWrangler</a>&#8230; and its easy.</p>
<p>Simply highlight the 2 files you want to compare in the Documents drawer, right click on them and select the option &#8216;<strong>Compare Selected Documents</strong>&#8216;.</p>
<p>Now the 2 files will open into 2 windows with a review of the differences below them. You can then apply the differences in either direction.</p>
<p>Another tip is adding keyboard shortcuts to TextWrangler&#8217;s menu options.<br />
<span id="more-195"></span><br />
I like to use the <strong>Search</strong>-&gt;<strong>Jump Back/Forward</strong> option to navigate around a large body of code but alas it has no keyboard shortcut. So each time you wish to move from one Jump mark to another, you need to go up to the Search menu&#8230; which kinda defeats the handiness of the option in the first place.</p>
<p>Anyways, to add a keyboard shortcut to this (or some other useful menu) option, go to <strong>Textwrangler</strong>-&gt;<strong>Preferences</strong>.</p>
<p>Select <strong>Menus</strong>&#8230;</p>
<p><img class="alignnone size-full wp-image-196" title="Menus option" src="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-39-03.png?w=184&#038;h=72" alt="" width="184" height="72" /></p>
<p>Find the menu heading for the option you want, in my case <strong>Search</strong>&#8230;</p>
<p><img class="alignnone size-full wp-image-197" title="Search Menu header" src="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-39-38.png?w=151&#038;h=143" alt="" width="151" height="143" /></p>
<p>In the menu header, find the option(s) you want to add a keyboard shortcut to.</p>
<p>Highlight an option and press the <strong>Set Key</strong> button.</p>
<p><img class="alignnone size-full wp-image-198" title="Set Key button" src="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-40-42.png?w=115&#038;h=32" alt="" width="115" height="32" /></p>
<p>Enter the keyboard shortcut and press the <strong>Set</strong> button.</p>
<p>Bingo.</p>
<p><img class="alignnone size-full wp-image-199" title="Shortcuts" src="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-41-49.png?w=347&#038;h=50" alt="" width="347" height="50" /></p>
<p>Lastly, a while back <a href="http://magp.ie/2010/02/15/format-xml-with-textwrangler/" target="_blank">I wrote a shell script to format my XML</a>. To add a shortcut to this, you need to select <strong>Window</strong>-&gt;<strong>Palettes</strong>-&gt;<strong>Unix Filters</strong></p>
<p>Select the script you want to shortcut and press the <strong>Set Key&#8230;</strong> button. Enter your keyboard shortcut and press the <strong>Set</strong> button and now when you want to format some messy XML, you have a keyboard shortcut to knock it into shape.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/195/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=195&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/06/16/textwrangler-tips-compare-files-keyboard-shortcuts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>53.734482 -8.990559</georss:point>
		<geo:lat>53.734482</geo:lat>
		<geo:long>-8.990559</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>

		<media:content url="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-39-03.png" medium="image">
			<media:title type="html">Menus option</media:title>
		</media:content>

		<media:content url="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-39-38.png" medium="image">
			<media:title type="html">Search Menu header</media:title>
		</media:content>

		<media:content url="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-40-42.png" medium="image">
			<media:title type="html">Set Key button</media:title>
		</media:content>

		<media:content url="http://blogalhost.files.wordpress.com/2010/06/screen-shot-2010-06-16-at-17-41-49.png" medium="image">
			<media:title type="html">Shortcuts</media:title>
		</media:content>
	</item>
		<item>
		<title>JavaScript Tricks; URLEncode, Foreach and Remove last character</title>
		<link>http://magp.ie/2010/05/13/javascript-tricks-urlencode-foreach-remove-last-character/</link>
		<comments>http://magp.ie/2010/05/13/javascript-tricks-urlencode-foreach-remove-last-character/#comments</comments>
		<pubDate>Thu, 13 May 2010 18:04:06 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[regular expression]]></category>
		<category><![CDATA[urlencode]]></category>

		<guid isPermaLink="false">http://magp.ie/?p=184</guid>
		<description><![CDATA[I have come across some neat (if not mind blowing) tricks with JavaScript recently. Firstly, I needed JavaScript code that copied PHP&#8217;s urlencode(). This function returns an encoded string where all non-alphanumeric characters except - _ . are replaced with a percent (%) sign followed by two hex digits and spaces encoded as plus (+) <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=184&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I have come across some neat (if not mind blowing) tricks with JavaScript recently. </p>
<p>Firstly, I needed JavaScript code that copied PHP&#8217;s <a href="http://php.net/manual/en/function.urlencode.php" target="_blank">urlencode()</a>.<br />
This function returns an encoded string where all non-alphanumeric characters except <b>- _ .</b> are replaced with a percent (%) sign followed by two hex digits and spaces encoded as plus (+) signs.</p>
<p>JavaScript has 2 functions to emulate urlencode(), but both fall short&#8230;<br />
The <strong>escape</strong> function encodes all non-alphanumeric characters except <b>* @ / + &#8211; _ .</b><br />
The <strong>encodeURIComponent</strong> function encodes all non-alphanumeric characters except <strong>spaces</strong> and <b>! &#8216; ( ) * ~</b></p>
<p>The winner for me though is encodeURIComponent as it encodes all UTF-8 characters while escape only encodes ISO Latin characters.</p>
<p>With this in hand, <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Global_Functions:encodeURIComponent" target="_blank">mozilla</a> help provide a neat function.<br />
<span id="more-184"></span></p>
<pre class="brush: plain;">
function url_encode( s ) {
	return encodeURIComponent( s ).replace( /\%20/g, '+' ).replace( /!/g, '%21' ).replace( /'/g, '%27' ).replace( /\(/g, '%28' ).replace( /\)/g, '%29' ).replace( /\*/g, '%2A' ).replace( /\~/g, '%7E' );
}
</pre>
<p>This basically uses regular expressions to do a global replace on characters encodeURIComponent misses.</p>
<p>Another tiny trick that I liked is a JavaScript foreach loop. I use this regularly in PHP but its not exactly obvious in JavaScript.<br />
Use the following code&#8230;</p>
<pre class="brush: plain;">
var some_array = new Array;
some_array['a'] = 1;
some_array['b'] = 2;
some_array['c'] = 3;
for ( var key in some_array ) {
  var value = some_array[key];
  echo 'Key: ' + key + ', Value: ' + value;
}
//outputs...
// Key: a, Value: 1
// Key: b, Value: 2
// Key: c, Value: 3
</pre>
<p>This is particularly handy with associative arrays like above.</p>
<p>Final <em>ickle</em> trick is a bit of code to remove the last character from a string. Use the JavaScript <strong>slice</strong> function and its easy peasy&#8230;</p>
<pre class="brush: plain;">
var some_string = '&quot;102&quot;,&quot;123&quot;,&quot;45&quot;,&quot;583&quot;,';
some_string = some_string.slice(0, -1);
</pre>
<p>Why is this handy? Well I use loops to construct formatted stings with some delimiter, like the comma in the code above.<br />
However the string usually ends up with the delimiter added on at the end. So I like to remove it at the end rather than checking if I should not append the delimiter with each iteration of the loop.<br />
I think it is much tidier and it is probably quicker but I am open to correction.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/184/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/184/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/184/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/184/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/184/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/184/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=184&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/05/13/javascript-tricks-urlencode-foreach-remove-last-character/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>
	</item>
		<item>
		<title>Post XML with HTTPS Authentication using PHP and cURL</title>
		<link>http://magp.ie/2010/04/12/post-xml-with-https-authentication-using-php-curl/</link>
		<comments>http://magp.ie/2010/04/12/post-xml-with-https-authentication-using-php-curl/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 19:56:44 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[cURL]]></category>
		<category><![CDATA[HTTPS Authentication]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://magp.ie/?p=175</guid>
		<description><![CDATA[Recently I needed to post XML to a particular API and this API required HTTPS authentication. So I needed to send a username / password with the request. This was pretty straightforward in C#.NET ( at least from my foggy memory ). You needed to use NetworkCredentials. But it was a bit difficult to find <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=175&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I needed to post XML to a particular API and this API required HTTPS authentication. So I needed to send a username / password with the request. </p>
<p>This was pretty straightforward in C#.NET ( at least from my foggy memory ). You needed to use <a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.net.networkcredential.username.aspx">NetworkCredentials</a>. But it was a bit difficult to find a similar way of doing this in PHP&#8230; but <i>eventually</i> I found this <a target="_blank" href="http://blog.taragana.com/index.php/archive/how-to-use-curl-in-php-for-authentication-and-ssl-communication/">gem</a>.</p>
<p>This uses <a target="_blank" href="http://www.php.net/manual/en/book.curl.php">cURL</a> which is just a library to send and receive data from remote sites. Now all I needed was a neat way of using cURL to post XML&#8230; and I found a neat implementation <a target="_blank" href="http://forums.digitalpoint.com/showthread.php?t=424619&amp;s=d790ff51b6a3b7b6262f37c396a06b9c#post4004636">here</a>.</p>
<p>Two plus two and you get &#8230;<br />
<span id="more-175"></span></p>
<pre class="brush: plain;">
$request_xml = &quot;&lt;?xml version='1.0' encoding='utf-8'?&gt;
&lt;request&gt;
	&lt;id&gt;12345&lt;/id&gt;
	&lt;email&gt;eoin@dolepaddy.com&lt;/email&gt;
&lt;request&gt;&quot;;

//Initialize handle and set options
$username = 'dolepaddy';
$password = 'secret123';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://connect.tosomeserver.com/xmlrpc');
curl_setopt($ch, CURLOPT_USERPWD, $username.':'.$password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_xml);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: close'));

//Execute the request and also time the transaction ( optional )
$start = array_sum(explode(' ', microtime()));
$result = curl_exec($ch);
$stop = array_sum(explode(' ', microtime()));
$totalTime = $stop - $start;

//Check for errors ( again optional )
if ( curl_errno($ch) ) {
	$result = 'ERROR -&gt; ' . curl_errno($ch) . ': ' . curl_error($ch);
} else {
	$returnCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
	switch($returnCode){
		case 200:
			break;
		default:
			$result = 'HTTP ERROR -&gt; ' . $returnCode;
			break;
	}
}

//Close the handle
curl_close($ch);

//Output the results and time
echo 'Total time for request: ' . $totalTime . &quot;\n&quot;;
echo $result;
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/175/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/175/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/175/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/175/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/175/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/175/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/175/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/175/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/175/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/175/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=175&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/04/12/post-xml-with-https-authentication-using-php-curl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>
	</item>
		<item>
		<title>Auto highlight text inside pre tags using jQuery</title>
		<link>http://magp.ie/2010/04/07/auto-highlight-text-inside-pre-tags-using-jquery/</link>
		<comments>http://magp.ie/2010/04/07/auto-highlight-text-inside-pre-tags-using-jquery/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 19:31:45 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[auto-select]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[pre tags]]></category>

		<guid isPermaLink="false">http://magp.ie/?p=168</guid>
		<description><![CDATA[We use pre tags in the Polldaddy plugin to display the embed codes and short URLs. We use pre tags because it formats the text inside the tags as we insert it, which is ideal for displaying code in particular. The thing is, people like to copy this code and they have to go to <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=168&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>We use pre tags in the <a href="http://wordpress.org/extend/plugins/polldaddy/" target="_blank">Polldaddy plugin</a> to display the embed codes and short URLs. We use <a href="http://www.w3schools.com/TAGS/tag_pre.asp" target="_blank">pre</a> tags because it formats the text inside the tags as we insert it, which is ideal for displaying code in particular. The thing is, people like to copy this code and they have to go to the <i>awful</i> bother of selecting all the text manually if they wish to copy the code or URL.</p>
<p>The alternative is to use an text input or text area which will allow you to use a select method that you can call on a click event, but then you lose the neat formatting that pre tags offer.</p>
<p>So I had a look for a jQuery hack to auto select all the text inside the pre tags. The only complication with this appears to be a cross platform solution as each browser appears to have their own way of selecting text.<br />
<span id="more-168"></span><br />
<strong>Internet Explorer</strong> uses <a href="http://msdn.microsoft.com/en-us/library/ms536401%28VS.85%29.aspx" target="_blank">createTextRange</a>.<br />
<strong>Opera</strong> and <strong>Firefox</strong> use <a href="http://www.wrox.com/WileyCDA/Section/JavaScript-DOM-Ranges.id-292301.html" target="_blank">createRange</a>.<br />
<strong>Safari</strong> uses <a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/WebKitDOMRef/DOMSelection_idl/Classes/DOMSelection/index.html" target="_blank">DOMSelection</a>.</p>
<p>So with a pre tag like &#8230;</p>
<pre class="brush: plain;">
&lt;pre class='code'&gt;http://poll.fm/11w3q&lt;/pre&gt;
</pre>
<p>&#8230; the following code will auto-select the all the text between the tags &#8230;</p>
<pre class="brush: plain;">
	jQuery( document ).ready(function() {
		jQuery( 'pre.code' ).click( function() {
			var refNode = $( this )[0];
			if ( $.browser.msie ) {
				var range = document.body.createTextRange();
				range.moveToElementText( refNode );
				range.select();
			} else if ( $.browser.mozilla || $.browser.opera ) {
				var selection = window.getSelection();
				var range = document.createRange();
				range.selectNodeContents( refNode );
				selection.removeAllRanges();
				selection.addRange( range );
			} else if ( $.browser.safari ) {
				var selection = window.getSelection();
				selection.setBaseAndExtent( refNode, 0, refNode, 1 );
			}
		} );
  	} );
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/168/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/168/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=168&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/04/07/auto-highlight-text-inside-pre-tags-using-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>
	</item>
		<item>
		<title>Revert or rollback a SVN revision</title>
		<link>http://magp.ie/2010/03/25/revert-or-rollback-a-svn-revision/</link>
		<comments>http://magp.ie/2010/03/25/revert-or-rollback-a-svn-revision/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 18:47:02 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Guides]]></category>
		<category><![CDATA[revert]]></category>
		<category><![CDATA[revision]]></category>
		<category><![CDATA[rollback]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://magp.ie/?p=154</guid>
		<description><![CDATA[If you have ever deployed code from a SVN repository with a bug in it and you need to revert to a working revision then you may find the following handy. First find the revision numbers for the file(s) in question. Use the log command to get the info from previous commits including revision numbers. <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=154&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>If you have ever deployed code from a SVN repository with a bug in it and you need to revert to a working revision then you may find the following handy.</p>
<p>First find the revision numbers for the file(s) in question.</p>
<p>Use the <a href="http://svnbook.red-bean.com/en/1.0/re15.html" target="_blank">log</a> command to get the info from previous commits including revision numbers.</p>
<p>So something like&#8230;<span id="more-154"></span></p>
<pre class="brush: plain;">
svn log update-data.php
--------------------------------------------------------------
r4057 | eoin | 2010-03-25 17:33:32 +0000 (Thu, 25 Mar 2010) | 1 line

turn on db errors
--------------------------------------------------------------
r4056 | eoin | 2010-03-25 17:32:36 +0000 (Thu, 25 Mar 2010) | 1 line

add update file
--------------------------------------------------------------
</pre>
<p>Use <a href="http://svnbook.red-bean.com/en/1.0/re09.html" target="_blank">diff</a> command to see the difference between the 2 revisions.</p>
<pre class="brush: plain;">
svn diff -r 4056:4057
Index: update-data.php
=============================================
--- update-data.php	(revision 4056)
+++ update-data.php	(revision 4057)
@@ -6,7 +6,7 @@

-$db-&gt;show_errors = false;
+$db-&gt;show_errors = true;
</pre>
<p>Sometimes this is all you need, as you can see the mistake you made. Now you can make a change to the working copy and commit a fix. However if there were too many changes to do yourself, you may prefer to revert to the last known good revision. In this case, you will need to merge the changes from your current revision back to the revision you want to revert to.</p>
<p>You should try a dry run to see what a the outcome of a merge will be before you execute the real merge.</p>
<pre class="brush: plain;">
svn merge --dry-run -r 4057:4056 update-data.php
U    update-data.php
</pre>
<p>Now execute the <a href="http://svnbook.red-bean.com/en/1.1/re16.html" target="_blank">merge</a> command to revert to previous revision.</p>
<pre class="brush: plain;">
svn merge -r 4057:4056 update-data.php
U    update-data.php

svn diff update-data.php
Index: update-data.php
==============================================
--- update-data.php	(revision 4057)
+++ update-data.php	(working copy)
@@ -6,7 +6,7 @@

-$db-&gt;show_errors = true;
+$db-&gt;show_errors = false;
</pre>
<p>Use a diff to see the changes made after the merge and you should see that the change(s) made have been undone. Now commit the working copy to include this change and all&#8217;s well in the world again.</p>
<pre class="brush: plain;">
svn -m 'turn off db errors again' commit update-data.php
</pre>
<p>One final point, be <strong>super</strong> careful with a merge, things can get real <em>messy</em>!<br />
Take your time, make sure you use <strong>diff</strong> to see what changes have been made and check again when your through <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Really good and detailed explanation of the revert process from <a href="http://aralbalkan.com/1381" target="_blank">aralbalkan</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/154/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/154/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/154/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=154&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/03/25/revert-or-rollback-a-svn-revision/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>
	</item>
		<item>
		<title>JavaScript, ExternalInterface, Flash and Local Shared Objects</title>
		<link>http://magp.ie/2010/03/22/javascript-externalinterface-flash-and-local-shared-objects/</link>
		<comments>http://magp.ie/2010/03/22/javascript-externalinterface-flash-and-local-shared-objects/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 10:28:00 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ExternalInterface]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Local Shared Objects]]></category>
		<category><![CDATA[LSO]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[DOM storage]]></category>

		<guid isPermaLink="false">http://magp.ie/?p=141</guid>
		<description><![CDATA[I was looking into flash&#8217;s local shared objects ( from here on LSO&#8217;s ) recently as a method of data persistence on a clients browser as the plain old HTTP cookie has its limitations. LSO&#8217;s are like cookies and are sometimes referred to flash cookies but there are 2 main differences between them. A normal <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=141&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I was looking into flash&#8217;s local shared objects ( from here on LSO&#8217;s ) recently as a method of data persistence on a clients browser as the plain old HTTP cookie has its limitations.</p>
<p>LSO&#8217;s are like cookies and are sometimes referred to flash cookies but there are 2 main differences between them. A normal HTTP cookie can store around 4k of data, while the flash cookie can store up to 100k. Also a normal cookie is pretty easy to remove while removing a flash cookie is far more convoluted, which is a matter of some contention.<br />
<span id="more-141"></span><br />
<strong>HANDY TIP:</strong> Removing LSO&#8217;s from your computer<br />
You can remove LSO&#8217;s using a tool on Adobe site, <a target="_blank" href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html">here</a>, which also allows you to configure your flash security settings. You can also install a Firefox plugin, <a target="_blank" href="http://objection.mozdev.org/">Objection</a>, which will allow you to see and remove whatever flash cookies are present on your computer.</p>
<p>I wanted to set a flash cookie using JavaScript. This is pretty straightforward thanks to Flash&#8217;s ExternalInterface class. This class allows you to set methods that can be accessed from an external script, like JavaScript. This class is bi-directional, so you can also call JavaScript methods from within the Flash&#8217;s ActionScript.</p>
<p>I used the site, <a target="_blank" href="http://www.viget.com/inspire/bi-directional-actionscript-javascript-communication">viget</a> and <a target="_blank" href="http://www.peachpit.com/guides/content.aspx?g=flash&amp;seqNum=340">peachpit</a>, to get an idea how to set this up and found some excellent, quirky tips from the <a target="_blank" href="http://www.schillmania.com/">schillmania</a> site.</p>
<p>On my web page I needed to reference a neat <a target="_blank" href="http://code.google.com/p/swfobject/">SWFObject</a> class to embed a flash player on the page. Once I had a handle on the flash player, I can call the Flash file&#8217;s ActionScript methods to request and set the LSO. The <a target="_blank" href="http://www.actionscript.org/resources/articles/118/1/SharedObjects/Page1.html">actionscript.org</a> site has a good tutorial on how to manage LSO&#8217;s using ActionScript.</p>
<p>So here&#8217;s the JavaScript&#8230;</p>
<pre class="brush: plain;">
var lso_value;

function init() {
	var so = new swfobject.embedSWF(&quot;pd_check.swf&quot;, &quot;pd_check&quot;, &quot;1&quot;, &quot;1&quot;, &quot;9.0.0&quot;);
	so.write(&quot;flash_container&quot;);
}

function getFlashMovie( movieName ) {
	var isIE = navigator.appName.indexOf(&quot;Microsoft&quot;) != -1;
	return (isIE) ? window[movieName] : document[movieName];
}

function requestLSOValue() {
	getFlashMovie('pd_check').requestLSOValue();
}

function updateLSOValue( value ) {
	lso_value = value;
}

function setLSOValue( value ) {
	getFlashMovie('pd_check').setLSOValue( value );
}
</pre>
<p>&#8230; and here&#8217;s the ActionScript. You can remove the console.log lines if you wish, they were just initially helpful in knowing what was going on under the flash hood.</p>
<pre class="brush: plain;">
import flash.external.ExternalInterface;
//call from javascript
ExternalInterface.addCallback( &quot;requestLSOValue&quot;, requestLSOValue );
ExternalInterface.addCallback( &quot;setLSOValue&quot;, setLSOValue );

function requestLSOValue():void
{
	try
	{
		ExternalInterface.call('console.log', 'Trace: requestLSOValue');
		var obj_value:String = '0';
		var lso=SharedObject.getLocal(&quot;pd_check&quot;);

		// If name variable is not available, we assume that this is a new user
		if (lso.data.value!=null)
		{
		  obj_value = lso.data.value;
		}
		if (ExternalInterface.available) {
			ExternalInterface.call('console.log', 'Trace: getLSOValue::' + obj_value);
			ExternalInterface.call(&quot;updateLSOValue&quot;, obj_value );
		}
	}
	catch(e) {
		ExternalInterface.call('console.log', 'Flash error: '+e.toString());
	}
}

function setLSOValue( obj_value ):void
{
	try{
		ExternalInterface.call('console.log', 'Trace: setLSOValue');
		var writeSuccess:Boolean = false;
		// Create a shared-object named &quot;userData&quot;
		var lso=SharedObject.getLocal(&quot;pd_check&quot;);
		// Store the name
		lso.data.value=obj_value;
		var success = lso.flush();
		if (success == &quot;pending&quot;) {
		 lso.onStatus = function(result) {
		  if (result.code == &quot;SharedObject.Flush.Success&quot;) {
		   ExternalInterface.call('console.log', 'Trace: Sucess writing to disk');
		   writeSuccess = true;
		  } else {
		   ExternalInterface.call('console.log', 'Trace: Failure writing to disk');
		   writeSuccess = false;
		  }
		 };
		} else {
		 writeSuccess = success;
		}
	}
	catch(e) {
		ExternalInterface.call('console.log', 'Flash error: '+e.toString());
	}
}
</pre>
<p>The main thing I learned from this is, it is pretty useless as a replacement for third party cookies. This will not allow you to set cookies across domains&#8230; not that I could find anyway. So the flash movie file ( pd_check.swf ), that the flash player embed references, has to be on the same domain as the website ( where the JavaScript is trying to access the Flash ActionScript ).</p>
<p>Down the road, I am going to look into <a target="_blank" href="http://ejohn.org/blog/dom-storage/">DOM Storage</a>, mainly as a curiosity. I came across it in researching LSO&#8217;s and it looks very interesting. This facility is part of the <a target="_blank" href="http://html5.org/">HTML 5</a> spec so its not fully available yet, but it looks like a neat evolution of standard HTTP cookies.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/141/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/141/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/141/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=141&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/03/22/javascript-externalinterface-flash-and-local-shared-objects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>
	</item>
		<item>
		<title>Regular Expressions</title>
		<link>http://magp.ie/2010/03/08/regular-expressions-email-url-parse-assignment/</link>
		<comments>http://magp.ie/2010/03/08/regular-expressions-email-url-parse-assignment/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 22:16:08 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[parse assignment value]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[regular expression]]></category>
		<category><![CDATA[validate email]]></category>
		<category><![CDATA[validate url]]></category>
		<category><![CDATA[xkcd]]></category>

		<guid isPermaLink="false">http://blogalhost.wordpress.com/?p=28</guid>
		<description><![CDATA[First off, regular expressions are great. They are a handy quick way to validate or parse data and you can use them in almost all languages. But of all things, I forget neat regex&#8217;s and in fairness they are a pita to recall as the syntax is plain nutty. This is where it ends. I <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=28&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>First off, regular expressions are great.</p>
<p>They are a handy quick way to validate or parse data and you can use them in almost all languages. But of all things, I forget neat regex&#8217;s and in fairness they are a pita to recall as the syntax is plain nutty.</p>
<p>This is where it ends. I am going to reference all the neat regex&#8217;s in this blog as I come across them rather than rely on mother Google.<br />
<span id="more-28"></span><br />
Starting with a couple of simple functions I use to validate email addresses (thanks WordPress core!) and URLs. </p>
<pre class="brush: plain;">
function is_url ( $url ) {
	return ( ! preg_match ( '/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i', $url ) ) ? FALSE : TRUE;
}

function is_email( $email ) {
	// Test for the minimum length the email can be
	if ( strlen( $email ) &lt; 3 ) {
		return false;
	}

	// Test for an @ character after the first position
	if ( strpos( $email, '@', 1 ) === false ) {
		return false;
	}

	// Split out the local and domain parts
	list( $local, $domain ) = explode( '@', $email, 2 );

	// LOCAL PART
	// Test for invalid characters
	if ( !preg_match( '/^[a-zA-Z0-9!#$%&amp;\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
		return false;
	}

	// DOMAIN PART
	// Test for sequences of periods
	if ( preg_match( '/\.{2,}/', $domain ) ) {
		return false;
	}

	// Test for leading and trailing periods and whitespace
	if ( trim( $domain, &quot; \t\n\r&#92;&#48;\x0B.&quot; ) !== $domain ) {
		return false;
	}

	// Split the domain into subs
	$subs = explode( '.', $domain );

	// Assume the domain will have at least two subs
	if ( 2 &gt; count( $subs ) ) {
		return false;
	}

	// Loop through each sub
	foreach ( $subs as $sub ) {
		// Test for leading and trailing hyphens and whitespace
		if ( trim( $sub, &quot; \t\n\r&#92;&#48;\x0B-&quot; ) !== $sub ) {
			return false;
		}

		// Test for invalid characters
		if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
			return false;
		}
	}

	// Congratulations your email made it!
	return true;
}
</pre>
<p>Lastly and most recently, I wanted to parse a string of code to find an assignment value.<br />
I came across a neat regex to help me parse out the values of these variables. </p>
<pre class="brush: plain;">
$code = &quot;var string_variable = Superduper;
var digit_variable = 123456;&quot;;

function get_assignment_value( $needle, $haystack, $type = 'string' ) {
	if( $type == 'digit' )
		preg_match( '/.'.$needle.' = (?P&lt;value&gt;\d+)/', $haystack, $matches );
	else
		preg_match( '/.'.$needle.' = (?P&lt;value&gt;\w+)/', $haystack, $matches );

	if( empty( $matches[ 'value' ] ) )
		return false;

	if( $type == 'digit' )
		return (int) $matches[ 'value' ];

	return $matches[ 'value' ];
}

var_dump( get_assignment_value( 'string_variable', $code ) ); // string(10) &quot;Superduper&quot;
var_dump( get_assignment_value( 'digit_variable', $code, 'digit' ) ); // int(123456)
var_dump( get_assignment_value( 'digit_variable', $code  ) ); // string(6) &quot;123456&quot;
</pre>
<p>My main source of guidance on this voodoo <a title="Guide to regexs" href="http://www.regular-expressions.info/" target="_blank">here</a>.</p>
<p>Also, <a href="http://nepalphp.org/content/10-practical-php-regular-expression-recipes" target="_blank">here</a> is a decent list of handy regex&#8217;s validations.</p>
<p><img class="alignnone" title="Wait, forgot to escape a space.  Wheeeeee[taptaptap]eeeeee." src="http://imgs.xkcd.com/comics/regular_expressions.png" alt="I know regular expressions" width="600" height="607" /></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=28&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/03/08/regular-expressions-email-url-parse-assignment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>

		<media:content url="http://imgs.xkcd.com/comics/regular_expressions.png" medium="image">
			<media:title type="html">Wait, forgot to escape a space.  Wheeeeee[taptaptap]eeeeee.</media:title>
		</media:content>
	</item>
		<item>
		<title>Microsoft SQL Service Broker</title>
		<link>http://magp.ie/2010/03/01/microsoft-sql-service-broker/</link>
		<comments>http://magp.ie/2010/03/01/microsoft-sql-service-broker/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 20:59:48 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Guides]]></category>
		<category><![CDATA[Microsoft SQL Server]]></category>
		<category><![CDATA[Service Broker]]></category>

		<guid isPermaLink="false">http://blogalhost.wordpress.com/?p=77</guid>
		<description><![CDATA[<strong>What is Microsofts SQL service broker?</strong>
Its a message queuing platform on Microsofts SQL Server. It allows you to queue up jobs for the database to deal with asynchronously. 

<strong>Why use it?</strong> 
I'm no DBA, but in my case, I was working with a database server that was at full tilt and there was work that it could be handle asynchronously to spread the load. In other words, there was data that needed processing but it did not need to be handled immediately, like data for some reports, that could be placed on a queue to be processed by the database server in it's own good time. <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=77&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p><strong>What is Microsoft&#8217;s SQL service broker?</strong><br />
Its a message queuing platform on Microsoft&#8217;s SQL Server. It allows you to queue up jobs for the database to deal with asynchronously. </p>
<p><strong>Why use it?</strong><br />
I&#8217;m no DBA, but in my case, I was working with a database server that was at full tilt and there was work that it could be handle asynchronously to spread the load. So there was data that needed processing but it did not need to be handled immediately, like data for some reports. This data could be placed on a queue to be processed by the database server in it&#8217;s own good time, evening out the demands on the server.</p>
<p><strong>How does it work?</strong><br />
Well its pretty straightforward yet it looks a bit ridiculous written down. I think this because as a platform it can handle a lot of data messaging scenario&#8217;s and as such the syntax and examples usually given are quite generic.</p>
<p>Here&#8217;s the official <a href="http://msdn.microsoft.com/en-us/library/ms166043%28SQL.90%29.aspx" target="_blank">guide</a>, happy mining through all that!</p>
<p>You can find better ones <a href="http://www.developer.com/article.php/3640771" target="_blank">here</a> and <a href="http://www.codeproject.com/KB/database/IntroServiceBroker.aspx" target="_blank">here</a>.</p>
<p>Now for my explanation&#8230;<span id="more-77"></span><br />
<i>( Warning: This is as <b>I</b> remember it working  2 years ago soooo I may be wrong! ).</i></p>
<p>There is no getting away from the terminology of the parts that make up the service broker. You have to have a gist of them to understand how it all works&#8230; again they make more sense (to me) with working with the service broker than any reading about it but anyways&#8230; here is the explanation from one of the guides above, but with my additions where I think its a little generic or jargony.</p>
<p>A <strong>Message</strong> is a piece of information exchanged between applications that use Service Broker. A message can optionally be validated to match a particular XML schema.<br />
<i>The data you are going to process and it can be formatted in XML for easier parsing.</i></p>
<p>A <strong>Conversation</strong> is a reliable, long-running, asynchronous exchange of messages.<br />
<i>Simple enough&#8230;</i></p>
<p>A <strong>Dialog</strong> is a conversation between two services. All Service Broker conversations are dialogs.<br />
<i>The exchange of your data from one table to another.</i></p>
<p>The <strong>Initiator</strong> is the participant that begins a dialog.<br />
<i>The stored procedure that initially places data in one queue to be sent to another to get processed.</i></p>
<p>The <strong>Target</strong> is the participant that accepts the dialog begun by the initiator.<br />
<i>The stored procedure that takes the data off the receiving queue to process it.</i></p>
<p>A <strong>Conversation Group</strong> is a group of related conversations. Every conversation belongs to exactly one conversation group.<br />
<i>Never had much dealings with this&#8230;</i></p>
<p>A <strong>Contract</strong> is an agreement between two services about the message types allowed in a conversation.<br />
<i>Pretty sure this just ties you to what message you are going to use&#8230;</i></p>
<p>A <strong>Queue</strong> stores the messages for a particular service.<br />
<i>Just a table for storing your message payload</i></p>
<p>A <strong>Service</strong> is a particular business task that can send and receive messages.<br />
<i>A stored procedure to manage and monitor the queues.</i></p>
<p>So let me give a brief explanation of where we were and what we wanted to do. We used stored procedures for all our data handling, we believed it to be best practice. We later found out its a nightmare to scale but that&#8217;s another post.. maybe.<br />
Anyways, the front end of our application would call these stored procedures to process some data, either writing to or reading from the database. Sometimes, the time it took to process exceeded what the front end demanded. So we decided that we could place some of this data on a queue to be processed asynchronously&#8230; enter the service broker.</p>
<p>Again I think its important to say that I am no DBA and there may be a thousand other uses and implementations for the service broker, hence the generic terminology I guess.. but here is what I did&#8230;</p>
<p><strong>Our service broker implementation:</strong><br />
First off you need to create the parts that make up the service broker. Just use the following code to get started. Here, you will create 2 queues, a queue for sending data and one for receiving messages. You will then create 2 services to manage these queues and lastly a message type that requires valid XML and a contract so the 2 services will now what message type to expect.</p>
<pre class="brush: plain;">
CREATE QUEUE receiving_queue
CREATE QUEUE sending_queue
CREATE Service sending_service ON QUEUE sending_queue
CREATE Service receiving_service ON QUEUE receiving_queue
CREATE MESSAGE TYPE my_message VALIDATION = WELL_FORMED_XML;
CREATE CONTRACT my_contract (my_message SENT BY ANY );
</pre>
<p>There are 2 stored procedures needed to handle placing the message on the sending queue (q_handler) and one to handle taking the message off the queue and process the data what ever way you need to (q_receiver).</p>
<p>I used a table SessionConversations to recycle the conversations used to exchange the messages from one queue to another. This is probably not always necessary but it is <a href="http://rusanu.com/2007/04/25/reusing-conversations/" target="_blank">recommended</a> to significantly improve performance.</p>
<pre class="brush: plain;">
-- This table associates the current connection (@@SPID)
-- with a conversation. The association key also
-- contains the conversation parameters:
-- from service, to service, contract used
--
CREATE TABLE [SessionConversations] (
	SPID INT NOT NULL,
	FromService SYSNAME NOT NULL,
	ToService SYSNAME NOT NULL,
	OnContract SYSNAME NOT NULL,
	Handle UNIQUEIDENTIFIER NOT NULL,
	PRIMARY KEY (SPID, FromService, ToService, OnContract),
	UNIQUE (Handle));
GO
</pre>
<p>A typical stored procedure to place data onto the sending queue usually uses this table to get a process to handle the message, but things get tricky when you want to do this.<br />
<b>Why?</b>&#8230; well there are a few issues described in admirable detail <a href="http://rusanu.com/2007/05/03/recycling-conversations/" target="_blank">here</a>, but invalid XML/ poisoned message were my main problem.<br />
The way this is usually handled is you try a number of times, if it fails then raise an error&#8230; well this was not enough for me as we could not risk the queue being down at any time, so the error, all errors, had to be handled in some manner.</p>
<p>I came up with a solution of using a blacklist table. If I trapped an error when trying to process the message (in the receiving stored procedure), I inserted this conversation onto this blacklist table. Then in the sending procedure, I check that the conversation handle is not on the blacklist, if it is I end it cleanly.<br />
The downside of this solution, is the message that caused the error does not get handled automatically, however I have the message in the blacklist so I can manually deal with this in my own good time.<br />
I also used an alert on this table to warn me (by email) when a message has been blacklisted. This worked really well for me, as poisoned messages were rare but always handled.</p>
<p>The stored procedures are pretty self explanatory&#8230;</p>
<h4>Sending Procedure</h4>
<pre class="brush: plain;">
-- SEND procedure. Will lookup to reuse an existing conversation
-- or start a new in case no conversation exists or the conversation
-- cannot be used
--
CREATE PROCEDURE [dbo].[q_handler] (
      @fromService SYSNAME,
      @toService SYSNAME,
      @onContract SYSNAME,
      @messageType SYSNAME,
      @messageBody XML)
AS
BEGIN
      SET NOCOUNT ON;
      DECLARE @handle UNIQUEIDENTIFIER;
      DECLARE @old_handle UNIQUEIDENTIFIER
      DECLARE @counter INT;
      DECLARE @error INT;
      DECLARE @state nvarchar(10);		

      SELECT @counter = 1;

      --BEGIN TRANSACTION XACT_q_Handler;
      -- Will need a loop to retry in case the conversation is
      -- in a state that does not allow transmission

      WHILE (1=1)
      BEGIN
            -- Seek an eligible conversation in [SessionConversations]

            SELECT @handle = Handle FROM [SessionConversations]  WHERE SPID = @@SPID AND FromService = @fromService AND ToService = @toService AND OnContract = @OnContract

			IF @handle IS NOT NULL
			BEGIN
				PRINT N'CHECK BLACKLIST';
				IF (EXISTS(SELECT count(tid) FROM brokerError WHERE handle = @handle))
				BEGIN
					SET @old_handle = @handle

					PRINT N'IN BLACKLIST SO END CONVERSATION';
					END CONVERSATION @handle

					PRINT N'BEGIN NEW DIALOG CONVERSATION';
					-- Need to start a new conversation for the current @@spid
					--
					BEGIN DIALOG CONVERSATION @handle FROM SERVICE @fromService TO SERVICE @toService ON CONTRACT @onContract WITH ENCRYPTION = OFF;
					-- Set an one hour timer on the conversation
					BEGIN CONVERSATION TIMER (@handle) TIMEOUT = 3600;

					UPDATE [SessionConversations]
					SET Handle = @handle
					WHERE handle = @old_handle AND SPID = @@SPID AND FromService = @fromService AND ToService = @toService AND OnContract = @onContract 

					PRINT N'End Dialog BL';
				END
				ELSE
				BEGIN
					PRINT N'CHECK HANDLE STATE';
					SET @state = (Select [state] FROM sys.conversation_endpoints WHERE conversation_handle = @handle)
					IF @state &lt;&gt; 'CO'
					BEGIN
						SET @old_handle = @handle

						PRINT N'HANDLE STATE IN ERROR!';
						end conversation @handle
						PRINT N'BEGIN NEW DIALOG CONVERSATION';
						-- Need to start a new conversation for the current @@spid
						--
						BEGIN DIALOG CONVERSATION @handle FROM SERVICE @fromService TO SERVICE @toService ON CONTRACT @onContract WITH ENCRYPTION = OFF;
						-- Set an one hour timer on the conversation
						BEGIN CONVERSATION TIMER (@handle) TIMEOUT = 3600;

						UPDATE [SessionConversations]
						SET Handle = @handle
						WHERE handle = @old_handle AND SPID = @@SPID AND FromService = @fromService AND ToService = @toService AND OnContract = @onContract 

						PRINT N'End Dialog CS';
					END
				END
			END
			ELSE
            BEGIN
				PRINT N'BEGIN DIALOG CONVERSATION';
				-- Need to start a new conversation for the current @@spid
				--
				BEGIN DIALOG CONVERSATION @handle FROM SERVICE @fromService TO SERVICE @toService ON CONTRACT @onContract WITH ENCRYPTION = OFF;
				-- Set an one hour timer on the conversation
				BEGIN CONVERSATION TIMER (@handle) TIMEOUT = 3600;

				INSERT INTO [SessionConversations]
					(SPID, FromService, ToService, OnContract, Handle)
					VALUES
					(@@SPID, @fromService, @toService, @onContract, @handle);

				PRINT N'End Dialog';
            END;
            -- Attempt to SEND on the associated conversation
            --
			PRINT N'SEND ON CONVERSATION';
            SEND ON CONVERSATION @handle
                  MESSAGE TYPE @messageType
                  (@messageBody)

            SELECT @error = @@ERROR

            IF @error = 0
            BEGIN
			      PRINT N'Successful send';
                  -- Successful send, just exit the loop
                  --
                  BREAK;
            END

			PRINT N'Error Found';
            SELECT @counter = @counter+1;
            IF @counter &gt; 10
            BEGIN
                  -- We failed 10 times in a  row, something must be broken
                  --
			      PRINT N'Failed to SEND on a conversation for more than 10 times. Error %i.';
                  RAISERROR (N'Failed to SEND on a conversation for more than 10 times. Error %i.', 16, 1, @error) WITH LOG;
            BREAK;
            END

            -- Delete the associated conversation from the table and try again

			PRINT N'DELETE HANDLE';
            DELETE FROM [SessionConversations]
            WHERE Handle = @handle;
            SELECT @handle = NULL;
      END
END
</pre>
<h4>Receiving Procedure</h4>
<pre class="brush: plain;">
CREATE PROCEDURE [dbo].[q_receiver]

AS
BEGIN

DECLARE @pID int
DECLARE @error int, @message nvarchar(max)

WHILE (1=1)
BEGIN TRY
		DECLARE @h UNIQUEIDENTIFIER
		DECLARE @msgBody XML
		DECLARE @messageTypeName sysname

		BEGIN TRANSACTION

		WAITFOR(RECEIVE TOP(1) @h = conversation_handle, @messageTypeName = message_type_name, @msgBody = message_body FROM pdReceivingQueue),TIMEOUT 60000;

		IF(@@rowcount = 0)
			BEGIN
			ROLLBACK TRANSACTION
			BREAK;
		END

		IF N'pdMessage' = @messageTypeName
		BEGIN
			PRINT N'pdMessage';

			SET @pID = @msgBody.value('(/pdMessage/pID)[1]', 'int');

			IF (@pID=1)
			BEGIN
				DECLARE @rID int
				DECLARE @fID int
				DECLARE @responseXML XML
				SET @rID = @msgBody.value('(/pdMessage/rID)[1]', 'int');
				SET @fID = @msgBody.value('(/pdMessage/fID)[1]','int');
				SET @responseXML = @msgBody.query('(/pdMessage/ResponseXML/answers)[1]');

                                PRINT N'Call Stored Procedure to process data';
				EXEC rLoad @rID, @fID, @responseXML

			END
			ELSE IF (@pID=2)
			BEGIN
				DECLARE @poll_id int
				DECLARE @user_ip bigint
				DECLARE @poll_type bit
				DECLARE @answer nvarchar(500)
				DECLARE @other_id int
				SET @poll_id = @msgBody.value('(/pdMessage/poll_id)[1]', 'int');
				SET @other_id = @msgBody.value('(/pdMessage/other_id)[1]', 'int');
				SET @user_ip = @msgBody.value('(/pdMessage/user_ip)[1]', 'bigint');
				SET @poll_type = @msgBody.value('(/pdMessage/poll_type)[1]','bit');
				SET @answer = @msgBody.value('(/pdMessage/answer)[1]','nvarchar(500)');

                                PRINT N'Call Stored Procedure to process data';
				EXEC VA_register  @poll_id, @user_ip, @poll_type, @answer, @other_id

			END
		END
		ELSE IF N'http://schemas.microsoft.com/SQL/ServiceBroker/DialogTimer' = @messageTypeName
			BEGIN
			PRINT N'EndDialog';
			END CONVERSATION @h;
		END
		ELSE IF N'http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog' = @messageTypeName
			BEGIN
			PRINT N'EndDialog';
			END CONVERSATION @h;
		END
		ELSE IF N'http://schemas.microsoft.com/SQL/ServiceBroker/Error' = @messageTypeName
		BEGIN
			PRINT N'Error';
			-- Log the received error into ERRORLOG and system Event Log (eventvwr.exe)
			DECLARE @h_string NVARCHAR(100);
			SELECT @h_string = CAST(@h AS NVARCHAR(100)), @message = CAST(@msgBody AS NVARCHAR(max));
			RAISERROR (N'Conversation %s was ended with error %s', 10, 1, @h_string, @message);-- WITH LOG;
			END CONVERSATION @h;
		END
		ELSE
		BEGIN
			PRINT N'Unable to process message.';
			END CONVERSATION @h WITH ERROR = 127 DESCRIPTION = N'Unable to process message.' ;
		END

	COMMIT TRANSACTION;
END TRY
BEGIN CATCH

	-- Test XACT_STATE for 0, 1, or -1.
	-- If 1, the transaction is committable.
	-- If -1, the transaction is uncommittable and should be rolled back.

	-- Test whether the transaction is uncommittable.
	IF (XACT_STATE()) = -1
	BEGIN
		ROLLBACK TRANSACTION --UndoReceive
		-- take corrective actions

		BEGIN TRANSACTION;
			RECEIVE TOP(1) @msgBody = message_body
			FROM pdReceivingQueue
			where conversation_handle = @h

			IF(@@rowcount = 0)
			BEGIN
				ROLLBACK TRANSACTION
			END
			ELSE
			BEGIN
				SELECT @error = ERROR_NUMBER(), @message = ERROR_MESSAGE();

				IF @error = 1205 --DEADLOCK
				BEGIN
					ROLLBACK TRANSACTION
				END
				ELSE
				BEGIN
					INSERT INTO [dbo].[brokerError] ([errorID],[errorContent],[posionedXML],[handle]) values (ISNULL(@error,'0'),ISNULL(@message,'No error message found!'),@msgBody,@h)
					COMMIT TRANSACTION
				END
			end
	end

	-- Test wether the transaction is active and valid.
	IF (XACT_STATE()) = 1
	BEGIN
		SELECT @error = ERROR_NUMBER(), @message = ERROR_MESSAGE();

		IF @error = 1205 --DEADLOCK
		BEGIN
			ROLLBACK TRANSACTION
		END
		ELSE
		BEGIN
			end conversation @h with error = @error description = @message
			INSERT INTO [dbo].[brokerError] ([errorID],[errorContent],[posionedXML],[handle]) values (ISNULL(@error,'0'),ISNULL(@message,'No error message found!'),@msgBody,@h)
			COMMIT TRANSACTION
		END
	END

END CATCH;
END
</pre>
<p>You need to now set up activation on the queue, so this basically tells the service that when you detect a message on the , what stored procedure you call to process it. There is room here for optimization with the number of queue readers, more <a href="http://www.sqlmag.com/article/performance/managing-service-broker-conversations/2.aspx" target="_blank">here</a>.</p>
<pre class="brush: plain;">
ALTER QUEUE sending_queue WITH STATUS=ON, ACTIVATION (
      STATUS = ON,
      MAX_QUEUE_READERS = 2,
      PROCEDURE_NAME = q_receiver,
      EXECUTE AS OWNER
);
</pre>
<p>You should have a functional broker messaging system now but what happens if its not working. Well this is my only crib about the service broker platform, I found it difficult to pin down why the broker was not working. One thing I vividly remember and it had a touch of voodoo about it, was if I made a change to the stored procedure that is called by the receiving stored procedure, I had to restart the activation on the queue again&#8230; never found out why!!</p>
<p>Here are a bunch of selects to help debug your broker.</p>
<pre class="brush: plain;">
SELECT * FROM sys.dm_broker_forwarded_messages
SELECT * FROM sys.dm_broker_connections
SELECT * FROM sys.dm_broker_activated_tasks
SELECT * FROM sys.dm_broker_queue_monitors
SELECT * FROM sys.service_broker_endpoints
SELECT * FROM sys.service_contract_message_usages
SELECT * FROM sys.service_contract_usages
SELECT * FROM sys.service_message_types
SELECT * FROM sys.service_queue_usages
SELECT * FROM sys.service_queues
SELECT * FROM sys.services
</pre>
<p>But I mostly found what I wanted in the error logs in SQL server.</p>
<p><strong>HANDY TIP:</strong> Enable Service Broker on you SQL Server!<br />
Now I know that sounds stupid but hear me out. As a platform, the service broker was great for me but it is a pain in the arse to debug. I worked with this over a year and a half ago, I still remember the pain it took to find the most simple of things&#8230; like the broker is not working because you never enabled it in the first place!.<br />
Here’s a <a href="http://www.geekzilla.co.uk/View8F3CFE18-774B-4ECB-9CBF-A6326EE8A86B.htm" target="_blank">guide</a> to do it… but one thing it fails to mention as do so many of them, you will get an error if you just try to alter the database without first killing all processes active on the database… yes that’s right, you will need to disable SQL server agent and take the database temporarily offline!.. yuck!</p>
<p>To conclude, I found this platform reliable, pretty straightforward to set up and I would recommend it if you have a situation of limited resources and data that can be handled asynchronously.</p>
<p>Feel free to correct my failing memory!.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/77/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/77/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/77/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=77&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/03/01/microsoft-sql-service-broker/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>
	</item>
		<item>
		<title>Odd or Even Number</title>
		<link>http://magp.ie/2010/02/19/php-odd-or-even-number/</link>
		<comments>http://magp.ie/2010/02/19/php-odd-or-even-number/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 22:45:18 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://magp.ie/?p=109</guid>
		<description><![CDATA[I love gems like this. I come across them from time to time but they never stick&#8230; then I do a search to find them again. Anyway a simple way to determine if a number is odd or even, use the following code. function is_odd( $number ) { return $number &#38; 1; } Quick explanation <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=109&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>I love gems like <a href="http://www.php-scripts.com/20051104/57/" target="_blank">this</a>. I come across them from time to time but they never stick&#8230; then I do a search to find them again.</p>
<p>Anyway a simple way to determine if a number is odd or even, use the following code.</p>
<pre class="brush: plain;">
function is_odd( $number ) {
    return $number &amp; 1;
}
</pre>
<p><strong>Quick explanation</strong><br />
<strong>&amp;</strong> is a binary <strong>AND</strong>.</p>
<p>If you have a binary value, and you <strong>AND</strong> with another binary value, then the result will be the bitwise <strong>AND</strong> of the two.</p>
<p>Binary values are a series of bits or 1&#8242;s and 0&#8242;s. However we are only concerned with the rightmost one ( the least significant bit ) as when a binary value ends with a 1, it is odd&#8230; when it ends with a 0 it is even.</p>
<p>Now, if I pass that function say the number 13, the binary value will look like <em>1101</em>.<br />
When you <strong>AND</strong> with a 1, or binary value <em>0001</em>, it looks like this&#8230;</p>
<p>1101 &amp; 0001 = 0001</p>
<p>We look to the least significant bit, which is a 1, which means the number is odd.</p>
<p>A simple explanation of binary can be found <a href="http://www.codemastershawn.com/library/tutorial/hex.bin.numbers.php" target="_blank">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/109/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/109/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/109/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=109&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/02/19/php-odd-or-even-number/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>
	</item>
		<item>
		<title>Format XML with TextWrangler</title>
		<link>http://magp.ie/2010/02/15/format-xml-with-textwrangler/</link>
		<comments>http://magp.ie/2010/02/15/format-xml-with-textwrangler/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 20:47:06 +0000</pubDate>
		<dc:creator>Eoin</dc:creator>
				<category><![CDATA[Shortcuts]]></category>
		<category><![CDATA[format xml]]></category>
		<category><![CDATA[textwrangler]]></category>
		<category><![CDATA[UNIX Script]]></category>

		<guid isPermaLink="false">http://blogalhost.wordpress.com/?p=97</guid>
		<description><![CDATA[My text editor of choice on the Mac is TextWrangler. It&#8217;s lightweight and it has pretty much all you need from a text editor. In particular, I like that I can SFTP into my development server. One issue that bugged me lately was when I opened an unindented, unformatted XML file. Basically, it looked a <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=97&subd=blogalhost&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<p>My text editor of choice on the Mac is <a href="http://www.barebones.com/products/TextWrangler/" target="_blank">TextWrangler</a>. It&#8217;s lightweight and it has pretty much all you need from a text editor. In particular, I like that I can SFTP into my development server.</p>
<p>One issue that bugged me lately was when I opened an <em>unindented</em>, <em>unformatted</em> XML file. Basically, it looked a mess and there was no way to tidy the file up so that I could read it easily.</p>
<p>However, I found a simple way to do this today&#8230; <span id="more-97"></span>thanks to <a href="http://groups.google.com/group/textwrangler/browse_thread/thread/ea4d509c9266a6b1" target="_blank">this</a> and <a href="http://www.entropy.ch/blog/Developer/2008/04/23/XML-Pretty-Printing-in-BBEdit-and-vi-With-xmllint.html" target="_blank">this</a>.</p>
<p><strong>Simple guide</strong><br />
We want to add a UNIX script to TextWrangler so it can format an XML file&#8230; to do this, do this&#8230;</p>
<ul>
<li>Open TextWrangler and open a new text file.</li>
<li>Copy and paste the code below into this file.</li>
<pre class="brush: plain;">
#!/bin/sh
xmllint --c14n &quot;$*&quot; | XMLLINT_INDENT=$'\t' xmllint --format -
</pre>
<li>Save the file, something like <strong>Tidy XML.sh</strong>, in the Filters folder.</li>
<li>You can find the filters folder by going to the <em>#! menu</em> and go to the <em>Unix Filters</em> sub-menu, and select the <em>Open Filters Folder</em>, like below.
<ul><img class="alignnone size-full wp-image-98" title="Scripts menu" src="http://blogalhost.files.wordpress.com/2010/02/picture-7.png?w=407&#038;h=215" alt="" width="407" height="215" /></p>
<li>Now anytime you want to format an XML file, just go to this menu and select the <strong>Tidy XML.sh</strong> script and BOOM, neat tidy XML.</li>
<p><img class="alignnone size-full wp-image-99" title="Select Script" src="http://blogalhost.files.wordpress.com/2010/02/picture-8.png?w=227&#038;h=183" alt="" width="227" height="183" /></ul>
</li>
</ul>
<p>This is an interesting facility to extend an already great text editor, and I will be looking into more cool scripts that can hopefully lessen my daily annoyances.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/blogalhost.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/blogalhost.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/blogalhost.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/blogalhost.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/blogalhost.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/blogalhost.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/blogalhost.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/blogalhost.wordpress.com/97/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/blogalhost.wordpress.com/97/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/blogalhost.wordpress.com/97/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=magp.ie&blog=11708208&post=97&subd=blogalhost&ref=&feed=1" />]]></content:encoded>
			<wfw:commentRss>http://magp.ie/2010/02/15/format-xml-with-textwrangler/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<georss:point>53.734750 -8.989992</georss:point>
		<geo:lat>53.734750</geo:lat>
		<geo:long>-8.989992</geo:long>
		<media:content url="http://1.gravatar.com/avatar/72dd449e5e79e046c1c09ed8712b525a?s=96&#38;d=wavatar&#38;r=PG" medium="image">
			<media:title type="html">eoigal</media:title>
		</media:content>

		<media:content url="http://blogalhost.files.wordpress.com/2010/02/picture-7.png" medium="image">
			<media:title type="html">Scripts menu</media:title>
		</media:content>

		<media:content url="http://blogalhost.files.wordpress.com/2010/02/picture-8.png" medium="image">
			<media:title type="html">Select Script</media:title>
		</media:content>
	</item>
	</channel>
</rss>