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
33 void MthModuleVersion (HTTPRequest *http, json::Value &request, json::Value &response)
35 std::string result = "GetVersion().ToString()";
36 response["result"] = result;
39 void system_list_methods (HTTPRequest *http, json::Value &request, json::Value &response)
42 json::Value method_list (json::arrayValue);
44 json::rpc::method_map::iterator it;
45 for (it = json::rpc::methods.begin(); it != json::rpc::methods.end(); ++it)
47 method_list[i] = json::Value (it->first);
51 response["result"] = method_list;
55 ModuleRpcJson(InspIRCd* Me) : Module(Me)
57 json::rpc::add_method ("system.listMethods", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::system_list_methods);
58 json::rpc::add_method ("ircd.moduleVersion", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::MthModuleVersion);
61 void OnEvent(Event* event)
63 std::stringstream data("");
65 if (event->GetEventID() == "httpd_url")
67 HTTPRequest* http = (HTTPRequest*)event->GetData();
69 if (http->GetURI() == "/jsonrpc" && http->GetType() == "POST")
73 std::string response_text;
74 json::rpc::process (http, response_text, http->GetPostData().c_str());
75 data << response_text;
77 catch (std::runtime_error &)
79 data << "{ \"result\": \"JSON Fault\", \"error\": \"Invalid RPC call\", \"id\": 1}";
82 /* Send the document back to m_httpd */
83 HTTPDocument response(http->sock, &data, 200, "X-Powered-By: m_rpc_json.so\r\n"
84 "Content-Type: application/json; charset=iso-8859-1\r\n");
85 Request req((char*)&response, (Module*)this, event->GetSource());
91 void Implements(char* List)
96 virtual ~ModuleRpcJson()
100 virtual Version GetVersion()
102 return Version(0, 1, 0, 0, VF_VENDOR, API_VERSION);
107 unreachable_internal (char const *file, int line, char const *function)
110 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
111 file, line, function);
113 throw std::runtime_error (buf);
117 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
120 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
121 file, line, function, condition);
123 throw std::runtime_error (buf);
127 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
130 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
131 file, line, function, message);
133 throw std::runtime_error (buf);
139 ValueIteratorBase::ValueIteratorBase ()
144 ValueIteratorBase::ValueIteratorBase (const Value::ObjectValues::iterator ¤t)
150 ValueIteratorBase::deref () const
152 return current_->second;
157 ValueIteratorBase::increment ()
164 ValueIteratorBase::decrement ()
170 ValueIteratorBase::difference_type
171 ValueIteratorBase::computeDistance (const SelfType &other) const
173 return difference_type (std::distance (current_, other.current_));
178 ValueIteratorBase::isEqual (const SelfType &other) const
180 return current_ == other.current_;
185 ValueIteratorBase::copy (const SelfType &other)
187 current_ = other.current_;
192 ValueIteratorBase::key () const
194 const Value::CZString czstring = (*current_).first;
195 if (czstring.c_str ())
197 if (czstring.isStaticString ())
198 return Value (StaticString (czstring.c_str ()));
199 return Value (czstring.c_str ());
201 return Value (czstring.index ());
206 ValueIteratorBase::index () const
208 const Value::CZString czstring = (*current_).first;
209 if (!czstring.c_str ())
210 return czstring.index ();
211 return unsigned (-1);
216 ValueIteratorBase::memberName () const
218 char const *name = (*current_).first.c_str ();
219 return name ? name : "";
223 ValueConstIterator::ValueConstIterator ()
228 ValueConstIterator::ValueConstIterator (const Value::ObjectValues::iterator ¤t)
229 : ValueIteratorBase (current)
234 ValueConstIterator::operator = (const ValueIteratorBase &other)
241 ValueIterator::ValueIterator ()
246 ValueIterator::ValueIterator (const Value::ObjectValues::iterator ¤t)
247 : ValueIteratorBase (current)
251 ValueIterator::ValueIterator (const ValueConstIterator &other)
252 : ValueIteratorBase (other)
256 ValueIterator::ValueIterator (const ValueIterator &other)
257 : ValueIteratorBase (other)
262 ValueIterator::operator = (const SelfType &other)
272 in (char c, char c1, char c2, char c3, char c4)
274 return c == c1 || c == c2 || c == c3 || c == c4;
278 in (char c, char c1, char c2, char c3, char c4, char c5)
280 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
289 Reader::parse (const std::string &document,
292 document_ = document;
293 char const *begin = document_.c_str ();
294 char const *end = begin + document_.length ();
295 return parse (begin, end, root);
299 Reader::parse (std::istream& sin,
303 std::getline (sin, doc, (char)EOF);
304 return parse (doc, root);
308 Reader::parse (char const *beginDoc, char const *endDOc,
317 while (!nodes_.empty ())
321 bool successful = readValue ();
332 while (token.type_ == tokenComment);
333 bool successful = true;
337 case tokenObjectBegin:
338 successful = readObject ();
340 case tokenArrayBegin:
341 successful = readArray ();
344 successful = decodeNumber (token);
347 successful = decodeString (token);
350 currentValue () = true;
353 currentValue () = false;
356 currentValue () = Value ();
359 return addError ("Syntax error: value, object or array expected.", token);
367 Reader::expectToken (TokenType type, Token &token, char const *message)
370 if (token.type_ != type)
371 return addError (message, token);
377 Reader::readToken (Token &token)
380 token.start_ = current_;
381 char c = getNextChar ();
386 token.type_ = tokenObjectBegin;
389 token.type_ = tokenObjectEnd;
392 token.type_ = tokenArrayBegin;
395 token.type_ = tokenArrayEnd;
398 token.type_ = tokenString;
406 case '0': case '1': case '2': case '3':
407 case '4': case '5': case '6': case '7':
411 token.type_ = tokenNumber;
415 token.type_ = tokenTrue;
416 ok = match ("rue", 3);
419 token.type_ = tokenFalse;
420 ok = match ("alse", 4);
423 token.type_ = tokenNull;
424 ok = match ("ull", 3);
427 token.type_ = tokenArraySeparator;
430 token.type_ = tokenMemberSeparator;
433 token.type_ = tokenEndOfStream;
440 token.type_ = tokenError;
441 token.end_ = current_;
447 Reader::skipSpaces ()
449 while (current_ != end_)
452 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
461 Reader::match (Location pattern, int patternLength)
463 if (end_ - current_ < patternLength)
465 int index = patternLength;
467 if (current_[index] != pattern[index])
469 current_ += patternLength;
475 Reader::readNumber ()
477 while (current_ != end_)
479 if (!(*current_ >= '0' && *current_ <= '9') &&
480 !in (*current_, '.', 'e', 'E', '+', '-'))
487 Reader::readString ()
490 while (current_ != end_)
503 Reader::readObject ()
507 currentValue () = Value (objectValue);
508 while (readToken (tokenName))
510 if (tokenName.type_ == tokenObjectEnd && name.empty ()) // empty object
512 if (tokenName.type_ != tokenString)
516 if (!decodeString (tokenName, name))
517 return recoverFromError (tokenObjectEnd);
520 if (!readToken (colon) || colon.type_ != tokenMemberSeparator)
522 return addErrorAndRecover ("Missing ':' after object member name",
526 Value &value = currentValue ()[ name ];
527 nodes_.push (&value);
528 bool ok = readValue ();
530 if (!ok) // error already set
531 return recoverFromError (tokenObjectEnd);
534 if (!readToken (comma)
535 || (comma.type_ != tokenObjectEnd &&
536 comma.type_ != tokenArraySeparator))
538 return addErrorAndRecover ("Missing ',' or '}' in object declaration",
542 if (comma.type_ == tokenObjectEnd)
545 return addErrorAndRecover ("Missing '}' or object member name",
554 currentValue () = Value (arrayValue);
556 if (*current_ == ']') // empty array
559 readToken (endArray);
565 Value &value = currentValue ()[ index++ ];
566 nodes_.push (&value);
567 bool ok = readValue ();
569 if (!ok) // error already set
570 return recoverFromError (tokenArrayEnd);
573 if (!readToken (token)
574 || (token.type_ != tokenArraySeparator &&
575 token.type_ != tokenArrayEnd))
577 return addErrorAndRecover ("Missing ',' or ']' in array declaration",
581 if (token.type_ == tokenArrayEnd)
589 Reader::decodeNumber (Token &token)
591 bool isDouble = false;
592 for (Location inspect = token.start_; inspect != token.end_; ++inspect)
595 || in (*inspect, '.', 'e', 'E', '+')
596 || (*inspect == '-' && inspect != token.start_);
599 return decodeDouble (token);
600 Location current = token.start_;
601 bool isNegative = *current == '-';
604 unsigned threshold = (isNegative ? unsigned (-Value::minInt)
605 : Value::maxUInt) / 10;
607 while (current < token.end_)
610 if (c < '0' || c > '9')
611 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
612 if (value >= threshold)
613 return decodeDouble (token);
614 value = value * 10 + unsigned (c - '0');
617 currentValue () = -int (value);
618 else if (value <= unsigned (Value::maxInt))
619 currentValue () = int (value);
621 currentValue () = value;
627 Reader::decodeDouble (Token &token)
630 const int bufferSize = 32;
632 int length = int (token.end_ - token.start_);
633 if (length <= bufferSize)
635 char buffer[bufferSize];
636 memcpy (buffer, token.start_, length);
638 count = sscanf (buffer, "%lf", &value);
642 std::string buffer (token.start_, token.end_);
643 count = sscanf (buffer.c_str (), "%lf", &value);
647 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
648 currentValue () = value;
654 Reader::decodeString (Token &token)
657 if (!decodeString (token, decoded))
659 currentValue () = decoded;
665 Reader::decodeString (Token &token, std::string &decoded)
667 Location current = token.start_ + 1; // skip '"'
668 Location end = token.end_ - 1; // do not include '"'
669 decoded.reserve (long (end - current));
671 while (current != end)
674 if (expect_false (c == '"'))
676 else if (expect_false (c == '\\'))
678 if (expect_false (current == end))
679 return addError ("Empty escape sequence in string", token, current);
680 char escape = *current++;
685 case '\\': decoded += escape; break;
687 case 'b': decoded += '\010'; break;
688 case 't': decoded += '\011'; break;
689 case 'n': decoded += '\012'; break;
690 case 'f': decoded += '\014'; break;
691 case 'r': decoded += '\015'; break;
695 if (!decodeUnicodeEscapeSequence (token, current, end, unicode))
697 // @todo encode unicode as utf8.
698 // @todo remember to alter the writer too.
702 return addError ("Bad escape sequence in string", token, current);
716 Reader::decodeUnicodeEscapeSequence (Token &token,
721 if (end - current < 4)
722 return addError ("Bad unicode escape sequence in string: four digits expected.", token, current);
724 for (int index = 0; index < 4; ++index)
728 if (c >= '0' && c <= '9')
730 else if (c >= 'a' && c <= 'f')
731 unicode += c - 'a' + 10;
732 else if (c >= 'A' && c <= 'F')
733 unicode += c - 'A' + 10;
735 return addError ("Bad unicode escape sequence in string: hexadecimal digit expected.", token, current);
742 Reader::addError (const std::string &message,
748 info.message_ = message;
750 errors_.push_back (info);
756 Reader::recoverFromError (TokenType skipUntilToken)
758 int errorCount = int (errors_.size ());
762 if (!readToken (skip))
763 errors_.resize (errorCount); // discard errors caused by recovery
764 if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
767 errors_.resize (errorCount);
773 Reader::addErrorAndRecover (const std::string &message,
775 TokenType skipUntilToken)
777 addError (message, token);
778 return recoverFromError (skipUntilToken);
783 Reader::currentValue ()
785 return *(nodes_.top ());
790 Reader::getNextChar ()
792 if (current_ == end_)
799 Reader::getLocationLineAndColumn (Location location,
803 Location current = begin_;
804 Location lastLineStart = current;
806 while (current < location && current != end_)
811 if (*current == '\n')
813 lastLineStart = current;
818 lastLineStart = current;
822 // column & line start at 1
823 column = int (location - lastLineStart) + 1;
829 Reader::getLocationLineAndColumn (Location location) const
832 getLocationLineAndColumn (location, line, column);
833 char buffer[18+16+16+1];
834 sprintf (buffer, "Line %d, Column %d", line, column);
840 Reader::error_msgs () const
842 std::string formattedMessage;
843 for (Errors::const_iterator itError = errors_.begin ();
844 itError != errors_.end ();
847 const ErrorInfo &error = *itError;
848 formattedMessage += "* " + getLocationLineAndColumn (error.token_.start_) + "\n";
849 formattedMessage += " " + error.message_ + "\n";
851 formattedMessage += "See " + getLocationLineAndColumn (error.extra_) + " for detail.\n";
853 return formattedMessage;
860 unreachable_internal (char const *file, int line, char const *function)
863 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
864 file, line, function);
866 throw std::runtime_error (buf);
870 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
873 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
874 file, line, function, condition);
876 throw std::runtime_error (buf);
880 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
883 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
884 file, line, function, message);
886 throw std::runtime_error (buf);
889 const Value Value::null;
890 const int Value::minInt = int (~ (unsigned (-1)/2));
891 const int Value::maxInt = int (unsigned (-1)/2);
892 const unsigned Value::maxUInt = unsigned (-1);
894 ValueAllocator::~ValueAllocator ()
898 class DefaultValueAllocator : public ValueAllocator
901 virtual ~DefaultValueAllocator ()
905 virtual char *makeMemberName (char const *memberName)
907 return duplicateStringValue (memberName);
910 virtual void releaseMemberName (char *memberName)
912 releaseStringValue (memberName);
915 virtual char *duplicateStringValue (char const *value, unsigned length = unknown)
917 //@todo invesgate this old optimization
919 if (!value || value[0] == 0)
923 if (length == unknown)
924 length = (unsigned)strlen (value);
925 char *newString = static_cast<char *> (malloc (length + 1));
926 memcpy (newString, value, length);
927 newString[length] = 0;
931 virtual void releaseStringValue (char *value)
938 static ValueAllocator *&valueAllocator ()
940 static DefaultValueAllocator defaultAllocator;
941 static ValueAllocator *valueAllocator = &defaultAllocator;
942 return valueAllocator;
945 static struct DummyValueAllocatorInitializer {
946 DummyValueAllocatorInitializer ()
948 valueAllocator (); // ensure valueAllocator () statics are initialized before main ().
950 } dummyValueAllocatorInitializer;
954 Value::CZString::CZString (int index)
960 Value::CZString::CZString (char const *cstr, DuplicationPolicy allocate)
961 : cstr_ (allocate == duplicate ? valueAllocator()->makeMemberName (cstr)
967 Value::CZString::CZString (const CZString &other)
968 : cstr_ (other.index_ != noDuplication && other.cstr_ != 0
969 ? valueAllocator()->makeMemberName (other.cstr_)
971 , index_ (other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
976 Value::CZString::~CZString ()
978 if (cstr_ && index_ == duplicate)
979 valueAllocator()->releaseMemberName (const_cast<char *> (cstr_));
983 Value::CZString::swap (CZString &other)
985 std::swap (cstr_, other.cstr_);
986 std::swap (index_, other.index_);
990 Value::CZString::operator = (const CZString &other)
992 CZString temp (other);
998 Value::CZString::operator < (const CZString &other) const
1001 return strcmp (cstr_, other.cstr_) < 0;
1002 return index_ < other.index_;
1006 Value::CZString::operator == (const CZString &other) const
1009 return strcmp (cstr_, other.cstr_) == 0;
1010 return index_ == other.index_;
1015 Value::CZString::index () const
1022 Value::CZString::c_str () const
1028 Value::CZString::isStaticString () const
1030 return index_ == noDuplication;
1034 // class Value::Value
1036 Value::Value (ValueType type)
1056 value_.map_ = new ObjectValues ();
1059 value_.bool_ = false;
1067 Value::Value (int value)
1070 value_.int_ = value;
1074 Value::Value (unsigned value)
1077 value_.uint_ = value;
1080 Value::Value (double value)
1083 value_.real_ = value;
1086 Value::Value (char const *value)
1087 : type_ (stringValue)
1090 value_.string_ = valueAllocator()->duplicateStringValue (value);
1093 Value::Value (const std::string &value)
1094 : type_ (stringValue)
1097 value_.string_ = valueAllocator()->duplicateStringValue (value.c_str (), (unsigned)value.length ());
1100 Value::Value (const StaticString &value)
1101 : type_ (stringValue)
1102 , allocated_ (false)
1104 value_.string_ = const_cast<char *> (value.c_str ());
1108 Value::Value (bool value)
1109 : type_ (booleanValue)
1111 value_.bool_ = value;
1115 Value::Value (const Value &other)
1116 : type_ (other.type_)
1125 value_ = other.value_;
1128 if (other.value_.string_)
1130 value_.string_ = valueAllocator()->duplicateStringValue (other.value_.string_);
1138 value_.map_ = new ObjectValues (*other.value_.map_);
1158 valueAllocator()->releaseStringValue (value_.string_);
1170 Value::operator = (const Value &other)
1178 Value::swap (Value &other)
1180 ValueType temp = type_;
1181 type_ = other.type_;
1183 std::swap (value_, other.value_);
1184 int temp2 = allocated_;
1185 allocated_ = other.allocated_;
1186 other.allocated_ = temp2;
1190 Value::type () const
1196 Value::operator < (const Value &other) const
1198 int typeDelta = type_ - other.type_;
1200 return typeDelta < 0 ? true : false;
1206 return value_.int_ < other.value_.int_;
1208 return value_.uint_ < other.value_.uint_;
1210 return value_.real_ < other.value_.real_;
1212 return value_.bool_ < other.value_.bool_;
1214 return (value_.string_ == 0 && other.value_.string_)
1215 || (other.value_.string_
1217 && strcmp (value_.string_, other.value_.string_) < 0);
1221 int delta = int (value_.map_->size () - other.value_.map_->size ());
1224 return (*value_.map_) < (*other.value_.map_);
1229 return 0; // unreachable
1233 Value::operator <= (const Value &other) const
1235 return !(other > *this);
1239 Value::operator >= (const Value &other) const
1241 return !(*this < other);
1245 Value::operator > (const Value &other) const
1247 return other < *this;
1251 Value::operator == (const Value &other) const
1253 if (type_ != other.type_)
1261 return value_.int_ == other.value_.int_;
1263 return value_.uint_ == other.value_.uint_;
1265 return value_.real_ == other.value_.real_;
1267 return value_.bool_ == other.value_.bool_;
1269 return (value_.string_ == other.value_.string_)
1270 || (other.value_.string_
1272 && strcmp (value_.string_, other.value_.string_) == 0);
1275 return value_.map_->size () == other.value_.map_->size ()
1276 && (*value_.map_) == (*other.value_.map_);
1280 return 0; // unreachable
1284 Value::operator != (const Value &other) const
1286 return !(*this == other);
1289 Value::operator char const * () const
1291 throw_unless (type_ == stringValue);
1292 return value_.string_;
1296 Value::operator std::string () const
1303 return value_.string_ ? value_.string_ : "";
1305 return value_.bool_ ? "true" : "false";
1311 throw_msg_unless (false, "Type is not convertible to string");
1315 return ""; // unreachable
1318 Value::operator int () const
1327 throw_msg_unless (value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
1328 return value_.uint_;
1330 throw_msg_unless (value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
1331 return int (value_.real_);
1333 return value_.bool_ ? 1 : 0;
1337 throw_msg_unless (false, "Type is not convertible to int");
1341 return 0; // unreachable;
1344 Value::operator unsigned () const
1351 throw_msg_unless (value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
1354 return value_.uint_;
1356 throw_msg_unless (value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
1357 return unsigned (value_.real_);
1359 return value_.bool_ ? 1 : 0;
1363 throw_msg_unless (false, "Type is not convertible to uint");
1367 return 0; // unreachable;
1370 Value::operator double () const
1379 return value_.uint_;
1381 return value_.real_;
1383 return value_.bool_ ? 1.0 : 0.0;
1387 throw_msg_unless (false, "Type is not convertible to double");
1391 return 0; // unreachable;
1394 Value::operator bool () const
1402 return value_.int_ != 0;
1404 return value_.real_ != 0.0;
1406 return value_.bool_;
1408 return value_.string_ && value_.string_[0] != 0;
1411 return value_.map_->size () != 0;
1415 return false; // unreachable;
1420 Value::isConvertibleTo (ValueType other) const
1427 return (other == nullValue && value_.int_ == 0)
1428 || other == intValue
1429 || (other == uintValue && value_.int_ >= 0)
1430 || other == realValue
1431 || other == stringValue
1432 || other == booleanValue;
1434 return (other == nullValue && value_.uint_ == 0)
1435 || (other == intValue && value_.uint_ <= (unsigned)maxInt)
1436 || other == uintValue
1437 || other == realValue
1438 || other == stringValue
1439 || other == booleanValue;
1441 return (other == nullValue && value_.real_ == 0.0)
1442 || (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt)
1443 || (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt)
1444 || other == realValue
1445 || other == stringValue
1446 || other == booleanValue;
1448 return (other == nullValue && value_.bool_ == false)
1449 || other == intValue
1450 || other == uintValue
1451 || other == realValue
1452 || other == stringValue
1453 || other == booleanValue;
1455 return other == stringValue
1456 || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
1458 return other == arrayValue
1459 || (other == nullValue && value_.map_->size () == 0);
1461 return other == objectValue
1462 || (other == nullValue && value_.map_->size () == 0);
1466 return false; // unreachable;
1470 /// Number of values in array or object
1472 Value::size () const
1483 case arrayValue: // size of the array is highest index + 1
1484 if (!value_.map_->empty ())
1486 ObjectValues::const_iterator itLast = value_.map_->end ();
1488 return itLast->first.index ()+1;
1492 return int (value_.map_->size ());
1496 return 0; // unreachable;
1501 Value::empty () const
1503 if (isNull () || isArray () || isObject ())
1504 return size () == 0u;
1511 Value::operator ! () const
1520 throw_unless (type_ == nullValue || type_ == arrayValue || type_ == objectValue);
1526 value_.map_->clear ();
1534 Value::resize (unsigned newSize)
1536 throw_unless (type_ == nullValue || type_ == arrayValue);
1537 if (type_ == nullValue)
1538 *this = Value (arrayValue);
1539 unsigned oldSize = size ();
1542 else if (newSize > oldSize)
1543 (*this)[ newSize - 1 ];
1546 for (unsigned index = newSize; index < oldSize; ++index)
1547 value_.map_->erase (index);
1548 throw_unless (size () == newSize);
1554 Value::operator [] (int index)
1556 return operator [] (static_cast<unsigned> (index));
1561 Value::operator [] (unsigned index)
1563 throw_unless (type_ == nullValue || type_ == arrayValue);
1564 if (type_ == nullValue)
1565 *this = Value (arrayValue);
1566 CZString key (index);
1567 ObjectValues::iterator it = value_.map_->lower_bound (key);
1568 if (it != value_.map_->end () && it->first == key)
1571 ObjectValues::value_type defaultValue (key, null);
1572 it = value_.map_->insert (it, defaultValue);
1578 Value::operator [] (int index) const
1580 return operator [] (static_cast<unsigned> (index));
1585 Value::operator [] (unsigned index) const
1587 throw_unless (type_ == nullValue || type_ == arrayValue);
1588 if (type_ == nullValue)
1590 CZString key (index);
1591 ObjectValues::const_iterator it = value_.map_->find (key);
1592 if (it == value_.map_->end ())
1599 Value::operator [] (char const *key)
1601 return resolveReference (key, false);
1606 Value::resolveReference (char const *key, bool isStatic)
1608 throw_unless (type_ == nullValue || type_ == objectValue);
1609 if (type_ == nullValue)
1610 *this = Value (objectValue);
1611 CZString actualKey (key, isStatic ? CZString::noDuplication
1612 : CZString::duplicateOnCopy);
1613 ObjectValues::iterator it = value_.map_->lower_bound (actualKey);
1614 if (it != value_.map_->end () && it->first == actualKey)
1617 ObjectValues::value_type defaultValue (actualKey, null);
1618 it = value_.map_->insert (it, defaultValue);
1619 Value &value = it->second;
1625 Value::get (int index, const Value &defaultValue) const
1627 return get (static_cast<unsigned> (index), defaultValue);
1632 Value::get (unsigned index, const Value &defaultValue) const
1634 const Value *value = &((*this)[index]);
1635 return value == &null ? defaultValue : *value;
1640 Value::isValidIndex (int index) const
1642 return isValidIndex (static_cast<unsigned> (index));
1647 Value::isValidIndex (unsigned index) const
1649 return index < size ();
1655 Value::operator [] (char const *key) const
1657 throw_unless (type_ == nullValue || type_ == objectValue);
1658 if (type_ == nullValue)
1660 CZString actualKey (key, CZString::noDuplication);
1661 ObjectValues::const_iterator it = value_.map_->find (actualKey);
1662 if (it == value_.map_->end ())
1669 Value::operator [] (const std::string &key)
1671 return (*this)[ key.c_str () ];
1676 Value::operator [] (const std::string &key) const
1678 return (*this)[ key.c_str () ];
1682 Value::operator [] (const StaticString &key)
1684 return resolveReference (key, true);
1689 Value::append (const Value &value)
1691 return (*this)[size ()] = value;
1696 Value::get (char const *key, const Value &defaultValue) const
1698 const Value *value = &((*this)[key]);
1699 return value == &null ? defaultValue : *value;
1704 Value::get (const std::string &key, const Value &defaultValue) const
1706 return get (key.c_str (), defaultValue);
1710 Value::removeMember (char const *key)
1712 throw_unless (type_ == nullValue || type_ == objectValue);
1713 if (type_ == nullValue)
1715 CZString actualKey (key, CZString::noDuplication);
1716 ObjectValues::iterator it = value_.map_->find (actualKey);
1717 if (it == value_.map_->end ())
1719 Value old (it->second);
1720 value_.map_->erase (it);
1725 Value::removeMember (const std::string &key)
1727 return removeMember (key.c_str ());
1731 Value::isMember (char const *key) const
1733 const Value *value = &((*this)[key]);
1734 return value != &null;
1739 Value::isMember (const std::string &key) const
1741 return isMember (key.c_str ());
1746 Value::getMemberNames () const
1748 throw_unless (type_ == nullValue || type_ == objectValue);
1749 if (type_ == nullValue)
1750 return Value::Members ();
1752 members.reserve (value_.map_->size ());
1753 ObjectValues::const_iterator it;
1754 ObjectValues::const_iterator itEnd = value_.map_->end ();
1755 for (it = value_.map_->begin (); it != itEnd; ++it)
1756 members.push_back (std::string (it->first.c_str()));
1761 Value::isNull () const
1763 return type_ == nullValue;
1768 Value::isBool () const
1770 return type_ == booleanValue;
1775 Value::isInt () const
1777 return type_ == intValue;
1782 Value::isUInt () const
1784 return type_ == uintValue;
1789 Value::isIntegral () const
1791 return type_ == intValue
1792 || type_ == uintValue
1793 || type_ == booleanValue;
1798 Value::isDouble () const
1800 return type_ == realValue;
1805 Value::isNumeric () const
1807 return isIntegral () || isDouble ();
1812 Value::isString () const
1814 return type_ == stringValue;
1819 Value::isArray () const
1821 return type_ == nullValue || type_ == arrayValue;
1826 Value::isObject () const
1828 return type_ == nullValue || type_ == objectValue;
1832 Value::const_iterator
1833 Value::begin () const
1840 return const_iterator (value_.map_->begin ());
1845 return const_iterator ();
1848 Value::const_iterator
1856 return const_iterator (value_.map_->end ());
1861 return const_iterator ();
1873 return iterator (value_.map_->begin ());
1889 return iterator (value_.map_->end ());
1900 static void uintToString (unsigned value,
1906 *--current = (value % 10) + '0';
1912 std::string valueToString (int value)
1915 char *current = buffer + sizeof (buffer);
1916 bool isNegative = value < 0;
1919 uintToString (unsigned (value), current);
1922 throw_unless (current >= buffer);
1927 std::string valueToString (unsigned value)
1930 char *current = buffer + sizeof (buffer);
1931 uintToString (value, current);
1932 throw_unless (current >= buffer);
1936 std::string valueToString (double value)
1939 sprintf (buffer, "%.16g", value);
1944 std::string valueToString (bool value)
1946 return value ? "true" : "false";
1949 std::string valueToQuotedString (char const *value)
1951 // Not sure how to handle unicode...
1952 if (std::strpbrk (value, "\"\\\b\f\n\r\t") == NULL)
1953 return std::string ("\"") + value + "\"";
1954 // We have to walk value and escape any special characters.
1955 // Appending to std::string is not efficient, but this should be rare.
1956 // (Note: forward slashes are *not* rare, but I am not escaping them.)
1957 unsigned maxsize = strlen (value) * 2 + 3; // allescaped+quotes+NULL
1959 result.reserve (maxsize); // to avoid lots of mallocs
1961 for (char const* c=value; *c != 0; ++c){
1985 // Even though \/ is considered a legal escape in JSON, a bare
1986 // slash is also legal, so I see no reason to escape it.
1987 // (I hope I am not misunderstanding something.)
1998 Writer::write (const Value &root)
2008 Writer::writeValue (const Value &value)
2010 switch (value.type ())
2013 document_ += "null";
2016 document_ += valueToString (static_cast<int> (value));
2019 document_ += valueToString (static_cast<unsigned> (value));
2022 document_ += valueToString (static_cast<double> (value));
2025 document_ += valueToQuotedString (static_cast<char const *> (value));
2028 document_ += valueToString (static_cast<bool> (value));
2033 int size = value.size ();
2034 for (int index = 0; index < size; ++index)
2038 writeValue (value[index]);
2045 Value::Members members (value.getMemberNames ());
2047 for (Value::Members::iterator it = members.begin ();
2048 it != members.end ();
2051 const std::string &name = *it;
2052 if (it != members.begin ())
2054 document_ += valueToQuotedString (name.c_str ());
2056 writeValue (value[name]);
2076 add_method (char *name, Module const *mod, method mth)
2078 mfp m = { mod, mth };
2083 service (HTTPRequest *http, Value &request, Value &response)
2085 char const *methodName = static_cast<char const *> (request["method"]);
2087 method_map::iterator mthit = methods.find (methodName);
2088 if (mthit != methods.end ())
2090 mfp m = mthit->second;
2091 Module *mod = new Module (*m.mod);
2093 (mod->*mth) (http, request, response);
2099 process (HTTPRequest *http, std::string &response_text, char const *request_text)
2103 Value request (objectValue);
2104 Value response (objectValue);
2108 parse_success = r.parse (request_text, request_text + strlen (request_text), request);
2110 service (http, request, response);
2112 text = w.write (response);
2114 response_text = text.c_str ();
2121 MODULE_INIT(ModuleRpcJson)