// // Format includes: // Control: // ^ Switch to big endian encoding // _ Switch to little endian encoding // % Switch to host (native) encoding // ! aligns the next data type to its natural boundary (for strings this is 4). // // Types: // s Int16 // S UInt16 // i Int32 // I UInt32 // l Int64 // L UInt64 // f float // d double // b byte // c 1-byte signed character // C 1-byte unsigned character // z8 string encoded as UTF8 with 1-byte null terminator // z6 string encoded as UTF16 with 2-byte null terminator // z7 string encoded as UTF7 with 1-byte null terminator // zb string encoded as BigEndianUnicode with 2-byte null terminator // z3 string encoded as UTF32 with 4-byte null terminator // z4 string encoded as UTF32 big endian with 4-byte null terminator // $8 string encoded as UTF8 // $6 string encoded as UTF16 // $7 string encoded as UTF7 // $b string encoded as BigEndianUnicode // $3 string encoded as UTF32 // $4 string encoded as UTF-32 big endian encoding // x null byte // // Repeats, these are prefixes: // N a number between 1 and 9, indicates a repeat count (process N items // with the following datatype // [N] For numbers larger than 9, use brackets, for example [20] // * Repeat the next data type until the arguments are exhausted // static public byte [] Pack (string description, params object [] args) { int argn = 0; PackContext b = new PackContext (); b.conv = CopyConv; b.description = description; for (b.i = 0; b.i < description.Length; ){ object oarg; if (argn < args.Length) oarg = args [argn]; else { if (b.repeat != 0) break; oarg = null; } int save = b.i; if (PackOne (b, oarg)){ argn++; if (b.repeat > 0){ if (--b.repeat > 0) b.i = save; else b.i++; } else b.i++; } else b.i++; } return b.Get (); }
static public byte [] PackEnumerable (string description, IEnumerable args) { PackContext b = new PackContext (); b.conv = CopyConv; b.description = description; IEnumerator enumerator = args.GetEnumerator (); bool ok = enumerator.MoveNext (); for (b.i = 0; b.i < description.Length; ){ object oarg; if (ok) oarg = enumerator.Current; else { if (b.repeat != 0) break; oarg = null; } int save = b.i; if (PackOne (b, oarg)){ ok = enumerator.MoveNext (); if (b.repeat > 0){ if (--b.repeat > 0) b.i = save; else b.i++; } else b.i++; } else b.i++; } return b.Get (); }