/************************************************************************* * ModernUO * * Copyright 2019-2024 - ModernUO Development Team * * Email: hi@modernuo.com * * File: IGenericReader.cs * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ using System; using System.Collections; using System.IO; using System.Net; namespace Server; public interface IGenericReader { string ReadString(bool intern = false); public string ReadStringRaw(bool intern = false); long ReadLong(); ulong ReadULong(); int ReadInt(); uint ReadUInt(); short ReadShort(); ushort ReadUShort(); double ReadDouble(); float ReadFloat(); byte ReadByte(); sbyte ReadSByte(); bool ReadBool(); Serial ReadSerial(); Type ReadType(); DateTime ReadDateTime() => new(ReadLong(), DateTimeKind.Utc); TimeSpan ReadTimeSpan() => new(ReadLong()); DateTime ReadDeltaTime() { return ReadLong() switch { long.MinValue => DateTime.MinValue, long.MaxValue => DateTime.MaxValue, var delta => new DateTime(delta + DateTime.UtcNow.Ticks, DateTimeKind.Utc) }; } decimal ReadDecimal() => new(stackalloc int[4] { ReadInt(), ReadInt(), ReadInt(), ReadInt() }); int ReadEncodedInt() { int v = 0, shift = 0; byte b; do { b = ReadByte(); v |= (b & 0x7F) << shift; shift += 7; } while (b >= 0x80); return v; } IPAddress ReadIPAddress() { byte length = ReadByte(); // Either 2 ushorts, or 8 ushorts Span integer = stackalloc byte[length]; Read(integer); return Utility.Intern(new IPAddress(integer)); } Point3D ReadPoint3D() => new(ReadInt(), ReadInt(), ReadInt()); Point2D ReadPoint2D() => new(ReadInt(), ReadInt()); Rectangle2D ReadRect2D() => new(ReadPoint2D(), ReadPoint2D()); Rectangle3D ReadRect3D() => new(ReadPoint3D(), ReadPoint3D()); Map ReadMap() => Map.Maps[ReadByte()]; Race ReadRace() => Race.Races[ReadByte()]; int Read(Span buffer); unsafe T ReadEnum() where T : unmanaged, Enum { switch (sizeof(T)) { case 1: { var num = ReadByte(); return *(T*)# } case 2: { var num = ReadShort(); return *(T*)# } case 4: { var num = ReadEncodedInt(); return *(T*)# } case 8: { var num = ReadLong(); return *(T*)# } } return default; } Guid ReadGuid() { Span bytes = stackalloc byte[16]; Read(bytes); return new Guid(bytes); } public BitArray ReadBitArray() { var byteArrayLength = ReadEncodedInt(); // We need an exact array size since the ctor doesn't allow for offset/length, not much we can do at this point. var byteArray = new byte[byteArrayLength]; Read(byteArray); return new BitArray(byteArray); } TextDefinition ReadTextDefinition() { return ReadEncodedInt() switch { 0 => TextDefinition.Empty, 1 => ReadEncodedInt(), 2 => ReadString(), _ => null }; } long Seek(long offset, SeekOrigin origin); }