static public IList Unpack (string description, byte [] buffer, int startIndex) { DataConverter conv = CopyConv; var result = new List<object> (); int idx = startIndex; bool align = false; int repeat = 0, n; for (int i = 0; i < description.Length && idx < buffer.Length; ){ int save = i; switch (description [i]){ case '^': conv = BigEndian; break; case '_': conv = LittleEndian; break; case '%': conv = Native; break; case 'x': idx++; break; case '!': align = true; break; // Type Conversions case 'i': if (Prepare (buffer, ref idx, 4, ref align)){ result.Add (conv.GetInt32 (buffer, idx)); idx += 4; } break; case 'I': if (Prepare (buffer, ref idx, 4, ref align)){ result.Add (conv.GetUInt32 (buffer, idx)); idx += 4; } break; case 's': if (Prepare (buffer, ref idx, 2, ref align)){ result.Add (conv.GetInt16 (buffer, idx)); idx += 2; } break; case 'S': if (Prepare (buffer, ref idx, 2, ref align)){ result.Add (conv.GetUInt16 (buffer, idx)); idx += 2; } break; case 'l': if (Prepare (buffer, ref idx, 8, ref align)){ result.Add (conv.GetInt64 (buffer, idx)); idx += 8; } break; case 'L': if (Prepare (buffer, ref idx, 8, ref align)){ result.Add (conv.GetUInt64 (buffer, idx)); idx += 8; } break; case 'f': if (Prepare (buffer, ref idx, 4, ref align)){ result.Add (conv.GetFloat (buffer, idx)); idx += 4; } break; case 'd': if (Prepare (buffer, ref idx, 8, ref align)){ result.Add (conv.GetDouble (buffer, idx)); idx += 8; } break; case 'b': if (Prepare (buffer, ref idx, 1, ref align)){ result.Add (buffer [idx]); idx++; } break; case 'c': case 'C': if (Prepare (buffer, ref idx, 1, ref align)){ char c; if (description [i] == 'c') c = ((char) ((sbyte)buffer [idx])); else c = ((char) ((byte)buffer [idx])); result.Add (c); idx++; } break; // Repeat acount; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': repeat = ((short) description [i]) - ((short) '0'); save = i + 1; break; case '*': repeat = Int32.MaxValue; break; case '[': int count = -1, j; for (j = i+1; j < description.Length; j++){ if (description [j] == ']') break; n = ((short) description [j]) - ((short) '0'); if (n >= 0 && n <= 9){ if (count == -1) count = n; else count = count * 10 + n; } } if (count == -1) throw new ArgumentException ("invalid size specification"); i = j; save = i + 1; repeat = count; break; case '$': case 'z': // bool with_null = description [i] == 'z'; i++; if (i >= description.Length) throw new ArgumentException ("$ description needs a type specified", "description"); char d = description [i]; Encoding e; if (align){ idx = Align (idx, 4); align = false; } if (idx >= buffer.Length) break; switch (d){ case '8': e = Encoding.UTF8; n = 1; break; case '6': e = Encoding.Unicode; n = 2; break; case '7': e = Encoding.UTF7; n = 1; break; case 'b': e = Encoding.BigEndianUnicode; n = 2; break; case '3': e = Encoding.GetEncoding (12000); n = 4; break; case '4': e = Encoding.GetEncoding (12001); n = 4; break; default: throw new ArgumentException ("Invalid format for $ specifier", "description"); } int k = idx; switch (n){ case 1: for (; k < buffer.Length && buffer [k] != 0; k++) ; result.Add (e.GetChars (buffer, idx, k-idx)); if (k == buffer.Length) idx = k; else idx = k+1; break; case 2: for (; k < buffer.Length; k++){ if (k+1 == buffer.Length){ k++; break; } if (buffer [k] == 0 && buffer [k+1] == 0) break; } result.Add (e.GetChars (buffer, idx, k-idx)); if (k == buffer.Length) idx = k; else idx = k+2; break; case 4: for (; k < buffer.Length; k++){ if (k+3 >= buffer.Length){ k = buffer.Length; break; } if (buffer[k]==0 && buffer[k+1] == 0 && buffer[k+2] == 0 && buffer[k+3]== 0) break; } result.Add (e.GetChars (buffer, idx, k-idx)); if (k == buffer.Length) idx = k; else idx = k+4; break; } break; default: throw new ArgumentException (String.Format ("invalid format specified `{0}'", description [i])); } if (repeat > 0){ if (--repeat > 0) i = save; } else i++; } return result; }
public static IList Unpack(string description, byte[] buffer, int startIndex) { DataConverter dataConverter = DataConverter.CopyConv; ArrayList arrayList = new ArrayList(); int num = startIndex; bool flag = false; int num2 = 0; int num3 = 0; while (num3 < description.Length && num < buffer.Length) { int num4 = num3; char c = description[num3]; switch (c) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num2 = (int)((short)description[num3] - 48); num4 = num3 + 1; break; default: switch (c) { case '[': { int num5 = -1; int i; for (i = num3 + 1; i < description.Length; i++) { if (description[i] == ']') { break; } int num6 = (int)((short)description[i] - 48); if (num6 >= 0 && num6 <= 9) { if (num5 == -1) { num5 = num6; } else { num5 = num5 * 10 + num6; } } } if (num5 == -1) { throw new ArgumentException("invalid size specification"); } num3 = i; num2 = num5; break; } default: { switch (c) { case '!': flag = true; goto IL_683; default: switch (c) { case 'I': if (DataConverter.Prepare(buffer, ref num, 4, ref flag)) { arrayList.Add(dataConverter.GetUInt32(buffer, num)); num += 4; } goto IL_683; default: switch (c) { case 'x': num++; goto IL_683; default: if (c == '*') { num2 = int.MaxValue; goto IL_683; } if (c == 'S') { if (DataConverter.Prepare(buffer, ref num, 2, ref flag)) { arrayList.Add(dataConverter.GetUInt16(buffer, num)); num += 2; } goto IL_683; } if (c != 's') { throw new ArgumentException(string.Format("invalid format specified `{0}'", description[num3])); } if (DataConverter.Prepare(buffer, ref num, 2, ref flag)) { arrayList.Add(dataConverter.GetInt16(buffer, num)); num += 2; } goto IL_683; case 'z': break; } break; case 'L': if (DataConverter.Prepare(buffer, ref num, 8, ref flag)) { arrayList.Add(dataConverter.GetUInt64(buffer, num)); num += 8; } goto IL_683; } break; case '$': break; case '%': dataConverter = DataConverter.Native; goto IL_683; } num3++; if (num3 >= description.Length) { throw new ArgumentException("$ description needs a type specified", "description"); } char c2 = description[num3]; if (flag) { num = DataConverter.Align(num, 4); flag = false; } if (num < buffer.Length) { char c3 = c2; int num6; Encoding encoding; switch (c3) { case '3': encoding = Encoding.GetEncoding(12000); num6 = 4; break; case '4': encoding = Encoding.GetEncoding(12001); num6 = 4; break; default: if (c3 != 'b') { throw new ArgumentException("Invalid format for $ specifier", "description"); } encoding = Encoding.BigEndianUnicode; num6 = 2; break; case '6': encoding = Encoding.Unicode; num6 = 2; break; case '7': encoding = Encoding.UTF7; num6 = 1; break; case '8': encoding = Encoding.UTF8; num6 = 1; break; } int j = num; switch (num6) { case 1: while (j < buffer.Length && buffer[j] != 0) { j++; } arrayList.Add(encoding.GetChars(buffer, num, j - num)); if (j == buffer.Length) { num = j; } else { num = j + 1; } break; case 2: while (j < buffer.Length) { if (j + 1 == buffer.Length) { j++; break; } if (buffer[j] == 0 && buffer[j + 1] == 0) { break; } j++; } arrayList.Add(encoding.GetChars(buffer, num, j - num)); if (j == buffer.Length) { num = j; } else { num = j + 2; } break; case 4: while (j < buffer.Length) { if (j + 3 >= buffer.Length) { j = buffer.Length; break; } if (buffer[j] == 0 && buffer[j + 1] == 0 && buffer[j + 2] == 0 && buffer[j + 3] == 0) { break; } j++; } arrayList.Add(encoding.GetChars(buffer, num, j - num)); if (j == buffer.Length) { num = j; } else { num = j + 4; } break; } } break; } case '^': dataConverter = DataConverter.BigEndian; break; case '_': dataConverter = DataConverter.LittleEndian; break; case 'b': if (DataConverter.Prepare(buffer, ref num, 1, ref flag)) { arrayList.Add(buffer[num]); num++; } break; case 'c': goto IL_300; case 'd': if (DataConverter.Prepare(buffer, ref num, 8, ref flag)) { arrayList.Add(dataConverter.GetDouble(buffer, num)); num += 8; } break; case 'f': if (DataConverter.Prepare(buffer, ref num, 4, ref flag)) { arrayList.Add(dataConverter.GetDouble(buffer, num)); num += 4; } break; case 'i': if (DataConverter.Prepare(buffer, ref num, 4, ref flag)) { arrayList.Add(dataConverter.GetInt32(buffer, num)); num += 4; } break; case 'l': if (DataConverter.Prepare(buffer, ref num, 8, ref flag)) { arrayList.Add(dataConverter.GetInt64(buffer, num)); num += 8; } break; } break; case 'C': goto IL_300; } IL_683: if (num2 > 0) { if (--num2 > 0) { num3 = num4; } continue; } num3++; continue; IL_300: if (DataConverter.Prepare(buffer, ref num, 1, ref flag)) { char c4; if (description[num3] == 'c') { c4 = (char)((sbyte)buffer[num]); } else { c4 = (char)buffer[num]; } arrayList.Add(c4); num++; } goto IL_683; } return(arrayList); }