1 //
2 // Copyright (c) 2010-2018 Antmicro
3 //
4 //  This file is licensed under the MIT License.
5 //  Full license text is available in 'licenses/MIT.txt'.
6 //
7 using System.Collections.Generic;
8 using System.Linq;
9 using Antmicro.Renode.Utilities;
10 
11 namespace Antmicro.Renode.Core.USB
12 {
13     public abstract class DescriptorProvider : IProvidesDescriptor
14     {
DescriptorProvider(byte type)15         public DescriptorProvider(byte type)
16         {
17             this.type = type;
18             subdescriptors = new List<IEnumerable<IProvidesDescriptor>>();
19         }
20 
DescriptorProvider(byte descriptorLength, byte type)21         public DescriptorProvider(byte descriptorLength, byte type) : this(type)
22         {
23             DescriptorLength = descriptorLength;
24         }
25 
GetDescriptor(bool recursive, BitStream buffer = null)26         public BitStream GetDescriptor(bool recursive, BitStream buffer = null)
27         {
28             if(buffer == null)
29             {
30                 buffer = new BitStream();
31             }
32 
33             buffer
34                 .Append((byte)DescriptorLength)
35                 .Append((byte)type);
36 
37             FillDescriptor(buffer);
38 
39             if(recursive)
40             {
41                 foreach(var sds in subdescriptors)
42                 {
43                     foreach(var sd in sds)
44                     {
45                         sd.GetDescriptor(true, buffer);
46                     }
47                 }
48             }
49 
50             return buffer;
51         }
52 
53         public virtual int DescriptorLength { get; }
54         public int RecursiveDescriptorLength => DescriptorLength + subdescriptors.Sum(sds => sds.Sum(sd => sd.RecursiveDescriptorLength));
55 
FillDescriptor(BitStream buffer)56         protected abstract void FillDescriptor(BitStream buffer);
57 
RegisterSubdescriptor(IProvidesDescriptor subdescriptor, int? index = null)58         protected void RegisterSubdescriptor(IProvidesDescriptor subdescriptor, int? index = null)
59         {
60             subdescriptors.Insert(index ?? subdescriptors.Count , new IProvidesDescriptor[] { subdescriptor });
61         }
62 
RegisterSubdescriptors(IEnumerable<IProvidesDescriptor> subdescriptors, int? index = null)63         protected void RegisterSubdescriptors(IEnumerable<IProvidesDescriptor> subdescriptors, int? index = null)
64         {
65             this.subdescriptors.Insert(index ?? this.subdescriptors.Count , subdescriptors);
66         }
67 
68         private readonly List<IEnumerable<IProvidesDescriptor>> subdescriptors;
69         private readonly byte type;
70     }
71 }