Re: json parsing/decoding

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 6 Feb 2013, Yehuda Sadeh wrote:
> The matter of json decoding was brought up as part of the discussion
> of the ceph management api. I recently had to deal with it with the
> rados gateway, as I wasn't too happy was the current mechanisms that
> were used for this purpose. So I introduced a new decode_json()
> functionality (now in common/ceph_json.* at the wip-json-decode
> branch). It's very similar to the regular encode/decode stuff that we
> use to encode/decode structures. Encoding is being done using the
> already existing dump() method, and decoding will be done through the
> new decode_json() method.
> 
> As an example we'll define a new UserInfo structure:
> 
> struct UserInfo {
>   string uid;
>   string display_name;
>   int max_buckets;
>   list<Key> keys;
> 
>   void dump(Formatter *f) const;
>   void decode_json(JSONObj *obj);
> };
> 
> The dump() method will look like this:
> 
> void UserInfo::dump(Formatter *f) const
> {
>   f->open_object_section("user_info");
>   f->dump_string("user_id", uid);
>   f->dump_string("display_name", display_name);
>   f->dump_int("max_buckets", (int)max_buckets);
> 
>   f->open_array_section("keys");
>   for (list<Key>::iterator iter = keys.begin(); siter != keys.end(); ++iter) {
>     iter->dump(f);
>   }
>   f->close_section();
> 
>   f->close_section();
> }
> 
> It is recommended that every dump() method opens an object section and
> puts everything within, so that every object could be easily embedded
> within other objects. We can also probably create some template that

The current loose convention is that the dump objects do not define the 
container they dump into.  It's a bit weird, but it lets you do things 
like:

map<Key, Value> foo;

   f->open_array_section("keys");
   for (map<Key,Value>::iterator iter = keys.begin(); siter != keys.end(); ++iter) {
     f->open_object_section("thing");
     f->dump_string("key", iter->first);
     iter->second.dump(f);
     f->close_section();
   }
   f->close_section();

Admittedly that doesn't come up *that* often, but it happened enough when 
we first started doing the dump stuff that all/most of the dumpers work 
that way.

How should we deal with that?

sage


> will remove the need of doing that inner loop, e.g.:
>   ...
>   f->dump_array("keys", keys);
>   ...
> 
> In any case, the corresponding json decoding function looks like this:
> 
> void UserInfo::decode_json(JSONObj *obj) {
>   JSONDecoder::decode_json("user_id", uid, obj);
>   JSONDecoder::decode_json("display_name", display_name, obj);
>   JSONDecoder::decode_json("max_buckets", max_buckets, obj);
>   JSONDecoder::decode_json("keys", keys, obj);
> }
> 
> 
> and we'll decode the structure like this:
> 
> ...
> 
> UserInfo user_info;
> 
> JSONParser parser;
> 
> if (!parser.parse(buf, len))
>   return -EINVAL;
> ...
> try {
>   user_info.decode(&parser);
> } catch (JSONDecoder::err& e) {
> ...
> }
> 
> 
> The default behavior is that every field is optional, so that it just
> ignores fields that are not found in the json structure. If a field is
> set to be mandatory (by extra param to the decode_json()), then an
> exception will be thrown. Note that all fields should be initialized
> to the default value before decoding as passed json might not contain
> any relevant field.
> 
> 
> Yehuda
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux