Exemplo n.º 1
0
        static string Update(this ReportDescriptorData descriptor, byte header, int data)
        {
            var type  = descriptor.GetType();
            var field = type.GetFields().Single(p => p.GetCustomAttribute <TagAttribute>().Match(header));

            field.SetValue(descriptor, data);
            return(field.Name);
        }
Exemplo n.º 2
0
        public static IEnumerable <ReportCollection> Parse(byte[] bytes)
        {
            using (var reader = new BinaryReader(new MemoryStream(bytes))) {
                var descriptor              = new ReportDescriptorData();
                var descriptorStack         = new Stack <ReportDescriptorData>();
                ReportCollection collection = null;

                while (reader.BaseStream.Position < bytes.Length)
                {
                    var header = reader.ReadByte();
                    var size   = 1 << (header & 0b11) >> 1;
                    var data   = 0;

                    for (int i = 0; i < size; i++)
                    {
                        var d = reader.ReadByte();
                        data |= d << (i * 8);
                    }
                    var type = (ItemType)(header >> 2 & 0b11);

                    // TODO: do we need to handle long items?

                    switch (type)
                    {
                    case ItemType.Main:
                        var itemType = (MainItems)(header >> 4);
                        switch (itemType)
                        {
                        case MainItems.Input:
                            collection.Add(new InputReport(data, descriptor));
                            break;

                        case MainItems.Output:
                            collection.Add(new OutputReport(data, descriptor));
                            break;

                        case MainItems.Feature:
                            collection.Add(new FeatureReport(data, descriptor));
                            break;

                        case MainItems.Collection:
                            collection = new ReportCollection(data, descriptor.UsagePage ?? 0, descriptor.Usage ?? 0, collection);
                            break;

                        case MainItems.EndCollection:
                            if (collection.Parent == null)
                            {
                                // we have reached the end of a top-level collection
                                if (collection.Type != CollectionType.Application)
                                {
                                    throw new InvalidDataException("Top-level collection must be Application");
                                }
                                yield return(collection);
                            }
                            collection = collection.Parent;
                            break;
                        }
                        descriptor.ClearLocals();
                        break;

                    case ItemType.Global:
                    case ItemType.Local:
                        switch (descriptor.Update(header, data))
                        {
                        // TODO: need to accumulate Usage as array
                        case nameof(ReportDescriptorData.Push):
                            descriptorStack.Push(descriptor.Copy());
                            break;

                        case nameof(ReportDescriptorData.Pop):
                            descriptor = descriptorStack.Pop();
                            break;
                        }
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                }
            }
        }
Exemplo n.º 3
0
 internal Report(ReportDescriptorData descriptor)
 {
     this.descriptor = descriptor?.Copy() ?? throw new ArgumentNullException(nameof(descriptor));
 }