1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
|
Code: NameschemeAttributes.C
Prefix:
// This is a hack to work around fact that we cannot define variables
// of arbitrary type, like a map, in the state object itself. So, we
// do it using a map with key being the object's this pointer.
static map<const void*, Namescheme*> nameschemesMap;
static map<const void*, bool> getNameCalledMap;
Postfix:
Code: NameschemeAttributes.h
Prefix:
using std::map;
using std::string;
using std::vector;
Postfix:
Code: ~NameschemeAttributes
Prefix:
// Clear any map entries for 'this' object.
map<const void*, Namescheme*>::iterator it2 = nameschemesMap.find(this);
if (it2 != nameschemesMap.end())
{
delete it2->second;
nameschemesMap.erase(it2);
}
map<const void*, bool>::iterator it3 = getNameCalledMap.find(this);
if (it3 != getNameCalledMap.end())
getNameCalledMap.erase(it3);
Postfix:
Function: AddExternalArray
Declaration: void AddExternalArray(const char *name, const int *data, int len);
Definition:
// ****************************************************************************
// Method: AddExternalArray
//
// Purpose: Add an array of integer values that is referenced from the
// namescheme expression.
//
// Programmer: Mark C. Miller
// Creation: August 28, 2009
//
// ****************************************************************************
void NameschemeAttributes::AddExternalArray(const char * name, const int *data, int len)
{
CheckIfGetNameCalled();
externalArrayNames.push_back(name);
externalArrayOffsets.push_back(externalArrayData.size());
for (int i = 0; i < len; i++)
externalArrayData.push_back(data[i]);
}
Function: AddExternalArray2
Declaration: void AddExternalArray(const string &name, const vector<int> &data);
Definition:
// ****************************************************************************
// See AddExternalArray
// ****************************************************************************
void NameschemeAttributes::AddExternalArray(const string &name, const vector<int> &data)
{
AddExternalArray(name.c_str(), &data[0], (int) data.size());
}
Function: SetAllNames
Declaration: void SetAllNames(const char *const *const names, int count);
Definition:
// ****************************************************************************
// Method: SetAllNames
//
// Purpose: Set ALL names to explicit values.
//
// In this case, since every name in the namescheme is an explicitly
// numerated name, it is assumed the names passed here are in 1:1 with
// the natural numbers so that GetName(n) returns the name at index n
// passed here.
//
// Programmer: Mark C. Miller
// Creation: August 28, 2009
//
// ****************************************************************************
void NameschemeAttributes::SetAllNames(const char *const *const names, int count)
{
CheckIfGetNameCalled();
for (int i = 0; i < count; i++)
allExplicitNames.push_back(names[i]);
}
Function: SetName
Declaration: void SetName(int i, const char *name);
Definition:
// ****************************************************************************
// Method: SetName
//
// Purpose: Explicitly set name for index i in the namescheme.
//
// Programmer: Mark C. Miller
// Creation: August 28, 2009
//
// ****************************************************************************
void NameschemeAttributes::SetName(int i, const char *name)
{
CheckIfGetNameCalled();
explicitIds.push_back(i);
explicitNames.push_back(name);
}
Function: SetName2
Declaration: void SetName(int i, const string &n);
Definition:
// ****************************************************************************
// See SetName
// ****************************************************************************
void NameschemeAttributes::SetName(int i, const string &n)
{
SetName(i, n.c_str());
}
Function: GetName
Declaration: const char *GetName(int n) const;
Definition:
// ****************************************************************************
// Method: GetName.
//
// Purpose: Main workhorse of this method. Compute a name from the namescheme.
//
// The FIRST call to this method indicates that caller is done building up
// the object and ready to start using it to compute names.
//
// Programmer: Mark C. Miller
// Creation: August 28, 2009
//
// Mark C. Miller, Tue Dec 8 14:33:27 PST 2009
// Added const qualification to map keys. Const qualified the method itself.
// ****************************************************************************
#define EA(N) &externalArrayData[externalArrayOffsets[N]]
const char *NameschemeAttributes::GetName(int n) const
{
// First, determine if this is FIRST call to GetName on this object
map<const void*, bool>::const_iterator cit4 = getNameCalledMap.find(this);
if (cit4 == getNameCalledMap.end())
{
// This is first call. Indicate that in the map.
getNameCalledMap[this] = true;
}
// First, see if we have ALL explicit names defined and, if so,
// ensure 'n' is in correct range for it.
if (n < allExplicitNames.size())
return allExplicitNames[n].c_str();
// Next, see if we have an explicit names map for this object.
if (explicitIds.size())
{
// If there is an explicit name for this entry, return it.
for (size_t i = 0; i < explicitIds.size(); i++)
{
if (explicitIds[i] == n)
return explicitNames[i].c_str();
}
}
// If we get here, we didn't have an explicit name, so
// use our Namescheme class to compute the name.
static char tmpname[128];
if (namescheme == "")
{
SNPRINTF(tmpname, sizeof(tmpname), "unknown_name_%d", n);
return tmpname;
}
// First, lets see if we've already got one constructed for this object.
Namescheme *ns = 0;
map<const void*, Namescheme*>::const_iterator cit3 = nameschemesMap.find(this);
if (cit3 != nameschemesMap.end())
{
ns = cit3->second;
}
else
{
// We didn't find a Namescheme object. That means we've yet to create
// it for this object. Create it now.
// We could make this switch larger to accomodate a larger number
// of external array references. But, for now, we're setting a
// limit at 4. If we want to increase it, we need to make sure the
// cooresponding Namescheme class can support it.
switch(externalArrayNames.size())
{
case 0: ns = new Namescheme(namescheme.c_str()); break;
case 1: ns = new Namescheme(namescheme.c_str(), EA(0)); break;
case 2: ns = new Namescheme(namescheme.c_str(), EA(0), EA(1)); break;
case 3: ns = new Namescheme(namescheme.c_str(), EA(0), EA(1), EA(2)); break;
case 4: ns = new Namescheme(namescheme.c_str(), EA(0), EA(1), EA(2), EA(3)); break;
default: { EXCEPTION0(StateObjectException); }
}
// Store the Namescheme pointer in the map for this object so
// we can find it again when we need to.
nameschemesMap[this] = ns;
}
// Compute the name from the Namescheme
const char *retval = ns ? ns->GetName(n) : 0;
if (retval && retval[0] != '\0') return retval;
// Ok, we can't compute a name. Make one up.
SNPRINTF(tmpname, sizeof(tmpname), "unknown_name_%d", n);
return tmpname;
}
Function: SetAllNames2
Declaration: void SetAllNames(const vector<string> &names);
Definition:
// ****************************************************************************
// See SetAllNames
// ****************************************************************************
void NameschemeAttributes::SetAllNames(const vector<string> &names)
{
CheckIfGetNameCalled();
for (size_t i = 0; i < names.size(); i++)
allExplicitNames.push_back(names[i]);
}
Function: CheckIfGetNameCalled
Declaration: void CheckIfGetNameCalled();
Definition:
// ****************************************************************************
// Method: CheckIfGetNameCalled.
//
// Purpose: An attempt to call GetName on this object is an indication
// that the object's specification is 'complete' in that no more calls to
// either add external arrays or set explict names will be made. This
// method is merely a helper function to ensure that behavior is enforced.
//
// Programmer: Mark C. Miller
// Creation: August 28, 2009
//
// Mark C. Miller, Tue Dec 8 14:33:27 PST 2009
// Added const qualification to map key
// ****************************************************************************
void NameschemeAttributes::CheckIfGetNameCalled()
{
map<const void*,bool>::const_iterator cit = getNameCalledMap.find(this);
if (cit == getNameCalledMap.end())
return;
EXCEPTION0(StateObjectException);
}
|