// crudwork
// Copyright 2004 by Steve T. Pham (http://www.crudwork.com)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with This program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Text;
namespace crudwork.Utilities
{
/// <summary>
/// Collection of manipulations, parsers, and other
/// methods related to Character.
/// </summary>
public static class CharUtil
{
/// <summary>
/// Test an input character if it is contained in a character list.
/// </summary>
/// <param name="inputChar"></param>
/// <param name="inputList"></param>
/// <returns></returns>
public static bool ContainsChar(char inputChar, char[] inputList)
{
List<char> clist = new List<char>();
clist.AddRange(inputList);
return clist.Contains(inputChar);
}
}
}
Month: February 2011
Buffer for characters
// CharBuffer.cs
//
// Copyright (C) 2003-2004 Ryan Seghers
//
// This software is provided AS IS. No warranty is granted,
// neither expressed nor implied. USE THIS SOFTWARE AT YOUR OWN RISK.
// NO REPRESENTATION OF MERCHANTABILITY or FITNESS FOR ANY
// PURPOSE is given.
//
// License to use this software is limited by the following terms:
// 1) This code may be used in any program, including programs developed
// for commercial purposes, provided that this notice is included verbatim.
//
// Also, in return for using this code, please attempt to make your fixes and
// updates available in some way, such as by sending your updates to the
// author.
using System;
namespace RTools_NTS.Util
{
/// <summary>
/// Buffer for characters. This approximates StringBuilder
/// but is designed to be faster for specific operations.
/// This is about 30% faster for the operations I'm interested in
/// (Append, Clear, Length, ToString).
/// This trades off memory for speed.
/// </summary>
/// <remarks>
/// <para>To make Remove from the head fast, this is implemented
/// as a ring buffer.</para>
/// <para>This uses head and tail indices into a fixed-size
/// array. This will grow the array as necessary.</para>
/// </remarks>
public class CharBuffer
{
#region Fields
int capacity = 128;
char[] buffer;
int headIndex; // index of first char
int tailIndex; // index 1 past last char
#endregion
#region Properties
/// <summary>
/// Gets/Sets the number of characters in the character buffer.
/// Increasing the length this way provides indeterminate results.
/// </summary>
public int Length
{
get { return(tailIndex - headIndex); }
set
{
tailIndex = headIndex + value;
if (tailIndex >= capacity) throw new
IndexOutOfRangeException("Tail index greater than capacity");
}
}
/// <summary>
/// Returns the capacity of this character buffer.
/// </summary>
public int Capacity
{
get { return(capacity); }
}
#endregion
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
public CharBuffer()
{
buffer = new char[capacity];
}
/// <summary>
/// Construct with a specific capacity.
/// </summary>
/// <param name="capacity"></param>
public CharBuffer(int capacity)
{
this.capacity = capacity;
buffer = new char[capacity];
}
#endregion
#region Non-Public Methods
/// <summary>
/// Reallocate the buffer to be larger. For the new size, this
/// uses the max of the requested length and double the current
/// capacity.
/// This does not shift, meaning it does not change the head or
/// tail indices.
/// </summary>
/// <param name="requestedLen">The new requested length.</param>
protected void Grow(int requestedLen)
{
int newLen = Math.Max(capacity*2, requestedLen);
newLen = Math.Max(newLen, 16);
char[] newBuffer = new char[newLen];
Array.Copy(buffer, 0, newBuffer, 0, capacity);
buffer = newBuffer;
capacity = newLen;
}
/// <summary>
/// Ensure that we're set for the requested length by
/// potentially growing or shifting contents.
/// </summary>
/// <param name="requestedLength"></param>
protected void CheckCapacity(int requestedLength)
{
if (requestedLength + headIndex >= capacity)
{
// have to do something
if ((requestedLength + headIndex > (capacity >> 1))
&& (requestedLength < capacity - 1))
{
// we're more than half-way through the buffer, and shifting is enough
// so just shift
ShiftToZero();
}
else
{
// not far into buffer or shift wouldn't be enough anyway
Grow(0);
}
}
}
/// <summary>
/// Move the buffer contents such that headIndex becomes 0.
/// </summary>
protected void ShiftToZero()
{
int len = Length;
for (int i = 0; i < len; i++)
{
buffer[i] = buffer[i + headIndex];
}
headIndex = 0;
tailIndex = len;
}
#endregion
#region Public Methods and Indexer
/// <summary>
/// Overwrite this object's underlying buffer with the specified
/// buffer.
/// </summary>
/// <param name="b">The character array.</param>
/// <param name="len">The number of characters to consider filled
/// in the input buffer.</param>
public void SetBuffer(char[] b, int len)
{
capacity = b.Length;
buffer = b;
headIndex = 0;
tailIndex = len;
}
/// <summary>
/// Append a character to this buffer.
/// </summary>
/// <param name="c"></param>
public void Append(char c)
{
if (tailIndex >= capacity) CheckCapacity(Length + 1);
buffer[tailIndex++] = c;
}
/// <summary>
/// Append a string to this buffer.
/// </summary>
/// <param name="s">The string to append.</param>
public void Append(string s)
{
if (s.Length + tailIndex >= capacity) CheckCapacity(Length + s.Length);
for(int i = 0; i < s.Length; i++)
buffer[tailIndex++] = s[i];
}
/// <summary>
/// Append a string to this buffer.
/// </summary>
/// <param name="s">The string to append.</param>
public void Append(CharBuffer s)
{
if (s.Length + tailIndex >= capacity) CheckCapacity(Length + s.Length);
for(int i = 0; i < s.Length; i++)
buffer[tailIndex++] = s[i];
}
/// <summary>
/// Remove a character at the specified index.
/// </summary>
/// <param name="i">The index of the character to remove.</param>
/// <returns></returns>
public void Remove(int i)
{
Remove(i, 1);
}
/// <summary>
/// Remove a specified number of characters at the specified index.
/// </summary>
/// <param name="i">The index of the characters to remove.</param>
/// <param name="n">The number of characters to remove.</param>
public void Remove(int i, int n)
{
n = Math.Min(n, Length);
if (i == 0)
{
headIndex += n;
}
else
{
Array.Copy(buffer, i + headIndex + n, buffer, i + headIndex,
tailIndex - (i + headIndex + n));
}
}
/// <summary>
/// Find the first instance of a character in the buffer, and
/// return its index. This returns -1 if the character is
/// not found.
/// </summary>
/// <param name="c">The character to find.</param>
/// <returns>The index of the specified character, or -1
/// for not found.</returns>
public int IndexOf(char c)
{
for (int i = headIndex; i < tailIndex; i++)
{
if (buffer[i] == c) return(i - headIndex);
}
return(-1);
}
/// <summary>
/// Empty the buffer.
/// </summary>
public void Clear()
{
headIndex = 0;
tailIndex = 0;
}
/// <summary>
/// Indexer.
/// </summary>
public char this [int index]
{
get { return(buffer[index + headIndex]); }
set { buffer[index + headIndex] = value; }
}
/// <summary>
/// Return the current contents as a string.
/// </summary>
/// <returns>The new string.</returns>
public override String ToString()
{
return(new String(buffer, headIndex, tailIndex - headIndex));
}
#endregion
}
}
demonstrates IsSymbol.
using System;
public class IsSymbolSample {
public static void Main() {
string str = "non-symbolic characters";
Console.WriteLine(Char.IsSymbol('+'));
Console.WriteLine(Char.IsSymbol(str, 8));
}
}
Char.IsLowSurrogate(), IsHighSurrogate(), IsSurrogatePair() method
using System;
class Sample
{
public static void Main()
{
char cHigh = 'uD800';
char cLow = 'uDC00';
string s1 = new String(new char[] {'a', 'uD800', 'uDC00', 'z'});
Console.WriteLine(“cHigh: {0:X4}”, (int)cHigh);
Console.WriteLine(“cLow: {0:X4}”, (int)cLow);
for(int i = 0; i < s1.Length; i++){
Console.WriteLine("{0:X4} ", (int)s1[i]);
}
Console.WriteLine("cLow? - {0}", Char.IsHighSurrogate(cLow));
Console.WriteLine("cHigh? - {0}", Char.IsHighSurrogate(cHigh));
Console.WriteLine("s1[0]? - {0}", Char.IsHighSurrogate(s1, 0));
Console.WriteLine("s1[1]? - {0}", Char.IsHighSurrogate(s1, 1));
Console.WriteLine("cLow? - {0}", Char.IsLowSurrogate(cLow));
Console.WriteLine("cHigh? - {0}", Char.IsLowSurrogate(cHigh));
Console.WriteLine("s1[0]? - {0}", Char.IsLowSurrogate(s1, 0));
Console.WriteLine("s1[2]? - {0}", Char.IsLowSurrogate(s1, 2));
Console.WriteLine("cHigh and cLow? - {0}", Char.IsSurrogatePair(cHigh, cLow));
Console.WriteLine("s1[0] and s1[1]? - {0}", Char.IsSurrogatePair(s1, 0));
Console.WriteLine("s1[1] and s1[2]? - {0}", Char.IsSurrogatePair(s1, 1));
Console.WriteLine("s1[2] and s1[3]? - {0}", Char.IsSurrogatePair(s1, 2));
}
}
[/csharp]
Char: Get Unicode Category
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
char[] chars = { 'a', 'X', '8', ',', ' ', 'u0009', '!' };
foreach (char ch in chars)
Console.WriteLine("'{0}': {1}", Regex.Escape(ch.ToString()), Char.GetUnicodeCategory(ch));
}
}
IsDigit, IsLetter, IsWhiteSpace, IsLetterOrDigit, IsPunctuation
using System;
using System.Collections.Generic;
using System.Text;
class Program {
static void Main(string[] args) {
Console.WriteLine("-> char.IsDigit('K'): {0}", char.IsDigit('K'));
Console.WriteLine("-> char.IsDigit('9'): {0}", char.IsDigit('9'));
Console.WriteLine("-> char.IsLetter('10', 1): {0}", char.IsLetter("10", 1));
Console.WriteLine("-> char.IsLetter('p'): {0}", char.IsLetter('p'));
Console.WriteLine("-> char.IsWhiteSpace('Hello There', 5): {0}",char.IsWhiteSpace("Hello There", 5));
Console.WriteLine("-> char.IsWhiteSpace('Hello There', 6): {0}",char.IsWhiteSpace("Hello There", 6));
Console.WriteLine("-> char.IsLetterOrDigit('?'): {0}",char.IsLetterOrDigit('?'));
Console.WriteLine("-> char.IsPunctuation('!'): {0}",char.IsPunctuation('!'));
Console.WriteLine("-> char.IsPunctuation('>'): {0}",char.IsPunctuation('>'));
Console.WriteLine("-> char.IsPunctuation(','): {0}",char.IsPunctuation(','));
}
}
A queue class for characters
/*
C# A Beginner's Guide
By Schildt
Publisher: Osborne McGraw-Hill
ISBN: 0072133295
*/
/*
Project 5-2
A queue class for characters.
*/
using System;
class Queue {
public char[] q; // this array holds the queue
public int putloc, getloc; // the put and get indices
public Queue(int size) {
q = new char[size+1]; // allocate memory for queue
putloc = getloc = 0;
}
// put a character into the queue
public void put(char ch) {
if(putloc==q.Length-1) {
Console.WriteLine(” — Queue is full.”);
return;
}
putloc++;
q[putloc] = ch;
}
// get a character from the queue
public char get() {
if(getloc == putloc) {
Console.WriteLine(” — Queue is empty.”);
return (char) 0;
}
getloc++;
return q[getloc];
}
}
// Demonstrate the Queue class.
public class QueueDemo1 {
public static void Main() {
Queue bigQ = new Queue(100);
Queue smallQ = new Queue(4);
char ch;
int i;
Console.WriteLine(“Using bigQ to store the alphabet.”);
// put some numbers into bigQ
for(i=0; i < 26; i++)
bigQ.put((char) ('A' + i));
// retrieve and display elements from bigQ
Console.Write("Contents of bigQ: ");
for(i=0; i < 26; i++) {
ch = bigQ.get();
if(ch != (char) 0) Console.Write(ch);
}
Console.WriteLine("
");
Console.WriteLine("Using smallQ to generate erros.");
// Now, use smallQ to generate some errors
for(i=0; i < 5; i++) {
Console.Write("Attempting to store " +
(char) ('Z' - i));
smallQ.put((char) ('Z' - i));
Console.WriteLine();
}
Console.WriteLine();
// more errors on smallQ
Console.Write("Contents of smallQ: ");
for(i=0; i < 5; i++) {
ch = smallQ.get();
if(ch != (char) 0) Console.Write(ch);
}
}
}
[/csharp]

