context: using System;
  using NLog;
  using WCell.Core;
  using WCell.Util;
  using WCell.Util.Graphics;
  
  namespace WCell.PacketAnalysis
  {
      /// <summary>
      /// Reads and renders the next segment of the given packet.
      /// </summary>
      public delegate object SegmentReader(PacketSegmentStructure segment, PacketParser parser);
  
      /// <summary>
      /// Reads and renders the next segment of the given packet.
      /// </summary>
      public delegate void SegmentRenderer(PacketSegmentStructure segment, PacketParser parser, IndentTextWriter writer);
  
      public delegate object SimpleTypeConverter(object obj);
  
      public static class SimpleTypes
      {
          private static readonly Logger log = LogManager.GetCurrentClassLogger();
  
          public static readonly Type[] SimpleTypeMap = new Type[(uint)SimpleType.Count];
          public static readonly SegmentReader[] SimpleReaders = new SegmentReader[(uint)SimpleType.Count];
          public static readonly SimpleTypeConverter[] SimpleTypeConverters = new SimpleTypeConverter[(uint)SimpleType.Count];
          public static readonly Func<string, object>[] SimpleStringReaders = new Func<string, object>[(uint)SimpleType.Count];
  
          static SimpleTypes()
          {
              InitTypeMap();
              InitReaders();
              InitConverters();
              InitStringReaders();
          }
  
          #region Init
  
          private static void InitReaders()
          {
              SimpleReaders[(uint)SimpleType.Byte] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 1)
                  {
                      WarnLength(SimpleType.Byte, segment, parser);
                      return (byte)0;
                  }
                  return parser.Packet.ReadByte();
              };
              //SimpleReaders[(uint)SimpleType.SByte] = (segment, parser) => {
              //    return parser.Packet.ReadByte();
              //};
              SimpleReaders[(uint)SimpleType.UShort] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 2)
                  {
                      WarnLength(SimpleType.UShort, segment, parser);
                      return (ushort)0;
                  }
                  return parser.Packet.ReadUInt16();
              };
              SimpleReaders[(uint)SimpleType.Short] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 2)
                  {
                      WarnLength(SimpleType.Short, segment, parser);
                      return (short)0;
                  }
                  return parser.Packet.ReadInt16();
              };
              SimpleReaders[(uint)SimpleType.UInt] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 4)
                  {
                      WarnLength(SimpleType.UInt, segment, parser);
                      return (uint)0;
                  }
                  return parser.Packet.ReadUInt32();
              };
              SimpleReaders[(uint)SimpleType.Int] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 4)
                  {
                      WarnLength(SimpleType.Int, segment, parser);
                      return 0;
                  }
                  return parser.Packet.ReadInt32();
              };
              SimpleReaders[(uint)SimpleType.ULong] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 8)
                  {
                      WarnLength(SimpleType.ULong, segment, parser);
                      return 0ul;
                  }
                  return parser.Packet.ReadUInt64();
              };
              SimpleReaders[(uint)SimpleType.Long] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 8)
                  {
                      WarnLength(SimpleType.Long, segment, parser);
                      return 0L;
                  }
                  return parser.Packet.ReadInt64();
              };
              SimpleReaders[(uint)SimpleType.Float] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 4)
                  {
                      WarnLength(SimpleType.Float, segment, parser);
                      return 0f;
                  }
                  return parser.Packet.ReadFloat();
              };
              SimpleReaders[(uint)SimpleType.Vector3] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 12)
                  {
                      WarnLength(SimpleType.Vector3, segment, parser);
                      return new Vector3();
                  }
                  return new Vector3(
                      parser.Packet.ReadFloat(),
                      parser.Packet.ReadFloat(),
                      parser.Packet.ReadFloat());
              };
              SimpleReaders[(uint)SimpleType.PackedVector3] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 4)
                  {
                      WarnLength(SimpleType.PackedVector3, segment, parser);
                      return new Vector3();
                  }
                  return Vector3.FromPacked(parser.Packet.ReadUInt32());
              };
              SimpleReaders[(uint)SimpleType.Vector4] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 16)
                  {
                      WarnLength(SimpleType.Vector4, segment, parser);
                      return new Vector4();
                  }
                  return new Vector4(
                      parser.Packet.ReadFloat(),
                      parser.Packet.ReadFloat(),
                      parser.Packet.ReadFloat(),
                      parser.Packet.ReadFloat());
              };
              SimpleReaders[(uint)SimpleType.Guid] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 8)
                  {
                      WarnLength(SimpleType.Guid, segment, parser);
                      return EntityId.Zero;
                  }
                  return new EntityId(parser.Packet.ReadUInt64());
              };
              SimpleReaders[(uint)SimpleType.PackedGuid] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 1)
                  {
                      WarnLength(SimpleType.PackedGuid, segment, parser);
                      return EntityId.Zero;
                  }
                  return EntityId.ReadPacked(parser.Packet);
              };
              SimpleReaders[(uint)SimpleType.CString] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 1)
                  {
                      WarnLength(SimpleType.CString, segment, parser);
                      return "";
                  }
                  return parser.Packet.ReadCString();
              };
  
              SimpleReaders[(uint)SimpleType.PascalStringByte] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 1)
                  {
                      WarnLength(SimpleType.PascalStringByte, segment, parser);
                      return "";
                  }
                  return parser.Packet.ReadPascalString();
              };
              SimpleReaders[(uint)SimpleType.PascalStringUShort] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 2)
                  {
                      WarnLength(SimpleType.PascalStringUShort, segment, parser);
                      return "";
                  }
                  return parser.Packet.ReadPascalStringUShort();
              };
              SimpleReaders[(uint)SimpleType.PascalStringUInt] = (segment, parser) =>
              {
                  if (parser.Packet.RemainingLength < 4)
                  {
                      WarnLength(SimpleType.PascalStringUInt, segment, parser);
                      return "";
                  }
                  return parser.Packet.ReadPascalStringUInt();
              };
  
              SimpleReaders[(int)SimpleType.PackedDate] =
                  (segment, parser) =>
                  {
  
gt:                     if (parser.Packet.RemainingLength < 4)