1 /* 2 * (C) 2018 Ribose Inc 3 * 4 * Botan is released under the Simplified BSD License (see license.txt) 5 */ 6 7 #include <botan/parsing.h> 8 #include <botan/exceptn.h> 9 10 namespace Botan { 11 read_kv(const std::string & kv)12std::map<std::string, std::string> read_kv(const std::string& kv) 13 { 14 std::map<std::string, std::string> m; 15 if(kv == "") 16 return m; 17 18 std::vector<std::string> parts; 19 20 try 21 { 22 parts = split_on(kv, ','); 23 } 24 catch(std::exception&) 25 { 26 throw Invalid_Argument("Bad KV spec"); 27 } 28 29 bool escaped = false; 30 bool reading_key = true; 31 std::string cur_key; 32 std::string cur_val; 33 34 for(char c : kv) 35 { 36 if(c == '\\' && !escaped) 37 { 38 escaped = true; 39 } 40 else if(c == ',' && !escaped) 41 { 42 if(cur_key.empty()) 43 throw Invalid_Argument("Bad KV spec empty key"); 44 45 if(m.find(cur_key) != m.end()) 46 throw Invalid_Argument("Bad KV spec duplicated key"); 47 m[cur_key] = cur_val; 48 cur_key = ""; 49 cur_val = ""; 50 reading_key = true; 51 } 52 else if(c == '=' && !escaped) 53 { 54 if(reading_key == false) 55 throw Invalid_Argument("Bad KV spec unexpected equals sign"); 56 reading_key = false; 57 } 58 else 59 { 60 if(reading_key) 61 cur_key += c; 62 else 63 cur_val += c; 64 65 if(escaped) 66 escaped = false; 67 } 68 } 69 70 if(!cur_key.empty()) 71 { 72 if(reading_key == false) 73 { 74 if(m.find(cur_key) != m.end()) 75 throw Invalid_Argument("Bad KV spec duplicated key"); 76 m[cur_key] = cur_val; 77 } 78 else 79 throw Invalid_Argument("Bad KV spec incomplete string"); 80 } 81 82 return m; 83 } 84 85 } 86