예제 #1
0
 public static XldDescriptor Serdes(int _, XldDescriptor d, ISerializer s)
 {
     d ??= new XldDescriptor();
     s.Begin();
     d.Size     = s.UInt32(nameof(Size), d.Size);
     d.Category = s.EnumU16(nameof(Category), d.Category);
     d.Number   = s.UInt16(nameof(Number), d.Number);
     s.End();
     return(d);
 }
예제 #2
0
 public static XldDescriptor Serdes(int _, XldDescriptor d, ISerializer s)
 {
     if (s == null)
     {
         throw new ArgumentNullException(nameof(s));
     }
     d ??= new XldDescriptor();
     d.Size     = s.UInt32(nameof(Size), d.Size);
     d.Category = s.EnumU16(nameof(Category), d.Category);
     d.Number   = s.UInt16(nameof(Number), d.Number);
     return(d);
 }
예제 #3
0
        public static void Serdes(XldCategory category, ushort xldNumber, ISerializer s, Action <int, int, ISerializer> func, IList <int> populatedIds)
        {
            s.Begin($"Xld{category}.{xldNumber}");
            if (s.Mode == SerializerMode.Reading)
            {
                var descriptor = s.Meta("XldDescriptor", (XldDescriptor)null, XldDescriptor.Serdes);
                ApiUtil.Assert(descriptor.Category == category);
                ApiUtil.Assert(xldNumber == descriptor.Number);

                var lengths = HeaderSerdes(null, s);

                ApiUtil.Assert(lengths.Sum() + HeaderSize(lengths.Length) == descriptor.Size);
                long offset = s.Offset;
                for (int i = 0; i < 100 && i < lengths.Length; i++)
                {
                    if (lengths[i] == 0)
                    {
                        continue;
                    }
                    func(i + xldNumber * 100, lengths[i], s);
                    offset += lengths[i];
                    ApiUtil.Assert(offset == s.Offset);
                }
            }
            else
            {
                int maxPopulatedId = populatedIds.Where(x => x >= xldNumber * 100 && x < (xldNumber + 1) * 100).Max() + 1 - xldNumber * 100;
                var buffers        = Enumerable.Range(0, maxPopulatedId).Select(x => new MemoryStream()).ToArray();

                var descriptorOffset = s.Offset;
                s.Seek(s.Offset + 8);

                try
                {
                    var lengths           = new int[maxPopulatedId];
                    int initialFakeOffset = (int)s.Offset + HeaderSize(maxPopulatedId);
                    int fakeOffset        = initialFakeOffset;
                    for (int i = 0; i < maxPopulatedId; i++)
                    {
                        lengths[i] = WithSerializer(
                            s.Mode,
                            buffers[i],
                            memorySerializer => func(i + xldNumber * 100, 0, memorySerializer), s, ref fakeOffset);
                    }

                    HeaderSerdes(lengths, s);
                    ApiUtil.Assert(initialFakeOffset == s.Offset);
                    switch (s.Mode)
                    {
                    case SerializerMode.WritingAnnotated:
                    {
                        for (int i = 0; i < buffers.Length; i++)
                        {
                            var content = Encoding.GetEncoding(850).GetString(buffers[i].ToArray());
                            s.NullTerminatedString($"{xldNumber}{i:D2}", content);
                        }
                        break;
                    }

                    case SerializerMode.WritingJson:
                    {
                        var jw = (JsonWriter)s;
                        for (int i = 0; i < buffers.Length; i++)
                        {
                            if (buffers[i].Length == 0)
                            {
                                continue;
                            }
                            var content = Encoding.GetEncoding(850).GetString(buffers[i].ToArray());
                            jw.Raw($"{xldNumber}{i:D2}", content);
                        }
                        break;
                    }

                    default:
                        foreach (var b in buffers)
                        {
                            s.ByteArray("XLD", b.ToArray(), (int)b.Length);
                        }
                        break;
                    }

                    var endOffset = s.Offset;
                    s.Seek(descriptorOffset);

                    var descriptor = new XldDescriptor
                    {
                        Category = category,
                        Number   = xldNumber,
                        Size     = (uint)(lengths.Sum() + lengths.Length * 4 + 8)
                    };
                    s.Meta("Descriptor", descriptor, XldDescriptor.Serdes);

                    s.Seek(endOffset);
                }
                finally
                {
                    foreach (var buffer in buffers)
                    {
                        buffer.Dispose();
                    }
                }
            }
            s.End();
        }