1 #ifndef devatlas_priv_h 2 #define devatlas_priv_h 3 #include <mtld/devatlas.h> 4 #include <mtld/common_priv.h> 7 namespace Mobi {
namespace Mtld {
namespace Da {
15 static const size_t LOCAL_PROP_COUNT=16;
39 typedef unsigned int I;
41 static const int mask =
sizeof (I) * 8 - 1;
43 static unsigned idxOf(
unsigned item) {
44 return item /
sizeof(I);
48 propset(
size_t maxcount = 200) {
49 size_t count = idxOf(maxcount | mask) + 1;
51 memset(vals, 0,
sizeof (I) * count);
57 bool find(
size_t v)
const {
58 return vals[idxOf(v)] & (1 << (v & mask));
65 void insert(
unsigned v) {
66 vals[idxOf(v)] |= 1 << (v & mask);
99 template <
typename T>
void visitR(T &t,
char key)
const;
102 bool isLeaf()
const {
return children.empty(); }
110 unsigned int nextTree;
111 unsigned int matchedDevices;
114 std::vector<size_t> *replacementStrings;
115 NodeData() : nextTree(0), matchedDevices(0), replacementStrings(0), resetWalkId(-1) {}
116 ~
NodeData() {
delete replacementStrings; }
117 const attrvec &getAttrs()
const {
return attrs; }
118 attrvec &getAttrs() {
return attrs; }
119 const propset &getConflicts()
const {
return conflicts; }
120 propset &getConflicts() {
return conflicts; }
121 unsigned getMatchedDeviceCount()
const {
return matchedDevices; }
122 unsigned getNextTreeMatchCount()
const {
return nextTree; }
123 const std::vector<size_t> *getReplacementStrings()
const {
return replacementStrings; }
124 int getResetWalkId()
const {
return resetWalkId; }
133 template <
typename T>
void 134 Node::visitR(T &t,
char key)
const 136 if (!t.pre(key,
this))
138 for (childmap::const_iterator it = children.begin(); it != children.end(); ++it)
140 (*it).second->visitR(t, (*it).first);
160 template <
typename T,
typename Allocator>
size_t 161 dafind(
const DeviceAtlas &atlas, T &t, TreeID tree, Allocator &a,
const char *rostr,
char **matched,
char **unmatched)
163 const Node *n = atlas.roots[tree];
164 size_t len = strlen(rostr);
166 a.allocate(str, len + 1);
167 strlcpy(str, rostr, len + 1);
170 a.allocate(*matched, atlas.maxDepth + 1);
172 Node::childmap::const_iterator it;
175 char *pathp = matched ? *matched : 0;
177 for (offset = 0;;++offset) {
178 NodeData *data = n->data;
181 if (data->getResetWalkId() > -1) {
183 const char *resetWalkString = atlas.getResetWalkString((
size_t)data->getResetWalkId()).c_str();
184 size_t resetWalkStringLen = strlen(resetWalkString);
185 size_t ostrlen = strlen(str + offset);
186 size_t pcount = atlas.getPropertyCount();
187 a.allocate(pstr, resetWalkStringLen + ostrlen + 1);
188 memcpy(pstr, resetWalkString, resetWalkStringLen);
189 memcpy(pstr + resetWalkStringLen, str + offset, ostrlen + 1);
195 for (
size_t i = 0; i < pcount; i ++)
198 return dafind(atlas, t, tree, a, pstr, matched, unmatched);
201 if (!t(*n, str, offset) || str[offset] == 0)
203 if ((atlas.flags & DeviceAtlas::NoREFold) == 0) {
204 const std::vector<size_t> *repls = data->replacementStrings;
206 atlas.doReplacements(repls, str, offset);
210 *pathp++ = str[offset];
211 it = n->children.find(str[offset]);
212 if (it == n->children.end())
219 (*matched)[dataoff] = 0;
221 *unmatched = str + dataoff;
226 template <
typename T>
void 227 visit(
const DeviceAtlas &atlas, T &t, TreeID tree)
229 atlas.roots[tree]->visitR(t,
'.');
257 std::vector<Rule *> rules;
265 std::map<int, int> selectionCriteria;
266 std::vector<RuleSet *> ruleSets;
269 const RuleSet *findSet(
const UAR *,
int,
const char *text)
const;
275 TaggedRegexMap allRegexes;
276 const std::vector<REInfo *> *langRegexes;
277 const std::vector<REInfo *> *defaultRegexes;
278 std::vector<int> skipProps;
279 std::vector<RuleGroup *> groups;
280 const REInfo *getRE(
size_t re)
const;
290 template <
typename T>
bool 291 testop(Operator op,
const T &lhs,
const T &rhs)
294 case Equal:
return lhs == rhs;
295 case NotEqual:
return lhs != rhs;
296 default: {
Exception err; err <<
"\"unknown\"";
throw err; }
307 const Property &p = da.getPropertyDescr(property);
309 case Bool:
return testop<bool>(op, *value, *candidate);
310 case Integer:
return testop<long>(op, *value, *candidate);
311 case String:
return testop<std::string>(op, *value, *candidate);
312 default:
throw Exception(
"unhandled property type");
320 typedef std::vector<CPRule> Rules;
325 void setProperty(
size_t,
const Value *) {}
327 bool operator() (
const Node &node,
const char *,
size_t);
330 std::ostream &operator<<(std::ostream &os,
const CPRuleGroup &);
331 std::ostream &operator<<(std::ostream &os,
const CPRule &);
332 std::ostream &operator<<(std::ostream &os,
const Operator &);
336 std::vector<const Value *> props;
339 void operator () (PropertyType type,
const char *,
const char *);
359 decodeLanguage(
char *language,
size_t *minuspos) {
361 if (*language ==
'*')
366 if ((m = strchr(language,
'-')) == NULL)
367 m = strchr(language,
'_');
371 if (mlen == 1 || mlen > 3)
380 if (strlen(language) > 2)
384 for(; *p; p++, mp++) {
385 if ((*p !=
'-' && !isalpha(*p) && !isspace(*p)))
387 if (*minuspos > 0 && mp > *minuspos)
398 template <
typename Allocator>
400 stripQlanguage(
const char *language,
size_t *minuspos, Allocator &a) {
402 size_t plen = strlen(language);
403 a.allocate(cp, plen + 1);
404 strlcpy(cp, language, plen + 1);
407 AcceptLanguagePreference apmax;
413 while((token = strtok_r(cp,
",", &ptr)) != NULL) {
417 while (isspace(*token) && token ++);
423 if ((qstr = strstr(token,
";")) != NULL) {
424 codelen = (qstr - token);
427 while (isspace(*qstr) && qstr ++);
428 if (strncmp(qstr,
"q=", 2) == 0) {
430 while (isspace(*qstr) && qstr ++);
432 float qtmp = strtod(qstr, 0);
443 size_t tminuspos = 0;
445 if ((codelen = decodeLanguage(token, &tminuspos)) > 0) {
446 a.allocate(code, codelen + 1);
447 strlcpy(code, token, codelen + 1);
452 apmax.minuspos = tminuspos;
454 }
else if (q == apmax.q) {
455 if (apmax.code && tminuspos > 0 &&
456 strncmp(apmax.code, code, tminuspos) == 0 &&
457 codelen > apmax.len) {
459 apmax.minuspos = tminuspos;
466 const char *finallanguage = (apmax.code ? (*apmax.code ==
'*' ? 0 : apmax.code) : 0);
467 *minuspos = (apmax.code ? apmax.minuspos : 0);
469 return finallanguage;
472 template <
typename T,
typename Allocator>
473 void decodeHeuristic(
const char *p, T &cprec, Allocator &a)
478 size_t plen = strlen(p);
479 a.allocate(cp, plen + 1);
480 strlcpy(cp, p, plen + 1);
486 while ((token = strtok_r(cp,
"|", &ptr)) != NULL) {
489 char key[124], *kp = key;
490 char escapedvalue[124], *ep = escapedvalue;
491 switch ((c = nextchar((
const char *&)token, Util::SKIPQUOTE | Util::NULLOK))) {
492 case 'b': type = Bool;
break;
493 case 'i': type = Integer;
break;
494 case 's': type = String;
break;
496 default: cprec.props.clear();
return;
499 char *sptr, *tmpkp, *tmpvp;
500 tmpkp = strtok_r(token,
":", &sptr);
501 tmpvp = strtok_r(NULL,
":", &sptr);
507 for (
char *p = tmpkp; m++ < (
sizeof(key)) - 1 && *p; ++p)
512 for (
const char *p = tmpvp; m++ < (
sizeof(escapedvalue) - 1) && *p; ++p) {
514 case '\"': ep += snprintf(ep,
sizeof(
""e;") + 1,
""e;");
break;
515 case '&': ep += snprintf(ep,
sizeof(
"&") + 1,
"&");
break;
516 case '<': ep += snprintf(ep,
sizeof(
"<") + 1,
"<");
break;
517 case '>': ep += snprintf(ep,
sizeof(
">") + 1,
">");
break;
518 default: *ep++ = *p;
break;
524 for (i = kp; *i && (isalnum(*i) || *i ==
'.'); ++i);
526 if (*i == 0 && i != kp)
527 cprec(type, kp, escapedvalue);
533 typedef std::vector<CPRuleGroup> RuleGroups;
534 RuleGroups ruleGroups;
540 #endif // devatlas_priv_h Definition: devatlas_priv.h:301
Definition: devatlas.h:105
Definition: devatlas_priv.h:531
Definition: exception.h:16
Definition: devatlas_priv.h:38
Definition: dajson.cpp:244
Definition: dajson.cpp:187
Definition: devatlas_priv.h:335
Definition: devatlas_priv.h:85
Definition: devatlas_priv.h:105
Definition: devatlas_priv.h:233
Definition: devatlas_priv.h:10
Definition: devatlas_priv.h:16
Definition: devatlas_priv.h:254
Definition: devatlas_priv.h:273
Definition: devatlas_priv.h:347
Definition: devatlas.h:218
Definition: devatlas_priv.h:262
Definition: devatlas_priv.h:317