1 // 2 // Copyright (c) 2010-2022 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; 8 using System.Collections.Generic; 9 10 namespace Antmicro.Renode.Utilities.RESD 11 { 12 public class MetadataBlock 13 { ReadFromStream(SafeBinaryReader reader)14 public static IDictionary<String, MetadataValue> ReadFromStream(SafeBinaryReader reader) 15 { 16 var metadata = new Dictionary<string, MetadataValue>(); 17 18 var metadataLength = reader.ReadUInt64(); 19 if(metadataLength == 0) 20 { 21 return metadata; 22 } 23 24 var startPosition = (ulong)reader.BaseStream.Position; 25 26 while((ulong)reader.BaseStream.Position < startPosition + metadataLength) 27 { 28 var keyName = reader.ReadCString(); 29 var valueType = (MetadataValueType)reader.ReadByte(); 30 MetadataValue value; 31 switch(valueType) 32 { 33 case MetadataValueType.Int8: 34 value = new MetadataValue(reader.ReadSByte()); 35 break; 36 case MetadataValueType.UInt8: 37 value = new MetadataValue(reader.ReadByte()); 38 break; 39 case MetadataValueType.Int16: 40 value = new MetadataValue(reader.ReadInt16()); 41 break; 42 case MetadataValueType.UInt16: 43 value = new MetadataValue(reader.ReadUInt16()); 44 break; 45 case MetadataValueType.Int32: 46 value = new MetadataValue(reader.ReadInt32()); 47 break; 48 case MetadataValueType.UInt32: 49 value = new MetadataValue(reader.ReadUInt32()); 50 break; 51 case MetadataValueType.Int64: 52 value = new MetadataValue(reader.ReadInt64()); 53 break; 54 case MetadataValueType.UInt64: 55 value = new MetadataValue(reader.ReadUInt64()); 56 break; 57 case MetadataValueType.Float: 58 value = new MetadataValue(reader.ReadSingle()); 59 break; 60 case MetadataValueType.Double: 61 value = new MetadataValue(reader.ReadDouble()); 62 break; 63 case MetadataValueType.String: 64 value = new MetadataValue(reader.ReadCString()); 65 break; 66 case MetadataValueType.Blob: 67 var blobLength = reader.ReadUInt32(); 68 value = new MetadataValue(reader.ReadBytes((int)blobLength)); 69 break; 70 default: 71 throw new RESDException($"Invalid metadata type ({valueType}), offset: {reader.BaseStream.Position - 1}"); 72 } 73 74 metadata.Add(keyName, value); 75 } 76 77 if((ulong)reader.BaseStream.Position != (startPosition + metadataLength)) 78 { 79 throw new RESDException($"Invalid amount of data read, expected: {metadataLength}, actual: {(ulong)reader.BaseStream.Position - startPosition}"); 80 } 81 82 return metadata; 83 } 84 } 85 } 86