using System; using System.Text; using System.Collections.Generic; namespace Woodpecker.Specialized.Encoding { /// /// Provides 'wire' encoding and decoding for numbers, better known as 'VL64' or 'LV64'. /// public static class wireEncoding { /// /// Encodes an integer to a VL64 string. /// /// The integer to encode. public static string Encode(int i) { try { byte[] res = new byte[6]; int p = 0; int sP = 0; int bytes = 1; int negativeMask = i >= 0 ? 0 : 4; i = Math.Abs(i); res[p++] = (byte)(64 + (i & 3)); for (i >>= 2; i != 0; i >>= 6) { bytes++; res[p++] = (byte)(64 + (i & 0x3f)); } res[sP] = (byte)(res[sP] | bytes << 3 | negativeMask); return new ASCIIEncoding().GetString(res).Replace("\0", ""); } catch { return ""; } } public static string Encode(uint i) { return Encode((int)i); } /// /// Encodes each integer in the input array and adds it to the 'wire'. Returns the result as a string. /// /// The integer array to wire up the values of. public static string Encode(int[] i) { string s = ""; foreach (int j in i) s += Encode(j); return s; } /// /// Encodes a boolean to a VL64 char. /// /// The boolean to encode. public static char Encode(bool b) { if (b) return 'I'; else return 'H'; } /// /// Decodes a wire encoded string to the first encoded number in the wire. /// /// The write to decode. public static int Decode(ref string s) { try { char[] raw = s.ToCharArray(); int pos = 0; int i = 0; bool negative = (raw[pos] & 4) == 4; int totalBytes = raw[pos] >> 3 & 7; i = raw[pos] & 3; pos++; int shiftAmount = 2; for (int b = 1; b < totalBytes; b++) { i |= (raw[pos] & 0x3f) << shiftAmount; shiftAmount = 2 + 6 * b; pos++; } if (negative == true) i *= -1; return i; } catch { return 0; } } public static int Decode(string s) { return Decode(ref s); } /// /// Decodes a wire encoded string to a boolean. This is fancy. /// /// The wire encoded boolean to decode. public static bool decodeBoolean(string s) { return (s == "I"); } /// /// Decodes a wire encoded char to a boolean. This is fancy. /// /// The wire encoded boolean to decode. public static bool decodeBoolean(char s) { return (s == 'I'); } public static int[] decodeWire(string s) { List Ret = new List(); try { while (s.Length > 0) { int i = Decode(ref s); Ret.Add(i); s = s.Substring(Encode(i).Length); } } catch { } return Ret.ToArray(); } public static string[] getMixedParameters(string s) { List Ret = new List(); while (s.Length > 0) { int len = 0; string sVar = ""; if (s[0] == '@') { len = base64Encoding.Decode(s.Substring(0, 2)); sVar = s.Substring(2, len); len += 2; } else { int w = wireEncoding.Decode(ref s); sVar = w.ToString(); len = wireEncoding.Encode(w).Length; } s = s.Substring(len); Ret.Add(sVar); } return Ret.ToArray(); } } }