1 
  
    2 
  
    3 
  
    4 
  
    5 
  
    6 using System;
  
    7 
  
    8 namespace System.IO
  
    9 {
  
   10     public class MemoryReader : IOBase
  
   11     {
  
   12         public MemoryReader(byte* ptr_, long count_) : base(), ptr(ptr_), pos(ptr), count(count_)
  
   13         {
  
   14         }
  
   15         [nodiscard]
  
   16         public Result<bool> ReadBool()
  
   17         {
  
   18             if (Error())
  
   19             {
  
   20                 return Result<bool>(ErrorId(GetErrorId()));
  
   21             }
  
   22             auto result = ReadByte();
  
   23             if (result.Error())
  
   24             {
  
   25                 return Result<bool>(ErrorId(result.GetErrorId()));
  
   26             }
  
   27             return Result<bool>(cast<bool>(result.Value()));
  
   28         }
  
   29         [nodiscard]
  
   30         public Result<byte> ReadByte()
  
   31         {
  
   32             if (Error())
  
   33             {
  
   34                 return Result<byte>(ErrorId(GetErrorId()));
  
   35             }
  
   36             if (pos - ptr >= count)
  
   37             {
  
   38                 int errorId = AllocateError("memory reader: unexpected end of data");
  
   39                 SetErrorId(errorId);
  
   40                 return Result<byte>(ErrorId(errorId));
  
   41             }
  
   42             return Result<byte>(*pos++);
  
   43         }
  
   44         [nodiscard]
  
   45         public Result<sbyte> ReadSByte()
  
   46         {
  
   47             if (Error())
  
   48             {
  
   49                 return Result<sbyte>(ErrorId(GetErrorId()));
  
   50             }
  
   51             auto result = ReadByte();
  
   52             if (result.Error())
  
   53             {
  
   54                 return Result<sbyte>(ErrorId(result.GetErrorId()));
  
   55             }
  
   56             return cast<sbyte>(result.Value());
  
   57         }
  
   58         [nodiscard]
  
   59         public Result<ushort> ReadUShort()
  
   60         {
  
   61             if (Error())
  
   62             {
  
   63                 return Result<ushort>(ErrorId(GetErrorId()));
  
   64             }
  
   65             auto b0 = ReadByte();
  
   66             if (b0.Error())
  
   67             {
  
   68                 return Result<ushort>(ErrorId(b0.GetErrorId()));
  
   69             }
  
   70             auto b1 = ReadByte();
  
   71             if (b1.Error())
  
   72             {
  
   73                 return Result<ushort>(ErrorId(b1.GetErrorId()));
  
   74             }
  
   75             return Result<ushort>((cast<ushort>(b0.Value()) << 8u) | cast<ushort>(b1.Value()));
  
   76         }
  
   77         [nodiscard]
  
   78         public Result<short> ReadShort()
  
   79         {
  
   80             if (Error())
  
   81             {
  
   82                 return Result<short>(ErrorId(GetErrorId()));
  
   83             }
  
   84             auto result = ReadUShort();
  
   85             if (result.Error())
  
   86             {
  
   87                 return Result<short>(ErrorId(result.GetErrorId()));
  
   88             }
  
   89             return Result<short>(cast<short>(result.Value()));
  
   90         }
  
   91         [nodiscard]
  
   92         public Result<uint> ReadUInt()
  
   93         {
  
   94             if (Error())
  
   95             {
  
   96                 return Result<uint>(ErrorId(GetErrorId()));
  
   97             }
  
   98             auto b0 = ReadByte();
  
   99             if (b0.Error())
  
  100             {
  
  101                 return Result<uint>(ErrorId(b0.GetErrorId()));
  
  102             }
  
  103             auto b1 = ReadByte();
  
  104             if (b1.Error())
  
  105             {
  
  106                 return Result<uint>(ErrorId(b1.GetErrorId()));
  
  107             }
  
  108             auto b2 = ReadByte();
  
  109             if (b2.Error())
  
  110             {
  
  111                 return Result<uint>(ErrorId(b2.GetErrorId()));
  
  112             }
  
  113             auto b3 = ReadByte();
  
  114             if (b3.Error())
  
  115             {
  
  116                 return Result<uint>(ErrorId(b3.GetErrorId()));
  
  117             }
  
  118             return Result<uint>((cast<uint>(b0.Value()) << 24u) | (cast<uint>(b1.Value()) << 16u) | (cast<uint>(b2.Value()) << 8u) | cast<uint>(b3.Value()));
  
  119         }
  
  120         [nodiscard]
  
  121         public Result<int> ReadInt()
  
  122         {
  
  123             if (Error())
  
  124             {
  
  125                 return Result<int>(ErrorId(GetErrorId()));
  
  126             }
  
  127             auto result = ReadUInt();
  
  128             if (result.Error())
  
  129             {
  
  130                 return Result<int>(ErrorId(result.GetErrorId()));
  
  131             }
  
  132             return Result<int>(cast<int>(result.Value()));
  
  133         }
  
  134         [nodiscard]
  
  135         public Result<ulong> ReadULong()
  
  136         {
  
  137             if (Error())
  
  138             {
  
  139                 return Result<ulong>(ErrorId(GetErrorId()));
  
  140             }
  
  141             auto b0 = ReadByte();
  
  142             if (b0.Error())
  
  143             {
  
  144                 return Result<ulong>(ErrorId(b0.GetErrorId()));
  
  145             }
  
  146             auto b1 = ReadByte();
  
  147             if (b1.Error())
  
  148             {
  
  149                 return Result<ulong>(ErrorId(b1.GetErrorId()));
  
  150             }
  
  151             auto b2 = ReadByte();
  
  152             if (b2.Error())
  
  153             {
  
  154                 return Result<ulong>(ErrorId(b2.GetErrorId()));
  
  155             }
  
  156             auto b3 = ReadByte();
  
  157             if (b3.Error())
  
  158             {
  
  159                 return Result<ulong>(ErrorId(b3.GetErrorId()));
  
  160             }
  
  161             auto b4 = ReadByte();
  
  162             if (b4.Error())
  
  163             {
  
  164                 return Result<ulong>(ErrorId(b4.GetErrorId()));
  
  165             }
  
  166             auto b5 = ReadByte();
  
  167             if (b5.Error())
  
  168             {
  
  169                 return Result<ulong>(ErrorId(b5.GetErrorId()));
  
  170             }
  
  171             auto b6 = ReadByte();
  
  172             if (b6.Error())
  
  173             {
  
  174                 return Result<ulong>(ErrorId(b6.GetErrorId()));
  
  175             }
  
  176             auto b7 = ReadByte();
  
  177             if (b7.Error())
  
  178             {
  
  179                 return Result<ulong>(ErrorId(b7.GetErrorId()));
  
  180             }
  
  181             return Result<ulong>((cast<ulong>(b0.Value()) << 56u) | (cast<ulong>(b1.Value()) << 48u) | (cast<ulong>(b2.Value()) << 40u) | (cast<ulong>(b3.Value()) << 32u) | 
  
  182                 (cast<ulong>(b4.Value()) << 24u) | (cast<ulong>(b5.Value()) << 16u) | (cast<ulong>(b6.Value()) << 8u) | cast<ulong>(b7.Value()));
  
  183         }
  
  184         [nodiscard]
  
  185         public Result<long> ReadLong()
  
  186         {
  
  187             if (Error())
  
  188             {
  
  189                 return Result<long>(ErrorId(GetErrorId()));
  
  190             }
  
  191             auto result = ReadULong();
  
  192             if (result.Error())
  
  193             {
  
  194                 return Result<long>(ErrorId(result.GetErrorId()));
  
  195             }
  
  196             return Result<long>(cast<long>(result.Value()));
  
  197         }
  
  198         [nodiscard]
  
  199         public Result<float> ReadFloat()
  
  200         {
  
  201             if (Error())
  
  202             {
  
  203                 return Result<float>(ErrorId(GetErrorId()));
  
  204             }
  
  205             auto result = ReadUInt();
  
  206             if (result.Error())
  
  207             {
  
  208                 return Result<float>(ErrorId(result.GetErrorId()));
  
  209             }
  
  210             uint x = result.Value();
  
  211             return Result<float>(*cast<float*>(cast<void*>(&x)));
  
  212         }
  
  213         [nodiscard]
  
  214         public Result<double> ReadDouble()
  
  215         {
  
  216             if (Error())
  
  217             {
  
  218                 return Result<double>(ErrorId(GetErrorId()));
  
  219             }
  
  220             auto result = ReadULong();
  
  221             if (result.Error())
  
  222             {
  
  223                 return Result<double>(ErrorId(result.GetErrorId()));
  
  224             }
  
  225             ulong x = result.Value();
  
  226             return Result<double>(*cast<double*>(cast<void*>(&x)));
  
  227         }
  
  228         [nodiscard]
  
  229         public Result<char> ReadChar()
  
  230         {
  
  231             if (Error())
  
  232             {
  
  233                 return Result<char>(ErrorId(GetErrorId()));
  
  234             }
  
  235             auto result = ReadByte();
  
  236             if (result.Error())
  
  237             {
  
  238                 return Result<char>(ErrorId(result.GetErrorId()));
  
  239             }
  
  240             return Result<char>(cast<char>(result.Value()));
  
  241         }
  
  242         [nodiscard]
  
  243         public Result<wchar> ReadWChar()
  
  244         {
  
  245             if (Error())
  
  246             {
  
  247                 return Result<wchar>(ErrorId(GetErrorId()));
  
  248             }
  
  249             auto result = ReadUShort();
  
  250             if (result.Error())
  
  251             {
  
  252                 return Result<wchar>(ErrorId(result.GetErrorId()));
  
  253             }
  
  254             return Result<wchar>(cast<wchar>(result.Value()));
  
  255         }
  
  256         [nodiscard]
  
  257         public Result<uchar> ReadUChar()
  
  258         {
  
  259             if (Error())
  
  260             {
  
  261                 return Result<uchar>(ErrorId(GetErrorId()));
  
  262             }
  
  263             auto result = ReadUInt();
  
  264             if (result.Error())
  
  265             {
  
  266                 return Result<uchar>(ErrorId(result.GetErrorId()));
  
  267             }
  
  268             return Result<uchar>(cast<uchar>(result.Value()));
  
  269         }
  
  270         [nodiscard]
  
  271         public Result<Date> ReadDate()
  
  272         {
  
  273             if (Error())
  
  274             {
  
  275                 return Result<Date>(ErrorId(GetErrorId()));
  
  276             }
  
  277             auto year = ReadShort();
  
  278             if (year.Error())
  
  279             {
  
  280                 return Result<Date>(ErrorId(year.GetErrorId()));
  
  281             }
  
  282             auto m = ReadSByte();
  
  283             if (m.Error())
  
  284             {
  
  285                 return Result<Date>(ErrorId(m.GetErrorId()));
  
  286             }
  
  287             Month month = cast<Month>(m.Value());
  
  288             auto day = ReadSByte();
  
  289             if (day.Error())
  
  290             {
  
  291                 return Result<Date>(ErrorId(day.GetErrorId()));
  
  292             }
  
  293             Date date(year.Value(), month, day.Value());
  
  294             return Result<Date>(date);
  
  295         }
  
  296         [nodiscard]
  
  297         public Result<DateTime> ReadDateTime()
  
  298         {
  
  299             if (Error())
  
  300             {
  
  301                 return Result<DateTime>(ErrorId(GetErrorId()));
  
  302             }
  
  303             auto date = ReadDate();
  
  304             if (date.Error())
  
  305             {
  
  306                 return Result<DateTime>(ErrorId(date.GetErrorId()));
  
  307             }
  
  308             auto secs = ReadInt();
  
  309             if (secs.Error())
  
  310             {
  
  311                 return Result<DateTime>(ErrorId(secs.GetErrorId()));
  
  312             }
  
  313             DateTime dt(date.Value(), secs.Value());
  
  314             return Result<DateTime>(dt);
  
  315         }
  
  316         [nodiscard]
  
  317         public Result<string> ReadString()
  
  318         {
  
  319             if (Error())
  
  320             {
  
  321                 return Result<string>(ErrorId(GetErrorId()));
  
  322             }
  
  323             string result;
  
  324             auto b = ReadByte();
  
  325             if (b.Error())
  
  326             {
  
  327                 return Result<string>(ErrorId(b.GetErrorId()));
  
  328             }
  
  329             while (b.Value() != 0u)
  
  330             {
  
  331                 result.Append(cast<char>(b.Value()));
  
  332                 b = ReadByte();
  
  333                 if (b.Error())
  
  334                 {
  
  335                     return Result<string>(ErrorId(b.GetErrorId()));
  
  336                 }
  
  337             }
  
  338             return Result<string>(result);
  
  339         }
  
  340         [nodiscard]
  
  341         public Result<Uuid> ReadUuid()
  
  342         {
  
  343             if (Error())
  
  344             {
  
  345                 return Result<Uuid>(ErrorId(GetErrorId()));
  
  346             }
  
  347             Uuid x;
  
  348             for (byte& b : x)
  
  349             {
  
  350                 auto result = ReadByte();
  
  351                 if (result.Error())
  
  352                 {
  
  353                     return Result<Uuid>(ErrorId(result.GetErrorId()));
  
  354                 }
  
  355                 b = result.Value();
  
  356             }
  
  357             return Result<Uuid>(x);
  
  358         }
  
  359         private byte* ptr;
  
  360         private byte* pos;
  
  361         private long count;
  
  362     }