33 readonly ReadOnlyMemory<byte> buf;
55 internal bool IsAtEnd => pos == buf.Length;
57 internal int Position => pos;
59 internal void Skip(uint count)
61 if (buf.Length - pos < count)
70 internal byte ReadByte()
72 if (pos == buf.Length)
75 return buf.Span[pos++];
78 internal sbyte ReadSByte()
80 if (pos == buf.Length)
83 return (sbyte)buf.Span[pos++];
86 internal double ReadDouble()
88 return BitConverter.Int64BitsToDouble(ReadInt64());
91 internal short ReadInt16()
93 if (buf.Length - pos < 2)
96 var s = (short)((buf.Span[pos] << 8) + buf.Span[pos + 1]);
102 internal int ReadInt32()
104 if (buf.Length - pos < 4)
107 var i = (int)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
112 internal long ReadInt64()
114 if (buf.Length - pos < 8)
117 var i1 = (uint)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
118 var i2 = (uint)((buf.Span[pos + 4] << 24) + (buf.Span[pos + 5] << 16) + (buf.Span[pos + 6] << 8) + buf.Span[pos + 7]);
119 var l = (((long)i1) << 32) + i2;
124 internal float ReadSingle()
126 return BitConverter.ToSingle(BitConverter.GetBytes(ReadInt32()), 0);
129 internal unsafe
string ReadString(
string classFile,
int majorVersion)
131 int len = ReadUInt16();
132 if (buf.Length - pos < len)
136 for (
int j = 0; j < len; j++)
138 if (buf.Span[pos + j] == 0 || buf.Span[pos + j] >= 128)
142 char[] ch =
new char[len];
144 for (
int i = 0; i < len; i++)
146 int c = buf.Span[pos + i];
168 char2 = buf.Span[pos + ++i];
169 if ((char2 & 0xc0) != 0x80 || i >= len)
173 c = (((c & 0x1F) << 6) | (char2 & 0x3F));
174 if (c < 0x80 && c != 0 && majorVersion >= 48)
181 char2 = buf.Span[pos + ++i];
182 char3 = buf.Span[pos + ++i];
183 if ((char2 & 0xc0) != 0x80 || (char3 & 0xc0) != 0x80 || i >= len)
187 c = (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
188 if (c < 0x800 && majorVersion >= 48)
194 throw new ClassFormatError(
"Illegal UTF8 string in constant pool in class file {0}", classFile ??
"<Unknown>");
199 return new string(ch, 0, l);
205 fixed (
byte* p = buf.Slice(pos, len).Span)
206 s = Encoding.ASCII.GetString(p, buf.Length);
208 var s = Encoding.ASCII.GetString(buf.Slice(pos, len).Span);
214 internal ushort ReadUInt16()
216 if (buf.Length - pos < 2)
219 var s = (ushort)((buf.Span[pos] << 8) + buf.Span[pos + 1]);
224 internal uint ReadUInt32()
226 if (buf.Length - pos < 4)
229 uint i = (uint)((buf.Span[pos] << 24) + (buf.Span[pos + 1] << 16) + (buf.Span[pos + 2] << 8) + buf.Span[pos + 3]);
234 internal byte[] ToArray()
236 var res =
new byte[buf.Length - pos];
237 buf.Slice(pos, res.Length).CopyTo(res);