]> git.proxmox.com Git - ceph.git/blob - ceph/src/mgr/PyFormatter.cc
update sources to v12.1.0
[ceph.git] / ceph / src / mgr / PyFormatter.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2015 Red Hat Inc
7 *
8 * Author: John Spray <john.spray@redhat.com>
9 *
10 * This is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License version 2.1, as published by the Free Software
13 * Foundation. See file COPYING.
14 *
15 */
16
17
18 #include "PyFormatter.h"
19
20 #define LARGE_SIZE 1024
21
22
23 void PyFormatter::open_array_section(const char *name)
24 {
25 PyObject *list = PyList_New(0);
26 dump_pyobject(name, list);
27 stack.push(cursor);
28 cursor = list;
29 }
30
31 void PyFormatter::open_object_section(const char *name)
32 {
33 PyObject *dict = PyDict_New();
34 dump_pyobject(name, dict);
35 stack.push(cursor);
36 cursor = dict;
37 }
38
39 void PyFormatter::dump_unsigned(const char *name, uint64_t u)
40 {
41 PyObject *p = PyLong_FromLongLong(u);
42 assert(p);
43 dump_pyobject(name, p);
44 }
45
46 void PyFormatter::dump_int(const char *name, int64_t u)
47 {
48 PyObject *p = PyLong_FromLongLong(u);
49 assert(p);
50 dump_pyobject(name, p);
51 }
52
53 void PyFormatter::dump_float(const char *name, double d)
54 {
55 dump_pyobject(name, PyFloat_FromDouble(d));
56 }
57
58 void PyFormatter::dump_string(const char *name, const std::string& s)
59 {
60 dump_pyobject(name, PyString_FromString(s.c_str()));
61 }
62
63 void PyFormatter::dump_bool(const char *name, bool b)
64 {
65 if (b) {
66 Py_INCREF(Py_True);
67 dump_pyobject(name, Py_True);
68 } else {
69 Py_INCREF(Py_False);
70 dump_pyobject(name, Py_False);
71 }
72 }
73
74 std::ostream& PyFormatter::dump_stream(const char *name)
75 {
76 // Give the caller an ostream, construct a PyString,
77 // and remember the association between the two. On flush,
78 // we'll read from the ostream into the PyString
79 auto ps = std::make_shared<PendingStream>();
80 ps->cursor = cursor;
81 ps->name = name;
82
83 pending_streams.push_back(ps);
84
85 return ps->stream;
86 }
87
88 void PyFormatter::dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap)
89 {
90 char buf[LARGE_SIZE];
91 vsnprintf(buf, LARGE_SIZE, fmt, ap);
92
93 dump_pyobject(name, PyString_FromString(buf));
94 }
95
96 /**
97 * Steals reference to `p`
98 */
99 void PyFormatter::dump_pyobject(const char *name, PyObject *p)
100 {
101 if (PyList_Check(cursor)) {
102 PyList_Append(cursor, p);
103 Py_DECREF(p);
104 } else if (PyDict_Check(cursor)) {
105 PyObject *key = PyString_FromString(name);
106 PyDict_SetItem(cursor, key, p);
107 Py_DECREF(key);
108 Py_DECREF(p);
109 } else {
110 ceph_abort();
111 }
112 }
113
114 void PyFormatter::finish_pending_streams()
115 {
116 for (const auto &i : pending_streams) {
117 PyObject *tmp_cur = cursor;
118 cursor = i->cursor;
119 dump_pyobject(
120 i->name.c_str(),
121 PyString_FromString(i->stream.str().c_str()));
122 cursor = tmp_cur;
123 }
124
125 pending_streams.clear();
126 }
127