]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/cmdparse: handle array of integer also
authorKefu Chai <kchai@redhat.com>
Sat, 9 Jan 2016 03:20:59 +0000 (11:20 +0800)
committerKefu Chai <kchai@redhat.com>
Tue, 3 May 2016 14:42:29 +0000 (22:42 +0800)
we need to handle cmd arg of [int..]. for example, the osdid in
"ceph osd pg-temp <pgid> <osdid>.." could be represented using an array
of integers instead of an array of strings.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/common/cmdparse.cc
src/common/cmdparse.h

index 6c1aae83db5ac1acb1135e804ee2e46cd5aa3af9..7c4ad58998d5521ba51518ac531ffddcd9f0164c 100644 (file)
@@ -155,16 +155,35 @@ cmdmap_from_json(vector<string> cmd, map<string, cmd_vartype> *mapp, stringstrea
       case json_spirit::array_type:
        {
          // array is a vector of values.  Unpack it to a vector
-         // of strings, the only type we handle.
-         vector<json_spirit::mValue> spvals = it->second.get_array();
-         vector<string> outv;
-         for (vector<json_spirit::mValue>::iterator sv = spvals.begin();
-              sv != spvals.end(); ++sv) {
-           if (sv->type() != json_spirit::str_type)
-             throw(runtime_error("Can't handle arrays of non-strings"));
-           outv.push_back(sv->get_str());
+         // of strings or int64_t, the only types we handle.
+         const vector<json_spirit::mValue>& spvals = it->second.get_array();
+         if (spvals.empty()) {
+           // if an empty array is acceptable, the caller should always check for
+           // vector<string> if the expected value of "vector<int64_t>" in the
+           // cmdmap is missing.
+           (*mapp)[it->first] = std::move(vector<string>());
+         } else if (spvals.front().type() == json_spirit::str_type) {
+           vector<string> outv;
+           for (const auto& sv : spvals) {
+             if (sv.type() != json_spirit::str_type) {
+               throw(runtime_error("Can't handle arrays of multiple types"));
+             }
+             outv.push_back(sv.get_str());
+           }
+           (*mapp)[it->first] = std::move(outv);
+         } else if (spvals.front().type() == json_spirit::int_type) {
+           vector<int64_t> outv;
+           for (const auto& sv : spvals) {
+             if (spvals.front().type() != json_spirit::int_type) {
+               throw(runtime_error("Can't handle arrays of multiple types"));
+             }
+             outv.push_back(sv.get_int64());
+           }
+           (*mapp)[it->first] = std::move(outv);
+         } else {
+           throw(runtime_error("Can't handle arrays of types other than "
+                               "int or string"));
          }
-         (*mapp)[it->first] = outv;
        }
        break;
       case json_spirit::str_type:
index 97c082037f7619904e750c6e2c03dd48711ce849..0d022af71cbd7a8fa19c56c6836bd0581a263117 100644 (file)
@@ -17,7 +17,12 @@ class CephContext;
 /* this is handy; can't believe it's not standard */
 #define ARRAY_SIZE(a)  (sizeof(a) / sizeof(*a))
 
-typedef boost::variant<std::string, bool, int64_t, double, std::vector<std::string> > cmd_vartype;
+typedef boost::variant<std::string,
+                      bool,
+                      int64_t,
+                      double,
+                      std::vector<std::string>,
+                      std::vector<int64_t>>  cmd_vartype;
 typedef std::map<std::string, cmd_vartype> cmdmap_t;
 
 void dump_cmd_to_json(ceph::Formatter *f, const std::string& cmd);