public MemRegister getFamilyRegister(string family, string regsiter_name) { try { XmlSerializer serializer = new XmlSerializer(typeof(MemRegisterList)); using (TextReader reader = new StreamReader(Path.Combine(mbase_path, "family_" + family + ".xml"))) { MemRegisterList list = serializer.Deserialize(reader) as MemRegisterList; if (list.Registers != null) { foreach (MemRegister xmlRegister in list.Registers) { if (xmlRegister.Id.ToLower().Equals(regsiter_name.ToLower())) { return(xmlRegister); } } } } }catch (Exception e) { } return(null); }
public MemoryMap(byte[] memory, string family, string pathUnityTest = "") { this.memory = memory; this.registersObjs = new Dictionary <string, dynamic>(); isUnityTest = !string.IsNullOrEmpty(pathUnityTest); // Read MTU family XML and prepare setters and getters Configuration config = Configuration.GetInstance(pathUnityTest); XmlSerializer serializer = new XmlSerializer(typeof(MemRegisterList)); // Parameter "family" when testing is full path to use string path = (!isUnityTest) ? Path.Combine(config.GetBasePath(), XML_PREFIX + family + XML_EXTENSION) : Path.Combine(pathUnityTest, family + XML_EXTENSION); using (TextReader reader = new StreamReader(path)) { MemRegisterList list = Validations.DeserializeXml <MemRegisterList> (reader); #region Registers if (list.Registers != null) { foreach (MemRegister xmlRegister in list.Registers) { try { // TEST: PARA PODER CAPTURAR LA EJECUCION EN UN REGISTRO CONCRETO //if ( string.Equals ( xmlRegister.Id, "P1MeterId" ) ) //{ // { } //} RegType type = ( RegType )Enum.Parse(typeof(RegType), xmlRegister.Type.ToUpper()); Type SysType = typeof(System.Object); switch (type) { case RegType.INT: SysType = typeof(int); break; case RegType.UINT: SysType = typeof(uint); break; case RegType.ULONG: SysType = typeof(ulong); break; case RegType.BOOL: SysType = typeof(bool); break; case RegType.CHAR: SysType = typeof(char); break; case RegType.STRING: SysType = typeof(string); break; } // Creates an instance of the generic class dynamic memoryRegister = Activator.CreateInstance(typeof(MemoryRegister <>) .MakeGenericType(SysType), xmlRegister.Id, type, xmlRegister.Description, xmlRegister.Address, xmlRegister.Size, xmlRegister.WriteAsBool, xmlRegister.Custom_Get, xmlRegister.Custom_Set); // Is not possible to use SysType as Type to invoke generic // method like CreateProperty_Get<T> and is necesary to use Reflection //typeof( MemoryMap ).GetMethod("CreateProperty_Get").MakeGenericMethod(SysType).Invoke(null, new object[] { regObj }); //typeof( MemoryMap ).GetMethod("CreateProperty_Set").MakeGenericMethod(SysType).Invoke(null, new object[] { regObj }); this.CreateProperty_Get(memoryRegister); this.CreateProperty_Get_ByteArray(memoryRegister); if (xmlRegister.WriteAsBool) { this.CreateProperty_Set(memoryRegister); this.CreateProperty_Set_String(memoryRegister); this.CreateProperty_Set_ByteArray(memoryRegister); } // References to write/set and get methods bool w = memoryRegister.write; dynamic get = base.registers[METHODS_GET_PREFIX + memoryRegister.id]; dynamic getC = (memoryRegister.HasCustomMethod_Get) ? base.registers[METHODS_GET_CUSTOM_PREFIX + memoryRegister.id] : null; dynamic getB = base.registers[METHODS_GET_BYTE_PREFIX + memoryRegister.id]; dynamic set = (w) ? base.registers[METHODS_SET_PREFIX + memoryRegister.id] : null; dynamic setC = (w && memoryRegister.HasCustomMethod_Set) ? base.registers[METHODS_SET_CUSTOM_PREFIX + memoryRegister.id] : null; dynamic setS = (w) ? base.registers[METHODS_SET_STRING_PREFIX + memoryRegister.id] : null; dynamic setB = (w) ? base.registers[METHODS_SET_BYTE_PREFIX + memoryRegister.id] : null; TypeCode tc = Type.GetTypeCode(SysType.GetType()); switch (type) { case RegType.INT: memoryRegister.funcGet = (Func <int>)get; memoryRegister.funcSet = (Action <int>)set; memoryRegister.funcGetCustom = (Func <int>)getC; break; case RegType.UINT: memoryRegister.funcGet = (Func <uint>)get; memoryRegister.funcSet = (Action <uint>)set; memoryRegister.funcGetCustom = (Func <uint>)getC; break; case RegType.ULONG: memoryRegister.funcGet = (Func <ulong>)get; memoryRegister.funcSet = (Action <ulong>)set; memoryRegister.funcGetCustom = (Func <ulong>)getC; break; case RegType.BOOL: memoryRegister.funcGet = (Func <bool>)get; memoryRegister.funcSet = (Action <bool>)set; memoryRegister.funcGetCustom = (Func <bool>)getC; break; case RegType.CHAR: memoryRegister.funcGet = (Func <char>)get; memoryRegister.funcSet = (Action <char>)set; memoryRegister.funcGetCustom = (Func <char>)getC; break; case RegType.STRING: memoryRegister.funcGet = (Func <string>)get; memoryRegister.funcSet = (Action <string>)set; memoryRegister.funcGetCustom = (Func <string>)getC; break; } memoryRegister.funcSetCustom = (Func <dynamic, dynamic>)setC; // All register have this three functions memoryRegister.funcGetByteArray = (Func <byte[]>)getB; memoryRegister.funcSetString = (Action <string>)setS; memoryRegister.funcSetByteArray = (Action <byte[]>)setB; // BAD: Reference to property itself // OK : Reference to register object and use TrySet|GetMember methods // to override set and get logic, avoiding ExpandoObject problems // NOTA: No se puede usar "base." porque parece ser invalidaria el comportamiento dinamico AddProperty(memoryRegister); // Add new object to collection where will be // filtered to only recover modified registers this.registersObjs.Add(xmlRegister.Id, memoryRegister); } catch (Exception e) { throw new MemoryMapParseXmlException("ERROR: " + e.Message); Console.WriteLine("ERROR! " + xmlRegister.Id + " -> " + e.Message + " " + e.InnerException); } } } #endregion #region Overloads if (list.Overloads != null) { foreach (MemOverload xmlOverload in list.Overloads) { try { RegType type = ( RegType )Enum.Parse(typeof(RegType), xmlOverload.Type.ToUpper()); Type SysType = typeof(System.Object); switch (type) { case RegType.INT: SysType = typeof(int); break; case RegType.UINT: SysType = typeof(uint); break; case RegType.ULONG: SysType = typeof(ulong); break; case RegType.BOOL: SysType = typeof(bool); break; case RegType.CHAR: SysType = typeof(char); break; case RegType.STRING: SysType = typeof(string); break; } // Creates an instance of the generic class dynamic memoryOverload = Activator.CreateInstance(typeof(MemoryOverload <>).MakeGenericType(SysType), xmlOverload.Id, type, xmlOverload.Description, xmlOverload.Registers.Select(o => o.Id).ToArray(), xmlOverload.CustomGet); this.CreateOverload_Get(memoryOverload); dynamic get = base.registers[METHODS_GET_PREFIX + memoryOverload.id]; TypeCode tc = Type.GetTypeCode(SysType.GetType()); switch (type) { case RegType.INT: memoryOverload.funcGet = (Func <int>)get; break; case RegType.UINT: memoryOverload.funcGet = (Func <uint>)get; break; case RegType.ULONG: memoryOverload.funcGet = (Func <ulong>)get; break; case RegType.BOOL: memoryOverload.funcGet = (Func <bool>)get; break; case RegType.CHAR: memoryOverload.funcGet = (Func <char>)get; break; case RegType.STRING: memoryOverload.funcGet = (Func <string>)get; break; } AddProperty(memoryOverload); } catch (Exception e) { throw new MemoryMapParseXmlException("ERROR: " + e.Message); Console.WriteLine("ERROR! " + xmlOverload.Id + " -> " + e.Message + " " + e.InnerException); } } } #endregion } }