<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Martin Plante</title>
  <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/" />
  <link rel="self" href="http://blogs.xceedsoft.com/plantem/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2006-06-01T08:20:06.6656230-04:00</updated>
  <author>
    <name>Xceed Software Inc.</name>
  </author>
  <subtitle>Open window on development at Xceed </subtitle>
  <id>http://blogs.xceedsoft.com/plantem/</id>
  <generator uri="http://www.dasblog.net" version="1.8.5223.0">DasBlog</generator>
  <entry>
    <title>Time to go now</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,8eb9b861-08f5-4bac-ba22-87f3dbc2d3d8.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,8eb9b861-08f5-4bac-ba22-87f3dbc2d3d8.aspx</id>
    <published>2006-06-01T08:20:06.6656230-04:00</published>
    <updated>2006-06-01T08:20:06.6656230-04:00</updated>
    <category term="General" label="General" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Today is my last day at Xceed... snif...
   </p>
        <p>
      I leave lighthearted, because I have made sure the transition here goes smootly. I
      have completed <a href="http://www.xceedsoft.com/products/ZipNet/whatsnew.htm">AES
      encryption support</a> in Xceed Zip for .NET, which was released a few weeks ago,
      and helped Jacques complete HTTP proxy support in Xceed FTP for .NET, currently in
      RC tests for the next package.
   </p>
        <p>
      It's been an incredible 9 years, and I thank Odi and Daniel for given me the latitude
      to come up with ambitious and non-conventional designs like the FileSystem Core.
   </p>
        <p>
      I also feel very lucky to have worked with such talented developers and coworkers.
      You are a second family. I'm sure the rest of the team won't be jealous if I address
      special thanks and admiration to Pascal, with whom I have designed and developed
      Xceed Zip v4+, Xceed Backup, Xceed Winsock, Xceed FTP and the amasing experience and
      fun we had creating Xceed Zip for .NET.
   </p>
        <p>
      Finally, It's been an honor having the chance to talk and chat with a few customers,
      through support, forums and this blog. It is very important for software developers
      building commercial applications to stay in touch with the customers, instead of hiding
      behind the marketing or support staff. True input comes from customers.
   </p>
        <p>
      Thank you.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=8eb9b861-08f5-4bac-ba22-87f3dbc2d3d8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PowerShell?</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,059518d6-3cbf-4835-980a-411c9d7a8096.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,059518d6-3cbf-4835-980a-411c9d7a8096.aspx</id>
    <published>2006-04-26T07:03:32.0150000-04:00</published>
    <updated>2006-04-26T07:03:32.0150000-04:00</updated>
    <category term="General" label="General" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Is it just me, or <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=2B0BBFCD-0797-4083-A817-5E6A054A85C9&amp;displaylang=en">that
      new name</a> for MSH (aka Monad), the new managed MS Shell, sounds aweful? PowerShell?
      Argh...
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=059518d6-3cbf-4835-980a-411c9d7a8096" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Releases come and go...</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,b637efea-3f3b-4ed3-84b9-99a588912b33.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,b637efea-3f3b-4ed3-84b9-99a588912b33.aspx</id>
    <published>2006-04-05T08:43:13.6990000-04:00</published>
    <updated>2006-04-05T15:47:42.7771250-04:00</updated>
    <category term=".NET" label=".NET" scheme="dasBlog" />
    <category term="FTP" label="FTP" scheme="dasBlog" />
    <category term="General" label="General" scheme="dasBlog" />
    <category term="Zip" label="Zip" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      It's been a long time since I've posted something "chewable". My energies were all
      directed on the soon to be released <a href="http://xceedsoft.com/products/ZipNet/">Xceed
      Zip for .NET</a> version 3.0. Though the apparent changes on the public interface
      are quite minor, and one can teach the new classes quite easily, the underlying code
      wasn't trivial.
   </p>
        <p>
      In short, for all of you who know what ZipArchive, ZippedFile and ZippedFolder are,
      say hello to TarArchive, TarredFile, TarredFolder, GZipArchive and GZippedFile.
   </p>
        <p>
      And when I say "easy to teach", what it really means is "find yourself a zipping example,
      and replace class name occurances of Zip{something} with Tar{somethong} or GZip{something}".
   </p>
        <p>
      Sure, there are some gotchas, like the fact that a GZIP archive cannot contain
      filenames with subfolders, are not well-suited to contain more than one compressed
      file, and can contain files without filenames. But these are details you'll get used
      to quite easily.
   </p>
        <p>
      There are two things that make me really proud in that product. One is under the hood,
      and the other is a sample. First, the engine: My colleague Jacques and I have come
      up with what we call the "Storage Engine". It's an abstraction of what an archiving
      library needs in term of temp storage, in-place archive updating, and transactional
      operations on an archive. Both the new TAR and GZIP implementations use it. In short,
      it abstracts the fact that we want to always update an archive in-place when possible,
      but revert to temp files and make sure to commit those temp files with any existing
      archive upon the last modification of it. If things go well, the ZIP implementation
      will benefit from it sooner than later.
   </p>
        <p>
      Second, the sample: The FTP Sample Explorer is gone, replaced with the FileSystem
      Snippet Explorer, a sample that let's you see, modify and run code snippets that show
      you the various tasks one might wish to implement. It goes straight to the point.
      No bells and whistle, no gravy, just the meat. The code is embedded in the executable
      as compressed serialized XML data. The main information (each topic's description
      and code) is nothing else than rich text. The nice thing about this sample is
      that in order for me to modify and add new topics, I simply need to compile the project
      with an extra define, and I'm now running the application in "admin" mode, enabling
      me to update the compressed XML file directly, for the next compilation to benefit
      from this update.
   </p>
        <p>
      Though I've finished work on this 3.0 version, I already have both hands in the two
      next releases of Xceed Zip for .NET and Xceed FTP for .NET. The first one will add
      support for AES encryption, and the second one will now offer proxy support.
   </p>
        <p>
      I didn't have much time to write because all those releases have a tight schedule
      I can't bust. I'm leaving Xceed in two months. Yup, I've decided it was time for me
      to move on. Until then, I have agreed to complete AES implementation, help Jacques
      kick-start proxy support and train about everybody here, each earning one of the numerous
      hats I'm wearing. It was a very difficult decision, since I have only friends at Xceed.
      Though the nine years or so I've spent here were exciting and challenging, I feel
      it's time for me to try new stuff... by myself. This isn't a divorce. I won't be far
      from Xceed, and still available to help them from time to time. As for you, dear customers
      and readers, rest assured you will stay in good hands. The team behind Xceed Zip and
      Xceed FTP, both .NET and ActiveX, will remain strong, even get stronger than it is
      now.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=b637efea-3f3b-4ed3-84b9-99a588912b33" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Podcast experience</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,11613427-a9c3-4afc-8418-435bfccdd80b.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,11613427-a9c3-4afc-8418-435bfccdd80b.aspx</id>
    <published>2006-03-10T12:07:10.3603750-05:00</published>
    <updated>2006-03-10T12:07:10.3603750-05:00</updated>
    <category term="General" label="General" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Last Wednesday, I was invited to the <a href="http://www.visualstudiotalkshow.com/Archives/8mars2006-MartinPlante.html">Visual
      Studio Talk Show</a>, a French podcast about software development. I enjoyed the experience
      a lot, but can only understand how you can be intimidated when it's the first time
      you express yourself such in a "live" way. I may have experience teaching in front
      of a small crowd, or presenting in front of a larger one, you cannot prepare yourself
      in the same way when you're an invitee, and depend on your host's questions and direction.
   </p>
        <p>
      For example, everybody agrees that <a href="http://www.hanselman.com/blog/">Scott
      Hanselman</a>'s <a href="http://hanselminutes.com/">HanselMinutes</a> improved dramatically,
      no later than starting with <a href="http://hanselminutes.com/default.aspx?showID=3">his
      second podcast</a>. That's probably why I'm left with mixed emotions. I'd repeat the
      experience anytime, just to have an opportunity to improve. But this time,
      I'd be the driver!
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=11613427-a9c3-4afc-8418-435bfccdd80b" />
      </div>
    </content>
  </entry>
  <entry>
    <title>It's only metal...</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,fe307583-e041-46c8-9099-24e86997e93c.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,fe307583-e041-46c8-9099-24e86997e93c.aspx</id>
    <published>2006-03-06T08:53:24.4478750-05:00</published>
    <updated>2006-03-06T08:53:24.4478750-05:00</updated>
    <category term="General" label="General" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Last week, I got a car accident. I was driving my son to the kindergarden. We were
      lucky, I hit the side of the other car, who was going in the opposite direction, so
      the impact was more friction than collision. My air bags did not open, that's a sign
      the impact was not a head-on collision.
   </p>
        <p>
      My first instinct was to make sure my boy was ok. He was, top shape, asking what was
      the noise he heard. I moved the car in a nearby parking lot, so did the lady in the
      other car. Everybody seemed ok. It felt good. "It's only metal" I kept saying to myself
      and the lady, who was very sorry about her mistake. She did not notice the red flashing
      lights indicating a defective light and requiring full stop. "I thought it was green"
      she even said.
   </p>
        <p>
      Anyway, my boy's fine, I'm fine, the car's at the garage and will be fixed soon (I
      hope), without me requiring to spend a single penny (thanks to a no-fault), courtesy
      car included. And to everybody I tell this story, I keep saying "It's only metal.
      The important thing is my son and I are ok."...
   </p>
        <p>
      No... I'm lying... It's not only metal. It's a damn bruise on your pride. I should
      have made sure all was clear before turning left on that red flashing light. I should
      have been a 100% focused instead of being distracted by my son pointing the damaged
      light post to our right. I should have steered the wheel full right faster when I
      saw the other car about to collide. It went so fast, I'm stuck with the feeling I
      did nothing, I was a spectator.
   </p>
        <p>
      Last week has been a difficult week. I've played real cool and calm with my son and
      wife, making sure they forget quickly. But something's broken... and it's not only
      metal.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=fe307583-e041-46c8-9099-24e86997e93c" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Heredity?</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,c87d9bf0-cdeb-45a6-9cb7-63c45b8813cf.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,c87d9bf0-cdeb-45a6-9cb7-63c45b8813cf.aspx</id>
    <published>2006-02-13T11:37:22.5372500-05:00</published>
    <updated>2006-02-13T11:37:22.5372500-05:00</updated>
    <category term="Fun" label="Fun" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I've seen some strange behavior from my 3 year old son Clément lately. I fear
      heredity...
   </p>
        <p>
          <img src="http://blogs.xceedsoft.com/plantem/content/binary/Pict0786.jpg" border="0" />
        </p>
        <p>
          <img src="http://blogs.xceedsoft.com/plantem/content/binary/Pict0789.jpg" border="0" />
        </p>
        <p>
          <img src="http://blogs.xceedsoft.com/plantem/content/binary/Pict0791.jpg" border="0" />
        </p>
        <p>
          <img src="http://blogs.xceedsoft.com/plantem/content/binary/Pict0793.jpg" border="0" />
        </p>
        <p>
          <img src="http://blogs.xceedsoft.com/plantem/content/binary/Pict0797.jpg" border="0" />
        </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=c87d9bf0-cdeb-45a6-9cb7-63c45b8813cf" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Build version number</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,0e2bbcd8-f941-43e4-859b-802745969f60.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,0e2bbcd8-f941-43e4-859b-802745969f60.aspx</id>
    <published>2006-02-09T15:24:57.9120000-05:00</published>
    <updated>2006-02-09T16:26:23.6778750-05:00</updated>
    <category term="Fun" label="Fun" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Wonder what's the formula behind Xceed's build numbers? Here's the secret recipe:
   </p>
        <p>
      ( Year - 2000 ) * 1000 + ( Month * 50 ) + ( Day )
   </p>
        <p>
      Heck, we even made ourselves an <a href="http://blogs.xceedsoft.com/plantem/content/binary/Xceed%20Version.widget.zip">Xceed
      Version Yahoo! Widget!!!</a></p>
        <p>
          <font size="1">
            <strong>Update</strong>: Until I learn how to open the ".widget" extension
      for downloading in dasBlog, I renamed the file to "Xceed Version.widget.zip". Just
      rename to "Xceed Version.widget" once downloaded.</font>
        </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=0e2bbcd8-f941-43e4-859b-802745969f60" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Pass-through streams</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,efb9c15a-a6e0-492b-af25-193e9be22594.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,efb9c15a-a6e0-492b-af25-193e9be22594.aspx</id>
    <published>2006-01-31T09:47:29.2970000-05:00</published>
    <updated>2006-01-31T09:47:29.2972447-05:00</updated>
    <category term=".NET" label=".NET" scheme="dasBlog" />
    <category term="Compression" label="Compression" scheme="dasBlog" />
    <category term="FileSystem" label="FileSystem" scheme="dasBlog" />
    <category term="FTP" label="FTP" scheme="dasBlog" />
    <category term="Zip" label="Zip" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Ever since I've been working with the .NET framework, most of my time was spent on
      the <a href="http://msdn2.microsoft.com/en-us/library/29kt2zfk(en-us,VS.80).aspx">System.IO</a> namespace.
      I'm not a UI guy, I'm an IO guy! The most important class in that namespace is <a href="http://msdn2.microsoft.com/en-us/library/system.io.stream.aspx">System.IO.Stream</a>.
      And since it was well-designed, probably inspired by other successful stream implementations
      (Delphi comes to mind), it's very easy to expose features using streams.
   </p>
        <p>
      My favorite use of streams is for pass-through streams. A pass-through stream
      is a class which derives from System.IO.Stream, but reads from or writes to an inner
      stream received at creation. It serves as a data modifyer or data analyser. When reading
      from a pass-through stream, it first reads from its inner stream, then processes the
      data read (potentially modifying it) and returns this data. When writing to a pass-through
      stream, it first processes the provided data (again potentially modifying it), then
      writes it to its inner stream.
   </p>
        <p>
      Xceed Zip for .NET and Xceed FTP for .NET both use a pletoria of pass-through streams.
      The most popular is <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.compression.compressedstream.html">Xceed.Compression.CompressedStream</a>,
      the stream responsible for compressing data before writing it to its inner stream,
      or decompressing data read from its inner stream. But most others are internal. We've
      been juggling with the idea of exposing them for a long time, but beleive it would
      only confuse developers to "see" those new namespaces and classes. Another useful
      thing with internal classes is that we can change their interface without causing
      breaking changes.
   </p>
        <h5>TransientStream
   </h5>
        <p>
      It was a long debate before we decided to go forth with the "transient" keyword. Not
      only is it used in the TransientStream type name, but also as a property on many of
      our pass-through streams. What we meant by "transient" is "volatile", or if you prefer
      more explicit keywords, "does-not-close-its-inner-stream-when-closed". A TransientStream
      is about the simplest expression of a pass-through stream. All required property and
      method overrides simply call the inner stream. The only exception is for the Close
      method, which simply makes sure not to call Close on the inner stream. This is very
      useful when you need to pass your stream to another routine which closes the stream,
      while you don't want your stream to get closed.
   </p>
        <h5>ChecksumStream
   </h5>
        <p>
      This stream does not modify the data read from or written to, but takes the opportunity
      to calculate either a CRC32 or an Adler32 on that data. When reading, it can also
      make sure, upon closing it, that the calculated checksum matches an expected stream, else
      throw an exception. In this way, we can insert checksum calculation anywhere in a
      process without interfering nor requiring code changes.
   </p>
        <h5>CombinedStream
   </h5>
        <p>
      The deflate compression algorithm has the ability to detect the end of the data when
      decompressing. The CompressedStream is itself a pass-through stream. When reading
      from it, it first reads from the inner stream, then decompresses the data. When
      it reaches the end of the compressed data, the CompressedStream has the ability to
      return a stream on the remaining data, in case this inner stream contains more data
      after the compressed block. Why isn't this equivalent to the inner stream you might
      ask? Let's say the inner stream isn't seekable. The CompressedStream's Read method
      first reads N bytes from the inner stream, but may have found that the end of the
      compressed data is after M bytes (M &lt; N). The inner stream is already N-M bytes
      too far. The CombinedStream receives both a byte array (the unused N-M bytes) and
      the inner stream as ctor parameters, and will expose those as one contiguous stream.
      Pretty slick!
   </p>
        <h5>HeaderFooterStream
   </h5>
        <p>
      Xceed Streaming Compression for .NET exposes stream-based (as opposed to archive-based)
      compression formats. Those formats all have one thing in common: they have a header
      and a footer. Not all of them can depend on the deflate algorithm to automatically
      detect the end of the stream. That's why they need to make sure to never return the
      first M bytes and last N bytes from the inner stream, where M is the expected header
      size and N the expected footer size.
   </p>
        <h5>WindowStream
   </h5>
        <p>
      When exposing part of a zip file as a single AbstractFile, we need to make sure we
      do not read past the boundaries of that file's data in the zip file. The WindowStream
      exposes a region of its inner stream as a zero-position, N-length stream.
   </p>
        <h5>ZCryptStream
   </h5>
        <p>
      This pass-though stream automatically encrypts or decrypts the data written or read,
      using the basic Zip encryption (which is as weak as me in front of a cheese cake).
      I will be working on AES encryption very soon, and it will most probably be implemented
      as a pass-through stream too!
   </p>
        <h5>NotifyStream
   </h5>
        <p>
      Though pass-through streams can do much of the task, it is often better for the clarity
      of the code to have processing done by other classes not deriving from System.IO.Stream.
      The NotifyStream class exposes three events: ReadingFromStream, WritingToStream and
      ClosingStream. Any other class can advise for those events to intervene in the reading
      or writing process. This old class exists since the beginning of Xceed Zip for .NET,
      but it has proven very useful in the current development we are doing for Tar and
      GZip support within Xceed Zip for .NET.
   </p>
        <h5>ForwardSeekableStream
   </h5>
        <p>
      This new class created for Xceed Zip for .NET 3.0 (Tar and GZip support) can expose
      a non-seekable stream as a seekable stream when reading, or at least a stream reporting
      a Position when writing. When reading, you can call Seek with an offset behond
      the current position, and it will simply read from the non-seekable inner stream until
      well positioned. And for both reading and writing operations, it counts the number
      of bytes read or written so it can report a position (granting we knew
      the original position when created).
   </p>
        <h5>FtpAsciiDataStream
   </h5>
        <p>
      Xceed FTP for .NET also uses pass-through streams. For example, the FtpAsciiDataStream
      wraps the NetworkStream to perform convertion of LF to CR/LF on the fly when sending
      a file in ASCII mode.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=efb9c15a-a6e0-492b-af25-193e9be22594" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Google Maps advertizing</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,04adca96-a075-4dfd-8aaf-20a01b6ecc45.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,04adca96-a075-4dfd-8aaf-20a01b6ecc45.aspx</id>
    <published>2006-01-17T09:46:11.6979139-05:00</published>
    <updated>2006-01-17T09:46:11.6979139-05:00</updated>
    <category term="Fun" label="Fun" scheme="dasBlog" />
    <category term="General" label="General" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Found <a href="http://adverlab.blogspot.com/2005/08/advertising-with-google-maps.html">this</a> from <a href="http://www.hanselman.com/blog/PermaLink.aspx?guid=8f8387ab-1880-4039-a194-aa841457abe5">Scott</a>...
      Hey! It was <a href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,9649b38a-6206-4f0a-b76c-f715a35a9d35.aspx">my
      idea</a>!
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=04adca96-a075-4dfd-8aaf-20a01b6ecc45" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Filtering files with the Xceed FileSystem</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,c29297be-30dd-42bc-a93e-2abeb12736aa.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,c29297be-30dd-42bc-a93e-2abeb12736aa.aspx</id>
    <published>2006-01-17T09:35:07.5480000-05:00</published>
    <updated>2006-01-18T12:05:13.8675000-05:00</updated>
    <category term=".NET" label=".NET" scheme="dasBlog" />
    <category term="FileSystem" label="FileSystem" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      One of the less known features of the Xceed FileSystem is its <a href="http://doc.xceedsoft.com/products/zipNet/doc/sources/using_filters.htm">file
      filtering capabilities</a>. Not only does it come with built-in support for filtering
      files based on name, size, attributes and dates, it also lets you easily combine criterias.
      Furthermore, as for all Xceed components, it's fully extensible.
   </p>
        <p>
      For example, let's say I want to copy files matching the <em>"*.txt"</em> filter that
      have the <em>archive</em> attribute on. The following code can be used:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, "*.txt", FileAttributes.Archive );</pre>
        <p>
      What is happening beneath the surface? The fouth parameter is <em>"params object[]
      filters"</em>. This means you can provide any number of any types of parameters. Any
      types? Not exactly. What you should see is <em>"params Filter[] filters"</em>. The <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.filtermembers.html">Filter</a> class
      is the base class for any type of filter you could think of. The Xceed FileSystem
      comes with seven built-in filter classes, divided in two categories:
   </p>
        <p>
      Operators: <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.andfiltermembers.html">AndFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.orfiltermembers.html">OrFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.notfiltermembers.html">NotFilter</a>.<br />
      Filters: <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.namefiltermembers.html">NameFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.attributefiltermembers.html">AttributeFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.sizefiltermembers.html">SizeFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.datetimefiltermembers.html">DateTimeFilter</a>.
   </p>
        <p>
      So the line of code above can be seen as this:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true,<br />
       new AndFilter( new NameFilter( "*.txt" ), new AttributeFilter(
   FileAttributes.Archive ) ) );</pre>
        <p>
      But we've decided that forcing the creation of a new <em>NameFilter</em> everytime
      you want to filter on a mask was overkill for such a common operation. That's why
      we also accept two other types of parameters. Strings are automatically converted
      to a <em>NameFilter</em>, and <em>FileAttributes</em> are automatically converted
      to an <em>AttributeFilter</em>. Finally, providing two or more filters as separate
      parameters automatically puts them in an <em>AndFilter</em>.
   </p>
        <p>
      But then, what happens to another common scenario: filtering files based on two name
      filters? Passing <em>"*.txt"</em> as the fourth parameter, and <em>"*.doc"</em> as
      the fifth would generate an <em>AndFilter</em> around them, thus only matching files
      that match the <em>".txt"</em> <strong>and</strong> the <em>".doc"</em> extensions...
      Oups!
   </p>
        <p>
      We support yet another exception: any string filter can contain a pipe character (|)
      for providing multiple name filters that will be grouped in an <em>OrFilter</em>,
      like this:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, "*.txt|*.doc" );</pre>
        <p>
      This will automatically be translated to:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, 
   <br />
       new OrFilter( new NameFilter( "*.txt" ), new NameFilter( "*.doc"
   ) ) );</pre>
        <p>
      By the way, most operator-like filters' constructors will accept strings and <em>FileAttributes</em> too,
      doing the translation to <em>NameFilter</em> and <em>AttributeFilter</em> instances for
      you.
   </p>
        <p>
      The final "hidden" feature relates to case sensitivity. By default, the FileSystem
      is case insensitive, as is the Windows platform. But since archives like zip files
      may come from other planets like Linux or Mac OS X, we wanted to support case-sensitive
      file matching. If you prepend your string with the "greater than" character (&lt;),
      the resulting <em>NameFilter</em> will be case-sensitive. The following code will
      only match files which have their extension in upper-case:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, "&gt;*.TXT" );</pre>
        <p>
      Since Windows does remember the casing of filenames, this can be very useful even
      on the Windows platform. Furthermore, since we released the library, the <a href="http://mono-project.com/Main_Page">Mono
      project</a> came to life, and our library can now be used on other platforms.
   </p>
        <h4>Extending filters
   </h4>
        <p>
      You can easily create custom filters by deriving from the <em>Xceed.FileSystem.Filter</em> class
      and overriding the <em>IsItemMatching</em> method. A <em>SearchFilter</em> class,
      which searches for a particular text within files could look like this:
   </p>
        <pre>  class SearchFilter : Filter<br />
     {<br />
       public SearchFilter( string text )<br />
         : base( FilterScope.File )<br />
       {<br />
         if( text == null )<br />
           throw new ArgumentNullException( "text"
   );<br /><br />
         if( text.Length == 0 )<br />
           throw new ArgumentException( "The text
   cannot be empty.", "text" );<br /><br />
         m_text = text;<br />
       }<br /><br />
       public override bool IsItemMatching( FileSystemItem item )<br />
       {<br />
         AbstractFile file = item as AbstractFile;<br /><br />
         if( file == null )<br />
           return false;<br /><br />
         try<br />
         {<br />
           int bufferSize = ( file.Size &lt; 0x1000000
   )<br />
             ? unchecked( ( int )file.Size
   ) 
   <br />
             : 0x1000000;<br /><br />
           byte[] search = System.Text.Encoding.Default.GetBytes(
   m_text );<br /><br />
           if( search.Length &lt;= bufferSize )<br />
           {<br />
             byte[] buffer = new byte[ bufferSize
   ];<br />
             int found = 0;<br /><br />
             using( BinaryReader reader
   = new BinaryReader( file.OpenRead( FileShare.ReadWrite ) ) )<br />
             {<br />
               int read = 0;<br /><br />
               while( ( read =
   reader.Read( buffer, 0, bufferSize ) ) &gt; 0 )<br />
               {<br />
                 found
   = FindBuffer( buffer, 0, read, search, found );<br /><br />
                 if(
   found == search.Length )<br />
                  
   return true;<br />
               }<br />
             }<br />
           }      
   <br />
         }<br />
         catch {}<br /><br />
         return false;<br />
       }<br /><br />
       private int FindBuffer( 
   <br />
         byte[] source, 
   <br />
         int sourceStart, 
   <br />
         int sourceCount, 
   <br />
         byte[] search, 
   <br />
         int searchIndex )<br />
       {<br />
         // TODO: Param check!<br /><br />
         for( int i=0; i&lt;sourceCount; i++ )<br />
         {<br />
           if( source[ sourceStart + i ] == search[
   searchIndex ] )<br />
           {<br />
             if( ++searchIndex == search.Length
   )<br />
               return searchIndex;<br />
           }<br />
           else<br />
           {<br />
             searchIndex = 0;<br />
           }<br />
         }<br /><br />
         return searchIndex;<br />
       }<br /><br />
       private string m_text; // = null<br />
     }</pre>
        <p>
      Using this custom filter, you can now copy only files that contain a particular text:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, new SearchFilter( "allo" ) );</pre>
        <h4>Conditionally recursing
   </h4>
        <p>
      One missing feature we had with the filtering will be addressed with today's release.
      There were no way to control which subfolders to recurse into or not when calling
      methods accepting filters (<em>CopyFilesTo</em>, <em>MoveFilesTo</em>, <em>GetFiles</em>, <em>GetFolders</em>).
      The <em>FilterScope.Folder</em> value wasn't preventing recursing into subfolders.
      It was only meant to include or exclude folder entries from being copied. But passing
      "true" or "false" as the "recurse" parameter was an all or nothing deal.
   </p>
        <p>
      Today, we introduce a new scope: <em>FilterScope.Recurse</em>. It does not interfere
      with the <em>File</em> or <em>Folder</em> socpe, and only determines if we should
      continue matching files into each subfolder. Its number one use is for excluding subfolders:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, 
   <br />
       "*.txt", new NotFilter( new NameFilter( "Bar", FilterScope.Recurse
   ) ) );</pre>
        <p>
      The way you combine <em>"Recurse"</em> filters and other filters is irrelevant. When
      deciding to copy files or folders, the library ignores any filters with the <em>Recurse</em> scope.
      When deciding to call itself recursively, the library ignores any filters with the <em>File</em> or <em>Folder</em> scope.
   </p>
        <p>
      We plan on providing new types of filters. Suggestions welcomed!
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=c29297be-30dd-42bc-a93e-2abeb12736aa" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Podcasting and me</title>
    <link rel="alternate" type="text/html" href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,0247049e-b188-4577-986f-62978c0f7f7e.aspx" />
    <id>http://blogs.xceedsoft.com/plantem/PermaLink,guid,0247049e-b188-4577-986f-62978c0f7f7e.aspx</id>
    <published>2006-01-11T09:09:26.3336250-05:00</published>
    <updated>2006-01-11T09:09:26.3336250-05:00</updated>
    <category term="General" label="General" scheme="dasBlog" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
      First, I wish all my readers health and happyness for the new year.
   </p>
        <p>
      Now, let's jump into the subject of the day: <a href="http://www.hanselman.com/blog/HanselminutesPodcast1.aspx">Scott
      Hanselman</a>'s <a href="http://hanselminutes.com/default.aspx?showID=2">HanselMinutes</a>.
      I'm currently listening to his first podcast. I've never been a real fan of podcasts,
      but since Scott Hanselman is about my number 1 blogger, I could not miss this event.
   </p>
        <p>
      Hmmm, how can I express my feelings about podcasting without hurting Scott's feelings?
      Is it me, or are computer subjects not fit for audio? I want links! I want screenshots!
      I want examples! I want immediate access to extended information upon my needs! With
      a podcast, I'm stuck listening to all the stream. Sure, I can fast forward, but you
      end-up playing the "find that show you recorded" game you play with your VCR. Worse,
      you don't know what you're looking for. You are at the mercy of the podcaster. You
      can't filter, you can't opt in or out of a subject.
   </p>
        <p>
      Maybe I'm not listening podcasts at the proper moment? Maybe I'm trying to use podcasts
      as if they were audio blogs, which they are not? I tried listening to a podcast in
      my car on the way to work, just to discover I was sad missing the local news and forecasts
      I usually listen to in the morning. I tried listening to a podcast at home in the
      evening when I push my computer geekness to its limits by moving back to a computer,
      but I generally need to disconnect from work, and I prefer playing Guild Wars! I tried
      listening to a podcast in bed before getting to sleep, just to find out I prefer doing
      other things in bed... like sleeping... and... ok, you get the picture!
   </p>
        <p>
      The funny part is that I've been approached by the <a href="http://www.visualstudiotalkshow.com">Visual
      Studio Talk Show</a> for a 45 minutes podcast-style interview in French, and I've
      said yes. But it's only a one time deal. Even though this show is mostly accessible
      as a podcast, I see this as an interview, and no way I could maintain a weekly podcast.
   </p>
        <p>
      So I'll conclude with Scott's own words: <a href="http://www.hanselman.com/blog/PermaLink.aspx?guid=63429b26-ba44-4f17-8f83-81f1e9a433b6">podcasting
      sucks</a>. It wastes my precious time. I would have liked it very much if <a href="http://weblogs.asp.net/cfranklin/">Carl
      Franklin</a> would have asked Scott about his background, his developer
      path, about himself. I want to know more about Scott. For links, I'll continue reading
      his blog.
   </p>
        <p>
      Oh, and one more thing: the damn advertising is barely tolerable.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=0247049e-b188-4577-986f-62978c0f7f7e" />
      </div>
    </content>
  </entry>
</feed>