| 56 | } |
| 57 | |
| 58 | Composition parseCompString(const string& ss, const vector<string>& names) |
| 59 | { |
| 60 | Composition x; |
| 61 | for (size_t k = 0; k < names.size(); k++) { |
| 62 | x[names[k]] = 0.0; |
| 63 | } |
| 64 | |
| 65 | size_t start = 0; |
| 66 | size_t stop = 0; |
| 67 | size_t left = 0; |
| 68 | while (stop < ss.size()) { |
| 69 | size_t colon = ss.find(':', left); |
| 70 | if (colon == npos) { |
| 71 | break; |
| 72 | } |
| 73 | size_t valstart = ss.find_first_not_of(" \t\n", colon+1); |
| 74 | stop = ss.find_first_of(", ;\n\t", valstart); |
| 75 | string name = ba::trim_copy(ss.substr(start, colon-start)); |
| 76 | if (!names.empty() && x.find(name) == x.end()) { |
| 77 | throw CanteraError("parseCompString", |
| 78 | "unknown species '" + name + "'"); |
| 79 | } |
| 80 | |
| 81 | double value; |
| 82 | try { |
| 83 | value = fpValueCheck(ss.substr(valstart, stop-valstart)); |
| 84 | } catch (CanteraError&) { |
| 85 | // If we have a key containing a colon, we expect this to fail. In |
| 86 | // this case, take the current substring as part of the key and look |
| 87 | // to the right of the next colon for the corresponding value. |
| 88 | // Otherwise, this is an invalid composition string. |
| 89 | string testname = ss.substr(start, stop-start); |
| 90 | if (testname.find_first_of(" \n\t") != npos) { |
| 91 | // Space, tab, and newline are never allowed in names |
| 92 | throw; |
| 93 | } else if (ss.substr(valstart, stop-valstart).find(':') != npos) { |
| 94 | left = colon + 1; |
| 95 | stop = 0; // Force another iteration of this loop |
| 96 | continue; |
| 97 | } else { |
| 98 | throw; |
| 99 | } |
| 100 | } |
| 101 | if (getValue(x, name, 0.0) != 0.0) { |
| 102 | throw CanteraError("parseCompString", |
| 103 | "Duplicate key: '" + name + "'."); |
| 104 | } |
| 105 | |
| 106 | x[name] = value; |
| 107 | start = ss.find_first_not_of(", ;\n\t", stop+1); |
| 108 | left = start; |
| 109 | } |
| 110 | if (left != start) { |
| 111 | throw CanteraError("parseCompString", "Unable to parse key-value pair:" |
| 112 | "\n'{}'", ss.substr(start, stop)); |
| 113 | } |
| 114 | if (stop != npos && !ba::trim_copy(ss.substr(stop)).empty()) { |
| 115 | throw CanteraError("parseCompString", "Found non-key:value data " |