public override void Visit(CodePoint expression) { terminal.Peek().Append(expression.Match); }
public override void Visit(CodePoint expression) { String matchtext = expression.Match; _matchStack.Push( delegate(IInputIterator iterator) { if (matchtext.StartsWith("#x")) { //hexadecimal evaluation String hexinput = matchtext.Substring(2); if (hexinput == String.Empty) throw new ArgumentException("Hex value specified is empty."); if (hexinput.Length % 2 != 0) hexinput = "0" + hexinput; // on incomplete byte boundaries shift right int total_compare_bytes = hexinput.Length / 2; for (int i = 0; i < total_compare_bytes; i++) { if (iterator.Current() == -1) return false; var compareWith = (Byte)iterator.Current(); for (Int32 j = 0; j < 2; j++) { // low nibble comparison Int32 nibbleOffset = 0; if (j == 0) { // high nibble comparison nibbleOffset = 4; } // j == 0 == high nibble // j == 1 == low nibble var tmp = (Byte)hexinput[i * 2 + j]; if (tmp >= (Byte)'0' && tmp <= (Byte)'9') { tmp = (Byte)((tmp - (Byte)'0') << nibbleOffset); } else if (tmp >= (Byte)'a' && tmp <= (Byte)'f') { tmp = (Byte)((tmp - (Byte)'A' + 10) << nibbleOffset); } else if (tmp >= (Byte)'A' && tmp <= (Byte)'F') { tmp = (Byte)((tmp - (Byte)'A' + 10) << nibbleOffset); } else if (tmp == (Byte)'x' || tmp == (Byte)'X') { // don't care ignore nibble comparison } else { throw new ArgumentException("Hex value specified contains invalid characters."); } if (!(tmp == (Byte)'x' || tmp == (Byte)'X')) { if ( ((compareWith & (1 << (nibbleOffset + 3))) >> (nibbleOffset + 3)) != ((tmp & (1 << (nibbleOffset + 3))) >> (nibbleOffset + 3)) || ((compareWith & (1 << (nibbleOffset + 2))) >> (nibbleOffset + 2)) != ((tmp & (1 << (nibbleOffset + 2))) >> (nibbleOffset + 2)) || ((compareWith & (1 << (nibbleOffset + 1))) >> (nibbleOffset + 1)) != ((tmp & (1 << (nibbleOffset + 1))) >> (nibbleOffset + 1)) || ((compareWith & (1 << nibbleOffset)) >> nibbleOffset) != ((tmp & (1 << nibbleOffset)) >> nibbleOffset) ) { return false; } } } iterator.Next(); } } else if (matchtext.StartsWith("#b")) { // binary evaluation String binaryinput = matchtext.Substring(2); if (binaryinput == String.Empty) throw new ArgumentException("Binary value specified is empty."); if (binaryinput.Length % 8 != 0) binaryinput = "".PadLeft(8 - (binaryinput.Length % 8), '0') + binaryinput; // on incomplete byte boundaries shift right int total_compare_bytes = binaryinput.Length / 8; for (int i = 0; i < total_compare_bytes; i++) { if (iterator.Current() == -1) return false; var compareWith = (Byte)iterator.Current(); for (Int32 j = 0; j < 8; j++) { var tmp = (Byte)binaryinput[i * 8 + j]; if (tmp == (Byte)'0') { tmp = 0x00; } else if (tmp == (Byte)'1') { tmp = 0x01; } else if (tmp == (Byte)'x' || tmp == (Byte)'X') { // don't care ignore nibble comparison } else { throw new ArgumentException( "Binary value specified contains invalid characters."); } if (!(tmp == (Byte)'x' || tmp == (Byte)'X')) { Int32 bit2compare = 7 - j; if ( ((compareWith & (1 << bit2compare)) >> bit2compare) != tmp ) { return false; } } } iterator.Next(); } } else { // decimal codepoint evaluation String decimalinput = matchtext.Substring(1); if (decimalinput == String.Empty) throw new ArgumentException("Decimal codepoint value specified is empty."); if (!Regex.IsMatch(decimalinput, @"^[0-9]+$")) throw new ArgumentException( "Decimal codepoint value specified contains invalid characters."); if (decimalinput.Length > 10) // 4,294,967,295 throw new ArgumentException( "Decimal codepoint value exceeds 4 byte maximum length. Largest decimal value possible 2^32"); UInt32 codepoint = UInt32.Parse(decimalinput); var c4 = (Byte)(codepoint >> 24); var c3 = (Byte)(codepoint >> 16); var c2 = (Byte)(codepoint >> 8); var c1 = (Byte)(codepoint); if (c4 != 0x00) { // consumes 4 bytes if (iterator.Current() == -1 || iterator.Current() != c1) { return false; } iterator.Next(); if (iterator.Current() == -1 || iterator.Current() != c2) { return false; } iterator.Next(); if (iterator.Current() == -1 || iterator.Current() != c3) { return false; } iterator.Next(); if (iterator.Current() == -1 || iterator.Current() != c4) { return false; } iterator.Next(); } else if (c3 != 0x00) { // consumes 3 bytes if (iterator.Current() == -1 || iterator.Current() != c1) { return false; } iterator.Next(); if (iterator.Current() == -1 || iterator.Current() != c2) { return false; } iterator.Next(); if (iterator.Current() == -1 || iterator.Current() != c3) { return false; } iterator.Next(); } else if (c2 != 0x00) { // consumes 2 bytes if (iterator.Current() == -1 || iterator.Current() != c1) { return false; } iterator.Next(); if (iterator.Current() == -1 || iterator.Current() != c2) { return false; } iterator.Next(); } else { // user must want to match null \0 // (c1 != 0x00) // consumes 1 byte if (iterator.Current() == -1 || iterator.Current() != c1) { return false; } iterator.Next(); } } return true; } ); }
public abstract void Visit(CodePoint expression);