Line data Source code
1 : #include "wibmod/WIB1/AddressTable.hh"
2 : #include "wibmod/WIB1/AddressTableException.hh"
3 : #include <boost/algorithm/string/case_conv.hpp> //to_upper
4 : #include <boost/regex.hpp> //regex
5 : #include <boost/tokenizer.hpp> //tokenizer
6 : #include <fstream>
7 : #include <stdlib.h> //strtoul & getenv
8 :
9 : static const char* SC_key_conv = "sc_conv";
10 :
11 : Item const*
12 0 : AddressTable::GetItem(std::string const& registerName)
13 : {
14 0 : std::map<std::string, Item*>::iterator itNameItem = nameItemMap.find(registerName);
15 0 : if (itNameItem == nameItemMap.end()) {
16 0 : BUException::INVALID_NAME e;
17 0 : e.Append("Can't find item with name \"");
18 0 : e.Append(registerName.c_str());
19 0 : e.Append("\"");
20 0 : throw e;
21 0 : }
22 0 : Item* item = itNameItem->second;
23 0 : return item;
24 : }
25 :
26 : void
27 0 : AddressTable::AddEntry(Item* item)
28 : {
29 : // Check for null item
30 0 : if (item == NULL) {
31 0 : BUException::NULL_POINTER e;
32 0 : e.Append("Null Item pointer passed to AddEntry\n");
33 0 : throw e;
34 0 : }
35 : // Check for invalid Mode
36 0 : if ((item->mode & Item::WRITE) && (item->mode & Item::ACTION)) {
37 0 : BUException::BAD_MODE e;
38 0 : e.Append("AddEntry called with both WRITE and ACTION modes\n");
39 0 : throw e;
40 0 : }
41 :
42 : // This function now owns the memory at item
43 :
44 : // Add the item to the address map and check that it doesn't conflict with
45 0 : std::map<uint32_t, std::vector<Item*>>::iterator itAddressItem = addressItemMap.find(item->address);
46 0 : if (itAddressItem == addressItemMap.end()) {
47 : // This is the first entry at this address.
48 : // Create the entry in addressItemMap and then push_back with our item.
49 0 : addressItemMap[item->address].push_back(item);
50 : // Update the iterator to the newly inserted item
51 0 : itAddressItem = addressItemMap.find(item->address);
52 : } else {
53 0 : std::vector<Item*>& addressItems = itAddressItem->second;
54 : // Check each entry for an overlap in masks. This is only ok if one is a subset, via it's name, of the other
55 0 : for (size_t iItem = 0; iItem < addressItems.size(); iItem++) {
56 : if (addressItems[iItem]->mask & item->mask) {
57 : // free for all now
58 :
59 : // These items overlap in mask
60 : // CHeck that one or the other contains the other starting at pos 0.
61 : // in other words, that they are the same up until the end of the shorter one
62 : // if( (addressItems[iItem]->name.find(item->name) != 0) &&
63 : // (item->name.find(addressItems[iItem]->name) != 0) ) {
64 : // BUException::BAD_MODE e;
65 : // e.Append("Entry: ");
66 : // e.Append(item->name.c_str());
67 : // e.Append(" conflicts with entry ");
68 : // e.Append(addressItems[iItem]->name.c_str());
69 : // e.Append("\n");
70 : // throw e;
71 : // }
72 : }
73 : }
74 0 : addressItems.push_back(item);
75 : }
76 :
77 : // Add the item to the list of addresses
78 0 : std::map<std::string, Item*>::iterator itNameItem = nameItemMap.find(item->name);
79 0 : if (itNameItem == nameItemMap.end()) {
80 : // Add this entry and everything is good.
81 0 : nameItemMap[item->name] = item;
82 : } else {
83 : // There was a collision in entry name, remote the newly added element and throw an exception
84 :
85 : // delete the addition to the vector
86 0 : std::vector<Item*>& addressItems = itAddressItem->second;
87 0 : for (size_t iItem = 0; iItem < addressItems.size(); iItem++) {
88 0 : if (addressItems[iItem] == item) {
89 : // Found what we just added, removing
90 0 : addressItems.erase(addressItems.begin() + iItem);
91 : }
92 : }
93 : // throw exception about collission
94 0 : BUException::NAME_COLLISION e;
95 0 : e.Append("Item ");
96 0 : e.Append(item->name.c_str());
97 0 : e.Append(" already existed\n");
98 :
99 : // delete the item
100 0 : delete item;
101 :
102 0 : throw e;
103 0 : }
104 :
105 : // Create Slow Control ItemConversion for this item
106 :
107 0 : item->sc_conv = (ItemConversion*)0x0;
108 :
109 0 : if (item->user.count(SC_key_conv)) {
110 0 : std::string convstring = item->user.at(SC_key_conv);
111 0 : item->sc_conv = ItemConversion::FromString(convstring);
112 0 : if (!item->sc_conv) {
113 0 : fprintf(stderr, "Warning: Unknown item conversion \"%s\"\n", convstring.c_str());
114 0 : item->sc_conv = ItemConversion::FromString("pass");
115 : }
116 0 : } else {
117 0 : item->sc_conv = ItemConversion::FromString("pass");
118 : }
119 :
120 : // Everything is good, we've added it
121 0 : }
|