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;
52 json::rpc::process (http, response_text, http->GetPostData().c_str());
54 catch (std::runtime_error &)
58 data << response_text;
60 /* Send the document back to m_httpd */
61 HTTPDocument response(http->sock, &data, 200, "X-Powered-By: m_rpc_json.so\r\n"
62 "Content-Type: application/json; charset=iso-8859-1\r\n");
63 Request req((char*)&response, (Module*)this, event->GetSource());
69 void Implements(char* List)
74 virtual ~ModuleRpcJson()
78 virtual Version GetVersion()
80 return Version(0, 1, 0, 0, VF_VENDOR, API_VERSION);
85 unreachable_internal (char const *file, int line, char const *function)
88 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
89 file, line, function);
91 throw std::runtime_error (buf);
95 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
98 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
99 file, line, function, condition);
101 throw std::runtime_error (buf);
105 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
108 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
109 file, line, function, message);
111 throw std::runtime_error (buf);
117 ValueIteratorBase::ValueIteratorBase ()
122 ValueIteratorBase::ValueIteratorBase (const Value::ObjectValues::iterator ¤t)
128 ValueIteratorBase::deref () const
130 return current_->second;
135 ValueIteratorBase::increment ()
142 ValueIteratorBase::decrement ()
148 ValueIteratorBase::difference_type
149 ValueIteratorBase::computeDistance (const SelfType &other) const
151 return difference_type (std::distance (current_, other.current_));
156 ValueIteratorBase::isEqual (const SelfType &other) const
158 return current_ == other.current_;
163 ValueIteratorBase::copy (const SelfType &other)
165 current_ = other.current_;
170 ValueIteratorBase::key () const
172 const Value::CZString czstring = (*current_).first;
173 if (czstring.c_str ())
175 if (czstring.isStaticString ())
176 return Value (StaticString (czstring.c_str ()));
177 return Value (czstring.c_str ());
179 return Value (czstring.index ());
184 ValueIteratorBase::index () const
186 const Value::CZString czstring = (*current_).first;
187 if (!czstring.c_str ())
188 return czstring.index ();
189 return unsigned (-1);
194 ValueIteratorBase::memberName () const
196 char const *name = (*current_).first.c_str ();
197 return name ? name : "";
201 ValueConstIterator::ValueConstIterator ()
206 ValueConstIterator::ValueConstIterator (const Value::ObjectValues::iterator ¤t)
207 : ValueIteratorBase (current)
212 ValueConstIterator::operator = (const ValueIteratorBase &other)
219 ValueIterator::ValueIterator ()
224 ValueIterator::ValueIterator (const Value::ObjectValues::iterator ¤t)
225 : ValueIteratorBase (current)
229 ValueIterator::ValueIterator (const ValueConstIterator &other)
230 : ValueIteratorBase (other)
234 ValueIterator::ValueIterator (const ValueIterator &other)
235 : ValueIteratorBase (other)
240 ValueIterator::operator = (const SelfType &other)
250 in (char c, char c1, char c2, char c3, char c4)
252 return c == c1 || c == c2 || c == c3 || c == c4;
256 in (char c, char c1, char c2, char c3, char c4, char c5)
258 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
267 Reader::parse (const std::string &document,
270 document_ = document;
271 char const *begin = document_.c_str ();
272 char const *end = begin + document_.length ();
273 return parse (begin, end, root);
277 Reader::parse (std::istream& sin,
281 std::getline (sin, doc, (char)EOF);
282 return parse (doc, root);
286 Reader::parse (char const *beginDoc, char const *endDOc,
295 while (!nodes_.empty ())
299 bool successful = readValue ();
310 while (token.type_ == tokenComment);
311 bool successful = true;
315 case tokenObjectBegin:
316 successful = readObject ();
318 case tokenArrayBegin:
319 successful = readArray ();
322 successful = decodeNumber (token);
325 successful = decodeString (token);
328 currentValue () = true;
331 currentValue () = false;
334 currentValue () = Value ();
337 return addError ("Syntax error: value, object or array expected.", token);
345 Reader::expectToken (TokenType type, Token &token, char const *message)
348 if (token.type_ != type)
349 return addError (message, token);
355 Reader::readToken (Token &token)
358 token.start_ = current_;
359 char c = getNextChar ();
364 token.type_ = tokenObjectBegin;
367 token.type_ = tokenObjectEnd;
370 token.type_ = tokenArrayBegin;
373 token.type_ = tokenArrayEnd;
376 token.type_ = tokenString;
384 case '0': case '1': case '2': case '3':
385 case '4': case '5': case '6': case '7':
389 token.type_ = tokenNumber;
393 token.type_ = tokenTrue;
394 ok = match ("rue", 3);
397 token.type_ = tokenFalse;
398 ok = match ("alse", 4);
401 token.type_ = tokenNull;
402 ok = match ("ull", 3);
405 token.type_ = tokenArraySeparator;
408 token.type_ = tokenMemberSeparator;
411 token.type_ = tokenEndOfStream;
418 token.type_ = tokenError;
419 token.end_ = current_;
425 Reader::skipSpaces ()
427 while (current_ != end_)
430 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
439 Reader::match (Location pattern, int patternLength)
441 if (end_ - current_ < patternLength)
443 int index = patternLength;
445 if (current_[index] != pattern[index])
447 current_ += patternLength;
453 Reader::readNumber ()
455 while (current_ != end_)
457 if (!(*current_ >= '0' && *current_ <= '9') &&
458 !in (*current_, '.', 'e', 'E', '+', '-'))
465 Reader::readString ()
468 while (current_ != end_)
481 Reader::readObject ()
485 currentValue () = Value (objectValue);
486 while (readToken (tokenName))
488 if (tokenName.type_ == tokenObjectEnd && name.empty ()) // empty object
490 if (tokenName.type_ != tokenString)
494 if (!decodeString (tokenName, name))
495 return recoverFromError (tokenObjectEnd);
498 if (!readToken (colon) || colon.type_ != tokenMemberSeparator)
500 return addErrorAndRecover ("Missing ':' after object member name",
504 Value &value = currentValue ()[ name ];
505 nodes_.push (&value);
506 bool ok = readValue ();
508 if (!ok) // error already set
509 return recoverFromError (tokenObjectEnd);
512 if (!readToken (comma)
513 || (comma.type_ != tokenObjectEnd &&
514 comma.type_ != tokenArraySeparator))
516 return addErrorAndRecover ("Missing ',' or '}' in object declaration",
520 if (comma.type_ == tokenObjectEnd)
523 return addErrorAndRecover ("Missing '}' or object member name",
532 currentValue () = Value (arrayValue);
534 if (*current_ == ']') // empty array
537 readToken (endArray);
543 Value &value = currentValue ()[ index++ ];
544 nodes_.push (&value);
545 bool ok = readValue ();
547 if (!ok) // error already set
548 return recoverFromError (tokenArrayEnd);
551 if (!readToken (token)
552 || (token.type_ != tokenArraySeparator &&
553 token.type_ != tokenArrayEnd))
555 return addErrorAndRecover ("Missing ',' or ']' in array declaration",
559 if (token.type_ == tokenArrayEnd)
567 Reader::decodeNumber (Token &token)
569 bool isDouble = false;
570 for (Location inspect = token.start_; inspect != token.end_; ++inspect)
573 || in (*inspect, '.', 'e', 'E', '+')
574 || (*inspect == '-' && inspect != token.start_);
577 return decodeDouble (token);
578 Location current = token.start_;
579 bool isNegative = *current == '-';
582 unsigned threshold = (isNegative ? unsigned (-Value::minInt)
583 : Value::maxUInt) / 10;
585 while (current < token.end_)
588 if (c < '0' || c > '9')
589 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
590 if (value >= threshold)
591 return decodeDouble (token);
592 value = value * 10 + unsigned (c - '0');
595 currentValue () = -int (value);
596 else if (value <= unsigned (Value::maxInt))
597 currentValue () = int (value);
599 currentValue () = value;
605 Reader::decodeDouble (Token &token)
608 const int bufferSize = 32;
610 int length = int (token.end_ - token.start_);
611 if (length <= bufferSize)
613 char buffer[bufferSize];
614 memcpy (buffer, token.start_, length);
616 count = sscanf (buffer, "%lf", &value);
620 std::string buffer (token.start_, token.end_);
621 count = sscanf (buffer.c_str (), "%lf", &value);
625 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
626 currentValue () = value;
632 Reader::decodeString (Token &token)
635 if (!decodeString (token, decoded))
637 currentValue () = decoded;
643 Reader::decodeString (Token &token, std::string &decoded)
645 Location current = token.start_ + 1; // skip '"'
646 Location end = token.end_ - 1; // do not include '"'
647 decoded.reserve (long (end - current));
649 while (current != end)
652 if (expect_false (c == '"'))
654 else if (expect_false (c == '\\'))
656 if (expect_false (current == end))
657 return addError ("Empty escape sequence in string", token, current);
658 char escape = *current++;
663 case '\\': decoded += escape; break;
665 case 'b': decoded += '\010'; break;
666 case 't': decoded += '\011'; break;
667 case 'n': decoded += '\012'; break;
668 case 'f': decoded += '\014'; break;
669 case 'r': decoded += '\015'; break;
673 if (!decodeUnicodeEscapeSequence (token, current, end, unicode))
675 // @todo encode unicode as utf8.
676 // @todo remember to alter the writer too.
680 return addError ("Bad escape sequence in string", token, current);
694 Reader::decodeUnicodeEscapeSequence (Token &token,
699 if (end - current < 4)
700 return addError ("Bad unicode escape sequence in string: four digits expected.", token, current);
702 for (int index = 0; index < 4; ++index)
706 if (c >= '0' && c <= '9')
708 else if (c >= 'a' && c <= 'f')
709 unicode += c - 'a' + 10;
710 else if (c >= 'A' && c <= 'F')
711 unicode += c - 'A' + 10;
713 return addError ("Bad unicode escape sequence in string: hexadecimal digit expected.", token, current);
720 Reader::addError (const std::string &message,
726 info.message_ = message;
728 errors_.push_back (info);
734 Reader::recoverFromError (TokenType skipUntilToken)
736 int errorCount = int (errors_.size ());
740 if (!readToken (skip))
741 errors_.resize (errorCount); // discard errors caused by recovery
742 if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
745 errors_.resize (errorCount);
751 Reader::addErrorAndRecover (const std::string &message,
753 TokenType skipUntilToken)
755 addError (message, token);
756 return recoverFromError (skipUntilToken);
761 Reader::currentValue ()
763 return *(nodes_.top ());
768 Reader::getNextChar ()
770 if (current_ == end_)
777 Reader::getLocationLineAndColumn (Location location,
781 Location current = begin_;
782 Location lastLineStart = current;
784 while (current < location && current != end_)
789 if (*current == '\n')
791 lastLineStart = current;
796 lastLineStart = current;
800 // column & line start at 1
801 column = int (location - lastLineStart) + 1;
807 Reader::getLocationLineAndColumn (Location location) const
810 getLocationLineAndColumn (location, line, column);
811 char buffer[18+16+16+1];
812 sprintf (buffer, "Line %d, Column %d", line, column);
818 Reader::error_msgs () const
820 std::string formattedMessage;
821 for (Errors::const_iterator itError = errors_.begin ();
822 itError != errors_.end ();
825 const ErrorInfo &error = *itError;
826 formattedMessage += "* " + getLocationLineAndColumn (error.token_.start_) + "\n";
827 formattedMessage += " " + error.message_ + "\n";
829 formattedMessage += "See " + getLocationLineAndColumn (error.extra_) + " for detail.\n";
831 return formattedMessage;
838 unreachable_internal (char const *file, int line, char const *function)
841 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
842 file, line, function);
844 throw std::runtime_error (buf);
848 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
851 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
852 file, line, function, condition);
854 throw std::runtime_error (buf);
858 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
861 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
862 file, line, function, message);
864 throw std::runtime_error (buf);
867 const Value Value::null;
868 const int Value::minInt = int (~ (unsigned (-1)/2));
869 const int Value::maxInt = int (unsigned (-1)/2);
870 const unsigned Value::maxUInt = unsigned (-1);
872 ValueAllocator::~ValueAllocator ()
876 class DefaultValueAllocator : public ValueAllocator
879 virtual ~DefaultValueAllocator ()
883 virtual char *makeMemberName (char const *memberName)
885 return duplicateStringValue (memberName);
888 virtual void releaseMemberName (char *memberName)
890 releaseStringValue (memberName);
893 virtual char *duplicateStringValue (char const *value, unsigned length = unknown)
895 //@todo invesgate this old optimization
897 if (!value || value[0] == 0)
901 if (length == unknown)
902 length = (unsigned)strlen (value);
903 char *newString = static_cast<char *> (malloc (length + 1));
904 memcpy (newString, value, length);
905 newString[length] = 0;
909 virtual void releaseStringValue (char *value)
916 static ValueAllocator *&valueAllocator ()
918 static DefaultValueAllocator defaultAllocator;
919 static ValueAllocator *valueAllocator = &defaultAllocator;
920 return valueAllocator;
923 static struct DummyValueAllocatorInitializer {
924 DummyValueAllocatorInitializer ()
926 valueAllocator (); // ensure valueAllocator () statics are initialized before main ().
928 } dummyValueAllocatorInitializer;
932 Value::CZString::CZString (int index)
938 Value::CZString::CZString (char const *cstr, DuplicationPolicy allocate)
939 : cstr_ (allocate == duplicate ? valueAllocator()->makeMemberName (cstr)
945 Value::CZString::CZString (const CZString &other)
946 : cstr_ (other.index_ != noDuplication && other.cstr_ != 0
947 ? valueAllocator()->makeMemberName (other.cstr_)
949 , index_ (other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
954 Value::CZString::~CZString ()
956 if (cstr_ && index_ == duplicate)
957 valueAllocator()->releaseMemberName (const_cast<char *> (cstr_));
961 Value::CZString::swap (CZString &other)
963 std::swap (cstr_, other.cstr_);
964 std::swap (index_, other.index_);
968 Value::CZString::operator = (const CZString &other)
970 CZString temp (other);
976 Value::CZString::operator < (const CZString &other) const
979 return strcmp (cstr_, other.cstr_) < 0;
980 return index_ < other.index_;
984 Value::CZString::operator == (const CZString &other) const
987 return strcmp (cstr_, other.cstr_) == 0;
988 return index_ == other.index_;
993 Value::CZString::index () const
1000 Value::CZString::c_str () const
1006 Value::CZString::isStaticString () const
1008 return index_ == noDuplication;
1012 // class Value::Value
1014 Value::Value (ValueType type)
1034 value_.map_ = new ObjectValues ();
1037 value_.bool_ = false;
1045 Value::Value (int value)
1048 value_.int_ = value;
1052 Value::Value (unsigned value)
1055 value_.uint_ = value;
1058 Value::Value (double value)
1061 value_.real_ = value;
1064 Value::Value (char const *value)
1065 : type_ (stringValue)
1068 value_.string_ = valueAllocator()->duplicateStringValue (value);
1071 Value::Value (const std::string &value)
1072 : type_ (stringValue)
1075 value_.string_ = valueAllocator()->duplicateStringValue (value.c_str (), (unsigned)value.length ());
1078 Value::Value (const StaticString &value)
1079 : type_ (stringValue)
1080 , allocated_ (false)
1082 value_.string_ = const_cast<char *> (value.c_str ());
1086 Value::Value (bool value)
1087 : type_ (booleanValue)
1089 value_.bool_ = value;
1093 Value::Value (const Value &other)
1094 : type_ (other.type_)
1103 value_ = other.value_;
1106 if (other.value_.string_)
1108 value_.string_ = valueAllocator()->duplicateStringValue (other.value_.string_);
1116 value_.map_ = new ObjectValues (*other.value_.map_);
1136 valueAllocator()->releaseStringValue (value_.string_);
1148 Value::operator = (const Value &other)
1156 Value::swap (Value &other)
1158 ValueType temp = type_;
1159 type_ = other.type_;
1161 std::swap (value_, other.value_);
1162 int temp2 = allocated_;
1163 allocated_ = other.allocated_;
1164 other.allocated_ = temp2;
1168 Value::type () const
1174 Value::operator < (const Value &other) const
1176 int typeDelta = type_ - other.type_;
1178 return typeDelta < 0 ? true : false;
1184 return value_.int_ < other.value_.int_;
1186 return value_.uint_ < other.value_.uint_;
1188 return value_.real_ < other.value_.real_;
1190 return value_.bool_ < other.value_.bool_;
1192 return (value_.string_ == 0 && other.value_.string_)
1193 || (other.value_.string_
1195 && strcmp (value_.string_, other.value_.string_) < 0);
1199 int delta = int (value_.map_->size () - other.value_.map_->size ());
1202 return (*value_.map_) < (*other.value_.map_);
1207 return 0; // unreachable
1211 Value::operator <= (const Value &other) const
1213 return !(other > *this);
1217 Value::operator >= (const Value &other) const
1219 return !(*this < other);
1223 Value::operator > (const Value &other) const
1225 return other < *this;
1229 Value::operator == (const Value &other) const
1231 if (type_ != other.type_)
1239 return value_.int_ == other.value_.int_;
1241 return value_.uint_ == other.value_.uint_;
1243 return value_.real_ == other.value_.real_;
1245 return value_.bool_ == other.value_.bool_;
1247 return (value_.string_ == other.value_.string_)
1248 || (other.value_.string_
1250 && strcmp (value_.string_, other.value_.string_) == 0);
1253 return value_.map_->size () == other.value_.map_->size ()
1254 && (*value_.map_) == (*other.value_.map_);
1258 return 0; // unreachable
1262 Value::operator != (const Value &other) const
1264 return !(*this == other);
1267 Value::operator char const * () const
1269 throw_unless (type_ == stringValue);
1270 return value_.string_;
1274 Value::operator std::string () const
1281 return value_.string_ ? value_.string_ : "";
1283 return value_.bool_ ? "true" : "false";
1289 throw_msg_unless (false, "Type is not convertible to string");
1293 return ""; // unreachable
1296 Value::operator int () const
1305 throw_msg_unless (value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
1306 return value_.uint_;
1308 throw_msg_unless (value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
1309 return int (value_.real_);
1311 return value_.bool_ ? 1 : 0;
1315 throw_msg_unless (false, "Type is not convertible to int");
1319 return 0; // unreachable;
1322 Value::operator unsigned () const
1329 throw_msg_unless (value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
1332 return value_.uint_;
1334 throw_msg_unless (value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
1335 return unsigned (value_.real_);
1337 return value_.bool_ ? 1 : 0;
1341 throw_msg_unless (false, "Type is not convertible to uint");
1345 return 0; // unreachable;
1348 Value::operator double () const
1357 return value_.uint_;
1359 return value_.real_;
1361 return value_.bool_ ? 1.0 : 0.0;
1365 throw_msg_unless (false, "Type is not convertible to double");
1369 return 0; // unreachable;
1372 Value::operator bool () const
1380 return value_.int_ != 0;
1382 return value_.real_ != 0.0;
1384 return value_.bool_;
1386 return value_.string_ && value_.string_[0] != 0;
1389 return value_.map_->size () != 0;
1393 return false; // unreachable;
1398 Value::isConvertibleTo (ValueType other) const
1405 return (other == nullValue && value_.int_ == 0)
1406 || other == intValue
1407 || (other == uintValue && value_.int_ >= 0)
1408 || other == realValue
1409 || other == stringValue
1410 || other == booleanValue;
1412 return (other == nullValue && value_.uint_ == 0)
1413 || (other == intValue && value_.uint_ <= (unsigned)maxInt)
1414 || other == uintValue
1415 || other == realValue
1416 || other == stringValue
1417 || other == booleanValue;
1419 return (other == nullValue && value_.real_ == 0.0)
1420 || (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt)
1421 || (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt)
1422 || other == realValue
1423 || other == stringValue
1424 || other == booleanValue;
1426 return (other == nullValue && value_.bool_ == false)
1427 || other == intValue
1428 || other == uintValue
1429 || other == realValue
1430 || other == stringValue
1431 || other == booleanValue;
1433 return other == stringValue
1434 || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
1436 return other == arrayValue
1437 || (other == nullValue && value_.map_->size () == 0);
1439 return other == objectValue
1440 || (other == nullValue && value_.map_->size () == 0);
1444 return false; // unreachable;
1448 /// Number of values in array or object
1450 Value::size () const
1461 case arrayValue: // size of the array is highest index + 1
1462 if (!value_.map_->empty ())
1464 ObjectValues::const_iterator itLast = value_.map_->end ();
1466 return itLast->first.index ()+1;
1470 return int (value_.map_->size ());
1474 return 0; // unreachable;
1479 Value::empty () const
1481 if (isNull () || isArray () || isObject ())
1482 return size () == 0u;
1489 Value::operator ! () const
1498 throw_unless (type_ == nullValue || type_ == arrayValue || type_ == objectValue);
1504 value_.map_->clear ();
1512 Value::resize (unsigned newSize)
1514 throw_unless (type_ == nullValue || type_ == arrayValue);
1515 if (type_ == nullValue)
1516 *this = Value (arrayValue);
1517 unsigned oldSize = size ();
1520 else if (newSize > oldSize)
1521 (*this)[ newSize - 1 ];
1524 for (unsigned index = newSize; index < oldSize; ++index)
1525 value_.map_->erase (index);
1526 throw_unless (size () == newSize);
1532 Value::operator [] (int index)
1534 return operator [] (static_cast<unsigned> (index));
1539 Value::operator [] (unsigned index)
1541 throw_unless (type_ == nullValue || type_ == arrayValue);
1542 if (type_ == nullValue)
1543 *this = Value (arrayValue);
1544 CZString key (index);
1545 ObjectValues::iterator it = value_.map_->lower_bound (key);
1546 if (it != value_.map_->end () && it->first == key)
1549 ObjectValues::value_type defaultValue (key, null);
1550 it = value_.map_->insert (it, defaultValue);
1556 Value::operator [] (int index) const
1558 return operator [] (static_cast<unsigned> (index));
1563 Value::operator [] (unsigned index) const
1565 throw_unless (type_ == nullValue || type_ == arrayValue);
1566 if (type_ == nullValue)
1568 CZString key (index);
1569 ObjectValues::const_iterator it = value_.map_->find (key);
1570 if (it == value_.map_->end ())
1577 Value::operator [] (char const *key)
1579 return resolveReference (key, false);
1584 Value::resolveReference (char const *key, bool isStatic)
1586 throw_unless (type_ == nullValue || type_ == objectValue);
1587 if (type_ == nullValue)
1588 *this = Value (objectValue);
1589 CZString actualKey (key, isStatic ? CZString::noDuplication
1590 : CZString::duplicateOnCopy);
1591 ObjectValues::iterator it = value_.map_->lower_bound (actualKey);
1592 if (it != value_.map_->end () && it->first == actualKey)
1595 ObjectValues::value_type defaultValue (actualKey, null);
1596 it = value_.map_->insert (it, defaultValue);
1597 Value &value = it->second;
1603 Value::get (int index, const Value &defaultValue) const
1605 return get (static_cast<unsigned> (index), defaultValue);
1610 Value::get (unsigned index, const Value &defaultValue) const
1612 const Value *value = &((*this)[index]);
1613 return value == &null ? defaultValue : *value;
1618 Value::isValidIndex (int index) const
1620 return isValidIndex (static_cast<unsigned> (index));
1625 Value::isValidIndex (unsigned index) const
1627 return index < size ();
1633 Value::operator [] (char const *key) const
1635 throw_unless (type_ == nullValue || type_ == objectValue);
1636 if (type_ == nullValue)
1638 CZString actualKey (key, CZString::noDuplication);
1639 ObjectValues::const_iterator it = value_.map_->find (actualKey);
1640 if (it == value_.map_->end ())
1647 Value::operator [] (const std::string &key)
1649 return (*this)[ key.c_str () ];
1654 Value::operator [] (const std::string &key) const
1656 return (*this)[ key.c_str () ];
1660 Value::operator [] (const StaticString &key)
1662 return resolveReference (key, true);
1667 Value::append (const Value &value)
1669 return (*this)[size ()] = value;
1674 Value::get (char const *key, const Value &defaultValue) const
1676 const Value *value = &((*this)[key]);
1677 return value == &null ? defaultValue : *value;
1682 Value::get (const std::string &key, const Value &defaultValue) const
1684 return get (key.c_str (), defaultValue);
1688 Value::removeMember (char const *key)
1690 throw_unless (type_ == nullValue || type_ == objectValue);
1691 if (type_ == nullValue)
1693 CZString actualKey (key, CZString::noDuplication);
1694 ObjectValues::iterator it = value_.map_->find (actualKey);
1695 if (it == value_.map_->end ())
1697 Value old (it->second);
1698 value_.map_->erase (it);
1703 Value::removeMember (const std::string &key)
1705 return removeMember (key.c_str ());
1709 Value::isMember (char const *key) const
1711 const Value *value = &((*this)[key]);
1712 return value != &null;
1717 Value::isMember (const std::string &key) const
1719 return isMember (key.c_str ());
1724 Value::getMemberNames () const
1726 throw_unless (type_ == nullValue || type_ == objectValue);
1727 if (type_ == nullValue)
1728 return Value::Members ();
1730 members.reserve (value_.map_->size ());
1731 ObjectValues::const_iterator it;
1732 ObjectValues::const_iterator itEnd = value_.map_->end ();
1733 for (it = value_.map_->begin (); it != itEnd; ++it)
1734 members.push_back (std::string (it->first.c_str()));
1739 Value::isNull () const
1741 return type_ == nullValue;
1746 Value::isBool () const
1748 return type_ == booleanValue;
1753 Value::isInt () const
1755 return type_ == intValue;
1760 Value::isUInt () const
1762 return type_ == uintValue;
1767 Value::isIntegral () const
1769 return type_ == intValue
1770 || type_ == uintValue
1771 || type_ == booleanValue;
1776 Value::isDouble () const
1778 return type_ == realValue;
1783 Value::isNumeric () const
1785 return isIntegral () || isDouble ();
1790 Value::isString () const
1792 return type_ == stringValue;
1797 Value::isArray () const
1799 return type_ == nullValue || type_ == arrayValue;
1804 Value::isObject () const
1806 return type_ == nullValue || type_ == objectValue;
1810 Value::const_iterator
1811 Value::begin () const
1818 return const_iterator (value_.map_->begin ());
1823 return const_iterator ();
1826 Value::const_iterator
1834 return const_iterator (value_.map_->end ());
1839 return const_iterator ();
1851 return iterator (value_.map_->begin ());
1867 return iterator (value_.map_->end ());
1878 static void uintToString (unsigned value,
1884 *--current = (value % 10) + '0';
1890 std::string valueToString (int value)
1893 char *current = buffer + sizeof (buffer);
1894 bool isNegative = value < 0;
1897 uintToString (unsigned (value), current);
1900 throw_unless (current >= buffer);
1905 std::string valueToString (unsigned value)
1908 char *current = buffer + sizeof (buffer);
1909 uintToString (value, current);
1910 throw_unless (current >= buffer);
1914 std::string valueToString (double value)
1917 sprintf (buffer, "%.16g", value);
1922 std::string valueToString (bool value)
1924 return value ? "true" : "false";
1927 std::string valueToQuotedString (char const *value)
1929 // Not sure how to handle unicode...
1930 if (std::strpbrk (value, "\"\\\b\f\n\r\t") == NULL)
1931 return std::string ("\"") + value + "\"";
1932 // We have to walk value and escape any special characters.
1933 // Appending to std::string is not efficient, but this should be rare.
1934 // (Note: forward slashes are *not* rare, but I am not escaping them.)
1935 unsigned maxsize = strlen (value) * 2 + 3; // allescaped+quotes+NULL
1937 result.reserve (maxsize); // to avoid lots of mallocs
1939 for (char const* c=value; *c != 0; ++c){
1963 // Even though \/ is considered a legal escape in JSON, a bare
1964 // slash is also legal, so I see no reason to escape it.
1965 // (I hope I am not misunderstanding something.)
1976 Writer::write (const Value &root)
1986 Writer::writeValue (const Value &value)
1988 switch (value.type ())
1991 document_ += "null";
1994 document_ += valueToString (static_cast<int> (value));
1997 document_ += valueToString (static_cast<unsigned> (value));
2000 document_ += valueToString (static_cast<double> (value));
2003 document_ += valueToQuotedString (static_cast<char const *> (value));
2006 document_ += valueToString (static_cast<bool> (value));
2011 int size = value.size ();
2012 for (int index = 0; index < size; ++index)
2016 writeValue (value[index]);
2023 Value::Members members (value.getMemberNames ());
2025 for (Value::Members::iterator it = members.begin ();
2026 it != members.end ();
2029 const std::string &name = *it;
2030 if (it != members.begin ())
2032 document_ += valueToQuotedString (name.c_str ());
2034 writeValue (value[name]);
2051 typedef std::map<std::string, void (*) (HTTPRequest *, Value &, Value &)> method_map;
2056 add_method (char *name, method mth)
2058 methods[name] = mth;
2062 system_list_methods (HTTPRequest *http, Value &request, Value &response)
2065 Value method_list (arrayValue);
2067 method_map::iterator it;
2068 for (it = methods.begin(); it != methods.end(); ++it)
2070 method_list[i] = Value (it->first);
2074 response["result"] = method_list;
2080 add_method ("system.listMethods", &system_list_methods);
2084 service (HTTPRequest *http, Value &request, Value &response)
2086 char const *methodName = static_cast<char const *> (request["method"]);
2088 method_map::iterator mth = methods.find (methodName);
2089 if (mth != methods.end ())
2090 (*mth->second) (http, request, response);
2094 process (HTTPRequest *http, std::string &response_text, char const *request_text)
2098 Value request (objectValue);
2099 Value response (objectValue);
2103 parse_success = r.parse (request_text, request_text + strlen (request_text), request);
2105 service (http, request, response);
2107 text = w.write (response);
2109 response_text = text.c_str ();
2116 MODULE_INIT(ModuleRpcJson)