Wednesday, November 16, 2005

Won't buy Sony any more

Here is why.

http://www.sysinternals.com/Blog/

or

http://www.sonybmg.com/

Customers should not stand for this. What is this ? Big brother?

click on "Information on XCP content protection"

I am now scanning my PC for rootkits. See www.sysinternals.com for details. They have a tool to scan your machine.



Yahoo! FareChase - Search multiple travel sites in one click.

Saturday, October 08, 2005

Book Review / The Pragmatic Programmer


An interesting title. After browsing a few pages at
the book store I bought it, and read it pretty
quickly. An easy read but a good one. I have to say
that I was pleased to find out that some people see
the light.

Most people look at a design / piece of code and do
not even see what's wrong. Worse, they see what's
wrong and do not do anything about it.

I agree with pretty much anything this book promotes.
I am no longer alone in the universe thinking this
way. For a while I thought I was an anomaly of nature.

The book is a collection of tips that can only be
acquired by years of experience. Experienced
programmers should read it to get a clear description
of what we sometimes do instinctively.

Newbies should read it too and learn from the older
guys and become good programmers quicker.

There are a lot of good analogies in this book as well
as quotes that I really liked.

The abstract nature of our craft deserved a human side
that this book provides.


__________________________________
Yahoo! Music Unlimited
Access over 1 million songs. Try it free.
http://music.yahoo.com/unlimited/

Saturday, September 10, 2005

Writing JSP pages in C#

Enough said. Go to my web site here.
http://www.t-d-n-g.com/default.aspx?P=AboutJsp

Saturday, September 03, 2005

New Samples on my web site

I am giving a talk at Microsoft (C# users group) on Tuesday about httpHandlers.
Since they are going to ask me where they can get the samples, I added them to my web site. Here is the link http://www.t-d-n-g.com/default.aspx?P=CodeSamples

Thursday, April 21, 2005

Make your own webhandler factory, why? Because you can!

In ASP.Net, the framework provide a default handler for ashx files. It is called
"System.Web.UI.SimpleHandlerFactory". You can find the mapping in machine.config.
The main job of this handler is to compile an ashx file, find the class that implements IHttpHandler, instanciate it and call its Process request so your handler can do its job.
This "System.Web.UI.SimpleHandlerFactory" does all this for you. I wanted to make my own, just for fun... Actually for my students who want to know a little more of what is going on behind the scene.

There are 3 parts to this:
- 1: A standard ashx file to make sure my new factory can create my handler and pass the request through.
- 2: A factory class that needs to be compiled as a library and placed in the bin directory. The name of the assembly needs to be webhandler.dll for this demo.
- 3: A web.config to remap the standard "System.Web.UI.SimpleHandlerFactory" to "DM.SimpleWebHandlerFactory"

Enjoy!

Part 1: Here is a standard ashx file


<%@ WebHandler Language="C#" class="SimplestHandlerEver" %>

using System;
using System.Web;

class SimplestHandlerEver : IHttpHandler
{
public SimplestHandlerEver()
{
}

public void ProcessRequest(HttpContext context)
{
context.Response.Write(this.GetType().FullName + " called");
}

public bool IsReusable
{
get
{
return false;
}
}
}
//--- End of File

Part 2: Here is the custom factory that you need to compile and place in the bin directory.

using System;
using System.Text;
using System.Web;
using Microsoft.CSharp;

namespace DM
{
///
/// Author: C. Fouquet
/// This is a very simple handler factory that can be used to replace the
/// standard System.Web.UI.SimpleHandlerFactory that is mapped to
/// the .ashx extension in the machine.config
/// Needless to say, this is a very crude implementation of an IHttpHandlerFactory.
/// This is just to illustrate the rough steps the actual System.Web.UI.SimpleHandlerFactory
/// goes through to create the handler.
/// It is very inefficient. The code is compiled every time, the generated assembly is
/// loaded every time.
/// Also, look at the web.config to see how we remap the default handler factory
///

public class SimpleWebHandlerFactory : IHttpHandlerFactory
{

public SimpleWebHandlerFactory()
{

}
#region IHttpHandlerFactory Members

public void ReleaseHandler(IHttpHandler handler)
{

}


public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
string HandlerRequested = pathTranslated;
string Language ;
string Class;

// Open the .ashx file being hit
using(System.IO.StreamReader fs = System.IO.File.OpenText(HandlerRequested))
{

// The first line is the webhandler directive. Or so we hope!
string Directive = fs.ReadLine();

// Extract the information we are looking for from the directive
if(ProcessDirective(Directive, out Language, out Class))
{
if(Language.ToUpper() != "C#" && Language.ToUpper()!="CSHARP")
{
throw new Exception(Language + " Language Not Supported");
}
}
else
{
throw new Exception("missing or badly formatted webhandler directive");
}

string TheCode = fs.ReadToEnd(); // This is the rest of the code

string Target = System.IO.Path.GetTempFileName(); // We need an output
// file name so let the OS pick it.

// For simplicity here, we just include what we need. Obviously
// we would have to process the import directives but .. not today
// This is just a demo remember?
string[] Imports = new string[] {
"System.Web.dll"
};

System.Collections.Specialized.ListDictionary options = new System.Collections.Specialized.ListDictionary();
options.Add("target","library"); // equivalent of doing csc /t:library ...

CompilerError[] Errors = Compiler.Compile(
new string[] { TheCode },
new string[] { "TheCode" },
Target,
Imports,
options);

// Now we can load it
System.Reflection.Assembly HandlerAssembly = System.Reflection.Assembly.LoadFile(Target);

// And find the type we listed in the directive
IHttpHandler TheActualHandler = (IHttpHandler) HandlerAssembly.CreateInstance(Class);

return TheActualHandler;
}
}


// This parses the Directive. It is a little heavy on regex.. but regex are so much fun!

private bool ProcessDirective(string Directive, out string Language, out string Class)
{
Language = Class = string.Empty;

string BackSlash ="\\";
string DoubleQuote ="\"";

StringBuilder sb = new StringBuilder();
sb.Append("<%@");
sb.Append(BackSlash);sb.Append("s+");
sb.Append("WebHandler");
sb.Append(BackSlash);sb.Append("s+");


// Language="C#"
sb.Append("Language=");sb.Append(DoubleQuote);
sb.Append("(?[A-Za-z0-9]");sb.Append(BackSlash);sb.Append("#?)");
sb.Append(DoubleQuote);

// Any space
sb.Append(BackSlash);sb.Append("s+");

// class="xyx"
sb.Append("class=");sb.Append(DoubleQuote);
sb.Append("(?");sb.Append(BackSlash);sb.Append("w+)");
sb.Append(DoubleQuote);

// Any space
sb.Append(BackSlash);sb.Append("s+");

sb.Append("%<");

string regex = sb.ToString();

System.Text.RegularExpressions.RegexOptions options = ((System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace | System.Text.RegularExpressions.RegexOptions.Singleline)
| System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(regex, options);

System.Text.RegularExpressions.Match m = reg.Match(Directive);
if(m.Success)
{
Language = m.Groups["Language"].Value;
Class = m.Groups["Class"].Value;
return true;
}

return false;

}


#endregion
}
}

Part 3: The web.config

<configuration>
<system.web>
<httpHandlers>
<remove verb="*" path="*.ashx"/>
<add verb="*" path="*.ashx" type="DM.SimpleWebHandlerFactory, webhandler"/>
</httpHandlers>
</system.web>
</configuration>

I got burnt by ToString()

I have encountered a gotcha that I want to share. Strong typing is my thing. There is nothing that
bothers me more than seeing hardcoded strings in code.

In ADO.Net it is common to do something like this
Data ds = GetDataSetFromDB()
...
DataRow dr = ...

string Name = (string) dr["Name"];

If you mistype "Name" you are doomed. So I used to do this: define an enum called "Columns" that had all the
column names I am interested in.
enum Columns
{
Name,
Email,
Zip
// etc...
}

I can check the names once (visually and programmtically against the database) and in the code use this


string Name = (string) dr[Columns.Name.ToString()];

As long as you remember to use the enum, you can't mess up.

Now, before you go do this, it is very very slow. You would think that it is straightforward for the runtime
to convert an enum into its string representation. That's not the case.

if you compile this into an exe

using System;

public class HelloClient
{

public enum Columns
{
Name
}

public static void Main()
{
Console.WriteLine(Columns.Name.ToString());
}
}


and look at the ToString() with Reflector here is what you get. This is the ToString() from the
Enum type.

public override string ToString()
{
Type type1 = base.GetType();
FieldInfo info1 = Enum.GetValueField(type1);
object obj1 = ((RuntimeFieldInfo) info1).InternalGetValue(this, false);
return Enum.InternalFormat(type1, obj1);
}

and look at what GetValueField does...

private static FieldInfo GetValueField(Type type)
{
FieldInfo[] infoArray1;
if (type is RuntimeType)
{
infoArray1 = ((RuntimeType) type).InternalGetFields(BindingFlags.NonPublic | (BindingFlags.Public | BindingFlags.Instance), false);
}
else
{
infoArray1 = type.GetFields(BindingFlags.NonPublic | (BindingFlags.Public | BindingFlags.Instance));
}
if ((infoArray1 == null) || (infoArray1.Length != 1))
{
throw new ArgumentException(Environment.GetResourceString("Arg_EnumMustHaveUnderlyingValueField"));
}
return infoArray1[0];
}


Arg!!! Reflexion all over the place. No wonder it is slow....

Now, this is the generic Enum.ToString(). I would hope that it does not do that for Booleans... Let's check.

// Part of Boolean

public override string ToString()
{
if (!this.m_value)
{
return bool.FalseString;
}
return bool.TrueString;
}

public static readonly string FalseString;
public static readonly string TrueString;

// End of Boolean


Good!! Somebody is thinking.

Well, I guess we are stuck with the implementation of ToString() for our custom Enums. It would be nice though to let the
compiler know to inline the Enum's ToString() like a custom attribute. For instance:

[HeyCompilerBeSmartAboutTheToStringMethodPleaaaaseAttribute()]
enum Columns
{
Name,
Email
}

It would be nice indeed.

So I am stuck and went back to using strings like this

string Name = (string) dr["Name"];

Cool. If you use reflector again you will see that a hashtable look up is done every time
you access that column. I did some timing and it is still slow for my standards!

Let's push it further. What we want is brute speed like this.

string Name = (string) dr[3]; // 3 == "Name"

That is fast but brittle. If you move the column around in your table, you are out of synch and you will
most likelt get a beautiful exception.

This is why you need to use the "Ordinal" property on the "DataColumn".

If you want speed, you need to precompute the ordinals when the application starts and then use them.

You need to use a few tricks to do this on start up but it is worth it. Now my code is fast. I am a happy man.

Friday, April 15, 2005

Computer History is available for you to see

I found this. It is an archive of all the TV shows of the "Computer Chronicles".
You probably remember the guy always introducing himself the same way. It is fun to
see the old machines and the discussions of the time.

http://www.archive.org/details/computerchronicles

Wednesday, February 09, 2005

An old friend, the ZX81

A friend of mine read my bio on the Developmentor web site and reminded me that I forgot to mention the ZX81 in my history of technologies I worked with. If you remember this machine, it was popular in the early 80s. It had 1K RAM , expandable to 16K (which I had bought). It seems so amazing that we could even do anything with it but we did. Saving the programs on an audio tape was really a pain but cheap. The internet was not even there but I managed to transfer a program through the air! A friend of mine was doing some radio show on a local FM station. We decided to tell our audience to start recording on tape the ZX81’s super cool program I had written. As he broadcasted 5 minutes of awful sounds, I recorded it and could reload my own program on my ZX81. Thinking of it, I was probably the only one listening to this anyway! The ultimate geeky evening but it was a lot of fun. Here is a link for the ZX81 http://www.zx81.nl/