1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2007 InspIRCd Development Team
6 * See: http://www.inspircd.org/wiki/index.php/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
23 #include "configreader.h"
25 #include "inspsocket.h"
29 /* $ModDesc: Provides a JSON-RPC interface for modules using m_httpd.so */
31 class ModuleRpcJson : public Module
34 ModuleRpcJson(InspIRCd* Me) : Module(Me)
39 void OnEvent(Event* event)
41 std::stringstream data("");
43 if (event->GetEventID() == "httpd_url")
45 HTTPRequest* http = (HTTPRequest*)event->GetData();
47 if (http->GetURI() == "/jsonrpc" && http->GetType() == "POST")
49 std::string response_text;
50 json::rpc::process (http, response_text, http->GetPostData().c_str());
51 data << response_text;
53 /* Send the document back to m_httpd */
54 HTTPDocument response(http->sock, &data, 200, "X-Powered-By: m_rpc_json.so\r\n"
55 "Content-Type: application/json; charset=iso-8859-1\r\n");
56 Request req((char*)&response, (Module*)this, event->GetSource());
62 void Implements(char* List)
67 virtual ~ModuleRpcJson()
71 virtual Version GetVersion()
73 return Version(0, 1, 0, 0, VF_VENDOR, API_VERSION);
78 unreachable_internal (char const *file, int line, char const *function)
81 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
82 file, line, function);
84 throw std::runtime_error (buf);
88 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
91 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
92 file, line, function, condition);
94 throw std::runtime_error (buf);
98 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
101 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
102 file, line, function, message);
104 throw std::runtime_error (buf);
110 ValueIteratorBase::ValueIteratorBase ()
115 ValueIteratorBase::ValueIteratorBase (const Value::ObjectValues::iterator ¤t)
121 ValueIteratorBase::deref () const
123 return current_->second;
128 ValueIteratorBase::increment ()
135 ValueIteratorBase::decrement ()
141 ValueIteratorBase::difference_type
142 ValueIteratorBase::computeDistance (const SelfType &other) const
144 return difference_type (std::distance (current_, other.current_));
149 ValueIteratorBase::isEqual (const SelfType &other) const
151 return current_ == other.current_;
156 ValueIteratorBase::copy (const SelfType &other)
158 current_ = other.current_;
163 ValueIteratorBase::key () const
165 const Value::CZString czstring = (*current_).first;
166 if (czstring.c_str ())
168 if (czstring.isStaticString ())
169 return Value (StaticString (czstring.c_str ()));
170 return Value (czstring.c_str ());
172 return Value (czstring.index ());
177 ValueIteratorBase::index () const
179 const Value::CZString czstring = (*current_).first;
180 if (!czstring.c_str ())
181 return czstring.index ();
182 return unsigned (-1);
187 ValueIteratorBase::memberName () const
189 char const *name = (*current_).first.c_str ();
190 return name ? name : "";
194 ValueConstIterator::ValueConstIterator ()
199 ValueConstIterator::ValueConstIterator (const Value::ObjectValues::iterator ¤t)
200 : ValueIteratorBase (current)
205 ValueConstIterator::operator = (const ValueIteratorBase &other)
212 ValueIterator::ValueIterator ()
217 ValueIterator::ValueIterator (const Value::ObjectValues::iterator ¤t)
218 : ValueIteratorBase (current)
222 ValueIterator::ValueIterator (const ValueConstIterator &other)
223 : ValueIteratorBase (other)
227 ValueIterator::ValueIterator (const ValueIterator &other)
228 : ValueIteratorBase (other)
233 ValueIterator::operator = (const SelfType &other)
243 in (char c, char c1, char c2, char c3, char c4)
245 return c == c1 || c == c2 || c == c3 || c == c4;
249 in (char c, char c1, char c2, char c3, char c4, char c5)
251 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
260 Reader::parse (const std::string &document,
263 document_ = document;
264 char const *begin = document_.c_str ();
265 char const *end = begin + document_.length ();
266 return parse (begin, end, root);
270 Reader::parse (std::istream& sin,
274 std::getline (sin, doc, (char)EOF);
275 return parse (doc, root);
279 Reader::parse (char const *beginDoc, char const *endDOc,
288 while (!nodes_.empty ())
292 bool successful = readValue ();
303 while (token.type_ == tokenComment);
304 bool successful = true;
308 case tokenObjectBegin:
309 successful = readObject ();
311 case tokenArrayBegin:
312 successful = readArray ();
315 successful = decodeNumber (token);
318 successful = decodeString (token);
321 currentValue () = true;
324 currentValue () = false;
327 currentValue () = Value ();
330 return addError ("Syntax error: value, object or array expected.", token);
338 Reader::expectToken (TokenType type, Token &token, char const *message)
341 if (token.type_ != type)
342 return addError (message, token);
348 Reader::readToken (Token &token)
351 token.start_ = current_;
352 char c = getNextChar ();
357 token.type_ = tokenObjectBegin;
360 token.type_ = tokenObjectEnd;
363 token.type_ = tokenArrayBegin;
366 token.type_ = tokenArrayEnd;
369 token.type_ = tokenString;
377 case '0': case '1': case '2': case '3':
378 case '4': case '5': case '6': case '7':
382 token.type_ = tokenNumber;
386 token.type_ = tokenTrue;
387 ok = match ("rue", 3);
390 token.type_ = tokenFalse;
391 ok = match ("alse", 4);
394 token.type_ = tokenNull;
395 ok = match ("ull", 3);
398 token.type_ = tokenArraySeparator;
401 token.type_ = tokenMemberSeparator;
404 token.type_ = tokenEndOfStream;
411 token.type_ = tokenError;
412 token.end_ = current_;
418 Reader::skipSpaces ()
420 while (current_ != end_)
423 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
432 Reader::match (Location pattern, int patternLength)
434 if (end_ - current_ < patternLength)
436 int index = patternLength;
438 if (current_[index] != pattern[index])
440 current_ += patternLength;
446 Reader::readNumber ()
448 while (current_ != end_)
450 if (!(*current_ >= '0' && *current_ <= '9') &&
451 !in (*current_, '.', 'e', 'E', '+', '-'))
458 Reader::readString ()
461 while (current_ != end_)
474 Reader::readObject ()
478 currentValue () = Value (objectValue);
479 while (readToken (tokenName))
481 if (tokenName.type_ == tokenObjectEnd && name.empty ()) // empty object
483 if (tokenName.type_ != tokenString)
487 if (!decodeString (tokenName, name))
488 return recoverFromError (tokenObjectEnd);
491 if (!readToken (colon) || colon.type_ != tokenMemberSeparator)
493 return addErrorAndRecover ("Missing ':' after object member name",
497 Value &value = currentValue ()[ name ];
498 nodes_.push (&value);
499 bool ok = readValue ();
501 if (!ok) // error already set
502 return recoverFromError (tokenObjectEnd);
505 if (!readToken (comma)
506 || (comma.type_ != tokenObjectEnd &&
507 comma.type_ != tokenArraySeparator))
509 return addErrorAndRecover ("Missing ',' or '}' in object declaration",
513 if (comma.type_ == tokenObjectEnd)
516 return addErrorAndRecover ("Missing '}' or object member name",
525 currentValue () = Value (arrayValue);
527 if (*current_ == ']') // empty array
530 readToken (endArray);
536 Value &value = currentValue ()[ index++ ];
537 nodes_.push (&value);
538 bool ok = readValue ();
540 if (!ok) // error already set
541 return recoverFromError (tokenArrayEnd);
544 if (!readToken (token)
545 || (token.type_ != tokenArraySeparator &&
546 token.type_ != tokenArrayEnd))
548 return addErrorAndRecover ("Missing ',' or ']' in array declaration",
552 if (token.type_ == tokenArrayEnd)
560 Reader::decodeNumber (Token &token)
562 bool isDouble = false;
563 for (Location inspect = token.start_; inspect != token.end_; ++inspect)
566 || in (*inspect, '.', 'e', 'E', '+')
567 || (*inspect == '-' && inspect != token.start_);
570 return decodeDouble (token);
571 Location current = token.start_;
572 bool isNegative = *current == '-';
575 unsigned threshold = (isNegative ? unsigned (-Value::minInt)
576 : Value::maxUInt) / 10;
578 while (current < token.end_)
581 if (c < '0' || c > '9')
582 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
583 if (value >= threshold)
584 return decodeDouble (token);
585 value = value * 10 + unsigned (c - '0');
588 currentValue () = -int (value);
589 else if (value <= unsigned (Value::maxInt))
590 currentValue () = int (value);
592 currentValue () = value;
598 Reader::decodeDouble (Token &token)
601 const int bufferSize = 32;
603 int length = int (token.end_ - token.start_);
604 if (length <= bufferSize)
606 char buffer[bufferSize];
607 memcpy (buffer, token.start_, length);
609 count = sscanf (buffer, "%lf", &value);
613 std::string buffer (token.start_, token.end_);
614 count = sscanf (buffer.c_str (), "%lf", &value);
618 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
619 currentValue () = value;
625 Reader::decodeString (Token &token)
628 if (!decodeString (token, decoded))
630 currentValue () = decoded;
636 Reader::decodeString (Token &token, std::string &decoded)
638 Location current = token.start_ + 1; // skip '"'
639 Location end = token.end_ - 1; // do not include '"'
640 decoded.reserve (long (end - current));
642 while (current != end)
645 if (expect_false (c == '"'))
647 else if (expect_false (c == '\\'))
649 if (expect_false (current == end))
650 return addError ("Empty escape sequence in string", token, current);
651 char escape = *current++;
656 case '\\': decoded += escape; break;
658 case 'b': decoded += '\010'; break;
659 case 't': decoded += '\011'; break;
660 case 'n': decoded += '\012'; break;
661 case 'f': decoded += '\014'; break;
662 case 'r': decoded += '\015'; break;
666 if (!decodeUnicodeEscapeSequence (token, current, end, unicode))
668 // @todo encode unicode as utf8.
669 // @todo remember to alter the writer too.
673 return addError ("Bad escape sequence in string", token, current);
687 Reader::decodeUnicodeEscapeSequence (Token &token,
692 if (end - current < 4)
693 return addError ("Bad unicode escape sequence in string: four digits expected.", token, current);
695 for (int index = 0; index < 4; ++index)
699 if (c >= '0' && c <= '9')
701 else if (c >= 'a' && c <= 'f')
702 unicode += c - 'a' + 10;
703 else if (c >= 'A' && c <= 'F')
704 unicode += c - 'A' + 10;
706 return addError ("Bad unicode escape sequence in string: hexadecimal digit expected.", token, current);
713 Reader::addError (const std::string &message,
719 info.message_ = message;
721 errors_.push_back (info);
727 Reader::recoverFromError (TokenType skipUntilToken)
729 int errorCount = int (errors_.size ());
733 if (!readToken (skip))
734 errors_.resize (errorCount); // discard errors caused by recovery
735 if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
738 errors_.resize (errorCount);
744 Reader::addErrorAndRecover (const std::string &message,
746 TokenType skipUntilToken)
748 addError (message, token);
749 return recoverFromError (skipUntilToken);
754 Reader::currentValue ()
756 return *(nodes_.top ());
761 Reader::getNextChar ()
763 if (current_ == end_)
770 Reader::getLocationLineAndColumn (Location location,
774 Location current = begin_;
775 Location lastLineStart = current;
777 while (current < location && current != end_)
782 if (*current == '\n')
784 lastLineStart = current;
789 lastLineStart = current;
793 // column & line start at 1
794 column = int (location - lastLineStart) + 1;
800 Reader::getLocationLineAndColumn (Location location) const
803 getLocationLineAndColumn (location, line, column);
804 char buffer[18+16+16+1];
805 sprintf (buffer, "Line %d, Column %d", line, column);
811 Reader::error_msgs () const
813 std::string formattedMessage;
814 for (Errors::const_iterator itError = errors_.begin ();
815 itError != errors_.end ();
818 const ErrorInfo &error = *itError;
819 formattedMessage += "* " + getLocationLineAndColumn (error.token_.start_) + "\n";
820 formattedMessage += " " + error.message_ + "\n";
822 formattedMessage += "See " + getLocationLineAndColumn (error.extra_) + " for detail.\n";
824 return formattedMessage;
831 unreachable_internal (char const *file, int line, char const *function)
834 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
835 file, line, function);
837 throw std::runtime_error (buf);
841 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
844 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
845 file, line, function, condition);
847 throw std::runtime_error (buf);
851 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
854 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
855 file, line, function, message);
857 throw std::runtime_error (buf);
860 const Value Value::null;
861 const int Value::minInt = int (~ (unsigned (-1)/2));
862 const int Value::maxInt = int (unsigned (-1)/2);
863 const unsigned Value::maxUInt = unsigned (-1);
865 ValueAllocator::~ValueAllocator ()
869 class DefaultValueAllocator : public ValueAllocator
872 virtual ~DefaultValueAllocator ()
876 virtual char *makeMemberName (char const *memberName)
878 return duplicateStringValue (memberName);
881 virtual void releaseMemberName (char *memberName)
883 releaseStringValue (memberName);
886 virtual char *duplicateStringValue (char const *value, unsigned length = unknown)
888 //@todo invesgate this old optimization
890 if (!value || value[0] == 0)
894 if (length == unknown)
895 length = (unsigned)strlen (value);
896 char *newString = static_cast<char *> (malloc (length + 1));
897 memcpy (newString, value, length);
898 newString[length] = 0;
902 virtual void releaseStringValue (char *value)
909 static ValueAllocator *&valueAllocator ()
911 static DefaultValueAllocator defaultAllocator;
912 static ValueAllocator *valueAllocator = &defaultAllocator;
913 return valueAllocator;
916 static struct DummyValueAllocatorInitializer {
917 DummyValueAllocatorInitializer ()
919 valueAllocator (); // ensure valueAllocator () statics are initialized before main ().
921 } dummyValueAllocatorInitializer;
925 Value::CZString::CZString (int index)
931 Value::CZString::CZString (char const *cstr, DuplicationPolicy allocate)
932 : cstr_ (allocate == duplicate ? valueAllocator()->makeMemberName (cstr)
938 Value::CZString::CZString (const CZString &other)
939 : cstr_ (other.index_ != noDuplication && other.cstr_ != 0
940 ? valueAllocator()->makeMemberName (other.cstr_)
942 , index_ (other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
947 Value::CZString::~CZString ()
949 if (cstr_ && index_ == duplicate)
950 valueAllocator()->releaseMemberName (const_cast<char *> (cstr_));
954 Value::CZString::swap (CZString &other)
956 std::swap (cstr_, other.cstr_);
957 std::swap (index_, other.index_);
961 Value::CZString::operator = (const CZString &other)
963 CZString temp (other);
969 Value::CZString::operator < (const CZString &other) const
972 return strcmp (cstr_, other.cstr_) < 0;
973 return index_ < other.index_;
977 Value::CZString::operator == (const CZString &other) const
980 return strcmp (cstr_, other.cstr_) == 0;
981 return index_ == other.index_;
986 Value::CZString::index () const
993 Value::CZString::c_str () const
999 Value::CZString::isStaticString () const
1001 return index_ == noDuplication;
1005 // class Value::Value
1007 Value::Value (ValueType type)
1027 value_.map_ = new ObjectValues ();
1030 value_.bool_ = false;
1038 Value::Value (int value)
1041 value_.int_ = value;
1045 Value::Value (unsigned value)
1048 value_.uint_ = value;
1051 Value::Value (double value)
1054 value_.real_ = value;
1057 Value::Value (char const *value)
1058 : type_ (stringValue)
1061 value_.string_ = valueAllocator()->duplicateStringValue (value);
1064 Value::Value (const std::string &value)
1065 : type_ (stringValue)
1068 value_.string_ = valueAllocator()->duplicateStringValue (value.c_str (), (unsigned)value.length ());
1071 Value::Value (const StaticString &value)
1072 : type_ (stringValue)
1073 , allocated_ (false)
1075 value_.string_ = const_cast<char *> (value.c_str ());
1079 Value::Value (bool value)
1080 : type_ (booleanValue)
1082 value_.bool_ = value;
1086 Value::Value (const Value &other)
1087 : type_ (other.type_)
1096 value_ = other.value_;
1099 if (other.value_.string_)
1101 value_.string_ = valueAllocator()->duplicateStringValue (other.value_.string_);
1109 value_.map_ = new ObjectValues (*other.value_.map_);
1129 valueAllocator()->releaseStringValue (value_.string_);
1141 Value::operator = (const Value &other)
1149 Value::swap (Value &other)
1151 ValueType temp = type_;
1152 type_ = other.type_;
1154 std::swap (value_, other.value_);
1155 int temp2 = allocated_;
1156 allocated_ = other.allocated_;
1157 other.allocated_ = temp2;
1161 Value::type () const
1167 Value::operator < (const Value &other) const
1169 int typeDelta = type_ - other.type_;
1171 return typeDelta < 0 ? true : false;
1177 return value_.int_ < other.value_.int_;
1179 return value_.uint_ < other.value_.uint_;
1181 return value_.real_ < other.value_.real_;
1183 return value_.bool_ < other.value_.bool_;
1185 return (value_.string_ == 0 && other.value_.string_)
1186 || (other.value_.string_
1188 && strcmp (value_.string_, other.value_.string_) < 0);
1192 int delta = int (value_.map_->size () - other.value_.map_->size ());
1195 return (*value_.map_) < (*other.value_.map_);
1200 return 0; // unreachable
1204 Value::operator <= (const Value &other) const
1206 return !(other > *this);
1210 Value::operator >= (const Value &other) const
1212 return !(*this < other);
1216 Value::operator > (const Value &other) const
1218 return other < *this;
1222 Value::operator == (const Value &other) const
1224 if (type_ != other.type_)
1232 return value_.int_ == other.value_.int_;
1234 return value_.uint_ == other.value_.uint_;
1236 return value_.real_ == other.value_.real_;
1238 return value_.bool_ == other.value_.bool_;
1240 return (value_.string_ == other.value_.string_)
1241 || (other.value_.string_
1243 && strcmp (value_.string_, other.value_.string_) == 0);
1246 return value_.map_->size () == other.value_.map_->size ()
1247 && (*value_.map_) == (*other.value_.map_);
1251 return 0; // unreachable
1255 Value::operator != (const Value &other) const
1257 return !(*this == other);
1260 Value::operator char const * () const
1262 throw_unless (type_ == stringValue);
1263 return value_.string_;
1267 Value::operator std::string () const
1274 return value_.string_ ? value_.string_ : "";
1276 return value_.bool_ ? "true" : "false";
1282 throw_msg_unless (false, "Type is not convertible to string");
1286 return ""; // unreachable
1289 Value::operator int () const
1298 throw_msg_unless (value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
1299 return value_.uint_;
1301 throw_msg_unless (value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
1302 return int (value_.real_);
1304 return value_.bool_ ? 1 : 0;
1308 throw_msg_unless (false, "Type is not convertible to int");
1312 return 0; // unreachable;
1315 Value::operator unsigned () const
1322 throw_msg_unless (value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
1325 return value_.uint_;
1327 throw_msg_unless (value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
1328 return unsigned (value_.real_);
1330 return value_.bool_ ? 1 : 0;
1334 throw_msg_unless (false, "Type is not convertible to uint");
1338 return 0; // unreachable;
1341 Value::operator double () const
1350 return value_.uint_;
1352 return value_.real_;
1354 return value_.bool_ ? 1.0 : 0.0;
1358 throw_msg_unless (false, "Type is not convertible to double");
1362 return 0; // unreachable;
1365 Value::operator bool () const
1373 return value_.int_ != 0;
1375 return value_.real_ != 0.0;
1377 return value_.bool_;
1379 return value_.string_ && value_.string_[0] != 0;
1382 return value_.map_->size () != 0;
1386 return false; // unreachable;
1391 Value::isConvertibleTo (ValueType other) const
1398 return (other == nullValue && value_.int_ == 0)
1399 || other == intValue
1400 || (other == uintValue && value_.int_ >= 0)
1401 || other == realValue
1402 || other == stringValue
1403 || other == booleanValue;
1405 return (other == nullValue && value_.uint_ == 0)
1406 || (other == intValue && value_.uint_ <= (unsigned)maxInt)
1407 || other == uintValue
1408 || other == realValue
1409 || other == stringValue
1410 || other == booleanValue;
1412 return (other == nullValue && value_.real_ == 0.0)
1413 || (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt)
1414 || (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt)
1415 || other == realValue
1416 || other == stringValue
1417 || other == booleanValue;
1419 return (other == nullValue && value_.bool_ == false)
1420 || other == intValue
1421 || other == uintValue
1422 || other == realValue
1423 || other == stringValue
1424 || other == booleanValue;
1426 return other == stringValue
1427 || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
1429 return other == arrayValue
1430 || (other == nullValue && value_.map_->size () == 0);
1432 return other == objectValue
1433 || (other == nullValue && value_.map_->size () == 0);
1437 return false; // unreachable;
1441 /// Number of values in array or object
1443 Value::size () const
1454 case arrayValue: // size of the array is highest index + 1
1455 if (!value_.map_->empty ())
1457 ObjectValues::const_iterator itLast = value_.map_->end ();
1459 return itLast->first.index ()+1;
1463 return int (value_.map_->size ());
1467 return 0; // unreachable;
1472 Value::empty () const
1474 if (isNull () || isArray () || isObject ())
1475 return size () == 0u;
1482 Value::operator ! () const
1491 throw_unless (type_ == nullValue || type_ == arrayValue || type_ == objectValue);
1497 value_.map_->clear ();
1505 Value::resize (unsigned newSize)
1507 throw_unless (type_ == nullValue || type_ == arrayValue);
1508 if (type_ == nullValue)
1509 *this = Value (arrayValue);
1510 unsigned oldSize = size ();
1513 else if (newSize > oldSize)
1514 (*this)[ newSize - 1 ];
1517 for (unsigned index = newSize; index < oldSize; ++index)
1518 value_.map_->erase (index);
1519 throw_unless (size () == newSize);
1525 Value::operator [] (int index)
1527 return operator [] (static_cast<unsigned> (index));
1532 Value::operator [] (unsigned index)
1534 throw_unless (type_ == nullValue || type_ == arrayValue);
1535 if (type_ == nullValue)
1536 *this = Value (arrayValue);
1537 CZString key (index);
1538 ObjectValues::iterator it = value_.map_->lower_bound (key);
1539 if (it != value_.map_->end () && it->first == key)
1542 ObjectValues::value_type defaultValue (key, null);
1543 it = value_.map_->insert (it, defaultValue);
1549 Value::operator [] (int index) const
1551 return operator [] (static_cast<unsigned> (index));
1556 Value::operator [] (unsigned index) const
1558 throw_unless (type_ == nullValue || type_ == arrayValue);
1559 if (type_ == nullValue)
1561 CZString key (index);
1562 ObjectValues::const_iterator it = value_.map_->find (key);
1563 if (it == value_.map_->end ())
1570 Value::operator [] (char const *key)
1572 return resolveReference (key, false);
1577 Value::resolveReference (char const *key, bool isStatic)
1579 throw_unless (type_ == nullValue || type_ == objectValue);
1580 if (type_ == nullValue)
1581 *this = Value (objectValue);
1582 CZString actualKey (key, isStatic ? CZString::noDuplication
1583 : CZString::duplicateOnCopy);
1584 ObjectValues::iterator it = value_.map_->lower_bound (actualKey);
1585 if (it != value_.map_->end () && it->first == actualKey)
1588 ObjectValues::value_type defaultValue (actualKey, null);
1589 it = value_.map_->insert (it, defaultValue);
1590 Value &value = it->second;
1596 Value::get (int index, const Value &defaultValue) const
1598 return get (static_cast<unsigned> (index), defaultValue);
1603 Value::get (unsigned index, const Value &defaultValue) const
1605 const Value *value = &((*this)[index]);
1606 return value == &null ? defaultValue : *value;
1611 Value::isValidIndex (int index) const
1613 return isValidIndex (static_cast<unsigned> (index));
1618 Value::isValidIndex (unsigned index) const
1620 return index < size ();
1626 Value::operator [] (char const *key) const
1628 throw_unless (type_ == nullValue || type_ == objectValue);
1629 if (type_ == nullValue)
1631 CZString actualKey (key, CZString::noDuplication);
1632 ObjectValues::const_iterator it = value_.map_->find (actualKey);
1633 if (it == value_.map_->end ())
1640 Value::operator [] (const std::string &key)
1642 return (*this)[ key.c_str () ];
1647 Value::operator [] (const std::string &key) const
1649 return (*this)[ key.c_str () ];
1653 Value::operator [] (const StaticString &key)
1655 return resolveReference (key, true);
1660 Value::append (const Value &value)
1662 return (*this)[size ()] = value;
1667 Value::get (char const *key, const Value &defaultValue) const
1669 const Value *value = &((*this)[key]);
1670 return value == &null ? defaultValue : *value;
1675 Value::get (const std::string &key, const Value &defaultValue) const
1677 return get (key.c_str (), defaultValue);
1681 Value::removeMember (char const *key)
1683 throw_unless (type_ == nullValue || type_ == objectValue);
1684 if (type_ == nullValue)
1686 CZString actualKey (key, CZString::noDuplication);
1687 ObjectValues::iterator it = value_.map_->find (actualKey);
1688 if (it == value_.map_->end ())
1690 Value old (it->second);
1691 value_.map_->erase (it);
1696 Value::removeMember (const std::string &key)
1698 return removeMember (key.c_str ());
1702 Value::isMember (char const *key) const
1704 const Value *value = &((*this)[key]);
1705 return value != &null;
1710 Value::isMember (const std::string &key) const
1712 return isMember (key.c_str ());
1717 Value::getMemberNames () const
1719 throw_unless (type_ == nullValue || type_ == objectValue);
1720 if (type_ == nullValue)
1721 return Value::Members ();
1723 members.reserve (value_.map_->size ());
1724 ObjectValues::const_iterator it;
1725 ObjectValues::const_iterator itEnd = value_.map_->end ();
1726 for (it = value_.map_->begin (); it != itEnd; ++it)
1727 members.push_back (std::string (it->first.c_str()));
1732 Value::isNull () const
1734 return type_ == nullValue;
1739 Value::isBool () const
1741 return type_ == booleanValue;
1746 Value::isInt () const
1748 return type_ == intValue;
1753 Value::isUInt () const
1755 return type_ == uintValue;
1760 Value::isIntegral () const
1762 return type_ == intValue
1763 || type_ == uintValue
1764 || type_ == booleanValue;
1769 Value::isDouble () const
1771 return type_ == realValue;
1776 Value::isNumeric () const
1778 return isIntegral () || isDouble ();
1783 Value::isString () const
1785 return type_ == stringValue;
1790 Value::isArray () const
1792 return type_ == nullValue || type_ == arrayValue;
1797 Value::isObject () const
1799 return type_ == nullValue || type_ == objectValue;
1803 Value::const_iterator
1804 Value::begin () const
1811 return const_iterator (value_.map_->begin ());
1816 return const_iterator ();
1819 Value::const_iterator
1827 return const_iterator (value_.map_->end ());
1832 return const_iterator ();
1844 return iterator (value_.map_->begin ());
1860 return iterator (value_.map_->end ());
1871 static void uintToString (unsigned value,
1877 *--current = (value % 10) + '0';
1883 std::string valueToString (int value)
1886 char *current = buffer + sizeof (buffer);
1887 bool isNegative = value < 0;
1890 uintToString (unsigned (value), current);
1893 throw_unless (current >= buffer);
1898 std::string valueToString (unsigned value)
1901 char *current = buffer + sizeof (buffer);
1902 uintToString (value, current);
1903 throw_unless (current >= buffer);
1907 std::string valueToString (double value)
1910 sprintf (buffer, "%.16g", value);
1915 std::string valueToString (bool value)
1917 return value ? "true" : "false";
1920 std::string valueToQuotedString (char const *value)
1922 // Not sure how to handle unicode...
1923 if (std::strpbrk (value, "\"\\\b\f\n\r\t") == NULL)
1924 return std::string ("\"") + value + "\"";
1925 // We have to walk value and escape any special characters.
1926 // Appending to std::string is not efficient, but this should be rare.
1927 // (Note: forward slashes are *not* rare, but I am not escaping them.)
1928 unsigned maxsize = strlen (value) * 2 + 3; // allescaped+quotes+NULL
1930 result.reserve (maxsize); // to avoid lots of mallocs
1932 for (char const* c=value; *c != 0; ++c){
1956 // Even though \/ is considered a legal escape in JSON, a bare
1957 // slash is also legal, so I see no reason to escape it.
1958 // (I hope I am not misunderstanding something.)
1969 Writer::write (const Value &root)
1979 Writer::writeValue (const Value &value)
1981 switch (value.type ())
1984 document_ += "null";
1987 document_ += valueToString (static_cast<int> (value));
1990 document_ += valueToString (static_cast<unsigned> (value));
1993 document_ += valueToString (static_cast<double> (value));
1996 document_ += valueToQuotedString (static_cast<char const *> (value));
1999 document_ += valueToString (static_cast<bool> (value));
2004 int size = value.size ();
2005 for (int index = 0; index < size; ++index)
2009 writeValue (value[index]);
2016 Value::Members members (value.getMemberNames ());
2018 for (Value::Members::iterator it = members.begin ();
2019 it != members.end ();
2022 const std::string &name = *it;
2023 if (it != members.begin ())
2025 document_ += valueToQuotedString (name.c_str ());
2027 writeValue (value[name]);
2044 typedef std::map<std::string, void (*) (HTTPRequest *, Value &, Value &)> method_map;
2049 add_method (char *name, method mth)
2051 methods[name] = mth;
2055 system_list_methods (HTTPRequest *http, Value &request, Value &response)
2058 Value method_list (arrayValue);
2060 method_map::iterator it;
2061 for (it = methods.begin(); it != methods.end(); ++it)
2063 method_list[i] = Value (it->first);
2067 response["result"] = method_list;
2073 add_method ("system.listMethods", &system_list_methods);
2077 service (HTTPRequest *http, Value &request, Value &response)
2079 char const *methodName = static_cast<char const *> (request["method"]);
2081 method_map::iterator mth = methods.find (methodName);
2082 if (mth != methods.end ())
2083 (*mth->second) (http, request, response);
2087 process (HTTPRequest *http, std::string &response_text, char const *request_text)
2091 Value request (objectValue);
2092 Value response (objectValue);
2096 parse_success = r.parse (request_text, request_text + strlen (request_text), request);
2098 service (http, request, response);
2100 text = w.write (response);
2102 response_text = text.c_str ();
2109 MODULE_INIT(ModuleRpcJson)