mostlylucid

April 2004 Entries

And now a poem...to mark Poem in your pocket day...

First post in a while...illness and other stuff I'll blog about later...but to mark Poem in your pocket day...a bit early, here's one from one of my homies - Robert Burns (born just down the read from where I was - we all speak like this you know!).

To A Louse
Robert Burns
ON SEEING ONE ON A LADY'S BONNET AT CHURCH
Ha! whare ye gaun, ye crowlin ferlie!
Your impudence protects you sairly:
I canna say but ye strunt rarely Owre gauze and lace;
Tho' faith, I fear ye dine but sparely On sic a place.
Ye ugly, creepin, blastit wonner,
Detested, shunned by saunt an' sinner,
How daur ye set your fit upon her,
Sae fine a lady!
Gae somewhere else and seek your dinner,
On some poor body.
Swith, in some beggar's haffet squattle;
There ye may creep, and sprawl, and sprattle
Wi' ither kindred, jumpin cattle,
In shoals and nations;
Whare horn or bane ne'er daur unsettle
Your thick plantations.
Now haud ye there, ye're out o' sight,
Below the fatt'rels, snug an' tight;
Na faith ye yet! ye'll no be right
Till ye've got on it,
The vera tapmost, towering height
O' Miss's bonnet.
My sooth! right bauld ye set your nose out,
As plump an' grey as onie grozet:
O for some rank, mercurial rozet,
Or fell, red smeddum,
I'd gie ye sic a hearty dose o't,
Wad dress your droddum!
I wad na been surprised to spy
You on an auld wife's flainen toy;
Or aiblins some bit duddie boy,
On's wyliecoat; But Miss's fine
Lunardi!—fie! How daur ye do't?
O Jenny, dinna toss your head, An' set your beauties a' abread!
Ye little ken what cursed speed
The blastie's makin!
Thae winks and finger-ends, I dread,
Are notice takin!
O, wad some Power the giftie gie us
To see oursels as others see us!
It wad frae monie a blunder free us
An' foolish notion:
What airs in dress an' gait wad lea'e us,
And ev'n Devotion!
You can read more about it here. So, on 30th April, put a poen on your blog and link to others...like these. I like this particular poem for a few reasons - it's in the dialect of my part of Scotland (it's a bit broader being so old...but basically the same), Mr Kelly, my favourite teacher in School taught us it - one of the best teachers I ever had and it has a great line -
O, wad some Power the giftie gie us
To see oursels as others see us!
Translation,
Oh would some power the gift to give us to see ourselves as others see us.
Which I think is a very nice sentiment - the poem is basically (to me) a warning that even though you might put on heirs and graces you can never really know how others percieve you.

For Future Reference: Creating Templated Emails...very nice method using UserControls

I've done this in a few ways in the past, ranging from custom XML templates with XSLT / Regular Expressions to screen scraping - this is just the simplest and cleanest way I've seen to do this (also a very nice example of using the RenderControl method...). Actually, be sure to check out the rest of the content on this blog, some really handy stuff on there...

Site Search with Index Server Companion

I've written previously that I've been hunting for a decent way to do web site search (specifically for CMS 2002 but just in general too...). I have been looking at Lucene.NET (which is in .TEXT 0.96) and a few other options. One interesting (and low cost - $39.99) option seems to be this. Essentially it provides a web crawler extension for Index Server, anyone tried this, any other options for low cost site search (as distinct from DB search / file-system based ones) I should consider?

Turning HTML Documents into images...the code

Well, after a bit of playing I've got something working now, I'm no Win32 coder but this seems to work:

using System;

using System.Drawing;

using System.Drawing.Imaging;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

using mshtml;

using System.Runtime.InteropServices;

using Microsoft.Win32;

 

namespace ThumbMaker

{   

     /// <summary>

     /// Summary description for Form1.

     /// </summary>

     public class Form1 : System.Windows.Forms.Form

    {

       private AxSHDocVw.AxWebBrowser axWebBrowser1;

 

       /// <summary>

       /// Required designer variable.

       /// </summary>

       private System.ComponentModel.Container components = null ;

 

       private const string urlStr = "http://news.bbc.co.uk/" ;

       public Form1()

      {

         //

         // Required for Windows Form Designer support

         //

        InitializeComponent();

         object o = null ;

         this .Visible= false ;

        axWebBrowser1.Navigate(urlStr, ref o, ref o, ref o, ref o);

    

      }

       const int WM_PAINT = 0x000F;

       const int WM_PRINTCLIENT = 0x0318;

       const int WM_ERASEBKGND = 0x0014;

       const int WM_PRINT = 0x0317;

       const int PRF_CHILDREN   = 0x00000010;

       const int PRF_CLIENT   = 0x00000004;

 

 

       public void GrabWindow()

      {

        

        

          IntPtr hWnd = this .Handle;

          IntPtr hBmp;

          Bitmap MyBitmap= null ;

 

          IntPtr hDCMem = GDI32.CreateCompatibleDC((IntPtr) null );

          IntPtr hDC = User32.GetWindowDC(hWnd);

          hBmp = GDI32.CreateCompatibleBitmap(hDC,(IntPtr)axWebBrowser1.Width ,(IntPtr)axWebBrowser1.Height);

          User32.ReleaseDC(hWnd, hDC);

          IntPtr hOld = GDI32.SelectObject(hDCMem, hBmp);

          User32.SendMessage(hWnd, WM_PRINT, hDCMem, new IntPtr(PRF_CLIENT | PRF_CHILDREN));

          GDI32.SelectObject(hDCMem, hOld);

          GDI32.DeleteObject(hDCMem);

          MyBitmap = Bitmap.FromHbitmap(hBmp);

          MyBitmap.Save( "test.png" ,ImageFormat.Png);

         this .Close();

      

      }

       /// <summary>

       /// Clean up any resources being used.

       /// </summary>

       protected override void Dispose( bool disposing )

      {

         if ( disposing )

        {

           if (components != null )

          {

            components.Dispose();

          }

        }

         base .Dispose( disposing );

      }

 

      #region Windows Form Designer generated code

       /// <summary>

       /// Required method for Designer support - do not modify

       /// the contents of this method with the code editor.

       /// </summary>

       private void InitializeComponent()

      {

        System.Resources.ResourceManager resources = new System.Resources.ResourceManager( typeof (Form1));

         this .axWebBrowser1 = new AxSHDocVw.AxWebBrowser();

        ((System.ComponentModel.ISupportInitialize)( this .axWebBrowser1)).BeginInit();

         this .SuspendLayout();

         //

         // axWebBrowser1

         //

         this .axWebBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;

         this .axWebBrowser1.Enabled = true ;

         this .axWebBrowser1.Location = new System.Drawing.Point(0, 0);

         this .axWebBrowser1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject( "axWebBrowser1.OcxState" )));

         this .axWebBrowser1.Size = new System.Drawing.Size(1024, 768);

         this .axWebBrowser1.TabIndex = 0;

         this .axWebBrowser1.DocumentComplete += new AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler( this .axWebBrowser1_DocumentComplete);

         //

         // Form1

         //

         this .AutoScale = false ;

         this .AutoScaleBaseSize = new System.Drawing.Size(5, 13);

         this .ClientSize = new System.Drawing.Size(1024, 768);

         this .Controls.Add( this .axWebBrowser1);

         this .FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;

         this .Name = "Form1" ;

         this .ShowInTaskbar = false ;

         this .Text = "Form1" ;

        ((System.ComponentModel.ISupportInitialize)( this .axWebBrowser1)).EndInit();

         this .ResumeLayout( false );

 

      }

      #endregion

 

       /// <summary>

       /// The main entry point for the application.

       /// </summary>

      [STAThread]

       static void Main()

      {

        Application.Run( new Form1());

      }

 

 

 

       private void axWebBrowser1_DocumentComplete( object sender, AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)

      {     

        GrabWindow();

      }

 

    }

 

class GDI32

{

  [DllImport( "GDI32.dll" )]

   public static extern bool BitBlt(IntPtr hdcDest,IntPtr nXDest,IntPtr nYDest,

    IntPtr nWidth,IntPtr nHeight,IntPtr hdcSrc,

    IntPtr nXSrc,IntPtr nYSrc,IntPtr dwRop);

  [DllImport( "GDI32.dll" )]

   public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc,IntPtr nWidth,

    IntPtr nHeight);

  [DllImport( "GDI32.dll" )]

   public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

  [DllImport( "GDI32.dll" )]

   public static extern bool DeleteDC(IntPtr hdc);

  [DllImport( "GDI32.dll" )]

   public static extern bool DeleteObject(IntPtr hObject);

  [DllImport( "GDI32.dll" )]

   public static extern IntPtr GetDeviceCaps(IntPtr hdc,IntPtr nIndex);

  [DllImport( "GDI32.dll" )]

   public static extern IntPtr SelectObject(IntPtr hdc,IntPtr hgdiobj);

 

}

 

   class User32

  {

    [DllImport( "User32.dll" )]

     public static extern IntPtr GetDesktopWindow();

    [DllImport( "User32.dll" )]

     public static extern IntPtr GetWindowDC(IntPtr hWnd);

    [DllImport( "User32.dll" )]

     public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDC);

    [DllImport( "User32.dll" )]

     public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

 

  }

}

Hmm..this is wierd...

A sudden problem has occurred on my blog and I'm not sure why...RSS feeds work fine, but the actual homepage does not, tried reindexing my SQL server, deleting a bunch of posts etc...still no joy! Very annoying!

UPDATE: So changing the skin seems to have cured the problem - I'll leave this boring one on for the moment, I'll upgrade to 0.95 (maybe 0.96 if I'm feeling brave) at the weekend.

This is very interesting - turn HTML documents into images

This is one of these things that's been running on a background thread in my brain for about a year, I have never seen a good example of how to do this but it just seems handy (I don't know what for but it 'feels' handy). Anyway, in the Codeproject mail  thingy today this article was hiding at the bottom. Now, one of the comments mentions a way to do this in C# - going to have to try to get this working!

UPDATE:  I almost have this working (just a very slight size issue right now) the handiest info is this discussion

 

One of the really sucky things about working for a small company...

You don't get to go to conferences. It really sucks, I would love to go to these things (though when I worked at a previous company which did send me to the Wrox conference in Amsterdam I umm... remember very little of it!). So, the choice is, blow almost £2000 of my own money going to a conference (so conference or holiday in the Bahamas would be my choice :-|) or just don't go..guess which is more likely. Incidnetally, if there is some Microsoft person who wants a gofer during the Teched Europe - or just someone to point at and laugh at and is willing to pay for me to go that would be just lovely :-) (not very likely is it -  but you have to try!)

Fonts for coding...am I in the minority

I was doing some work on the new version of my first article last night and I got to thinking, all the code in the new version is in the same font / colours that I use in my VS.NET. So, I was showing the new version to a friend and he mentioned that most people use fixed-width fonts when coding like profont. This got me to thinking, am I missing some trick here, I always use Verdana 8pt on a 1600x1200 120DPI screen with tuned Cleartype when I code - what's the disadvantages of this - why would I want to use a fixed-width font?

My wide and varied experience - or Jack of all trades, master of none.

I worte a few days about reasons I'd never be an MVP - today is a great exemplar of that. So far, I've fixed a few bugs on a bespoke community application (event handlers, HTML changes, T-SQL the lot), I' have  some more work on a generic search control based on Lucene.NET for inclusion in some of our projects,I have bit more work on an HttpModule I'm writing to hook CMS2002's workflow and security systems in with an external one we require and done some initial planning on a new pitch...I'm also in the planning stage of a quick Forum control which can work inside and outside of a CMS2002 placeholder.
Well...at least it keeps me busy :-)
I sometimes wonder if I'd be happy just focussing on one area all day - I really don't know if I could handle working on a single tool day after day...maybe a job on the MS Office for Macintosh team isn't in my future ;-)

Interesting new Googleized search engine from Amazon - a9 is born (and coincidentally a road from Perth to Aviemore)

Been having a play with the new search engine of the moment, a9...hmm...one suspects that Amazon will be collecting a fair bit of market info from this engine (can you think of another reason they'd want to do this?). First impressions are that it's very 'feature rich' (i.e, packed with stuff I'll never use), the popup site infor thing is pretty good I have a Traffic Rank of 1369996 - which probably puts me around the realms of the native Latin speakers portal.

It's the little things that make you happy

I've been lurking about in the ASP.NET forums a fair bit this evening and lo and behold I'm not moderated any more! Very cool - I guess I may have accidentally stumbled upon some right answers (see, you can apply JSP knowledge to ASP.NET  ;-))

Pet hate...well one of many..

I tried my experiment again today. I don't know about overseas but in the UK at crossings we have a green man and a red man - you walk at the green man. Now, I had believed it was commonly known that the green man doesn't appear unless you press the little button at the crossing which activates the 'wait' sign - which then triggers the crossing to change to green. Apparently this is not common knowledge (not in Edinburgh at least). Today I tried my experiment (I had a little time to spare :-)) when I arrived at the crossing, it was at red with about 20 people standing waiting to cross - but no-one had pressed the little button...so I waited...another 20 or so people joined over the next 6 minutes or so...still no-one pressed the button...I waited...a total of 10 minutes had passed and about 50 people were waiting to cross...I pushed the button, 15 seconds later, the green man appeared. Now I have never claimed to be some godlike genius but really, come on how dumb do you have to be not to realise that not pressing the button leads to the crossing not activating? (note this excludes IR sensor based crossings - of which there are a very few)

Scanning for viruses during file uploads

I'll be honest, this one puzzled me and I came up with some really hackneyed solutions to manage the situation where a user-uploaded file contained a virus (I develop lots of community sites which allow file uploads). Most of the solutions I came up with relied on using a FileSystemWatcher running as a service that detected when the Visrus Scanner on the server moved a file to quarantine - which works, but the fact is that even for a short period you have a virus laden file on your Web Server - sysadmins hate that! So, I was doing a little digging around and discovered this, it's basically a virus scanner which works as an ISAPI filter, monitoring all traffic passing into and out of IIS for viruses...probably really old news to most but I though it was cool!

Fairly interesting ASP.NET forums question - on using Global static variables instead of Application state in ASP.NET

I was replying to this forum post I actually couldn't find a good example on how to do this - wierd, it's such a common thing to do. So, the problem is, is there a better method than using the Application object to store objects which should be available for the entire lifetime of the application? Yes, global static variables are a great way to do this. Simply, you use the global.asax.cs file to define a static property - you can then access this simply using the Global.* in your code. For example, in the global.asax.cs:

public static ArrayList TestArrayList = new ArrayList();

Now, in any class I can access this...like so...

 

if(Global.TestArrayList != null)

{

          for(int i=0; i <1000; i++)

          {

                    Global.TestArrayList.Add(i);

          }

}

 

Cool, no copy required, (yes I do realise I should actually be locking this first to ensure thread safety...)So, short one, but might come in handy for someone! Oh, I did a little example app which also shows using this in an HttpModule, you can download it here

Why I will never be an MVP...

Oddly I've had a couple of email (even one from a Microserf) asking why I thought I would never become an MVP. Well, the simple answer is - time. Keeping a blog takes relatively little time, I probably spend an hour a day max posting to this thing and leaving selacious comments on other peoples - fine, I have no problem doing that. The problem arises when I have to block out significant periods of time to do stuff. In any one day I probably have about 2 hours where I can truly devote time to doing stuff of a technical nature, usually I spend my time reading articles and / or my book d'jour (currently Practical Cryptography which is excellent by the way). That's kind of the problem I get bored very quickly so the chances of spending enough time on one subject to be seen as any type of authority is pretty unlikely.
I do trawl through the ASP.NET forums on occasion and hunt down questions which I feel I could answer and that no-one else has (or has answered in such a dumb way that it amounts to the same thing) - but for me this usually takes an amount of time. I tend not just to link to KB articles / provide simple Googlized information, for this reason the number of posts I make there is pretty small (in the 200s the last time I looked). I've literally spent 3-4 hours writing example projects / code before now trying to find the best solution to a problem asked in the forums.
So in short, I'll never be an MVP because I don't have the time to devote to participating in the community that would seem to be a prerequisite.

For future reference...Page Events article

Just noticed this article by Paul Wilson from reading this post on his V1.x MasterPages Stuff. Nice, compact article on the timing of Page events in ASP.NET...very handy!

The morning after the night before...and please give the value back to the MVP label.

Roy clarifies his position on the whole Rory thing...(incidentally, Rory, I tried to email you but it bounced back)

My response, well, I posted an ill concieved post yesterday about the whole debacle which I have since withdrawn. Here's the response only response I'm willing to give on the whole thing - I will not enter into a debate on this - sorry!

I will never be made an MVP - so I have no vested interest in this apart from the desire to form a strong .NET community.

Sad thing is, the MVP title is worth something it's just not transparent enough and the few bad ones can tend to sour the whole barrel. It would be really nice if the community was more involved in the selection of MVPs and once they were announced, the reason for the selection was made more public.
Some current MVPs do seem to have been awarded for purely PR / other reasons - I hate to say, bribe but for some it does look that way. So, what does everyone think, should this be more open? Do you think that writing a book should justify you being made an MVP? 
So someone who wasn't an MVP got to go (probably a few people if truth be told, just that Rory blabbed). Unfortunately, this kind of thing does leave a bad taste - not because I  have anything against Rory. Problem is, building a community; something which seems to meet Microsofts' current PR aims; requires trust, it has to have leaders of course but those leaders must be seen as having earned that position once you single out an individual for 'special treatment' it can tend to cause friction within the community. Some MVPs have pointed out that they couldn't really see the reason that Rory was asked - most MVPs work hard to earn their award, one of the (as I see it relatively few) perks is getting in on the undisclosed information at the summit, having a back-door to getting there does seem a little unfair on these people. Again, this is not an attack on anyone but Microsoft, if you're really going to build a community, transparency in the selection for your proclaimed 'community leaders' - which is how you want us to view MVPs now, right? - would be a good first step.

Version 2 of my Nested Repeater article...new source code available.

Someone emailed me asking when the new version of my nested repeater article would be available - all I can say is very soon - hopefully I'll get some time to finish it this week. Anyway, the source code for the examples is complete, I'll probably add a couple more things to it when I publish the next version but these are the basics. You can download the archive here. I the archive you'll find examples of nesting using 'member method' and 'declarative' syntaxes as well as the ItemDataBound method detailed in my earlier article.

Outage...again...

Sorry, I had some downtime over the weeken - I was away for the Easter break and so was only able to restart just now. If you've sent me any mail over the last couple of days, chances are I haven't recieved it.

Lost it for a while but found it again...ILMerge - merge multiple assemblies into a single one (can make deployment easier)

I was reading SampoSofts blog when came across this which links to ILMerge, this is a little tool made by MSR (who are kind of the smartest guys at the smartest compnays - i.e., pretty smart!). What this does is combine multiple assemblies into one - why would you want to do that? Well, it can make deployment a bit easier for one and it lets you distribute a single exe instead of an exe and the 10 assemblies you you to provide most of the functionality (a lot cleaner)! Anyway, you can read more about it here. Also just found a really cool little code snippet here which lets you add this stuff to a post-build event in VS.NET. Currently using it for a little scheduled job where it makes it easier to manage versioning etc...

Hmm...should I ditch .NET?

OK, let me start by saying that I enjoy working in C# / .NET more than I have any other language / framework in my working life. The problem is, that's just not enough.
The simple fact is that I've chosen to live and work in Scotland and this severly limits my choices so far as my career goes - there's just not that many jobs up here in .NET and even fewer at my current level - if I hear the phrase 'I'm afraid the client thinks you have too much experience' once more I may have to start killing recruitment leeches.
So, I'm at one of my turning points again, I have them every 3 years or so.
My position is, do I keep going with .NET / C# knowing that the chances are that this will limit my job prospects severly for the forseeable future or do I switch (in my own time for the present) back over to Java / J2EE or even C / C++ - for which there are a TON of well paid, fairly interesting jobs around here (lots of banks in Edinburgh - most of which just don't trust .NET yet).
Well, I have an  Easter break coming up - could be decision time (I have just installed JBuilder X and it's looking pretty good!)

nLucene - full text search crawler / engine for .NET

I've been doing some work on using MSCMS2002 and have had to look at ways to implement search (by default it doesn't have it and requires that you buy a much expensive Sharepoint license) well, I revisited the nLucene project - this had stalled for a while but looks like it's back in development. Interestingly, one of the contributors seems to be Scott W.  - so I wouldn't be surprised if this became integrated with .TEXT in the near future... Anyway, take a look, it does seem incredibly cool and it would seem to benefit from the tons of development already exisitng for the Jakarta-Lucene Java version, even stating that the Java docs also apply to this version!

UPDATE: As Ryan Rinaldi pointed out in the comments,.TEXT 0.96 does have Lucene.NET (the new name for nLucene) already integrated, I was having a poke around the code today and it's pretty sweet. I reall recommend you check it out if you need a simple to implement, quick search engine for your site! Oh, and the next version of .TEXT will have an awesome search engine!

Excellent article on the new ASP.NET 2.0 Caching features from G. Andrew Duthie

Really exciting changes by the looks of it - not long now before we can actually use these features (well about a year). Anyway, a usual an excellent article from G. Andrew Duthie (or G. for short).

Probably old news but...Exchange Intelligent Message filter

I was scouting around to find a solution to my current spam overload (I currently use Cloudmark's Spamnet but it only runs on a client) and I came across this I just think it's really interesting that MS is planning to address the Spam plague in such a proactive way - and at long last!
The real pain in the butt though is this:

Intelligent Message Filter, scheduled for release in 2004, will be available exclusively to customers enrolled in Software Assurance. If your Exchange servers and associated client access licenses (CALs) are enrolled in Software Assurance (SA) when Intelligent Message Filter is released, you will be eligible to receive one complimentary license for the Intelligent Messaging Filter software for each Exchange server license that you have enrolled in SA. To receive a complimentary license for Intelligent Messaging Filter, make sure that your company is eligible. Your SA benefits coordinator can verify your company’s eligibility by visiting the Microsoft Volume Licensing Services site.

Why are they doing this? It's my belief that the more Spam removal tools are used then the less profitable Spam will become...go on, make it free and make it widely available!

My little compression helper...improved version

I posted my compression helper class before and realised almost instantly that it suffered from 'legacy lag' - so it'd been changed so much over the months that it was really bad!
Anyway, presented below is a modified version of that class (which I've also tried out my new formatting scheme on) as a reminder, it's just a simple wrapper around SharpZipLib.

using System;

using System.Text;

using System.IO;

using ICSharpCode.SharpZipLib;

 

 

namespace SerializableJob.Compression

{

            public enum CompressionType

            {

                        GZip,

                        BZip2,

                        Zip

            }

 

            public class Compression

            {

                        public static CompressionType CompressionProvider = CompressionType.GZip;

 

 

                        private static Stream OutputStream(Stream inputStream)

                        {

                                    switch(CompressionProvider)

                                    {

                                                case CompressionType.BZip2:

                                                            return new ICSharpCode.SharpZipLib.BZip2.BZip2OutputStream(inputStream);

                                                case CompressionType.GZip:

                                                            return new ICSharpCode.SharpZipLib.GZip.GZipOutputStream(inputStream);

                                                case CompressionType.Zip:

                                                            return new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(inputStream);

                                                default:

                                                            return new ICSharpCode.SharpZipLib.GZip.GZipOutputStream(inputStream);

                                               

                                    }

                        }

                        private static Stream InputStream(Stream inputStream)

                        {

                                    switch(CompressionProvider)

                                    {

                                                case CompressionType.BZip2:

                                                            return new ICSharpCode.SharpZipLib.BZip2.BZip2InputStream(inputStream);

                                                case CompressionType.GZip:

                                                            return new ICSharpCode.SharpZipLib.GZip.GZipInputStream(inputStream);

                                                case CompressionType.Zip:

                                                            return new ICSharpCode.SharpZipLib.Zip.ZipInputStream(inputStream);

                                                default:

                                                            return new ICSharpCode.SharpZipLib.GZip.GZipInputStream(inputStream);                                                                       

                                    }

                        }

           

                        public static byte[] Compress(byte[] bytesToCompress)

                        {

                                    MemoryStream ms = new MemoryStream();

                                    Stream s = OutputStream(ms);

                                    s.Write(bytesToCompress,0, bytesToCompress.Length);

                                    s.Close();

                                    return  ms.ToArray();

                        }

 

                        public static string Compress(string stringToCompress)

                        {

                                    byte[] compressedData = CompressToByte(stringToCompress);

                                    string strOut = Convert.ToBase64String(compressedData);

                                    return strOut;

                        }

                        public static  byte[] CompressToByte(string stringToCompress)

                        {

                                    byte[] bytData = Encoding.Unicode.GetBytes(stringToCompress);

                                    return Compress(bytData);;

                        }

 

                        public string DeCompress(string stringToDecompress)

                        {

                                    string outString = string.Empty;

                                    if (stringToDecompress == null)

                                                {

                                                            throw new ArgumentNullException("stringToDecompress","You tried to use an empty string");

                                                }

                                    try

                                    {

                                                byte[] inArr = Convert.FromBase64String(stringToDecompress.Trim());

                                                outString = System.Text.Encoding.Unicode.GetString(DeCompress(inArr));

                                    }

                                    catch (NullReferenceException  nEx)

                                    {

                                                return nEx.Message;

                                    }

                                    return outString;

                        }

 

                        public static  byte[]  DeCompress(byte[] bytesToDecompress)

                        {

                                    byte[] writeData = new byte[4096];

                                    Stream s2 = InputStream(new MemoryStream(bytesToDecompress));

                                    MemoryStream outStream = new MemoryStream();

                                    while(true)

                                    {

                                                int size = s2.Read(writeData,0,writeData.Length);

                                                if(size>0)

                                                {

                                                            outStream.Write(writeData,0,size);

                                                }

                                                else

                                                {

                                                            break;

                                                }

                                    }

                                    s2.Close();

                                    byte[] outArr = outStream.ToArray();

                                    outStream.Close();

                                    return outArr;

                        }

            }

 

}

 

?>

The 'factoryised' version of the cryptography class I mentioned previously...

I posted earlier about the really useful little encryption class by Ian Medvedev and mentioned that this could be factoryised pretty easy (well not really factoryised but you can switch the encryption provider). Anyway, here's what I can up with, pretty simple extension of the original allowing you to use whichever encryption type you want.

using System;

using System.IO;

using System.Security.Cryptography;

 

namespace SerializableJob.Compression

{

            public enum EncryptionType

            {

                        DES,

                        RC2,

                        TripleDES,

                        Rijndael

            }

            public class Encryption

            {

                        public static EncryptionType Algorithm = EncryptionType.Rijndael;

                        private static SymmetricAlgorithm m_cAlg

                        {

                                    get

                                    {

                                                switch(Algorithm)

                                                {

                                                            case(EncryptionType.Rijndael):

                                                                        return Rijndael.Create();

                                                            case(EncryptionType.DES):

                                                                        return DES.Create();

                                                            case(EncryptionType.RC2):

                                                                        return RC2.Create();

                                                            case(EncryptionType.TripleDES):

                                                                        return TripleDES.Create();

                                                            default:

                                                                        return Rijndael.Create();

                                                }         

                                    }

            }

 

                        public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)

                        {

                                    // Create a MemoryStream that is going to accept the encrypted bytes

                                    MemoryStream ms = new MemoryStream();

                                    SymmetricAlgorithm alg = m_cAlg;

                                    alg.Key = Key;

                                    alg.IV = IV;

                                    CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);

                                    cs.Write(clearData, 0, clearData.Length);

                                    cs.Close();

                                    byte[] encryptedData = ms.ToArray();

                                    return encryptedData;

                        }

 

                        public static string Encrypt(string clearText, string Password)

                        {

                                    byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);

                                    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

                                                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,  0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

                                    byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));

                                    return Convert.ToBase64String(encryptedData);

                        }

 

                        public static byte[] Encrypt(byte[] clearData, string Password)

                        {

                                    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

                                                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,  0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

                                    return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16));

                        }

 

                        public static void Encrypt(string fileIn, string fileOut, string Password)

                        {

                                    FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read);

                                    FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate, FileAccess.Write);

                                    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

                                                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,  0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

                                    SymmetricAlgorithm alg = m_cAlg;

                                    alg.Key = pdb.GetBytes(32);

                                    alg.IV = pdb.GetBytes(16);

                                    CryptoStream cs = new CryptoStream(fsOut, alg.CreateEncryptor(), CryptoStreamMode.Write);

                                    int bufferLen = 4096;

                                    byte[] buffer = new byte[bufferLen];

                                    int bytesRead;

                                    do

                                    {

                                                bytesRead = fsIn.Read(buffer, 0, bufferLen);

                                                cs.Write(buffer, 0, bytesRead);

                                    } while(bytesRead != 0);

                                    cs.Close();

                                    fsIn.Close();    

                        }

 

                        // Decrypt a byte array into a byte array using a key and an IV

                        public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV)

                        {

                                    MemoryStream ms = new MemoryStream();

                                    SymmetricAlgorithm alg = m_cAlg;

                                    alg.Key = Key;

                                    alg.IV = IV;

                                    CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);

                                    cs.Write(cipherData, 0, cipherData.Length);

                                    cs.Close();

                                    byte[] decryptedData = ms.ToArray();

      Â