Line data Source code
1 : #include "wibmod/WIB1/AddressTable.hh"
2 : #include <fstream>
3 : #include "wibmod/WIB1/AddressTableException.hh"
4 : #include <boost/tokenizer.hpp> //tokenizer
5 : #include <stdlib.h> //strtoul & getenv
6 : #include <boost/regex.hpp> //regex
7 : #include <boost/algorithm/string/case_conv.hpp> //to_upper
8 :
9 : static const char *SC_key_conv = "sc_conv";
10 :
11 0 : Item const * AddressTable::GetItem(std::string const & registerName){
12 0 : std::map<std::string,Item *>::iterator itNameItem = nameItemMap.find(registerName);
13 0 : if(itNameItem == nameItemMap.end()){
14 0 : BUException::INVALID_NAME e;
15 0 : e.Append("Can't find item with name \"");
16 0 : e.Append(registerName.c_str());
17 0 : e.Append("\"");
18 0 : throw e;
19 0 : }
20 0 : Item * item = itNameItem->second;
21 0 : return item;
22 : }
23 :
24 0 : void AddressTable::AddEntry(Item * item){
25 : //Check for null item
26 0 : if(item == NULL){
27 0 : BUException::NULL_POINTER e;
28 0 : e.Append("Null Item pointer passed to AddEntry\n");
29 0 : throw e;
30 0 : }
31 : //Check for invalid Mode
32 0 : if((item->mode & Item::WRITE) &&
33 : (item->mode & Item::ACTION)){
34 0 : BUException::BAD_MODE e;
35 0 : e.Append("AddEntry called with both WRITE and ACTION modes\n");
36 0 : throw e;
37 0 : }
38 :
39 : //This function now owns the memory at item
40 :
41 :
42 :
43 : //Add the item to the address map and check that it doesn't conflict with
44 0 : std::map<uint32_t,std::vector<Item*> >::iterator itAddressItem = addressItemMap.find(item->address);
45 0 : if(itAddressItem == addressItemMap.end()){
46 : //This is the first entry at this address.
47 : //Create the entry in addressItemMap and then push_back with our item.
48 0 : addressItemMap[item->address].push_back(item);
49 : //Update the iterator to the newly inserted item
50 0 : itAddressItem = addressItemMap.find(item->address);
51 : }else{
52 0 : std::vector<Item*> & addressItems = itAddressItem->second;
53 : //Check each entry for an overlap in masks. This is only ok if one is a subset, via it's name, of the other
54 0 : for(size_t iItem = 0; iItem < addressItems.size();iItem++){
55 : if(addressItems[iItem]->mask & item->mask){
56 : //free for all now
57 :
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",
114 : convstring.c_str());
115 0 : item->sc_conv = ItemConversion::FromString("pass");
116 : }
117 0 : } else {
118 0 : item->sc_conv = ItemConversion::FromString("pass");
119 : }
120 :
121 : //Everything is good, we've added it
122 0 : }
123 :
124 :
|