github.com/platinasystems/nvram@v1.0.1-0.20190709235807-51a23abd5aec/layout.go (about) 1 package nvram 2 3 import ( 4 "fmt" 5 "sort" 6 ) 7 8 type CMOSEnumItem struct { 9 id uint 10 value uint 11 text string 12 } 13 14 func (i CMOSEnumItem) String() string { 15 return fmt.Sprintf("%d %d %s", i.id, i.value, i.text) 16 } 17 18 func (i CMOSEnumItem) Id() uint { 19 return i.id 20 } 21 22 func (i CMOSEnumItem) Value() uint { 23 return i.value 24 } 25 26 func (i CMOSEnumItem) Text() string { 27 return i.text 28 } 29 30 type CMOSEnum struct { 31 itos map[uint]string 32 stoi map[string]uint 33 } 34 35 type Layout struct { 36 enums map[uint]*CMOSEnum 37 entries map[string]*CMOSEntry 38 entrieslist []*CMOSEntry 39 cmosChecksum *CMOSChecksum 40 } 41 42 func NewLayout() *Layout { 43 c, _ := NewCMOSChecksum(392, 1007, 1008) 44 return &Layout{ 45 enums: make(map[uint]*CMOSEnum), 46 entries: make(map[string]*CMOSEntry), 47 cmosChecksum: c} 48 } 49 50 func (l *Layout) AddCMOSEntry(entry *CMOSEntry) (err error) { 51 // Verify CMOS Entry 52 err = verifyCMOSEntry(entry) 53 if err != nil { 54 return 55 } 56 57 // Add entries to entry list sorted by starting bit. 58 var pos int = 0 59 for i, e := range l.entrieslist { 60 pos = i 61 if entry.bit < e.bit { 62 break 63 } 64 } 65 66 // Check if new entry overlaps current entry in sorted list. 67 if len(l.entrieslist) > 0 { 68 if pos > 0 { 69 if entry.IsOverlap(l.entrieslist[pos-1]) { 70 err = fmt.Errorf("Entry %s overlaps %s", *entry, l.entrieslist[pos-1]) 71 return 72 } 73 } 74 75 if entry.IsOverlap(l.entrieslist[pos]) { 76 err = fmt.Errorf("Entry %s overlaps %s", *entry, l.entrieslist[pos]) 77 return 78 } 79 } 80 81 // Add new entry to list at correct position 82 l.entrieslist = append(l.entrieslist, nil) 83 copy(l.entrieslist[pos+1:], l.entrieslist[pos:]) 84 l.entrieslist[pos] = entry 85 86 // Add entry to enteries map 87 l.entries[entry.name] = entry 88 return 89 } 90 91 func (l *Layout) GetCMOSEntriesList() []*CMOSEntry { 92 // Return a copy of the sorted CMOS entry list. 93 return l.entrieslist 94 } 95 96 func (l *Layout) FindCMOSEntry(name string) (entry *CMOSEntry, ok bool) { 97 entry, ok = l.entries[name] 98 return 99 } 100 101 func (l *Layout) AddCMOSEnum(item *CMOSEnumItem) { 102 103 // Create new CMOS Enum for each item's id. 104 enum, ok := l.enums[item.id] 105 if !ok { 106 enum = new(CMOSEnum) 107 // Create maps to search by enum name or value. 108 enum.itos = make(map[uint]string) 109 enum.stoi = make(map[string]uint) 110 l.enums[item.id] = enum 111 } 112 113 // Add item text and value to maps 114 enum.itos[item.value] = item.text 115 enum.stoi[item.text] = item.value 116 } 117 118 func (l *Layout) FindCMOSEnumText(id uint, value uint) (text string, ok bool) { 119 var enum *CMOSEnum 120 121 // Find CMOS Enum by id 122 enum, ok = l.enums[id] 123 if !ok { 124 return "", false 125 } 126 127 // Find CMOS Enum text from value 128 text, ok = enum.itos[value] 129 return 130 } 131 132 func (l *Layout) FindCMOSEnumValue(id uint, text string) (value uint, ok bool) { 133 var enum *CMOSEnum 134 135 // Find CMOS Enum by id 136 enum, ok = l.enums[id] 137 if !ok { 138 return 0, false 139 } 140 141 // Find CMOS Enum value from text. 142 value, ok = enum.stoi[text] 143 return 144 } 145 146 func (l *Layout) GetCMOSEnumItemsById(id uint) (items []CMOSEnumItem, ok bool) { 147 148 // Find CMOS Enum by id 149 enum, ok := l.enums[id] 150 if !ok { 151 return 152 } 153 154 // Create sorted list of Enum values 155 var values []int 156 for value := range enum.itos { 157 values = append(values, int(value)) 158 } 159 sort.Ints(values) 160 161 // Add CMOS Itmes to list sorted by value 162 for _, value := range values { 163 var text string 164 text, ok = enum.itos[uint(value)] 165 if !ok { 166 continue 167 } 168 items = append(items, CMOSEnumItem{uint(id), uint(value), text}) 169 } 170 171 return 172 } 173 174 func (l *Layout) GetCMOSEnumItems() (items []CMOSEnumItem) { 175 // Create sorted list of enum ids. 176 var ids []int 177 for id := range l.enums { 178 ids = append(ids, int(id)) 179 } 180 sort.Ints(ids) 181 182 // Add all enum items for all ids to list 183 for _, id := range ids { 184 items_for_id, _ := l.GetCMOSEnumItemsById(uint(id)) 185 items = append(items, items_for_id...) 186 } 187 188 return 189 } 190 191 func (l *Layout) GetCheckChecksum() CMOSChecksum { 192 return *l.cmosChecksum 193 }