Saturday, August 29, 2009

Perl Unicode

Recently I was struggling with the unicode in Perl, there are a few things I found it is tricky:

From here, there is a clear explanation on the encode/decode functions. If my perl program is a command line program which accepts cp950 arguments in a chinese windows, the arguments need to be "decoded" into Perl's internal form.

for(my $i=0; $i < scalar(@ARGV); $i++) {
$ARGV[$i] = Encode::Byte::decode("cp950", $ARGV[$i]);
}

When you send the arguments to a server that accepts UTF8, you need to send

$data =~ s/(\P{IsASCII})/sprintf('%2x;',ord($1))/eg;

After getting the server response, if it is in UTF8, you need to decode the response one more into Perl's internal form.

$response = Encode::decode_utf8($response);

So, the last step is, we need to change the Perl's internal form to cp950 for the STDOUT.

binmode STDOUT, ":cp950";

This is all from my memory if there is any mistake.

Tuesday, August 04, 2009

Processing EDI, XML, CSV and more with Smooks

Getting this headline in TSS, and remember it was used to be a tedious task to handle that in my previous company. Posting this for future reference.

http://www.theserverside.com/news/thread.tss?thread_id=55339

Monday, August 03, 2009

Windows Gadget experience

Recently I have finished a windows gadget that uses ajax to grab the data. The examples I followed were the official gadgets from Microsoft: Stocks and Feed Headlines.

As being told in several sites and books, Windows Gadget is composed of html, css and javascript. It wasn't that easy at the first glance on the stocks gadget. Drilling down the code to see how the data is parsed from the web led to an ActiveX object with an dll. I googled this and found out it is really the case: http://www.cnblogs.com/yayx/archive/2007/09/04/881879.html (a chinese webpage however). Anyway, another problem with the stocks javascript is that, it's all structured as static class way, click here for the difference on what javascript you have normally seen in the past. Additionally, the number of the code lines is horrible too, >4000 lines doesnt help, the reason is that basically the author put all the logic INCLUDING all the html creation like "tables,TDs" in the javascript instead of in the html layer.

Anyway, the very first issue was to try to put the data retrieval to something that can be easily tested. Replaced ActiveX with ajax with the helps from these pages:

http://developer.novell.com/wiki/index.php/Using_the_XMLHttpRequest_object
http://www.ibm.com/developerworks/web/library/wa-ajaxintro2/
http://www.jibbering.com/2002/4/httprequest.html

The way to link the server code with the UI code is by using the listener pattern, you just need to define the functions that you want to run into the server code listeners, once the data is retrieved OR the status message from the connection is changed, the listener functions will be triggered, and your UI will be updated.

12029 is the status code that indicates "unable to establish connection".
setTimeout() and setInterval() are the functions to constantly perform a function.
Reusing the XMLHTTP Object is described here.

Once the server communication code was ready, I was trying to code the same way as in stocks but failed with the elements positioning. On the contrary, feed headlines is a much better example to deal with. The author defined the tables in the html, defined a number of methods to trigger by following the html trigger like onmouseout, onwheelmove etc.

There is a function from the web that can transform the milliseconds to human readable date in javascript. Watch out the "var day = Math.floor(hr/60)", it should be divided by 24?!

At last, two more tricky places that wasted me few hours of debugging:
1. I have tried the gadget, and it only worked on one server, it didnt connect to other server and the XMLHttpRequest status code was zero and empty XML response. The only way to make this problem disappear was to kill the sidebar.exe process and start it over.

2. In the setting.js in the feed headlines gadget, loadSettings(); in the load() seemed to be duplicated by my eyes at the first place, after several hours of struggling why the saved settings cannot be successfully passed to the setting UI, this line was the missing piece.

Overall, the experience was great, and I am really satisfied with the results.