Simple PHP MVC

One of the much talked about patterns of the moment is the model-view-controller or model-view-presenter or any of the undoubtedly thousands of variants thereof. Here’s a deliberately really simple one to illustrate the pattern. If you can read it and understand it I hope its useful to you.

Interestingly a vague attempt at inversion of control, another design pattern which IMHO is more of a guide line, is in play here. It is done specifically to allow good component separation and useful test patterns. Hence as long as you have a class that fits the dependency obligations you can use it with the ones given here.

Now for the seriously crazy bit, the code on this page has not been tested to work. Its just here to give you some idea of what the model-view-controller pattern and how it could be implemented.

mvc.controller.php

Overview:

At the heart of each variant implementation of the model view controller pattern is the controller. A controller basically directs requests to the appropriate model or view processing functionality. In the case below it only makes the distinction between the two types and not the instances of functionality.

Some controllers combine a lot more but its not actually necessary and generally ends up making the controller very configuration and platform specific. By keeping configuration out of the controller we make it as general as it can be.

Notes:

Note that there is no exception handling here either. It is not wanted. Consider for a moment that if an exception was not caught, there would be no response to the client, which is a security requirement in many instances. However it there would be a log to trace to the point of failure because of the log entry call.

If exception handling were introduced it would compromise the generic nature of the controller as the controller would need to know what type of response to send to the client. For example if the error was thrown before the content of the request could be analysed and what data would you respond to the request with? HTML? XML? A media stream? A GIF? A JPG? The rule of thumb here is only respond if you know what language to talk in, if you don’t know the requested format you can’t even use clever configuration to determine how respond to a request.

Documented dependencies:

  • class ‘Model’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘new request for either model processing or view generation’
  • class ‘View’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘a view generated from the accumulated data in the request’

Undocumented dependencies:

  • class ‘Log’ : method ‘writestr’ : parameters ‘string to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Log’ : method ‘writereq’ : parameters ‘request to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Request’ : method ‘is_a_model_request’ : parameters ‘none’ : returns ‘true if the request is to be processed by the model’

Listing:


<?php

Log::getInstance()->writestr( "file:".__FILE__.":loaded", "debug" );

class Controller {

  private $model;

  private $view;

 /*

  * build this controller object

  */

  public function __Construct ( $model, $view ) {

    $this->model = $model;

    $this->view = $view;

  }

 /*

  * process a request

  */

  public function process_request ( $request ) {

    Log::getInstance()->writestr( 

      "class:".__CLASS__.":process_request", "debug" );

    Log::getInstance()->writereq( $request, "debug" );

   /*

    * first process the model request

    */

    $new_request = $this->model->process_request( $request );

   /*

    * if this request results in another model request

    */

    if ( $new_request->is_a_model_request( ) )

      return $this->process_request( $new_request );

   /*

    * otherwise generate view

    */ 

    return $this->view->process_request( $new_request );

  }

}

?>

mvc.model.php

Overview:

A model is responsible for the production of data for the view. Essentially it contains access points to the various methods of the underlying application called actions. In this case it simply has a list of actions that it locates and then executes the action sending the results back to the caller.

Notes:

As with the controller (see above) the model does little more than the basics leaving other classes that know what they are doing to handle the specifics of content. In line with this the model simply logs progress and fails silently.

Undocumented dependencies:

  • class ‘Log’ : method ‘writestr’ : parameters ‘string to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Log’ : method ‘writereq’ : parameters ‘request to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Actions’ : method ‘find_requested_action’ : parameters ‘request to locate action for’ : returns ‘an Action object’
  • class ‘Action’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘new request for either model processing or view generation’

Listing:


<?php

Log::getInstance()->writestr( "file:".__FILE__.":loaded", "debug" );

class Model {

  private $actions;

 /*

  * build this model object

  */

  public function __Construct ( $actions ) {

    $this->actions = $actions;

  }

 /*

  * process a request

  */

  public function process_request ( $request ) {

    Log::getInstance()->writestr( 

      "class:".__CLASS__.":process_request", "debug" );

    Log::getInstance()->writereq( $request, "debug" );

   /*

    * find the action from the list of actions

    */

    $action = $this->actions->find_requested_action( $request );

   /*

    * run the action and return the resulting request

    */

    return $action->process_request( $request );

  }

}

?>

mvc.view.php

Overview:

A view is called to format the data retrieved from the model into the format that the original client requested. Essentially it contains access points to the various view methods of the underlying application. In this case it simply has a list of views that it locates and then executes sending the results back to the caller.

Notes:

Now those sharp of eye will realise something; this looks pretty much like the model class above, and you’d be right. Apart from a a simple renaming of a few items the code is the same. In practice both the above model class and this view class would be implemented as a single class and simply configured differently. They are only provided in their separate formats here to highlight the model-view-controller form.

Undocumented dependencies:

  • class ‘Log’ : method ‘writestr’ : parameters ‘string to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Log’ : method ‘writereq’ : parameters ‘request to log’, ‘name of log level to record string at’ : returns ‘nothing’
  • class ‘Views’ : method ‘find_requested_view’ : parameters ‘request to locate view for’ : returns ‘an View object’
  • class ‘View’ : method ‘process_request’ : parameters ‘request to process’ : returns ‘the final generated view’

Listing:


<?php

Log::getInstance()->writestr( "file:".__FILE__.":loaded", "debug" );

class View {

  private $views;

 /*

  * build this view object

  */

  public function __Construct ( $views ) {

    $this->views = $views;

  }

 /*

  * process a request

  */

  public function process_request ( $request ) {

    Log::getInstance()->writestr( 

      "class:".__CLASS__.":process_request", "debug" );

    Log::getInstance()->writereq( $request, "debug" );

   /*

    * find the view from the list of views

    */

    $view = $this->views->find_requested_view( $request );

   /*

    * process the request and return the resulting view

    */

    return $view->process_request( $request );

  }

}

?>

LDAP vs RDBMS is the war over?

Perhaps the question is better put, ‘Did the war even happen?’ What war you might well ask; well when different ways of looking at potentially the same data are viewed then there are bound to be zealots on either side fanning the flames of FUD on the opposition and extolling the vitues of their chosen creed. However although both RDBMS and LDAP are commonly used to host the same data for applications there appears to be little controversy.

Mostly, I think, there is no conflict because in general LDAP is not even an option for the vast masses of application developers out there. Especially as the bulk of application development appears to be done facing the Internet. Normally hosting environments provide a choice of RDBMS or RDBMS. LDAP is just too difficult a concept, and that’s probably the first reason that it has fallen out of contention for storing the masses of organisational data out there. Yet it is probably the best candidate that I know of for holding operational control of that data.

To illustrate this conceptual difficulty lets consider the contention between software developer and database architecht perspectives. Typically the developer does not really understand the various tools that the RDBMS offers to manage data. The database expert loaths the way that developers start implementing relational contraints in code instead of applying the appropriate design concepts of foriegn keys, triggers, stored procedures etc. I’ve seen this many times. Often I’ve seen the opposite where database folk have decided to embed code into their domain. To really get this right each party needs to understand the value that the other brings to the table. But I continually read laments from either side criticising the way that this or that should really be done over here and not there.

Which brings us into LDAP. This underused gem is typically used by the development community simply as a convienient pre-built authentication tool. Even when LDAP is used a lot of information is then stored in an RDBMS that it really does not do well; or at least as well as LDAP. I’ll spare you the history of why this is so and how it came to be but the fundamental difference between the two is that RDBMS generally is a collection of flat file tables that are related by loose rules; whereas the LDAP server is a tightly coupled hierarchy of objects (called the Directory Information Tree – DIT) similar in nature to that of other concepts like XML.

LDAP servers are generally built for high speed retrieval and mass replication focussed on the enterprise, where RDBMS is a general ledger store house, and pretty primative too. The kind of data then that you should store in the LDAP directory is structural data. Like say configuration data for a telephone system or contact information for a customer relationship management (CRM) type of application. Even the configuration and preferences information of WordPress for this blog should really be stored in an LDAP server. But its not.

If you want to know if the data that you are looking at is suited to LDAP then consider.

  • Is the data dynamic or relatively static?
  • Does the data need to be distributed?
  • Can the data be used by more than one application?
  • Is the data multi-valued?
  • Can your data or application take advantage of a hierarchical relationship?
  • Do you need flexible security options?
  • Do you need single sign-on?
  • Do you need distributed or delegated administration capabilities?

If you can answer yes to some or all of these questions, then directories and directory-based applications would likely be useful to your application or project.

So why did I write this post? Basically it is a pointer into the world of LDAP for those who’ve not thought of it. A start. If you really want a better introduction go here. Have fun.


Driven to Reinvent

Its nice to have a standards based platform and in that vein C certainly has progressed a long way. But you still get the odd system that isn’t either set correctly up by default with my favorite extensions; namely all things GNU! Yes I admit to liking non-standard well coded extensions, in fact who would work without them these days except under a very specific set of requirements or academic interest. Things just would not get done so quickly without them.

So I got a Mac. Yep its sooo cool that when my 5 year old daughter walked in the room and saw it for the first time she exclaimed ‘Daddy! That’s sooo cool!’ Kind of an ego boost for someone who gave up on cool and cool things 20 years ago. However cool comes at a price, its got great development tools but I want cross platform development to run on my Linux boxen too. Long story short, it doesn’t have the standard GNU extensions so I had two choices, fart around with the environment or rewrite one or two functions myself.

So here’s the goods. Now because I don’t want people to just copy and paste my material without thinking about it (I don’t mind the copying I just like people to put in some effort and think) I’ve copied an earlier version of the functions which works for some situations but not for others. Its close tot he real deal but there are about 5 significant issues which would make it dangerous to use this code without doing something about them.

Here it is, have fun, have a play! (Note: the whole thing is under GPL 3, comments from GNU)


/*

ssize_t getdelim (char **lineptr, size_t *n, int delimiter, FILE *stream)  

This function is like getline except that the character which tells it to stop 

reading is not necessarily newline. The argument delimiter specifies the 

delimiter character; getdelim keeps reading until it sees that character (or end 

of file).

The text is stored in lineptr, including the delimiter character and a 

terminating null. Like getline, getdelim makes lineptr bigger if it isn't big 

enough.

getline is in fact implemented in terms of getdelim

*/

ssize_t getdelim( char **lineptr, size_t *n, int delimiter, FILE *stream ) 

{

	/* setup the environment */

	int c = getc( stream );

	long i = 0;

	char *a = NULL;

	/* count the characters needed for the buffer */

	while ( c != delimiter && c != EOF ) {

		c = getc( stream );

		i++;

	}

	/* test for and arrange the buffer size */

	if ( i == 0 ) 

		return -1;

	if ( fseek( stream, -i, SEEK_CUR ) ) 

		return -2;

	if ( *n < i + 1 ) {

		a = ( char * )realloc( *lineptr, i + 1 );

		if ( a == NULL )

			return -3;

		*lineptr = a;

		*n = i;

	}

	/* read the data into the buffer */

	if ( fread( *lineptr, sizeof( char ), i, stream ) != i )

		return -4;

	( *lineptr )[i] = 0;

	/* return the number of chars read */

	return i;

}

/*

ssize_t getline (char **lineptr, size_t *n, FILE *stream)

This function reads an entire line from stream, storing the text (including the 

newline and a terminating null character) in a buffer and storing the buffer 

address in *lineptr.

Before calling getline, you should place in *lineptr the address of a buffer *n 

bytes long, allocated with malloc. If this buffer is long enough to hold the 

line, getline stores the line in this buffer. Otherwise, getline makes the 

buffer bigger using realloc, storing the new buffer address back in *lineptr and 

the increased size back in *n. See Unconstrained Allocation.

If you set *lineptr to a null pointer, and *n to zero, before the call, then 

getline allocates the initial buffer for you by calling malloc.

In either case, when getline returns, *lineptr is a char * which points to the 

text of the line.

When getline is successful, it returns the number of characters read (including 

the newline, but not including the terminating null). This value enables you to 

distinguish null characters that are part of the line from the null character 

inserted as a terminator.

This function is a GNU extension, but it is the recommended way to read lines 

from a stream. The alternative standard functions are unreliable.

If an error occurs or end of file is reached without any bytes read, getline 

returns -1. 

*/

ssize_t getline (char **lineptr, size_t *n, FILE *stream)

{

	return getdelim ( lineptr, n, '\n', stream );

}

Size Matters – the Quest for the ideal MTU

One of the fundamental aspects of communication is the amount of information that can be communicated in one chunk before allowing others to communicate through the same channel; the maximum transmission unit (MTU).

In computer communications the MTU is the amount of data transportable across the lowest layer of the communication stack; Ethernet, FDDI, etc. From the base MTU each layer above in the networking stack breaks the data that it has to send into packets that will fit in the next layer down. For TCP/IP over Ethernet the base Ethernet specification includes a MTU of 1500 bytes (octets in the IETF RFC) not including the Ethernet header and the TCP/IP layers expand their default packet size from 536 and 576 bytes respectively to 1460 and 1500. Effectively the MTU sets the packet size of higher protocols in the OSI model.

Networks are often unable to transport a maximum sized packet. In which case the packets are fragmented either by the sender and receiver or some device(s) in the network in between. There are many reasons for this, for example:

  • Change in base network media i.e. Ethernet to FDDI conversion.
  • Poor line quality.
  • Protocol tunnelling consuming part of the transmission with embedded headers etc.
  • Network device capacity.
  • Data transmission streams with conflicting efficient packet size efficiencies i.e. FTP and VOIP.

Using the standard MTU dynamic shaping protocols normally gets around the these transmission problems. If a device can’t handle a delivered MTU it responds with an ICMP message that informs the sender and advertises its acceptable MTU. However it doesn’t always work and can produce various effects from black hole routing, to delayed responses and network application transmission jitter (very annoying in media streaming applications). Some of the reasons for this are hardend or unsophisticated systems that do not support dynamic MTU discovery or IPsec bridges or other tunnels improperly configured.

To remedy issues it is best to replace the networking infrastructure that is causing the issue with components that are well behaved and can support dynamic MTU. Some times however this is not possible so you have two options, configure a gateway to the device to clamp the MTU to an acceptable size (which you have already found out) or manually configure the sending devices to have an appropriate MTU for the affected route. If you have Windows devices then your best option is to use an existing or introduce a new Unix/Linux based gateway to clamp for you.

Linux (specifically Redhat/Fedora distributions) provides many facilities for the manipulation of MTU. The tools include the ‘/proc’ system components and various applications from the nettools package as well as our old friend ifconfig. So the facilities that I generally use at the start are:

  • ifconfig – to view the MTU and other network information.
  • tcpdump – to look for MTU dynamic shaping ICMP responses.
  • ethtool – to set the MTU and other network card options.
  • route – for fixed MTU setting based on route.
  • ‘/proc/sys/net/ipv4/ip_no_pmtu_disc’ – for fixing the MTU for testing.

ifconfig is the first place to start, it will tell you without any fuss what your network card is set to. A simple ifconfig on the command line will give you something that looks like this:

[root@bluetop ipv4]# ifconfig
 eth0      Link encap:Ethernet  HWaddr 00:0B:DB:19:46:4D
 inet addr:10.0.0.176  Bcast:10.0.0.255  Mask:255.255.255.0
 UP BROADCAST MULTICAST  MTU:1500  Metric:1
 RX packets:0 errors:0 dropped:0 overruns:0 frame:0
 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000
 RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
 Interrupt:10
lo        Link encap:Local Loopback
 inet addr:127.0.0.1  Mask:255.0.0.0
 inet6 addr: ::1/128 Scope:Host
 UP LOOPBACK RUNNING  MTU:16436  Metric:1
 RX packets:6178 errors:0 dropped:0 overruns:0 frame:0
 TX packets:6178 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:0
 RX bytes:309060 (301.8 KiB)  TX bytes:309060 (301.8 KiB)
wlan0     Link encap:Ethernet  HWaddr 00:11:50:FD:7B:65
 inet addr:192.168.2.98  Bcast:192.168.2.255  Mask:255.255.255.0
 inet6 addr: fe80::211:50ff:fefd:7b65/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
 RX packets:4126 errors:0 dropped:0 overruns:0 frame:0
 TX packets:2447 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000
 RX bytes:4505043 (4.2 MiB)  TX bytes:393742 (384.5 KiB)

From this you can see that I’ve three interfaces running and eth0 is not being used. However note that the MTU value of each interface is shown here. This is the MTU for the device but not the path. Note also that the MTU for a particular path may be much smaller. In Fedora this value can be set a number of ways but the two simplest are the GUI network tool, which is very simple just look at it as it doesn’t need to be discussed here discussed here, and once again ifconfig:

[root@bluetop ipv4]# ifconfig lo
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16430  Metric:1
          RX packets:6417 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6417 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:336104 (328.2 KiB)  TX bytes:336104 (328.2 KiB)
[root@bluetop ipv4]# ifconfig lo mtu 16436
[root@bluetop ipv4]# ifconfig lo
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:6417 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6417 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:336104 (328.2 KiB)  TX bytes:336104 (328.2 KiB)

In the example above the loopback device has had its MTU set to 16436 from 16430. If we echo 1 to ‘/proc/sys/net/ipv4/ip_no_pmtu_disc’ then MTU dynamic shaping will be turned off and the machine will not send data packets less than the maximum if it has data to fill it. This is some times useful when trying to simulate devices on a network that do not have dynamic MTU built in or disabled.

ip is another tool that can be used for manipulating the MTU. But instead of altering the MTU for the whole device it can be targeted to a specific network. This is especially useful when a network device is shared between different networks. This tool can do all sorts of things so its a good place to start when considering things like tunnelling and complex routing. But here we’ll stick to setting MTU’s on specific routes. For example lets say that we’ve discovered that the network 10.0.0.0 really needs to have an MTU of 1400 but its behind our default gateway and its just not going to work out well for all of the other networks if we clamp to an MTU of 1400 for everyone. So here’s the answer:

[root@bluetop ipv4]# route -ee
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface    MSS   Window irtt
192.168.2.0     *               255.255.255.0   U     0      0        0 wlan0    0     0      0
default         192.168.2.1     0.0.0.0         UG    0      0        0 wlan0    0     0      0
[root@bluetop ipv4]# ip route add 10.0.0.0/24 via 192.168.2.1 mtu 1400
[root@bluetop ipv4]# ip route show
10.0.0.0/24 via 192.168.2.1 dev wlan0  mtu 1400
192.168.2.0/24 dev wlan0  proto kernel  scope link  src 192.168.2.98
default via 192.168.2.1 dev wlan0  proto static
[root@bluetop ipv4]# route -ee
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface    MSS   Window irtt
10.0.0.0        192.168.2.1     255.255.255.0   UG    0      0        0 wlan0    0     0      0
192.168.2.0     *               255.255.255.0   U     0      0        0 wlan0    0     0      0
default         192.168.2.1     0.0.0.0         UG    0      0        0 wlan0    0     0      0

Neat? Well this can be surprisingly useful in many places. In fact the inverse of the previous example is uncommonly useful when dealing with an artificially clamped default path. Consider your ADSL connection which probably uses PPoE (Point to Point over Ethernet) tunnelling. Your local machine undoubtedly uses an Ethernet MTU of 1500 and the ADSL device probably does on the connection to your network provider (which is invariably different from your ISP). However PPoE consumes a little of that 1500 bytes to pack in its tunnelling protocol. This means that on large data transfers your machine is pumping out 1500 bytes of TCP/IP to your ADSL connection and that device is quite likely fragmenting those packets into 2 so that it can get its tunnelling protocol messages into the same packets. Effectively you are adding a small but significant overhead to the whole data transfer process increasing the consumption of your ISP data cap and causing your ADSL device to work harder than required. Yes you are in fact solely responsible for global warming. You crim!

Often in professional networks where PPoE tunnels are used you will see various counter measures to avoid the side effects of the tunnelling overhead. One way is to configure jumbo (oversized MTU) packets on the tunnelling devices. However that really requires you to configure both ends and its not really normal for you to be able to configure your network supplier’s routers. At least not legally. However you can clamp your default routes from your devices and set your local LAN MTU to, well, whatever you want. That way you don’t affect your local LAN performance and you can improve your gateway throughput.

Naturally this is reasonably dangerous so I’m just going to give you the command and let you break your network yourself. I guarantee that you will stuff this up so have a play when you don’t mind spending the time on it; and by the way this sort of stupidity can raise the temperature on your physical devices: so you can actually physically damage your equipment or alter its life expectancy this way. BE WARNED you own ALL of the risk on this one. But do have fun!

ip route add default via 10.0.0.1 mtu 1470

Rewriting the Wheel: bin2hex – hex2bin

Yep everybody does it; repetition.  In the grand old days of old we all rebuilt the wheel leading to the establishment of patterns.  For me patterns often help me get to achieve my goals faster than using Google.  Using Google to find simple tools normally means understanding the search engine, browsing the results and evaluating each alternative in turn.  Invariably this means slightly altering someone else’s code, compromising objectives or installing a bulky tool that is bloated by a thousand functions you don’t need or want.  Naturally this last list is not exhaustive; just consider the dependencies that an external solution often requires.  If its simple and quick its often better to reinvent your wheel.

A perennial favourite of mine is base translation; specifically hexadecimal to binary and binary to hexadecimal.  This is so simple and so useful it’s the subject of thousands of Google results.  Yet the useful bits are rarely on the first page of results.  So I coded it in about 30 minutes, and debugged it in about 30 minutes – because I was tired at the time.  Interestingly this is not the first time that I’ve written this code.  My earliest recollection of having written it was about 1986 over 22 years ago.  Of course it was coded in basic at the time on an Atari, however it wasn’t too long before I started translating it into C.

Patterns have long been a formal word in Computer Science.  In 1996 a very famous book, the name of which escapes me now and I’m too lazy to get it off my shelf, was dedicated to the development of patterns in software development.  Interestingly the way that the patterns were described was almost a deterrent to the patterns themselves.  Being of academic nature the usefulness of the book was somewhat tarnished by its lack of pragmatic style and appeal to the great unwashed.  Its a fantastic book though which every software engineer should read.

For me patterns are best expressed in real world examples and in the languages that I understand.  It makes them instantly available to me and much more likely to improve my work.  Yes they do need some formal definition most of the time.  However if its so simple as to be obvious then don’t clutter the example with an explanation other than to say what you used it for.  If its really that useful to be made into a pattern it’ll resurface again in the form of ‘now what did I do with that code I wrote 22 years ago that solved this problem?’

Well here it is, I used it to translate a Hexadecimal network packet lifted from an application log back into binary so that it could be replayed over a network for testing the application time and again.  Note the use of redirected standard input and output; its clean – no Swiss army knife in this one, what would I need a spoon on it for anyway?

hex2bin.c

#include "stdio.h"

#include "stdlib.h"

int main( int argc, char ** argv, char ** env ) {

  char h = '0';
  FILE * fi = stdin;
  FILE * fo = stdout;

  if ( argc > 1 ) {

    printf( "Usage: redirect input and output to stdin and stdout respectively.\n" );
    return 0;
  }

  h = getc( fi );

  while ( h != EOF ) {

    char b = 0;

    if ( h - '0' < 10 ) b = h - '0';
    else if ( h - 'a' < 'g' - 'a' ) b = ( h - 'a' ) + 10;
    else if ( h - 'A' < 'G' - 'A' ) b = ( h - 'A' ) + 10;

    b = b << 4;

    h = getc( fi );
    if ( h == EOF ) return 0;

    if ( h - '0' < 10 ) b += h - '0';
    else if ( h - 'a' < 'g' - 'a' ) b += ( h - 'a' ) + 10;
    else if ( h - 'A' < 'G' - 'A' ) b += ( h - 'A' ) + 10;

    if ( putc( b, fo ) == EOF ) return 0;

    h = getc( fi );
  }

  return 0;

}

Of course in this case it was just too tempting to write it’s sister as well: binary to hex. If you combine these two tools on the command line with netcat and some other favourite script favourites you can make quite a useful test tool.

bin2hex.c

#include "stdio.h"

#include "stdlib.h"

int main( int argc, char ** argv, char ** env ) {

  char b = '0';
  FILE * fi = stdin;
  FILE * fo = stdout;

  if ( argc > 1 ) {

    printf( "Usage: redirect input and output to stdin and stdout respectively.\n" );
    return 0;
  }

  b = getc( fi );

  while ( b != EOF ) {

    char h = 0;

    h = b >> 4;
    if ( h < 10 ) h = h + '0';
    else if ( h < 16 ) h = h + 'a';
    if ( putc( h, fo ) == EOF ) return 0;

    h = b & 0x0f;
    if ( h < 10 ) h = h + '0';
    else if ( h < 16 ) h = h + 'a';
    if ( putc( h, fo ) == EOF ) return 0;

    b = getc( fi );
  }

  return 0;

}

Lastly there is a point that is quite good to note about such simple patterns: they make really a really good basis for recruitment tests. You can always tell how good an organisation is in recruitment by the quality of this process. If they complain about spelling it generally means that the organisation is focussed on minutia and micro-management is probably the order of the day. Normally that’s a warning sign. So I always include spelling mistakes in my submissions. However if you are asked about the various ways of implementing the illustrated code (once of course you’ve rewritten it for them from requirements!) and integration strategies, impact on speed, memory usage along with testing and comparison of the requirements provided you’re probably to a good thing.

So just for fun let’s look at one aspect of this. IF you go do that dreaded Google search and sift through the cruft out there you will find a very specific approach often used that is quite different to that which I’ve used above to determine binary or hex value in translation; it normally involves using a switch statement like this:

char h;
int b;

switch ( h ) {
  '0'  :  b = 0;
          break;
  '1'  :  b = 1;
          break;
  '2'  :  b = 2;
          break;
  '3'  :  b = 3;
          break;
  '4'  :  b = 4;
          break;
  '5'  :  b = 5;
          break;
  '6'  :  b = 6;
          break;
  '7'  :  b = 7;
          break;
  '8'  :  b = 8;
          break;
  '9'  :  b = 9;
          break;
  'A'  :
  'a'  :  b = 10;
          break;
  'B'  :
  'b'  :  b = 11;
          break;
  'C'  :
  'c'  :  b = 12;
          break;
  'D'  :
  'd'  :  b = 13;
          break;
  'E'  :
  'e'  :  b = 14;
          break;
  'F'  :
  'f'  :  b = 15;
          break;
  default : return -1;
}

All this seems reasonable. Yes its going to be bigger than my code but its going to be quicker right? Actually that’s not right. You see the code is larger so its going to take a larger number of get requests to the memory. My code is small enough to fit inside most modern processor’s register sets not even touching the processor cache which the static example just given would have to sit in. Next the compiler on average will make twice the number of comparisons to jump into the switch statement, than the corresponding number of operations for my version. But this is also compiler and processor dependent. Coding simply in this case makes the optimiser’s job easier but an optimiser normally doesn’t have the nous to translate the code to another approach, just apply obvious short cuts to the code already presented. Naturally this could lead into discussions about optimisers and their abilities and limitations.

In fact there are a large number of optimisations that could be made to my code that would improve its performance too. But I’ll stop here because I could write a book on this one piece of code. So you see a particularly innocuous, been-done-before, simple piece of code can be interesting and be used to draw out the depth of a person’s knowledge. Plus there’s a certain amount of satisfaction in being able to go back an polish old code, it’s like visiting an old friend.


Random Passwords

Most of the time the best way of generating passwords is by using ‘passphrases’ which you can remember. But in this day and age of having a unique password for everything this approach is not always practical. For most users the temptation to generate a really secure password and then use it everywhere is just too much. Its not necessarily the remembering aspect of the equation either; it can take a lot just to generate a good secure password in the first place. Especially when each site that you visit or application that you use has similar but crucially differing requirements. For me the best way to store multiple passwords is in a secured store using a regularly rolled key, in my case PGP encrypted files.

To easily generate a random password in Linux all you need to do is:

  'dd if=/dev/urandom count=1 4> /dev/null | uuencode -m - \
  | sed -ne 2p | cut -c-16'

Note that this does rely on you having /dev/urandom, uuencode, sed and cut available on your system. Which in my case generated the following output:

  [user@blackbox ~]$ dd if=/dev/urandom count=1 4> /dev/null \
  | uuencode -m - | sed -ne 2p | cut -c-16
  1+0 records in
  1+0 records out
  512 bytes (512 B) copied, 0.000223 seconds, 2.3 MB/s
  fQ6XFnhsNWbeMtph

The password generated in this case is of course ‘fQ6XFnhsNWbeMtph’, a pain to remember for sure but very secure. A slight alteration allows for a number of passwords to be generated:

  'for ((n=0;n<10;n++)); do head -c16 /dev/urandom | uuencode -m - \
  | sed -ne 2p | cut -c-8; done'

Lists of passwords are good in the odd case where the generated password may not contain quite the flavour of included characters that you were looking for. They’re often good too when you need to roll a bunch of passwords at once or if you’re setting up a number of systems at the same time. Note the alteration in password length as set by the cut tool. There’s also a change to using head to read the random data too. Here’s an example of a set of passwords generated by the command above:

  [user@blackbox ~]$ for ((n=0;n<10;n++)); do head -c16 /dev/urandom \
  | uuencode -m -| sed -ne 2p | cut -c-8; done
  x41jVgKc
  vC+IxVLU
  xkzOfyVu
  5WwEWEat
  Ymw4C52m
  BQ5Gtcjj
  ByRqTEY
  CO79z599
  VJlcIzU7
  3mJ1F3b8

Apart from this there are a number of other things that you can do with the passwords; but these have mostly to do with the characters generated. So for example if you wanted to generate 16 digit pins you could use some variant of the following:

  head -c16 /dev/urandom | od -t u8 | awk '{ print $2 }' | cut -c-16

Naturally you could add in a grep statement to the earlier commands to do something similar by capturing only numeric characters. But such a method is statistically inefficient due to the small number of digits in the earlier streams. Other cases, for example removing the non-alpha-numeric characters could be better suited for grep filtering. Quite naturally I’ve left this as an exercise for the reader as I don’t need that right now. Here’s an example execution of the pin generation command:

  [user@blackbox ~]$ head -c16 /dev/urandom | od -t u8 \
  | awk '{ print $2 }' | cut -c-16
  9815394141245590

One significant observation is that there are many statements to be found that are critical of using a random number generator to generate password data. Normally the arguments are based around the fact that automata are easily replicated and hence the passwords generated may be weak. The flaw in this argument is that the methods shown here are not intended to be infallible, just accountably strong, and in general passwords are always fallible. It’s just a question of educated guessing. However one last word, always be sure that your passwords are vetted in sample against some standard of strength and protect your generation mechanism.

Its a dangerous world out there, take care of your passwords with good policy and procedure.


Squid Grep

Just a wee note to remind myself of the best way to view your squid.conf file if you’re in a hurry:

'cat squid.conf | grep -v ^# | grep -v ^$'

Its interesting to note that many people recommend stripping the comments from the active squid.conf with a command similar to this:

'cat /etc/squid/squid.conf | tee /etc/squid/squid.conf.commented \
 | grep -v ^# | grep -v ^$ > /etc/squid/squid.conf.nocomment'

Naturally you would normally not have ‘.nocomment’ on the active file.  You need to be root to do this too.


A Few Ajax Links

AJAX is a now a well established technology. It has been around for a long time but only recently (2005) was the term ‘AJAX’ coined to mean Asynchronous JavaScript And XML and unify the previously disjointed technologies it represents. Essentially it is an amalgamation of technologies to provide good user interface tools for Web browser applications.

Now of course there are a myriad of these toolkits, most born soon after the publishing to the AJAX article in 2005, and most not really suitable IMHO for real application. But they are all useful to look at. For me the most interesting ones are the following:

There is pretty good AJAX web site here if you need a place for starting to look for AJAX resources.


C++ Valarray Matrix Madness

Numeric STL container valarray began life partially as an attempt to make C++ appealing to the supercomputing community. At the time the big thing in those big machines was, the ironically named, vector processing. However the valarray fell by the wayside as the people driving its development left the STL development group. Perhaps they realised that it didn’t really fit 100% with the STL, or maybe they just got sidetracked; who knows. But it is still useful, and here are a few reasons why:

  • Can be used to write faster code for numeric spaces than possible with other STL types like the ubiquitous vector template.
  • Offers the coder the possibility of staying within the comfort zone of the STL and familiar object oriented concepts with a small speed sacrifice over hand carved C.
  • Allows library developers a way of writing optimized libraries for different environments so that coder can concentrate on the development at hand and not loose track in the complexity of the target environment.

So I’ve been playing around with valarray. It seemed that the best example to play with is that old classic the matrix. So here it is. Yes I know that there are some particularly hairy things wrong with it, but its not meant as a copy and paste solution. Its here as the results of a learning exercise and an example of what’s possible with valarray. There are one or two places which are not implemented or have not been tested, but you should be able to complete or test these by just looking at the rest of the examples. It should compile and run as is.

Have a look and have fun.

#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <valarray>
#include <vector>

/*------------------------------------------------------------------------------
  matrix2d interface

  This is the template for the matrix class.  Its not that fancy and there could
  be a lot more added to it but that was not the point of the exercise.  It is
  also limited by the number of types supported by the underlying valarray data
  container.  From an OO point of view its really not that good either given
  that a lot of the manipulation or generator methods really don't need to have
  access directly to the data part of the construct.  However on a practical
  basis including those methods in this class provide small benefits in speed
  and allow things to be a little more obvious.  There are also problems in the
  way that the generators return new matrix2d objects.  But I've no intention to
  fix them as this was just a learning exercise.  I've tossed the implementation
  of the methods into seperate compilation objects to make the interface cleaner
  for inspection purposes.  In keeping with the valarray perspective there is no
  bounds checking anywhere - you have been warned.
  ----------------------------------------------------------------------------*/

template<ypename T>

class matrix2d {
public:

  // creates based on the rows and data size
  matrix2d(std::size_t rows, std::valarray<T> data);
  // creates an empty rows x size matrix
  matrix2d(std::size_t rows, std::size_t cols);
  // direct initialisation - beware that rows x cols must equal data.size()
  matrix2d(std::size_t rows, std::size_t cols, std::valarray<T> data);

  // get the number of rows in the matrix2d
  std::size_t rows() const;
  // get the number of columns in the matrix2d
  std::size_t cols() const;
  // get a copy of the data in the matrix2d
  std::valarray<T> array() const;

  // retrieve the data from row r of the matrix
  std::valarray<T> row(std::size_t r) const;
  // retrieve the data from col c of the matrix
  std::valarray<T> col(std::size_t c) const;

  // retrieve refernce to the data from row r of the matrix
  std::slice_array<T> row(std::size_t r);
  // retrieve refernce to the data from col c of the matrix
  std::slice_array<T> col(std::size_t c);

  // basic item reference
  T & operator()(std::size_t r, std::size_t c);
  // basic item retrieval
  T operator()(std::size_t r, std::size_t c) const;

  // generate a matrix sort each row then sort the rows - UNIMPLEMENTED
  matrix2d<T> sort();
  // genetate a new matrix that is the transposition of this one
  matrix2d<T> transpose();
  // generate a new matrix with this matrix's data and sort each row
  matrix2d<T> rowItmSort();
  // generate a new matrix with this matrix's data and sort each row in reverse
  matrix2d<T> rowItmSortRev();
  // generate a new matrix with this matrix's data and sort each col
  matrix2d<T> colItmSort();
  // generate a new matrix with this matrix's data and sort each col in reverse
  matrix2d<T> colItmSortRev();

  // generate a new matrix of this one with m appended below
  matrix2d<T> appendRows(matrix2d<T> &m);
  // generate a new matrix of this one with m appended to the right
  matrix2d<T> appendCols(matrix2d<T> &m);
  // generate a matrix of this one, upper left corner at row t col l - UNTESTED
  matrix2d<T> extractMatrix2d(size_t t, size_t l, size_t w, size_t h);

protected:

  std::size_t rows_;
  std::size_t cols_;
  std::valarray<T> data_;

};

/*------------------------------------------------------------------------------
  matrix2d implementation
  ----------------------------------------------------------------------------*/

/*------------------------------------------------------------------------------
  matrix2d constructors
  ----------------------------------------------------------------------------*/

template<class T>
matrix2d<T>::matrix2d(std::size_t rows, std::valarray<T> data) :
rows_(rows), cols_(data.size() / rows), data_(data) {}

template<class T>
matrix2d<T>::matrix2d(std::size_t rows, std::size_t columns) :
rows_(rows), cols_(columns), data_(rows * columns) {}

template<class T>
matrix2d<T>::matrix2d(std::size_t rows, std::size_t columns,
std::valarray<T> data) :
rows_(rows), cols_(columns), data_(data) {}

/*------------------------------------------------------------------------------
  matrix2d operations
  ----------------------------------------------------------------------------*/

template<class T>
std::size_t matrix2d<T>::rows() const {
  return rows_;
}

template<class T>
std::size_t matrix2d<T>::cols() const {
  return cols_;
}

template<class T>
std::valarray<T> matrix2d<T>::array() const {
  return data_;
}

template<class T>
std::valarray<T> matrix2d<T>::row(std::size_t r) const {
  return data_[std::slice(r * cols(), cols(), 1)];
}

template<class T>
std::valarray<T> matrix2d<T>::col(std::size_t c) const {
  return data_[std::slice(c, rows(), cols())];
}

template<class T>
std::slice_array<T> matrix2d<T>::row(std::size_t r) {
  return data_[std::slice(r * cols(), cols(), 1)];
}

template<class T>
std::slice_array<T> matrix2d<T>::col(std::size_t c) {
  return data_[std::slice(c, rows(), cols())];
}

template<class T>
T& matrix2d<T>::operator()(std::size_t r, std::size_t c) {
  return data_[r * cols() + c];
}

template<class T>
T matrix2d<T>::operator()(std::size_t r, std::size_t c) const {
  return row(r)[c];
}

/*------------------------------------------------------------------------------
  matrix2d generators
  ----------------------------------------------------------------------------*/

template<class T>
matrix2d<T> matrix2d<T>::sort() {

  matrix2d<T> result(rows_, cols_);

  /* TO DO TO DO TO DO TO DO TO DO TO DO TO DO TO DO TO DO TO DO TO DO TO DO */

  return result;
}

template<class T>
matrix2d<T> matrix2d<T>::transpose() {

  matrix2d<T> result(cols_, rows_);

  for (std::size_t i = 0; i < rows_; ++i)
    result.col(i) = static_cast<std::valarray<T> > (row(i));

  return result;
}

template<class T>
matrix2d<T> matrix2d<T>::rowItmSort() {

  matrix2d<T> result(rows_, cols_);

  for (std::size_t i = 0; i < rows_; ++i) {

    std::valarray<T> x = static_cast<std::valarray<T> > (row(i));
    std::sort(&x[0], &x[cols_]);
    result.row(i) = x;
  }

  return result;
}

template<class T> bool rev (const T & a, const T & b) { return a > b; }

template<class T>
matrix2d<T> matrix2d<T>::rowItmSortRev() {

  matrix2d<T> result(rows_, cols_);

  for (std::size_t i = 0; i < rows_; ++i) {

    std::valarray<T> x = static_cast<std::valarray<T> > (row(i));
    std::sort(&x[0], &x[cols_], rev<T>);
    result.row(i) = x;
  }

  return result;
}

template<class T>
matrix2d<T> matrix2d<T>::colItmSort() {

  matrix2d<T> result(rows_, cols_);

  for (std::size_t i = 0; i < cols_; ++i) {

    std::valarray<T> x = static_cast<std::valarray<T> > (col(i));
    std::sort(&x[0], &x[rows_]);
    result.col(i) = x;
  }

  return result;
}

template<class T>
matrix2d<T> matrix2d<T>::colItmSortRev() {

  matrix2d<T> result(rows_, cols_);

  for (std::size_t i = 0; i < cols_; ++i) {

    std::valarray<T> x = static_cast<std::valarray<T> > (col(i));
    std::sort(&x[0], &x[rows_], rev<T>);
    result.col(i) = x;
  }

  return result;
}

template<class T>
matrix2d<T> matrix2d<T>::appendRows(matrix2d<T> &m) {

  matrix2d<T> result(rows_ + m.rows_, cols_);

  result.data_[std::slice(0, rows_ * cols_, 1)] = data_;
  result.data_[std::slice(rows_ * cols_, m.rows_ * m.cols_, 1)] = m.data_;

  return result;
}

template<class T>
matrix2d<T> matrix2d<T>::appendCols(matrix2d<T> &m) {

  matrix2d<T> result(rows_, cols_ + m.cols_);

  std::size_t s1[] = {rows_,cols_}; // shape of left matrix
  std::size_t p1[] = {result.cols_,1}; // position of left matrix in result
  std::size_t s2[] = {m.rows_,m.cols_}; // shape of right matrix
  std::size_t p2[] = {result.cols_,1}; // position or right matrix in result

  std::valarray<std::size_t> sv1(s1, 2);
  std::valarray<std::size_t> pv1(p1, 2);
  std::valarray<std::size_t> sv2(s2, 2);
  std::valarray<std::size_t> pv2(p2, 2);

  result.data_[std::gslice(0, sv1, pv1)] = data_; // copy left matrix into place
  result.data_[std::gslice(cols_, sv2, pv2)] = m.data_; // repeat for m

  return result;
}

template<class T>
matrix2d<T> matrix2d<T>::extractMatrix2d(size_t x, size_t y, size_t w,
size_t h) {

  /* TEST ME TEST ME TEST ME TEST ME TEST ME TEST ME TEST ME TEST ME TEST ME */

  matrix2d<T> result(h, w);

  size_t x2[] = {h, w}, s[] = {rows_, 1};
  std::valarray<size_t> xa(x2, 2), sa(s, 2);

  result.data_ = data_[(const std::gslice)std::gslice(y * rows_ + x, xa, sa)];

  return result;
}

/*------------------------------------------------------------------------------
  matrix2d general input output

  This is a simple class to help collect methods of serialising the matrix2d
  data forms.  Really they should be done another way but once again I don't
  really care as they are throw away code for the purpoese of demonstration
  only.
  ----------------------------------------------------------------------------*/

template<typename T>

class matrix2dio {
public:

  matrix2d<T> textToM2d(std::istream & is, size_t w);
  matrix2d<T> fileToM2d(std::string file, size_t w);
  void m2dToText(std::ostream & os, const matrix2d<T> & m);
  void printValarray(std::ostream & os, const std::valarray<int> & va);
};

/*------------------------------------------------------------------------------
  matrix2dio operations
  ----------------------------------------------------------------------------*/

typedef std::istream_iterator<int> int_istrm_iter;

template<class T>
matrix2d<T> matrix2dio<T>::textToM2d(std::istream & is, size_t w) {

  std::vector<T> v;
  std::valarray<T> a;

  if (!is.good() || is.eof())
    return;

  copy(int_istrm_iter(is), int_istrm_iter(), back_inserter(v));
  a.resize(v.size(), sizeof ( int));
  copy(v.begin(), v.end(), &a[0]);

  return new matrix2d<T > (w, a);
}

template<class T>
matrix2d<T> matrix2dio<T>::fileToM2d(std::string file, size_t w) {

  std::filebuf fb;
  std::istream is(&fb);

  fb.open(file.c_str(), std::ios::in);
  matrix2d<T> m = textToM2d(is, w);
  fb.close();

  return m;
}

template<class T>
void matrix2dio<T>::m2dToText(std::ostream & os, const matrix2d<T> & m) {

  size_t i = 0, j = 0;

  for (i = 0; i < m.rows(); i++) {

    std::valarray<T> r = m.row(i);
    os << r[0];

    for (j = 1; j < m.cols(); j++)
      std::cout << ' ' << r[j];

    os << '\n';
  }

  os << std::flush;
}

template<class T>
void matrix2dio<T>::printValarray(std::ostream & os,
const std::valarray<int> & va) {

  copy(&va[0], &va[va.size() - 1], std::ostream_iterator<T > (os, " "));
  os << va[va.size() - 1] << std::endl;
}

/*------------------------------------------------------------------------------
  matrix2d tests
  ----------------------------------------------------------------------------*/

void testConstructors() {

  std::cout << "\n\n\nRunning Constructor Tests\n\n";

  int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
  std::valarray<int> v( a, 12 );
  std::size_t x = 3, y = 4;
  matrix2dio<int> i;

  std::cout <<
    "\nTesting: matrix2d(std::size_t rows, std::size_t columns, "
    "std::valarray<T> data);\n";
  matrix2d<int> m1( x, y, v );

  std::cout << "number of rows: " << m1.rows() << '\n'
  << "number of cols: " << m1.cols() << '\n'
  << "matrix content:\n";
  i.m2dToText( std::cout, m1 );

  std::cout << "\nTesting: matrix2d(std::size_t rows, std::size_t columns);\n";
  matrix2d<int> m2( x, y );

  std::cout << "number of rows: " << m2.rows() << '\n'
  << "number of cols: " << m2.cols() << '\n'
  << "matrix content:\n";
  i.m2dToText( std::cout, m2 );

  std::cout <<
    "\nTesting: matrix2d(std::size_t rows, std::valarray<T> data);\n";
  matrix2d<int> m3( x, v );

  std::cout << "number of rows: " << m3.rows() << '\n'
  << "number of cols: " << m3.cols() << '\n'
  << "matrix content:\n";
  i.m2dToText( std::cout, m3 );
}

void testRowsAndCols() {

  std::cout << "\n\n\nRunning Row/Col Accessor Tests\n\n";

  int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
  std::valarray<int> v( a, 12 );
  std::size_t x = 3, y = 4;
  matrix2dio<int> i;

  matrix2d<int> m1( x, y, v );

  std::cout << "\nTesting: std::valarray<T> row(std::size_t r) const;\n";

  std::valarray<int> r1 = m1.row(0);
  std::valarray<int> r2 = m1.row(1);
  std::valarray<int> r3 = m1.row(2); 

  std::cout << "row 1:\n";
  i.printValarray( std::cout, r1 );
  std::cout << "row 2:\n";
  i.printValarray( std::cout, r2 );
  std::cout << "row 3:\n";
  i.printValarray( std::cout, r3 );

  std::cout << "\nTesting: std::valarray<T> col(std::size_t r) const;\n";

  std::valarray<int> c1 = m1.col(0);
  std::valarray<int> c2 = m1.col(1);
  std::valarray<int> c3 = m1.col(2);
  std::valarray<int> c4 = m1.col(3); 

  std::cout << "col 1:\n";
  i.printValarray( std::cout, c1 );
  std::cout << "col 2:\n";
  i.printValarray( std::cout, c2 );
  std::cout << "col 3:\n";
  i.printValarray( std::cout, c3 );
  std::cout << "col 4:\n";
  i.printValarray( std::cout, c4 );

  std::cout << "\nTesting: std::slice_array<T> row(std::size_t r);\n";

  std::slice_array<int> rs1 = m1.row(0);
  std::slice_array<int> rs2 = m1.row(1);
  std::slice_array<int> rs3 = m1.row(2); 

  std::cout << "row 1:\n";
  i.printValarray( std::cout, rs1 );
  std::cout << "row 2:\n";
  i.printValarray( std::cout, rs2 );
  std::cout << "row 3:\n";
  i.printValarray( std::cout, rs3 );

  std::cout << "\nTesting: std::slice_array<T> col(std::size_t r);\n";

  std::slice_array<int> cs1 = m1.col(0);
  std::slice_array<int> cs2 = m1.col(1);
  std::slice_array<int> cs3 = m1.col(2);
  std::slice_array<int> cs4 = m1.col(3); 

  std::cout << "col 1:\n";
  i.printValarray( std::cout, cs1 );
  std::cout << "col 2:\n";
  i.printValarray( std::cout, cs2 );
  std::cout << "col 3:\n";
  i.printValarray( std::cout, cs3 );
  std::cout << "col 4:\n";
  i.printValarray( std::cout, cs4 );
}

void testGenerators() {

  std::cout << "\n\n\nRunning Generator Tests\n\n";

  int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
  int b[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120 };
  std::valarray<int> v1( a, 12 );
  std::valarray<int> v2( b, 12 );
  std::size_t x = 3, y = 4;
  matrix2dio<int> i;

  matrix2d<int> m1( x, y, v1 );
  matrix2d<int> m2( x, y, v2 );

  std::cout << "\nTesting: matrix2d<T> transpose();\noriginal:\n";

  matrix2d<int> m3 = m1.transpose();
  i.m2dToText( std::cout, m1 );
  std::cout << "transposed:\n";
  i.m2dToText( std::cout, m3 );

  std::cout << "\nTesting: matrix2d<T> appendRows(matrix2d<T> &v);\n";

  matrix2d<int> m4 = m2.appendRows(m1);
  i.m2dToText( std::cout, m4 );

  std::cout << "\nTesting: matrix2d<T> appendCols(matrix2d<T> &m);\n";

  matrix2d<int> m5 = m2.appendCols(m1);
  i.m2dToText( std::cout, m5 );

  std::cout << "\nTesting: matrix2d<T> rowItmSort();\n";

  matrix2d<int> m6 = m5.rowItmSort();
  i.m2dToText( std::cout, m6 );

  std::cout << "\nTesting: matrix2d<T> rowItmSortRev();\n";

  matrix2d<int> m7 = m5.rowItmSortRev();
  i.m2dToText( std::cout, m7 );

  std::cout << "\nTesting: matrix2d<T> colItmSort();\n";

  matrix2d<int> m8 = m4.colItmSort();
  i.m2dToText( std::cout, m8 );

  std::cout << "\nTesting: matrix2d<T> colItmSortRev();\n";

  matrix2d<int> m9 = m4.colItmSortRev();
  i.m2dToText( std::cout, m9 );
}

void testMatrix2d() {

    testConstructors();
    testRowsAndCols();
    testGenerators();
}

/*------------------------------------------------------------------------------
  matrix2d test entry point
  ----------------------------------------------------------------------------*/

int main( int argc, char** argv ) {

  testMatrix2d();
  return (EXIT_SUCCESS);
}

NZ e-Commerce Payment Gateways

If you are in business on-line you need a payments gateway and there seem to be a never ending supply of them now. Just no real directory for them and as with any product there are suppliers and resellers and integrators and franchises and .. I guess that you get the picture. Naturally there are good and bad flavors of each too and the only way that you’ll know is by trying them out. Just because they are listed on this page does NOT mean that I endorse them.

DISCLAIMER: this information does not constitute advice to you or any other person, no one is responsible for your disaster except you. I guarantee YOU WILL GET HURT and that is no-body’s fault except your own for trading on line.

So how do you begin? Well you begin by defining your business needs and parameters. Don’t guess, you’ll just get yourself into a world of financial hurt. If you don’t know then start off small, in general, but not always, smaller mistakes are less costly. So the things to consider are:

  • Number of customers that you reasonibly expect to make purchases through your site. This will affect which pricing model you use and how robust your site needs to be.
  • Where your customers will be purchasing from. Customers who live and buy from overseas will have specific shipping and billing needs. It is also more difficult to deal with fraud when you send your product to a foriegn country. With local customers in the same country as you you can choose to use localised payments solutions too.
  • Your bank. Often you will find it quite difficult to work with your bank. They’re big, and some times it seems like an overly arduous journey just to get set up with the right type of merchant account and product. You may need to go to a wallet solution to handle your transactions simply to make the whole management thing simple.
  • Risk and fraud. You really, really need to understand how these things work to make sure that your business that was profitable yesterday was not wiped out last night by the effects of the dangers of on-line trade. Research everything that you can about this you really are on your own here it is your business.

Once you have defined your business model and know what your want to do start looking around at your options. I like to broadly catagorise the payment gateways in three categories: bank, wallet and account based. However in all categories, if you have not done this before get help from someone who has done it successfully or professionals who come accredited by the bank or gateway that you choose.

Bank based is normally the more expensive option; it involves geting your existing, or finding a new, bank’s gateway product integrated with your site. Normally this involves setting up a commercial account and providing endless details for the bank to scrutinise and will end up with the most expensive product. Often its quite limiting too. However for merchants of significant size this is really the only way to go. The charges for set up can be quite large, but unlike wallet options the charges per transaction can be negotiated and generally they can be fixed.

Wallet based retailing is generally through a third party like Pago, Paypal or Paymate. The idea is that you open or host a wallet with the third party and your customers pay money into it through whatever card scheme (Visa, Mastercard, etc.) for a price. For the priviledge you normally get billed a tidy little percentage of the transaction value along with whatever other fees that the wallet system owners feel like charging you. You need to be really careful about how suspect transactions are contested. There are normally limits of various sizes (amount, frequency, etc.) applied to wallets.

Account based payment systems are hosted by you and are for your well recognised customers. These are the people that you have had a long term relationship with and can hold a tab open with. Frequent flyers that you have had experience with and trust. The idea is that you maintain your accounts as you would any other person coming into your shop, extend a line of credit and bill them at the end of month. It aviods loads of bank fees, you can use other forms of payment like cheque or on-line bank payment / transfer.

Whatever your model you are going to get hurt. Minimise your risks, expect damage and don’t come crying to anybody else: especially me. I guarantee that you will get hit sooner or later, the Internet is a nasty place.

Now here’s a small list of gateways that you can look at:


Copyright © 1996-2010 Code Snips. All rights reserved.
iDream theme by Templates Next | Powered by WordPress