July 2005 - Posts

I saw in this post that the Google toolbar could be extracted and looked at. So, I spend an afternoon reverse engineering the spell checker api. The api ends up to be very easy to use. Checking is done with an HTTP post to http://www.google.com/tbproxy/spell?lang=en&hl=en. The xml structure looks like this...
 
<?xml version="1.0" encoding="utf-8" ?>
<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">
    <text>Ths is a tst</text>
</spellrequest
>
 
The response look like ...
 
<?xml version="1.0" encoding="UTF-8"?>
<spellresult error="0" clipped="0" charschecked="12">
    <c o="0" l="3" s="1">This Th's Thus Th HS</c>
    <c o="9" l="3" s="1">test tat ST St st</c>
</spellresult
>
 
Tag
Description
o
the offset from the start of the text of the word
l
length of misspelled word
s
Confidence of the suggestion
text
tab delimited list of suggestions
 
I created a complete C# GoogleSpell library as a demo. The library can be download at http://www.loresoft.com/downloads/googlespell.zip
 
Here is an example on how to use GoogleSpell …
 
string text = "ths is a tst";
SpellRequest request = new SpellRequest(text);

SpellResult result = SpellCheck.Check(request);

foreach (SpellCorrection correction in result.Corrections)
{
    Console.WriteLine("Misspelled: {0} ({1}:{2})"
        text.Substring(correction.Offset, correction.Length), 
        correction.Offset, correction.Length);

    foreach(string suggestion in correction.Suggestions)
    {
        Console.WriteLine("    {0}", suggestion);
    }
}
 
I plan to develop an ajax web client for the google spell api.  This will be really sweet as it won't require anything to be installed on the sever other then a js file.  I'll post again when I have the web client complete.
 
~ Paul
with 17 comment(s)
Filed under:
Here is the handy Stopwatch class from .net 2.0 framework back ported .net 1.1. Enjoy…
/// <summary>Provides a set of methods and properties that you can use to accurately measure elapsed time.</summary>
public class Stopwatch
{
    #region SafeNativeMethods
    [DllImport("kernel32.dll")]
    private static extern bool QueryPerformanceFrequency(out long lpFrequency);
    [DllImport("kernel32.dll")]
    private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
    #endregion //SafeNativeMethods
    #region Public Fields        
    /// <summary>Gets the frequency of the timer as the number of ticks per second. This field is read-only.</summary>
    public static readonly long Frequency;
    
    /// <summary>Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.</summary>
    public static readonly bool IsHighResolution;
    
    #endregion //Public Fields
    
    #region Private Fields
    private long elapsed;        
    private bool isRunning;
    private long startTimeStamp;
    
    private static readonly double tickFrequency;
    #endregion //Private Fields
    #region Constructors
    static Stopwatch()
    {
        if (!QueryPerformanceFrequency(out Stopwatch.Frequency))
        {
            Stopwatch.IsHighResolution = false;
            Stopwatch.Frequency = TimeSpan.TicksPerSecond;
            Stopwatch.tickFrequency = 1;
        }
        else
        {
            Stopwatch.IsHighResolution = true;
            Stopwatch.tickFrequency = TimeSpan.TicksPerSecond;
            Stopwatch.tickFrequency /= ((double)Stopwatch.Frequency);
        }
    }
    
    /// <summary>Initializes a new instance of the Stopwatch class.</summary>
    public Stopwatch()
    {
        this.Reset();
    }
    #endregion //Constructors
    
    #region Private Methods
    private long GetElapsedDateTimeTicks()
    {
        long ticks = this.GetRawElapsedTicks();
        if (Stopwatch.IsHighResolution)
        {
            double highTicks = ticks;
            highTicks *= Stopwatch.tickFrequency;
            return (long)highTicks;
        }
        return ticks;
    }
    private long GetRawElapsedTicks()        
    {
        long elapsedTimestamp = this.elapsed;
        if (this.isRunning)
        {
            long currentTimestamp = Stopwatch.GetTimestamp();
            long endTimestamp = currentTimestamp - this.startTimeStamp;
            elapsedTimestamp += endTimestamp;
        }
        return elapsedTimestamp;
    }
    #endregion //Private Methods
    #region Public Methods
    /// <summary>Gets the current number of ticks in the timer mechanism.</summary>
    /// <returns>A long integer representing the tick counter value of the underlying timer mechanism.</returns>
    public static long GetTimestamp()        
    {
        if (Stopwatch.IsHighResolution)
        {
            long ticks = 0;
            QueryPerformanceCounter(out ticks);
            return ticks;
        }
        return DateTime.UtcNow.Ticks;
    }
    /// <summary>Stops time interval measurement and resets the elapsed time to zero.</summary>
    public void Reset()        
    {
        this.elapsed = 0;
        this.isRunning = false;
        this.startTimeStamp = 0;
    }
    /// <summary>Starts, or resumes, measuring elapsed time for an interval.</summary>
    public void Start()        
    {
        if (!this.isRunning)
        {
            this.startTimeStamp = Stopwatch.GetTimestamp();
            this.isRunning = true;
        }
    }
    /// <summary>Initializes a new Stopwatch instance, sets the elapsed time property to zero, and starts measuring elapsed time.</summary>
    /// <returns>A Stopwatch that has just begun measuring elapsed time.</returns>
    public static Stopwatch StartNew()        
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();
        return stopwatch;
    }
    /// <summary>Stops measuring elapsed time for an interval.</summary>
    public void Stop()        
    {
        if (this.isRunning)
        {
            long currentTimestamp = Stopwatch.GetTimestamp();
            long endTimestamp = currentTimestamp - this.startTimeStamp;
            this.elapsed += endTimestamp;
            this.isRunning = false;
        }
    }
    #endregion //Public Methods
    
    #region Public Properties
    /// <summary>Gets the total elapsed time measured by the current instance.</summary>
    /// <value>A read-only System.TimeSpan representing the total elapsed time measured by the current instance.</value>
    public TimeSpan Elapsed
    {
        get { return new TimeSpan(this.GetElapsedDateTimeTicks()); }
    }
    
    /// <summary>Gets the total elapsed time measured by the current instance, in milliseconds.</summary>
    public long ElapsedMilliseconds
    {
        get { return (this.GetElapsedDateTimeTicks() / TimeSpan.TicksPerMillisecond); }
    }
    /// <summary>Gets the total elapsed time measured by the current instance, in timer ticks.</summary>
    public long ElapsedTicks
    {
        get { return this.GetRawElapsedTicks(); }
    }
    
    /// <summary>Gets a value indicating whether the Stopwatch timer is running.</summary>
    public bool IsRunning
    {
        get { return this.isRunning; }
    }
    #endregion //Public Properties
}

with 2 comment(s)
Filed under:
More Posts