Fix last commit
[carla.git] / source / rest / buffers.cpp
blob985a8c8f4c61f75a8ad1e7ddb53c1defee5c2972
1 /*
2 * Carla REST API Server
3 * Copyright (C) 2018 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "buffers.hpp"
19 #include "CarlaMathUtils.hpp"
21 #include <cstdio>
22 #include <cstring>
24 // -------------------------------------------------------------------------------------------------------------------
26 enum {
27 kJsonBufSize = 4095,
28 kStrBufSize = 1023,
29 kSizeBufSize = 31,
32 // static buffer to return json
33 // NOTE size is never checked for json, the buffer is big enough in order to assume it all always fits
34 static char jsonBuf[kJsonBufSize+1];
36 // static buffer to return size
37 static char sizeBuf[kSizeBufSize+1];
39 // static buffer to return regular strings
40 static char strBuf[kStrBufSize+1];
42 // -------------------------------------------------------------------------------------------------------------------
44 const char* size_buf(const char* const buf)
46 const std::size_t size = std::strlen(buf);
47 std::snprintf(sizeBuf, kSizeBufSize, P_SIZE, size);
48 sizeBuf[kSizeBufSize] = '\0';
49 return sizeBuf;
52 // -------------------------------------------------------------------------------------------------------------------
54 const char* str_buf_bool(const bool value)
56 strBuf[0] = value ? '1' : '0';
57 strBuf[1] = '\0';
58 return strBuf;
61 // -------------------------------------------------------------------------------------------------------------------
63 const char* str_buf_float(const double value)
65 std::snprintf(strBuf, kStrBufSize, "%f", value);
66 strBuf[kStrBufSize] = '\0';
67 return strBuf;
70 const char* str_buf_float_array(const double* const values, const char sep)
72 std::size_t bytesRead = 0;
73 char tmpBuf[32];
75 for (int i=0; carla_isNotZero(values[i]) && bytesRead < kStrBufSize; ++i)
77 std::snprintf(tmpBuf, 31, "%f", values[i]);
78 tmpBuf[31] = '\0';
80 const std::size_t size = std::strlen(tmpBuf);
82 if (bytesRead + size > kStrBufSize)
83 break;
85 std::strncpy(strBuf+bytesRead, tmpBuf, kStrBufSize - bytesRead);
86 bytesRead += size;
87 strBuf[bytesRead] = sep;
88 bytesRead += 1;
91 strBuf[bytesRead > 0 ? bytesRead-1 : 0] = '\0';
92 return strBuf;
95 // -------------------------------------------------------------------------------------------------------------------
97 const char* str_buf_string(const char* const string)
99 std::strncpy(strBuf, string, kStrBufSize);
100 strBuf[kStrBufSize] = '\0';
101 return strBuf;
104 const char* str_buf_string_array(const char* const* const array)
106 std::size_t bytesRead = 0;
108 for (int i=0; array[i] != nullptr && bytesRead < kStrBufSize; ++i)
110 const std::size_t size = std::strlen(array[i]);
112 if (bytesRead + size > kStrBufSize)
113 break;
115 std::strncpy(strBuf+bytesRead, array[i], kStrBufSize - bytesRead);
116 bytesRead += size;
117 strBuf[bytesRead] = '\n';
118 bytesRead += 1;
121 strBuf[bytesRead > 0 ? bytesRead-1 : 0] = '\0';
122 return strBuf;
125 const char* str_buf_string_quoted(const char* const string)
127 const std::size_t size = std::strlen(string);
128 char* strBufPtr = strBuf;
130 *strBufPtr++ = '"';
132 for (std::size_t i=0, bytesWritten=0; i < size && bytesWritten < kStrBufSize-1; ++i)
134 switch (string[i])
136 case '"':
137 case '\\':
138 *strBufPtr++ = '\\';
139 ++bytesWritten;
140 break;
141 case '\n':
142 *strBufPtr++ = '\\';
143 *strBufPtr++ = 'n';;
144 bytesWritten += 2;
145 continue;
146 case '\f':
147 *strBufPtr++ = '\\';
148 *strBufPtr++ = 'f';;
149 bytesWritten += 2;
150 continue;
153 *strBufPtr++ = string[i];
154 ++bytesWritten;
157 *strBufPtr++ = '"';
158 *strBufPtr++ = '\0';
159 return strBuf;
162 // -------------------------------------------------------------------------------------------------------------------
164 const char* str_buf_int(const int value)
166 std::snprintf(strBuf, kStrBufSize, "%i", value);
167 strBuf[kStrBufSize] = '\0';
168 return strBuf;
171 const char* str_buf_int64(const int64_t value)
173 std::snprintf(strBuf, kStrBufSize, P_INT64, value);
174 strBuf[kStrBufSize] = '\0';
175 return strBuf;
178 const char* str_buf_uint(const uint value)
180 std::snprintf(strBuf, kStrBufSize, "%u", value);
181 strBuf[kStrBufSize] = '\0';
182 return strBuf;
185 const char* str_buf_uint64(const uint64_t value)
187 std::snprintf(strBuf, kStrBufSize, P_UINT64, value);
188 strBuf[kStrBufSize] = '\0';
189 return strBuf;
192 const char* str_buf_uint_array(const uint* const values, const char sep)
194 std::size_t bytesRead = 0;
195 char tmpBuf[32];
197 for (int i=0; values[i] != 0 && bytesRead < kStrBufSize; ++i)
199 std::snprintf(tmpBuf, 31, "%u", values[i]);
200 tmpBuf[31] = '\0';
202 const std::size_t size = std::strlen(tmpBuf);
204 if (bytesRead + size > kStrBufSize)
205 break;
207 std::strncpy(strBuf+bytesRead, tmpBuf, kStrBufSize - bytesRead);
208 bytesRead += size;
209 strBuf[bytesRead] = sep;
210 bytesRead += 1;
213 strBuf[bytesRead > 0 ? bytesRead-1 : 0] = '\0';
214 return strBuf;
217 // -------------------------------------------------------------------------------------------------------------------
219 char* json_buf_start()
221 std::strcpy(jsonBuf, "{");
222 return jsonBuf + 1;
225 char* json_buf_add(char* jsonBufPtr, const char* const key, const char* const valueBuf)
227 if (jsonBufPtr != jsonBuf+1)
228 *jsonBufPtr++ = ',';
230 *jsonBufPtr++ = '"';
232 std::strcpy(jsonBufPtr, key);
233 jsonBufPtr += std::strlen(key);
235 *jsonBufPtr++ = '"';
236 *jsonBufPtr++ = ':';
238 std::strcpy(jsonBufPtr, valueBuf);
239 jsonBufPtr += std::strlen(valueBuf);
241 return jsonBufPtr;
244 template <typename T, typename Fn>
245 char* json_buf_add_fn(char* jsonBufPtr, const char* const key, const T value, const Fn fn)
247 return json_buf_add(jsonBufPtr, key, fn(value));
250 template <typename T, typename Fn>
251 char* json_buf_add_fn_array(char* jsonBufPtr, const char* const key, const T value, const Fn fn)
253 return json_buf_add(jsonBufPtr, key, fn(value, ','));
256 // -------------------------------------------------------------------------------------------------------------------
258 char* json_buf_add_bool(char* jsonBufPtr, const char* const key, const bool value)
260 static const char* const kTrue = "true";
261 static const char* const kFalse = "false";
262 return json_buf_add_fn(jsonBufPtr, key, value ? kTrue : kFalse, str_buf_string);
265 char* json_buf_add_float(char* jsonBufPtr, const char* const key, const double value)
267 return json_buf_add_fn(jsonBufPtr, key, value, str_buf_float);
270 char* json_buf_add_float_array(char* jsonBufPtr, const char* const key, const double* const values)
272 return json_buf_add_fn_array(jsonBufPtr, key, values, str_buf_float_array);
275 char* json_buf_add_string(char* jsonBufPtr, const char* const key, const char* const value)
277 return json_buf_add_fn(jsonBufPtr, key, value, str_buf_string_quoted);
280 char* json_buf_add_int(char* jsonBufPtr, const char* const key, const int value)
282 return json_buf_add_fn(jsonBufPtr, key, value, str_buf_int);
285 char* json_buf_add_int64(char* jsonBufPtr, const char* const key, const int64_t value)
287 return json_buf_add_fn(jsonBufPtr, key, value, str_buf_int64);
290 char* json_buf_add_uint(char* jsonBufPtr, const char* const key, const uint value)
292 return json_buf_add_fn(jsonBufPtr, key, value, str_buf_uint);
295 char* json_buf_add_uint_array(char* jsonBufPtr, const char* const key, const uint* const values)
297 return json_buf_add_fn_array(jsonBufPtr, key, values, str_buf_uint_array);
300 char* json_buf_add_uint64(char* jsonBufPtr, const char* const key, const uint64_t value)
302 return json_buf_add_fn(jsonBufPtr, key, value, str_buf_uint64);
305 const char* json_buf_end(char* jsonBufPtr)
307 *jsonBufPtr++ = '}';
308 *jsonBufPtr++ = '\0';
309 return jsonBuf;
312 // -------------------------------------------------------------------------------------------------------------------