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 |
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
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
}