return -EINVAL;
bson_init(out);
+
list_for_each_entry(child, &obj->val.children, node) {
switch (child->type) {
case TYPE_OID:
bson_append_int(out, child->key, child->val.i);
break;
case TYPE_TIMESPEC:
- /* TODO */
- break;
+ {
+ bson_append_start_object(out, child->key);
+ bson_append_int(out, "tv_sec", child->val.ts.tv_sec);
+ bson_append_long(out, "tv_nsec", child->val.ts.tv_nsec);
+ bson_append_finish_object(out);
+ break;
+ }
case TYPE_TIME_T:
bson_append_time_t(out, child->key, child->val.time);
break;
return 0;
}
+static int bson_to_timespec(bson *in, struct timespec *ts)
+{
+ bson_iterator it;
+
+ BSON_ITERATOR_INIT(&it, in);
+
+ if ((bson_iterator_next(&it) == BSON_INT) &&
+ (strcmp(bson_iterator_key(&it), "tv_sec") == 0))
+
+ ts->tv_sec = bson_iterator_int(&it);
+ else
+ return -ENOENT;
+
+ if ((bson_iterator_next(&it) == BSON_LONG) &&
+ (strcmp(bson_iterator_key(&it), "tv_nsec") == 0))
+
+ ts->tv_nsec = bson_iterator_long(&it);
+ else
+ return -ENOENT;
+
+ if (bson_iterator_next(&it) != BSON_EOO)
+ return -ENOENT;
+
+ return 0;
+}
+
static int bson_to_faultd_object(bson *b, struct faultd_object *out)
{
bson_type bt;
case BSON_INT:
ret = faultd_object_append_int(out, key, bson_iterator_int(&it));
break;
- case BSON_TIMESTAMP:
- /* TODO */
- ret = 0;
- break;
case BSON_LONG:
ret = faultd_object_append_time_t(out, key, bson_iterator_time_t(&it));
break;
+ case BSON_DATE:
+ ret = faultd_object_append_time_t(out, key, bson_iterator_time_t(&it));
+ break;
case BSON_BINDATA:
- /* FIXME: find information about subtype */
- /* we assume every bindata is uuid */
- ret = faultd_object_append_uuid(out, key, (sd_id128_t *)bson_iterator_bin_data(&it));
+ switch (bson_iterator_bin_type(&it)) {
+ case BSON_BIN_UUID:
+ ret = faultd_object_append_uuid(out, key,
+ (sd_id128_t *)bson_iterator_bin_data(&it));
+ break;
+ default:
+ ret = -ENOTSUP;
+ break;
+ }
break;
case BSON_OBJECT:
- /* TODO */
- ret = -ENOTSUP;
- break;
+ {
+ struct timespec ts;
+ bson b;
+
+ bson_iterator_subobject(&it, &b);
+
+ if (bson_to_timespec(&b, &ts) == 0) {
+ ret = faultd_object_append_timespec(out, key, &ts);
+ } else {
+ struct faultd_object *child;
+
+ ret = faultd_object_new(&child);
+ if (ret != 0)
+ break;
+
+ ret = bson_to_faultd_object(&b, child);
+ if (ret != 0)
+ goto cleanup;
+
+ ret = faultd_object_append_object(out, key, child);
+
+ cleanup:
+ faultd_object_unref(child);
+ }
+
+ break;
+ }
+
default:
ret = -ENOTSUP;
}