private IList <TSpec> ReadTSpecs() { var tspecs = new List <TSpec>(); while (true) { SkipWhite(); switch (PeekChar()) { case '[': // SZArray, Array, or GenericInst ReadChar(); SkipWhite(); var peeked = PeekChar(); if (peeked == ']') { // SZ array Verify(ReadChar() == ']', "Expected ']'"); tspecs.Add(SZArraySpec.Instance); } else if (peeked == '*' || peeked == ',' || peeked == '-' || char.IsDigit((char)peeked)) { // Array var arraySpec = new ArraySpec(); arraySpec.rank = 0; while (true) { SkipWhite(); var c = PeekChar(); if (c == '*') { ReadChar(); } else if (c == ',' || c == ']') { } else if (c == '-' || char.IsDigit((char)c)) { var lower = ReadInt32(); uint?size; SkipWhite(); Verify(ReadChar() == '.', "Expected '.'"); Verify(ReadChar() == '.', "Expected '.'"); if (PeekChar() == '.') { ReadChar(); size = null; } else { SkipWhite(); if (PeekChar() == '-') { var upper = ReadInt32(); Verify(upper >= lower, "upper < lower"); size = (uint)(upper - lower + 1); Verify(size.Value != 0 && size.Value <= 0x1FFFFFFF, "Invalid size"); } else { var upper = ReadUInt32(); var lsize = upper - lower + 1; Verify(lsize > 0 && lsize <= 0x1FFFFFFF, "Invalid size"); size = (uint)lsize; } } if (arraySpec.lowerBounds.Count == arraySpec.rank) { arraySpec.lowerBounds.Add(lower); } if (size.HasValue && arraySpec.sizes.Count == arraySpec.rank) { arraySpec.sizes.Add(size.Value); } } else { Verify(false, "Unknown char"); } arraySpec.rank++; SkipWhite(); if (PeekChar() != ',') { break; } ReadChar(); } Verify(ReadChar() == ']', "Expected ']'"); tspecs.Add(arraySpec); } else { // Generic args var ginstSpec = new GenericInstSpec(); while (true) { SkipWhite(); peeked = PeekChar(); var needSeperators = peeked == '['; if (peeked == ']') { break; } Verify(!needSeperators || ReadChar() == '[', "Expected '['"); ginstSpec.args.Add(ReadType(needSeperators)); SkipWhite(); Verify(!needSeperators || ReadChar() == ']', "Expected ']'"); SkipWhite(); if (PeekChar() != ',') { break; } ReadChar(); } Verify(ReadChar() == ']', "Expected ']'"); tspecs.Add(ginstSpec); } break; case '&': // ByRef ReadChar(); tspecs.Add(ByRefSpec.Instance); break; case '*': // Ptr ReadChar(); tspecs.Add(PtrSpec.Instance); break; default: return(tspecs); } } }
IList<TSpec> ReadTSpecs() { var tspecs = new List<TSpec>(); while (true) { SkipWhite(); switch (PeekChar()) { case '[': // SZArray, Array, or GenericInst ReadChar(); SkipWhite(); var peeked = PeekChar(); if (peeked == ']') { // SZ array Verify(ReadChar() == ']', "Expected ']'"); tspecs.Add(SZArraySpec.Instance); } else if (peeked == '*' || peeked == ',' || peeked == '-' || char.IsDigit((char)peeked)) { // Array var arraySpec = new ArraySpec(); arraySpec.rank = 0; while (true) { SkipWhite(); int c = PeekChar(); if (c == '*') ReadChar(); else if (c == ',' || c == ']') { } else if (c == '-' || char.IsDigit((char)c)) { int lower = ReadInt32(); uint? size; SkipWhite(); Verify(ReadChar() == '.', "Expected '.'"); Verify(ReadChar() == '.', "Expected '.'"); if (PeekChar() == '.') { ReadChar(); size = null; } else { SkipWhite(); if (PeekChar() == '-') { int upper = ReadInt32(); Verify(upper >= lower, "upper < lower"); size = (uint)(upper - lower + 1); Verify(size.Value != 0 && size.Value <= 0x1FFFFFFF, "Invalid size"); } else { uint upper = ReadUInt32(); long lsize = (long)upper - (long)lower + 1; Verify(lsize > 0 && lsize <= 0x1FFFFFFF, "Invalid size"); size = (uint)lsize; } } if (arraySpec.lowerBounds.Count == arraySpec.rank) arraySpec.lowerBounds.Add(lower); if (size.HasValue && arraySpec.sizes.Count == arraySpec.rank) arraySpec.sizes.Add(size.Value); } else Verify(false, "Unknown char"); arraySpec.rank++; SkipWhite(); if (PeekChar() != ',') break; ReadChar(); } Verify(ReadChar() == ']', "Expected ']'"); tspecs.Add(arraySpec); } else { // Generic args var ginstSpec = new GenericInstSpec(); while (true) { SkipWhite(); peeked = PeekChar(); bool needSeperators = peeked == '['; if (peeked == ']') break; Verify(!needSeperators || ReadChar() == '[', "Expected '['"); ginstSpec.args.Add(ReadType(needSeperators)); SkipWhite(); Verify(!needSeperators || ReadChar() == ']', "Expected ']'"); SkipWhite(); if (PeekChar() != ',') break; ReadChar(); } Verify(ReadChar() == ']', "Expected ']'"); tspecs.Add(ginstSpec); } break; case '&': // ByRef ReadChar(); tspecs.Add(ByRefSpec.Instance); break; case '*': // Ptr ReadChar(); tspecs.Add(PtrSpec.Instance); break; default: return tspecs; } } }