Scenario: I received raw binary data via HTTP and saved the data in an array of bytes. I have documentation describing various fields that can represent binary data, but the actual value of the data must be determined at runtime. For example, if the byte representing the occurrence of the error = 1, the value of the next byte is changed.
Using C # with .NET 4, I want to create one or more classes that reflect the fields described in the documentation, and then somehow initialize the classes using an array of bytes of binary data. I would like the solution to minimize code duplication, and also be modular and elegant.
I studied the creation of Serializable classes, but I donβt see how this can work, since I start with an array of bytes that was not created (and therefore not serialized) by me.
I also tried using generics and reflection to get the sizes and types of fields contained in custom classes. Then I used this information to dynamically slice data from an array of bytes and assign them the appropriate fields. However, this method has led to a lot of ugly, unmanaged code.
Any advice or pointers on developing an extensible, untied solution to this problem would be greatly appreciated.
Edit: example classes containing fields that reflect fields in a specification
public class PriceHistoryResponse : BinaryResponse { public List<Quote> quotes { get; set; } private CountData countData { get; set; } private EndingDelimiterSection endingDelimiterSection { get; set; } public PriceHistoryResponse(byte[] responseBytes) : base(responseBytes) { countData = new CountData(); ParseResponseSection(countData); quotes = new List<Quote>(); for (int i = 0; i < countData.quoteCount; i++) { quotes.Add(new Quote()); quotes[i].symbolData = new SymbolData(); ParseResponseSection(quotes[i].symbolData); if (quotes[i].symbolData.errorCode == 1) { quotes[i].errorData = new ErrorData(); ParseResponseSection(quotes[i].errorData); break; } quotes[i].chartBarData = new ChartBarData(); ParseResponseSection(quotes[i].chartBarData); quotes[i].chartBars = new List<ChartBar>(); for (int j = 0; j < quotes[i].chartBarData.chartBarCount; j++) { quotes[i].chartBars.Add(new ChartBar()); ParseResponseSection(quotes[i].chartBars[j]); } } endingDelimiterSection = new EndingDelimiterSection(); ParseResponseSection(endingDelimiterSection); } } class CountData : IResponseSection { public int quoteCount { get; set; } } public class Quote { public SymbolData symbolData { get; set; } public ErrorData errorData { get; set; } public ChartBarData chartBarData { get; set; } public List<ChartBar> chartBars { get; set; } } public class SymbolData : IResponseSection { public string symbol { get; set; } public byte errorCode { get; set; } } public class ErrorData : IResponseSection { public string errorText { get; set; } } public class ChartBarData : IResponseSection { public int chartBarCount { get; set; } } public class ChartBar : IResponseSection { public float close { get; set; } public float high { get; set; } public float low { get; set; } public float open { get; set; } public float volume { get; set; } public long timestamp { get; set; } }
source share