Monthly Archives: February 2006

Reading unmanaged structs with .NET

Last week i’ve spend a lot of time studying System::Runtime::InteropServices. It took me a while to figure out how i could read unmanaged structs with .NET System::IO. Here is a bit of sample code (Should be obvious enough to write a template or generic class for all sorts of structs, just like i did at the office)

typedef struct {
  char name[9];
  int name;
  double sterr;
} TEST;

FileStream ^f = gcnew FileStream("C:\\TEST.DAT", FileMode::Open, FileAccess::ReadWrite);
BinaryReader ^r = gcnew BinaryReader(f);
array<byte> ^buf = r->ReadBytes(sizeof(TEST));
TEST test;
Marshal::Copy(buf, 0, (IntPtr) &test, sizeof(TEST));

Access a control by name

I know a mathematician that can do magic with stats. That’s also the reason why he works at Eurostat. He’s automating a lot of his work by programming in Visual Basic for Applications. He asked me if i wanted to look at his code because he had the feeling there was a smell. Here are a couple lines:

With SomeForm
 .txtJanvier60.Value = vaData1(1, 2)
 .txtFevrier60.Value = vaData1(1, 3)
 .txtJanvier61.Value = vaData1(1, 2)
 .txtFevrier61.Value = vaData1(1, 3)
 ...
 .txtJanvier70.Value = vaData1(1, 2)
 .txtFevrier70.Value = vaData1(1, 3)
End With

It took me 5 minutes to search the web and change his code as following:

Dim months(1) as String
months(0) = "Janvier"
months(1) = "Fevrier"

With SomeForm
 For i = 60 to 70
  For j = 0 to UBound(months)
   .Controls("txt" & months(j) & CStr(i)).Value = vaData1(1, j + 2)
  Next j
 Next i
End With

Removing selected items from a ListBox

Today i was experimenting with a couple of windows controls. For some reason i wasn’t able to remove the selected items from a ListBox. Here is the code that didn’t work:

For Each index As Integer = ListBox1.SelectedIndices
  ListBox2.Items.Add(ListBox1.Items(index))
  ListBox1.Items.Remove(index)
End For

The problem is that when you remove an item from the collection the indices change. Here is a possible solution:

Dim index As Integer = ListBox1.SelectedIndex
While index <> -1
  ListBox2.Items.Add(ListBox1.Items(index))
  ListBox1.Items.Remove(index)
  index = ListBox1.SelectedIndex
End While

Pagination for all

Suppose you have a a large collection of items and you want to display them. Users don’t want to see 5000 items at once. They only want to see a couple of items and have the possibility to look at the next (or previous) couple of items. The solution for this problem is usually named pagination. You can compare this technique with paging. Most people seem to come up with their own (My)SQL specific implementation. Here are a couple of examples how you can use mine:

<?php
require('http://www.timvw.be/wp-content/code/php/pagination.txt');

// step 1 - create pageable data: array example
$data = array(
	array('name' => 'Jameson', 'surname' => 'Jenna'),
	array('name' => 'Banks', 'surname' => 'Briana'),
	array('name' => 'Giovanni', 'surname' => 'Aria'),
	array('name' => 'Rush', 'surname' => 'Daniella'),
	array('name' => 'Flowers', 'surname' => 'April')
);
$pageabledata = new PageableArray($data);

// step 2 - create the pager
$pager = new Pager($pageabledata);

// step 3 - create the pagewriter
$pagewriter = new PageWriter($pager);

// step 4 - create the paginator
$paginator = new Paginator($pagewriter);

// step 5 - run the paginators
$paginator->run();

// setp 6 - output
$paginator->output();
?>

I have also provided code for situations where you want to paginate File contents, MySQL or ADODB resultsets. In that case the code for step 1 would look like:

<?php
// file example
$pageabledata = new PageableFile("/home/users/timvw/.bash_history");

// mysql example
$dblink = mysql_connect('localhost', 'username', 'password');
mysql_select_db('dbname', $dblink);
$pageabledata = new PageableMySQL('SELECT * FROM wp_posts ORDER BY 1', $dblink);

// adodb example
require('adodb/adodb.inc.php');
$db = NewADOConnection('mysql://username:password@localhost/dbname');
$pageabledata = new PageableADODB('SELECT * FROM wp_posts ORDER BY 1', $db);
?>

You will probably want to modify the code so that it generates the html you want. Here is how an example of such a change:

<?php
/**
 * This class represents a PageJumpWriter
 */
class PageJumpWriter extends PageWriter {
        /**
         * Default constructor
         * @param $pager the pager
         * @param $base_url the baseurl for the pager
         * @param $page_param the name of the page parameter
	 * @param $items_per_page_param the name of the items per page parameter
	 * @param $params additional url parameters in the form of a name=>value array
         */
	function PageJumpWriter(&$pager, $base_url = '', $page_param = 'page', $items_per_page_param = 'items_per_page', $params = null) {
		parent::PageWriter($pager, $base_url, $page_param, $items_per_page_param, $params);
	}

	/**
	 * Generate html for the items pager
	 * @see PageWriter#makeItemsPager
	 */
	function makeItemsPager() {
                $current_page = $this->pager->getCurrentPage();
                $last_page = $this->pager->getLastPage();
                $prev_page = $current_page - 1;
                $next_page = $current_page + 1;
		$items_per_page = $this->pager->getItemsPerPage();
                $html = "<div class='itemspager'>";
		$html .= "<form method='GET' action='{$this->base_url}' onChange='this.submit()'>";
		$html .= "<select name='{$this->page_param}'>";
		for ($i = 1; $i <= $last_page; ++$i) {
			if ($i != $current_page) {
				$html .= "<option value='{$i}'>Page {$i} of {$last_page}</option>";
			} else {
				$html .= "<option value='{$i}' selected>Page {$i} of {$last_page}</option>";
			}
		}
		$html .= "</select>";
		$html .= "<input type='hidden' name='{$this->items_per_page_param}' value='{$items_per_page}'/>";
		foreach($this->params as $name => $value) {
			$html .= "<input type='hidden' name='{$name}' value='{$value}'/>";
		}
		$html .= "<input type='submit' value='Go'/>";
		$html .= "</form>";
                $html .= "</div>";
                return $html;
	}
}
?>

If you want to use this customized html generator you simple change the code in step 3 as following:

<?php
$pagewriter2 = new PageJumpWriter($pager2);
?>

The problem with most of these paginators is that you can only use one per page. This is a serious PITA. It’s your lucky day, here is an example of two paginators that can run separately in the same page:

<?php
// step 1 - create the pageable data
$dblink = mysql_connect('localhost', 'username', 'password');
mysql_select_db('dbname', $dblink);
$pageabledata = new PageableMySQL('SELECT * FROM wp_posts ORDER BY 1', $dblink);
$pageabledata2 = new PageableFile('/var/www/somefile.txt');

// step 2 - create the pagers
$pager = new Pager($pageabledata);
$pager2 = new Pager($pageabledata2);

// step 3 - create the pagewriters
$pagewriter = new PageWriter($pager);
$pagewriter2 = new PageJumpWriter($pager2, '', 'page2', 'items_per_page2');

// step 4 - create the paginators
$paginator = new Paginator($pagewriter);
$paginator2 = new Paginator($pagewriter2);

// step 5 - run the paginators
$paginator->run();
$paginator2->run();

// add extra url parameters for pagewriters
$pagewriter->setParameters(array(
	$pagewriter2->getPageParam() => $pagewriter2->pager->getCurrentPage(),
	$pagewriter2->getItemsPerPageParam() => $pagewriter2->pager->getItemsPerPage()
));

$pagewriter2->setParameters(array(
	$pagewriter->getPageParam() => $pagewriter->pager->getCurrentPage(),
	$pagewriter->getItemsPerPageParam() => $pagewriter->pager->getItemsPerPage()
));

// step 6 - output
$paginator->output();
$paginator2->output();
?>

Preparing for my internship

Only two more days before my internship starts. I’m a bit nervous and excited to dive into this adventure. Today i decided to fresh my knowledge of (MS)-C++ a bit up. I’ve read a tutorial on function pointers and naming conventions. A couple of weeks ago i already had a look at pointers to member functions.

#include <iostream>
using namespace std;

void customcallback() {
        cout << "running custom callback" << endl;
}

typedef int (*method)(int, int);

int sum(int a, int b) {
        return a + b;
}

method dosum() {
        return &sum;
}

int main() {
        void (*plugin)() = NULL;
        plugin = &customcallback;
        plugin();

        method mymethod = dosum();
        cout << mymethod(10, 4) << endl;

        return 0;
}

GNU screen

Another tool that belongs to my favorites is GNU Screen. A couple of years ago i had a bad internet connection and when i was working on a remote shell i was always logged out and had to start over. I really hated that ;) Today i don’t have this problem anymore, but i like to keep Irssi (an IRC user-agent) running, even when i’m not logged in. TIP Using Screen is an article that gives a couple of other reasons to use it and explains how it works. The default settings suck if you also use GNU Emacs. So i had to figure out a couple of keypresses. With “cat -v” i could easily see what those keypresses were. Here is my .screenrc file:

##############################################
# Author: Tim Van Wassenhove
# Update: 2006-02-06 03:02
##############################################
startup_message off
escape ^Oo

bind i screen -t 'irssi'        3 irssi
bind v screen -t 'vim'          4 vim
bind m screen -t 'mutt'         5 mutt
bind b screen -t 'slrn belnet'  6 slrn -h news.belnet.be
bind r screen -t 'slrn php'     7 slrn -h news.php.net
bind e screen -t 'elinks'       8 elinks http://www.google.com

GNU sort

I already wrote that GNU Core Utilities (GNU Textutils) have become my favorite text processing tools. Today i wanted to sort a couple of lines using the last three numbers of each line. Here is an example:

c:/data/backup/JA-229
c:/data/backup/JA-221
c:/data/backup/JA-233
c:/data/backup/NE-046
c:/data/backup/NE-049
c:/data/backup/JA-217
c:/data/backup/JA-225

With the command “sort -n -t- -k2 myfile.txt” i quickly got what i needed.

Multiple joins explained

I’ll try to explain how a join on more than one table works. I’ve noticed people get confused by it. Assume we have the following tables:

  • newsitems(news_id,post_id)
  • postitems(post_id,user_id,content)
  • users(user_id,name,password)

We want to display for each newsitem the content and the author.

Our base table would be the newsitems, and then we join using the item_id. Thus the query would be:

SELECT *
FROM newsitems
INNER JOIN ON postitems USING (post_id)

This returns a “virtual table” that has looks like this result(news_id,post_id,user_id,content).

Now we still need to get the username, so we use our result table and perform a join on the users table. Thus the query would be:

SELECT *
FROM result
INNER JOIN users USING (user_id)

If we combine our first two queries, we end up with this:

SELECT *
FROM newsitems
INNER JOIN postitems USING (post_id)
INNER JOIN users USING (user_id)

Conclusion: Look at A*B*C as (A*B)*C to easily understand multiple joins