#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <utility>
using StrView = std::pair<const char*, size_t>;
StrView makeStrView(const char *str, size_t size) {
return std::make_pair(str, size);
}
struct compareStrView {
bool operator()(const StrView &lhs, const StrView &rhs) const {
if (lhs.second == rhs.second)
return (std::char_traits<char>::compare(lhs.first, rhs.first, lhs.second) < 0);
return (lhs.second < rhs.second);
}
};
std::ostream& operator<<(std::ostream &os, const StrView &rhs) {
return os.write(rhs.first, rhs.second);
}
int main() {
std::string str("0=My,1=comma,2=separated,3=string,0=with,3=repeated,7=IDs");
std::vector<StrView> out0;
std::map<StrView, StrView, compareStrView> out;
size_t startPos = 0, delimPos, nameStart, nameEnd, valueStart, valueEnd;
// loop over the string, collecting "key=value" pairs
while (startPos < str.size()){
nameStart = startPos;
delimPos = str.find_first_of("=,", startPos, 2);
if (delimPos == std::string::npos) {
nameEnd = valueStart = valueEnd = str.size();
}
else {
nameEnd = delimPos;
if (str[delimPos] == '=') {
valueStart = nameEnd + 1;
valueEnd = str.find(',', valueStart);
if (valueEnd == std::string::npos) {
valueEnd = str.size();
}
}
else {
valueStart = valueEnd = nameEnd;
}
}
// TODO: if needed, adjust nameStart/End and valueStartEnd to
// ignore leading/trailing whitespace around the name and value
// substrings...
if (str.compare(nameStart, nameEnd - nameStart, "0", 1) == 0) {
out0.push_back(makeStrView(&str[valueStart], valueEnd - valueStart));
} else {
out[makeStrView(&str[nameStart], nameEnd - nameStart)] = makeStrView(&str[valueStart], valueEnd - valueStart);
}
startPos = valueEnd + 1;
}
// print out the data structures
std::cout << "out0:";
for (auto& entry : out0) {
std::cout << ' ' << entry;
}
std::cout << std::endl;
std::cout << "out:";
for (auto &it : out) {
std::cout << ' ' << it.first << '=' << it.second;
}
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dXRpbGl0eT4KCnVzaW5nIFN0clZpZXcgPSBzdGQ6OnBhaXI8Y29uc3QgY2hhciosIHNpemVfdD47CgpTdHJWaWV3IG1ha2VTdHJWaWV3KGNvbnN0IGNoYXIgKnN0ciwgc2l6ZV90IHNpemUpIHsKCXJldHVybiBzdGQ6Om1ha2VfcGFpcihzdHIsIHNpemUpOwp9CgpzdHJ1Y3QgY29tcGFyZVN0clZpZXcgewoJYm9vbCBvcGVyYXRvcigpKGNvbnN0IFN0clZpZXcgJmxocywgY29uc3QgU3RyVmlldyAmcmhzKSBjb25zdCB7CgkJaWYgKGxocy5zZWNvbmQgPT0gcmhzLnNlY29uZCkKCQkJcmV0dXJuIChzdGQ6OmNoYXJfdHJhaXRzPGNoYXI+Ojpjb21wYXJlKGxocy5maXJzdCwgcmhzLmZpcnN0LCBsaHMuc2Vjb25kKSA8IDApOwoJCXJldHVybiAobGhzLnNlY29uZCA8IHJocy5zZWNvbmQpOwoJfQp9OwoKc3RkOjpvc3RyZWFtJiBvcGVyYXRvcjw8KHN0ZDo6b3N0cmVhbSAmb3MsIGNvbnN0IFN0clZpZXcgJnJocykgewoJcmV0dXJuIG9zLndyaXRlKHJocy5maXJzdCwgcmhzLnNlY29uZCk7Cn0KCmludCBtYWluKCkgewogICAgc3RkOjpzdHJpbmcgc3RyKCIwPU15LDE9Y29tbWEsMj1zZXBhcmF0ZWQsMz1zdHJpbmcsMD13aXRoLDM9cmVwZWF0ZWQsNz1JRHMiKTsKICAgIHN0ZDo6dmVjdG9yPFN0clZpZXc+IG91dDA7CiAgICBzdGQ6Om1hcDxTdHJWaWV3LCBTdHJWaWV3LCBjb21wYXJlU3RyVmlldz4gb3V0OwoKICAgIHNpemVfdCBzdGFydFBvcyA9IDAsIGRlbGltUG9zLCBuYW1lU3RhcnQsIG5hbWVFbmQsIHZhbHVlU3RhcnQsIHZhbHVlRW5kOwoKICAgIC8vIGxvb3Agb3ZlciB0aGUgc3RyaW5nLCBjb2xsZWN0aW5nICJrZXk9dmFsdWUiIHBhaXJzCiAgICB3aGlsZSAoc3RhcnRQb3MgPCBzdHIuc2l6ZSgpKXsKICAgICAgICBuYW1lU3RhcnQgPSBzdGFydFBvczsKICAgICAgICBkZWxpbVBvcyA9IHN0ci5maW5kX2ZpcnN0X29mKCI9LCIsIHN0YXJ0UG9zLCAyKTsKICAgICAgICBpZiAoZGVsaW1Qb3MgPT0gc3RkOjpzdHJpbmc6Om5wb3MpIHsKICAgICAgICAgICAgbmFtZUVuZCA9IHZhbHVlU3RhcnQgPSB2YWx1ZUVuZCA9IHN0ci5zaXplKCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBuYW1lRW5kID0gZGVsaW1Qb3M7CiAgICAgICAgICAgIGlmIChzdHJbZGVsaW1Qb3NdID09ICc9JykgewogICAgICAgICAgICAgICAgdmFsdWVTdGFydCA9IG5hbWVFbmQgKyAxOwogICAgICAgICAgICAgICAgdmFsdWVFbmQgPSBzdHIuZmluZCgnLCcsIHZhbHVlU3RhcnQpOwogICAgICAgICAgICAgICAgaWYgKHZhbHVlRW5kID09IHN0ZDo6c3RyaW5nOjpucG9zKSB7CiAgICAgICAgICAgICAgICAgICAgdmFsdWVFbmQgPSBzdHIuc2l6ZSgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdmFsdWVTdGFydCA9IHZhbHVlRW5kID0gbmFtZUVuZDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy8gVE9ETzogaWYgbmVlZGVkLCBhZGp1c3QgbmFtZVN0YXJ0L0VuZCBhbmQgdmFsdWVTdGFydEVuZCB0bwogICAgICAgIC8vIGlnbm9yZSBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2UgYXJvdW5kIHRoZSBuYW1lIGFuZCB2YWx1ZQogICAgICAgIC8vIHN1YnN0cmluZ3MuLi4KCiAgICAgICAgaWYgKHN0ci5jb21wYXJlKG5hbWVTdGFydCwgbmFtZUVuZCAtIG5hbWVTdGFydCwgIjAiLCAxKSA9PSAwKSB7CiAgICAgICAgICAgIG91dDAucHVzaF9iYWNrKG1ha2VTdHJWaWV3KCZzdHJbdmFsdWVTdGFydF0sIHZhbHVlRW5kIC0gdmFsdWVTdGFydCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG91dFttYWtlU3RyVmlldygmc3RyW25hbWVTdGFydF0sIG5hbWVFbmQgLSBuYW1lU3RhcnQpXSA9IG1ha2VTdHJWaWV3KCZzdHJbdmFsdWVTdGFydF0sIHZhbHVlRW5kIC0gdmFsdWVTdGFydCk7CgkJfQoKICAgICAgICBzdGFydFBvcyA9IHZhbHVlRW5kICsgMTsKICAgIH0KCiAgICAvLyBwcmludCBvdXQgdGhlIGRhdGEgc3RydWN0dXJlcwogICAgc3RkOjpjb3V0IDw8ICJvdXQwOiI7CiAgICBmb3IgKGF1dG8mIGVudHJ5IDogb3V0MCkgewogICAgICAgIHN0ZDo6Y291dCA8PCAnICcgPDwgZW50cnk7Cgl9CiAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoKICAgIHN0ZDo6Y291dCA8PCAib3V0OiI7CiAgICBmb3IgKGF1dG8gJml0IDogb3V0KSB7CiAgICAgICAgc3RkOjpjb3V0IDw8ICcgJyA8PCBpdC5maXJzdCA8PCAnPScgPDwgaXQuc2Vjb25kOwogICAgfQp9