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 Version v = this->GetVersion();
36 std::string result = ConvToStr(v.Major) + "." + ConvToStr(v.Minor) + "." + ConvToStr(v.Revision) + "." + ConvToStr(v.Build);
37 response["result"] = result;
40 void system_list_methods (HTTPRequest *http, json::Value &request, json::Value &response)
43 json::Value method_list (json::arrayValue);
45 json::rpc::method_map::iterator it;
46 for (it = json::rpc::methods.begin(); it != json::rpc::methods.end(); ++it)
48 method_list[i] = json::Value (it->first);
52 response["result"] = method_list;
56 ModuleRpcJson(InspIRCd* Me) : Module(Me)
58 ServerInstance->PublishInterface("JSON-RPC", this);
59 json::rpc::add_method ("system.listMethods", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::system_list_methods);
60 json::rpc::add_method ("ircd.moduleVersion", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::MthModuleVersion);
63 void OnEvent(Event* event)
65 std::stringstream data("");
67 if (event->GetEventID() == "httpd_url")
69 HTTPRequest* http = (HTTPRequest*)event->GetData();
71 if (http->GetURI() == "/jsonrpc" && http->GetType() == "POST")
75 std::string response_text;
76 json::rpc::process (http, response_text, http->GetPostData().c_str());
77 data << response_text;
79 catch (std::runtime_error &)
81 data << "{ \"result\": \"JSON Fault\", \"error\": \"Invalid RPC call\", \"id\": 1}";
84 /* Send the document back to m_httpd */
85 HTTPDocument response(http->sock, &data, 200, "X-Powered-By: m_rpc_json.so\r\n"
86 "Content-Type: application/json; charset=iso-8859-1\r\n");
87 Request req((char*)&response, (Module*)this, event->GetSource());
93 void Implements(char* List)
98 virtual ~ModuleRpcJson()
100 ServerInstance->UnpublishInterface("JSON-RPC", this);
103 virtual Version GetVersion()
105 return Version(0, 1, 0, 0, VF_VENDOR, API_VERSION);
111 ValueIteratorBase::ValueIteratorBase ()
116 ValueIteratorBase::ValueIteratorBase (const Value::ObjectValues::iterator ¤t)
122 ValueIteratorBase::deref () const
124 return current_->second;
129 ValueIteratorBase::increment ()
136 ValueIteratorBase::decrement ()
142 ValueIteratorBase::difference_type
143 ValueIteratorBase::computeDistance (const SelfType &other) const
145 return difference_type (std::distance (current_, other.current_));
150 ValueIteratorBase::isEqual (const SelfType &other) const
152 return current_ == other.current_;
157 ValueIteratorBase::copy (const SelfType &other)
159 current_ = other.current_;
164 ValueIteratorBase::key () const
166 const Value::CZString czstring = (*current_).first;
167 if (czstring.c_str ())
169 if (czstring.isStaticString ())
170 return Value (StaticString (czstring.c_str ()));
171 return Value (czstring.c_str ());
173 return Value (czstring.index ());
178 ValueIteratorBase::index () const
180 const Value::CZString czstring = (*current_).first;
181 if (!czstring.c_str ())
182 return czstring.index ();
183 return unsigned (-1);
188 ValueIteratorBase::memberName () const
190 char const *name = (*current_).first.c_str ();
191 return name ? name : "";
195 ValueConstIterator::ValueConstIterator ()
200 ValueConstIterator::ValueConstIterator (const Value::ObjectValues::iterator ¤t)
201 : ValueIteratorBase (current)
206 ValueConstIterator::operator = (const ValueIteratorBase &other)
213 ValueIterator::ValueIterator ()
218 ValueIterator::ValueIterator (const Value::ObjectValues::iterator ¤t)
219 : ValueIteratorBase (current)
223 ValueIterator::ValueIterator (const ValueConstIterator &other)
224 : ValueIteratorBase (other)
228 ValueIterator::ValueIterator (const ValueIterator &other)
229 : ValueIteratorBase (other)
234 ValueIterator::operator = (const SelfType &other)
244 in (char c, char c1, char c2, char c3, char c4)
246 return c == c1 || c == c2 || c == c3 || c == c4;
250 in (char c, char c1, char c2, char c3, char c4, char c5)
252 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
261 Reader::parse (const std::string &document,
264 document_ = document;
265 char const *begin = document_.c_str ();
266 char const *end = begin + document_.length ();
267 return parse (begin, end, root);
271 Reader::parse (std::istream& sin,
275 std::getline (sin, doc, (char)EOF);
276 return parse (doc, root);
280 Reader::parse (char const *beginDoc, char const *endDOc,
289 while (!nodes_.empty ())
293 bool successful = readValue ();
304 while (token.type_ == tokenComment);
305 bool successful = true;
309 case tokenObjectBegin:
310 successful = readObject ();
312 case tokenArrayBegin:
313 successful = readArray ();
316 successful = decodeNumber (token);
319 successful = decodeString (token);
322 currentValue () = true;
325 currentValue () = false;
328 currentValue () = Value ();
331 return addError ("Syntax error: value, object or array expected.", token);
339 Reader::expectToken (TokenType type, Token &token, char const *message)
342 if (token.type_ != type)
343 return addError (message, token);
349 Reader::readToken (Token &token)
352 token.start_ = current_;
353 char c = getNextChar ();
358 token.type_ = tokenObjectBegin;
361 token.type_ = tokenObjectEnd;
364 token.type_ = tokenArrayBegin;
367 token.type_ = tokenArrayEnd;
370 token.type_ = tokenString;
378 case '0': case '1': case '2': case '3':
379 case '4': case '5': case '6': case '7':
383 token.type_ = tokenNumber;
387 token.type_ = tokenTrue;
388 ok = match ("rue", 3);
391 token.type_ = tokenFalse;
392 ok = match ("alse", 4);
395 token.type_ = tokenNull;
396 ok = match ("ull", 3);
399 token.type_ = tokenArraySeparator;
402 token.type_ = tokenMemberSeparator;
405 token.type_ = tokenEndOfStream;
412 token.type_ = tokenError;
413 token.end_ = current_;
419 Reader::skipSpaces ()
421 while (current_ != end_)
424 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
433 Reader::match (Location pattern, int patternLength)
435 if (end_ - current_ < patternLength)
437 int index = patternLength;
439 if (current_[index] != pattern[index])
441 current_ += patternLength;
447 Reader::readNumber ()
449 while (current_ != end_)
451 if (!(*current_ >= '0' && *current_ <= '9') &&
452 !in (*current_, '.', 'e', 'E', '+', '-'))
459 Reader::readString ()
462 while (current_ != end_)
475 Reader::readObject ()
479 currentValue () = Value (objectValue);
480 while (readToken (tokenName))
482 if (tokenName.type_ == tokenObjectEnd && name.empty ()) // empty object
484 if (tokenName.type_ != tokenString)
488 if (!decodeString (tokenName, name))
489 return recoverFromError (tokenObjectEnd);
492 if (!readToken (colon) || colon.type_ != tokenMemberSeparator)
494 return addErrorAndRecover ("Missing ':' after object member name",
498 Value &value = currentValue ()[ name ];
499 nodes_.push (&value);
500 bool ok = readValue ();
502 if (!ok) // error already set
503 return recoverFromError (tokenObjectEnd);
506 if (!readToken (comma)
507 || (comma.type_ != tokenObjectEnd &&
508 comma.type_ != tokenArraySeparator))
510 return addErrorAndRecover ("Missing ',' or '}' in object declaration",
514 if (comma.type_ == tokenObjectEnd)
517 return addErrorAndRecover ("Missing '}' or object member name",
526 currentValue () = Value (arrayValue);
528 if (*current_ == ']') // empty array
531 readToken (endArray);
537 Value &value = currentValue ()[ index++ ];
538 nodes_.push (&value);
539 bool ok = readValue ();
541 if (!ok) // error already set
542 return recoverFromError (tokenArrayEnd);
545 if (!readToken (token)
546 || (token.type_ != tokenArraySeparator &&
547 token.type_ != tokenArrayEnd))
549 return addErrorAndRecover ("Missing ',' or ']' in array declaration",
553 if (token.type_ == tokenArrayEnd)
561 Reader::decodeNumber (Token &token)
563 bool isDouble = false;
564 for (Location inspect = token.start_; inspect != token.end_; ++inspect)
567 || in (*inspect, '.', 'e', 'E', '+')
568 || (*inspect == '-' && inspect != token.start_);
571 return decodeDouble (token);
572 Location current = token.start_;
573 bool isNegative = *current == '-';
576 unsigned threshold = (isNegative ? unsigned (-Value::minInt)
577 : Value::maxUInt) / 10;
579 while (current < token.end_)
582 if (c < '0' || c > '9')
583 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
584 if (value >= threshold)
585 return decodeDouble (token);
586 value = value * 10 + unsigned (c - '0');
589 currentValue () = -int (value);
590 else if (value <= unsigned (Value::maxInt))
591 currentValue () = int (value);
593 currentValue () = value;
599 Reader::decodeDouble (Token &token)
602 const int bufferSize = 32;
604 int length = int (token.end_ - token.start_);
605 if (length <= bufferSize)
607 char buffer[bufferSize];
608 memcpy (buffer, token.start_, length);
610 count = sscanf (buffer, "%lf", &value);
614 std::string buffer (token.start_, token.end_);
615 count = sscanf (buffer.c_str (), "%lf", &value);
619 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
620 currentValue () = value;
626 Reader::decodeString (Token &token)
629 if (!decodeString (token, decoded))
631 currentValue () = decoded;
637 Reader::decodeString (Token &token, std::string &decoded)
639 Location current = token.start_ + 1; // skip '"'
640 Location end = token.end_ - 1; // do not include '"'
641 decoded.reserve (long (end - current));
643 while (current != end)
646 if (expect_false (c == '"'))
648 else if (expect_false (c == '\\'))
650 if (expect_false (current == end))
651 return addError ("Empty escape sequence in string", token, current);
652 char escape = *current++;
657 case '\\': decoded += escape; break;
659 case 'b': decoded += '\010'; break;
660 case 't': decoded += '\011'; break;
661 case 'n': decoded += '\012'; break;
662 case 'f': decoded += '\014'; break;
663 case 'r': decoded += '\015'; break;
667 if (!decodeUnicodeEscapeSequence (token, current, end, unicode))
669 // @todo encode unicode as utf8.
670 // @todo remember to alter the writer too.
674 return addError ("Bad escape sequence in string", token, current);
688 Reader::decodeUnicodeEscapeSequence (Token &token,
693 if (end - current < 4)
694 return addError ("Bad unicode escape sequence in string: four digits expected.", token, current);
696 for (int index = 0; index < 4; ++index)
700 if (c >= '0' && c <= '9')
702 else if (c >= 'a' && c <= 'f')
703 unicode += c - 'a' + 10;
704 else if (c >= 'A' && c <= 'F')
705 unicode += c - 'A' + 10;
707 return addError ("Bad unicode escape sequence in string: hexadecimal digit expected.", token, current);
714 Reader::addError (const std::string &message,
720 info.message_ = message;
722 errors_.push_back (info);
728 Reader::recoverFromError (TokenType skipUntilToken)
730 int errorCount = int (errors_.size ());
734 if (!readToken (skip))
735 errors_.resize (errorCount); // discard errors caused by recovery
736 if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
739 errors_.resize (errorCount);
745 Reader::addErrorAndRecover (const std::string &message,
747 TokenType skipUntilToken)
749 addError (message, token);
750 return recoverFromError (skipUntilToken);
755 Reader::currentValue ()
757 return *(nodes_.top ());
762 Reader::getNextChar ()
764 if (current_ == end_)
771 Reader::getLocationLineAndColumn (Location location,
775 Location current = begin_;
776 Location lastLineStart = current;
778 while (current < location && current != end_)
783 if (*current == '\n')
785 lastLineStart = current;
790 lastLineStart = current;
794 // column & line start at 1
795 column = int (location - lastLineStart) + 1;
801 Reader::getLocationLineAndColumn (Location location) const
804 getLocationLineAndColumn (location, line, column);
805 char buffer[18+16+16+1];
806 sprintf (buffer, "Line %d, Column %d", line, column);
812 Reader::error_msgs () const
814 std::string formattedMessage;
815 for (Errors::const_iterator itError = errors_.begin ();
816 itError != errors_.end ();
819 const ErrorInfo &error = *itError;
820 formattedMessage += "* " + getLocationLineAndColumn (error.token_.start_) + "\n";
821 formattedMessage += " " + error.message_ + "\n";
823 formattedMessage += "See " + getLocationLineAndColumn (error.extra_) + " for detail.\n";
825 return formattedMessage;
832 unreachable_internal (char const *file, int line, char const *function)
835 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
836 file, line, function);
838 throw std::runtime_error (buf);
842 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
845 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
846 file, line, function, condition);
848 throw std::runtime_error (buf);
852 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
855 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
856 file, line, function, message);
858 throw std::runtime_error (buf);
861 #define throw_unreachable unreachable_internal (__FILE__, __LINE__, CURFUNC)
862 #define throw_unless(condition) if (!expect_false (condition)) throw_unless_internal (__FILE__, __LINE__, CURFUNC, #condition)
863 #define throw_msg_unless(condition, message) if (!expect_false (condition)) throw_msg_unless_internal (__FILE__, __LINE__, CURFUNC, message)
865 const Value Value::null;
866 const int Value::minInt = int (~ (unsigned (-1)/2));
867 const int Value::maxInt = int (unsigned (-1)/2);
868 const unsigned Value::maxUInt = unsigned (-1);
870 ValueAllocator::~ValueAllocator ()
874 class DefaultValueAllocator : public ValueAllocator
877 virtual ~DefaultValueAllocator ()
881 virtual char *makeMemberName (char const *memberName)
883 return duplicateStringValue (memberName);
886 virtual void releaseMemberName (char *memberName)
888 releaseStringValue (memberName);
891 virtual char *duplicateStringValue (char const *value, unsigned length = unknown)
893 //@todo invesgate this old optimization
895 if (!value || value[0] == 0)
899 if (length == unknown)
900 length = (unsigned)strlen (value);
901 char *newString = static_cast<char *> (malloc (length + 1));
902 memcpy (newString, value, length);
903 newString[length] = 0;
907 virtual void releaseStringValue (char *value)
914 static ValueAllocator *&valueAllocator ()
916 static DefaultValueAllocator defaultAllocator;
917 static ValueAllocator *valueAllocator = &defaultAllocator;
918 return valueAllocator;
921 static struct DummyValueAllocatorInitializer {
922 DummyValueAllocatorInitializer ()
924 valueAllocator (); // ensure valueAllocator () statics are initialized before main ().
926 } dummyValueAllocatorInitializer;
930 Value::CZString::CZString (int index)
936 Value::CZString::CZString (char const *cstr, DuplicationPolicy allocate)
937 : cstr_ (allocate == duplicate ? valueAllocator()->makeMemberName (cstr)
943 Value::CZString::CZString (const CZString &other)
944 : cstr_ (other.index_ != noDuplication && other.cstr_ != 0
945 ? valueAllocator()->makeMemberName (other.cstr_)
947 , index_ (other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
952 Value::CZString::~CZString ()
954 if (cstr_ && index_ == duplicate)
955 valueAllocator()->releaseMemberName (const_cast<char *> (cstr_));
959 Value::CZString::swap (CZString &other)
961 std::swap (cstr_, other.cstr_);
962 std::swap (index_, other.index_);
966 Value::CZString::operator = (const CZString &other)
968 CZString temp (other);
974 Value::CZString::operator < (const CZString &other) const
977 return strcmp (cstr_, other.cstr_) < 0;
978 return index_ < other.index_;
982 Value::CZString::operator == (const CZString &other) const
985 return strcmp (cstr_, other.cstr_) == 0;
986 return index_ == other.index_;
991 Value::CZString::index () const
998 Value::CZString::c_str () const
1004 Value::CZString::isStaticString () const
1006 return index_ == noDuplication;
1010 // class Value::Value
1012 Value::Value (ValueType type)
1032 value_.map_ = new ObjectValues ();
1035 value_.bool_ = false;
1043 Value::Value (int value)
1046 value_.int_ = value;
1050 Value::Value (unsigned value)
1053 value_.uint_ = value;
1056 Value::Value (double value)
1059 value_.real_ = value;
1062 Value::Value (char const *value)
1063 : type_ (stringValue)
1066 value_.string_ = valueAllocator()->duplicateStringValue (value);
1069 Value::Value (const std::string &value)
1070 : type_ (stringValue)
1073 value_.string_ = valueAllocator()->duplicateStringValue (value.c_str (), (unsigned)value.length ());
1076 Value::Value (const StaticString &value)
1077 : type_ (stringValue)
1078 , allocated_ (false)
1080 value_.string_ = const_cast<char *> (value.c_str ());
1084 Value::Value (bool value)
1085 : type_ (booleanValue)
1087 value_.bool_ = value;
1091 Value::Value (const Value &other)
1092 : type_ (other.type_)
1101 value_ = other.value_;
1104 if (other.value_.string_)
1106 value_.string_ = valueAllocator()->duplicateStringValue (other.value_.string_);
1114 value_.map_ = new ObjectValues (*other.value_.map_);
1134 valueAllocator()->releaseStringValue (value_.string_);
1146 Value::operator = (const Value &other)
1154 Value::swap (Value &other)
1156 ValueType temp = type_;
1157 type_ = other.type_;
1159 std::swap (value_, other.value_);
1160 int temp2 = allocated_;
1161 allocated_ = other.allocated_;
1162 other.allocated_ = temp2;
1166 Value::type () const
1172 Value::operator < (const Value &other) const
1174 int typeDelta = type_ - other.type_;
1176 return typeDelta < 0 ? true : false;
1182 return value_.int_ < other.value_.int_;
1184 return value_.uint_ < other.value_.uint_;
1186 return value_.real_ < other.value_.real_;
1188 return value_.bool_ < other.value_.bool_;
1190 return (value_.string_ == 0 && other.value_.string_)
1191 || (other.value_.string_
1193 && strcmp (value_.string_, other.value_.string_) < 0);
1197 int delta = int (value_.map_->size () - other.value_.map_->size ());
1200 return (*value_.map_) < (*other.value_.map_);
1205 return 0; // unreachable
1209 Value::operator <= (const Value &other) const
1211 return !(other > *this);
1215 Value::operator >= (const Value &other) const
1217 return !(*this < other);
1221 Value::operator > (const Value &other) const
1223 return other < *this;
1227 Value::operator == (const Value &other) const
1229 if (type_ != other.type_)
1237 return value_.int_ == other.value_.int_;
1239 return value_.uint_ == other.value_.uint_;
1241 return value_.real_ == other.value_.real_;
1243 return value_.bool_ == other.value_.bool_;
1245 return (value_.string_ == other.value_.string_)
1246 || (other.value_.string_
1248 && strcmp (value_.string_, other.value_.string_) == 0);
1251 return value_.map_->size () == other.value_.map_->size ()
1252 && (*value_.map_) == (*other.value_.map_);
1256 return 0; // unreachable
1260 Value::operator != (const Value &other) const
1262 return !(*this == other);
1265 Value::operator char const * () const
1267 throw_unless (type_ == stringValue);
1268 return value_.string_;
1272 Value::operator std::string () const
1279 return value_.string_ ? value_.string_ : "";
1281 return value_.bool_ ? "true" : "false";
1287 throw_msg_unless (false, "Type is not convertible to string");
1291 return ""; // unreachable
1294 Value::operator int () const
1303 throw_msg_unless (value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
1304 return value_.uint_;
1306 throw_msg_unless (value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
1307 return int (value_.real_);
1309 return value_.bool_ ? 1 : 0;
1313 throw_msg_unless (false, "Type is not convertible to int");
1317 return 0; // unreachable;
1320 Value::operator unsigned () const
1327 throw_msg_unless (value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
1330 return value_.uint_;
1332 throw_msg_unless (value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
1333 return unsigned (value_.real_);
1335 return value_.bool_ ? 1 : 0;
1339 throw_msg_unless (false, "Type is not convertible to uint");
1343 return 0; // unreachable;
1346 Value::operator double () const
1355 return value_.uint_;
1357 return value_.real_;
1359 return value_.bool_ ? 1.0 : 0.0;
1363 throw_msg_unless (false, "Type is not convertible to double");
1367 return 0; // unreachable;
1370 Value::operator bool () const
1378 return value_.int_ != 0;
1380 return value_.real_ != 0.0;
1382 return value_.bool_;
1384 return value_.string_ && value_.string_[0] != 0;
1387 return value_.map_->size () != 0;
1391 return false; // unreachable;
1396 Value::isConvertibleTo (ValueType other) const
1403 return (other == nullValue && value_.int_ == 0)
1404 || other == intValue
1405 || (other == uintValue && value_.int_ >= 0)
1406 || other == realValue
1407 || other == stringValue
1408 || other == booleanValue;
1410 return (other == nullValue && value_.uint_ == 0)
1411 || (other == intValue && value_.uint_ <= (unsigned)maxInt)
1412 || other == uintValue
1413 || other == realValue
1414 || other == stringValue
1415 || other == booleanValue;
1417 return (other == nullValue && value_.real_ == 0.0)
1418 || (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt)
1419 || (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt)
1420 || other == realValue
1421 || other == stringValue
1422 || other == booleanValue;
1424 return (other == nullValue && value_.bool_ == false)
1425 || other == intValue
1426 || other == uintValue
1427 || other == realValue
1428 || other == stringValue
1429 || other == booleanValue;
1431 return other == stringValue
1432 || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
1434 return other == arrayValue
1435 || (other == nullValue && value_.map_->size () == 0);
1437 return other == objectValue
1438 || (other == nullValue && value_.map_->size () == 0);
1442 return false; // unreachable;
1446 /// Number of values in array or object
1448 Value::size () const
1459 case arrayValue: // size of the array is highest index + 1
1460 if (!value_.map_->empty ())
1462 ObjectValues::const_iterator itLast = value_.map_->end ();
1464 return itLast->first.index ()+1;
1468 return int (value_.map_->size ());
1472 return 0; // unreachable;
1477 Value::empty () const
1479 if (isNull () || isArray () || isObject ())
1480 return size () == 0u;
1487 Value::operator ! () const
1496 throw_unless (type_ == nullValue || type_ == arrayValue || type_ == objectValue);
1502 value_.map_->clear ();
1510 Value::resize (unsigned newSize)
1512 throw_unless (type_ == nullValue || type_ == arrayValue);
1513 if (type_ == nullValue)
1514 *this = Value (arrayValue);
1515 unsigned oldSize = size ();
1518 else if (newSize > oldSize)
1519 (*this)[ newSize - 1 ];
1522 for (unsigned index = newSize; index < oldSize; ++index)
1523 value_.map_->erase (index);
1524 throw_unless (size () == newSize);
1530 Value::operator [] (int index)
1532 return operator [] (static_cast<unsigned> (index));
1537 Value::operator [] (unsigned index)
1539 throw_unless (type_ == nullValue || type_ == arrayValue);
1540 if (type_ == nullValue)
1541 *this = Value (arrayValue);
1542 CZString key (index);
1543 ObjectValues::iterator it = value_.map_->lower_bound (key);
1544 if (it != value_.map_->end () && it->first == key)
1547 ObjectValues::value_type defaultValue (key, null);
1548 it = value_.map_->insert (it, defaultValue);
1554 Value::operator [] (int index) const
1556 return operator [] (static_cast<unsigned> (index));
1561 Value::operator [] (unsigned index) const
1563 throw_unless (type_ == nullValue || type_ == arrayValue);
1564 if (type_ == nullValue)
1566 CZString key (index);
1567 ObjectValues::const_iterator it = value_.map_->find (key);
1568 if (it == value_.map_->end ())
1575 Value::operator [] (char const *key)
1577 return resolveReference (key, false);
1582 Value::resolveReference (char const *key, bool isStatic)
1584 throw_unless (type_ == nullValue || type_ == objectValue);
1585 if (type_ == nullValue)
1586 *this = Value (objectValue);
1587 CZString actualKey (key, isStatic ? CZString::noDuplication
1588 : CZString::duplicateOnCopy);
1589 ObjectValues::iterator it = value_.map_->lower_bound (actualKey);
1590 if (it != value_.map_->end () && it->first == actualKey)
1593 ObjectValues::value_type defaultValue (actualKey, null);
1594 it = value_.map_->insert (it, defaultValue);
1595 Value &value = it->second;
1601 Value::get (int index, const Value &defaultValue) const
1603 return get (static_cast<unsigned> (index), defaultValue);
1608 Value::get (unsigned index, const Value &defaultValue) const
1610 const Value *value = &((*this)[index]);
1611 return value == &null ? defaultValue : *value;
1616 Value::isValidIndex (int index) const
1618 return isValidIndex (static_cast<unsigned> (index));
1623 Value::isValidIndex (unsigned index) const
1625 return index < size ();
1631 Value::operator [] (char const *key) const
1633 throw_unless (type_ == nullValue || type_ == objectValue);
1634 if (type_ == nullValue)
1636 CZString actualKey (key, CZString::noDuplication);
1637 ObjectValues::const_iterator it = value_.map_->find (actualKey);
1638 if (it == value_.map_->end ())
1645 Value::operator [] (const std::string &key)
1647 return (*this)[ key.c_str () ];
1652 Value::operator [] (const std::string &key) const
1654 return (*this)[ key.c_str () ];
1658 Value::operator [] (const StaticString &key)
1660 return resolveReference (key, true);
1665 Value::append (const Value &value)
1667 return (*this)[size ()] = value;
1672 Value::get (char const *key, const Value &defaultValue) const
1674 const Value *value = &((*this)[key]);
1675 return value == &null ? defaultValue : *value;
1680 Value::get (const std::string &key, const Value &defaultValue) const
1682 return get (key.c_str (), defaultValue);
1686 Value::removeMember (char const *key)
1688 throw_unless (type_ == nullValue || type_ == objectValue);
1689 if (type_ == nullValue)
1691 CZString actualKey (key, CZString::noDuplication);
1692 ObjectValues::iterator it = value_.map_->find (actualKey);
1693 if (it == value_.map_->end ())
1695 Value old (it->second);
1696 value_.map_->erase (it);
1701 Value::removeMember (const std::string &key)
1703 return removeMember (key.c_str ());
1707 Value::isMember (char const *key) const
1709 const Value *value = &((*this)[key]);
1710 return value != &null;
1715 Value::isMember (const std::string &key) const
1717 return isMember (key.c_str ());
1722 Value::getMemberNames () const
1724 throw_unless (type_ == nullValue || type_ == objectValue);
1725 if (type_ == nullValue)
1726 return Value::Members ();
1728 members.reserve (value_.map_->size ());
1729 ObjectValues::const_iterator it;
1730 ObjectValues::const_iterator itEnd = value_.map_->end ();
1731 for (it = value_.map_->begin (); it != itEnd; ++it)
1732 members.push_back (std::string (it->first.c_str()));
1737 Value::isNull () const
1739 return type_ == nullValue;
1744 Value::isBool () const
1746 return type_ == booleanValue;
1751 Value::isInt () const
1753 return type_ == intValue;
1758 Value::isUInt () const
1760 return type_ == uintValue;
1765 Value::isIntegral () const
1767 return type_ == intValue
1768 || type_ == uintValue
1769 || type_ == booleanValue;
1774 Value::isDouble () const
1776 return type_ == realValue;
1781 Value::isNumeric () const
1783 return isIntegral () || isDouble ();
1788 Value::isString () const
1790 return type_ == stringValue;
1795 Value::isArray () const
1797 return type_ == nullValue || type_ == arrayValue;
1802 Value::isObject () const
1804 return type_ == nullValue || type_ == objectValue;
1808 Value::const_iterator
1809 Value::begin () const
1816 return const_iterator (value_.map_->begin ());
1821 return const_iterator ();
1824 Value::const_iterator
1832 return const_iterator (value_.map_->end ());
1837 return const_iterator ();
1849 return iterator (value_.map_->begin ());
1865 return iterator (value_.map_->end ());
1876 static void uintToString (unsigned value,
1882 *--current = (value % 10) + '0';
1888 std::string valueToString (int value)
1891 char *current = buffer + sizeof (buffer);
1892 bool isNegative = value < 0;
1895 uintToString (unsigned (value), current);
1898 throw_unless (current >= buffer);
1903 std::string valueToString (unsigned value)
1906 char *current = buffer + sizeof (buffer);
1907 uintToString (value, current);
1908 throw_unless (current >= buffer);
1912 std::string valueToString (double value)
1915 sprintf (buffer, "%.16g", value);
1920 std::string valueToString (bool value)
1922 return value ? "true" : "false";
1925 std::string valueToQuotedString (char const *value)
1927 // Not sure how to handle unicode...
1928 if (std::strpbrk (value, "\"\\\b\f\n\r\t") == NULL)
1929 return std::string ("\"") + value + "\"";
1930 // We have to walk value and escape any special characters.
1931 // Appending to std::string is not efficient, but this should be rare.
1932 // (Note: forward slashes are *not* rare, but I am not escaping them.)
1933 unsigned maxsize = strlen (value) * 2 + 3; // allescaped+quotes+NULL
1935 result.reserve (maxsize); // to avoid lots of mallocs
1937 for (char const* c=value; *c != 0; ++c){
1961 // Even though \/ is considered a legal escape in JSON, a bare
1962 // slash is also legal, so I see no reason to escape it.
1963 // (I hope I am not misunderstanding something.)
1974 Writer::write (const Value &root)
1984 Writer::writeValue (const Value &value)
1986 switch (value.type ())
1989 document_ += "null";
1992 document_ += valueToString (static_cast<int> (value));
1995 document_ += valueToString (static_cast<unsigned> (value));
1998 document_ += valueToString (static_cast<double> (value));
2001 document_ += valueToQuotedString (static_cast<char const *> (value));
2004 document_ += valueToString (static_cast<bool> (value));
2009 int size = value.size ();
2010 for (int index = 0; index < size; ++index)
2014 writeValue (value[index]);
2021 Value::Members members (value.getMemberNames ());
2023 for (Value::Members::iterator it = members.begin ();
2024 it != members.end ();
2027 const std::string &name = *it;
2028 if (it != members.begin ())
2030 document_ += valueToQuotedString (name.c_str ());
2032 writeValue (value[name]);
2052 add_method (char *name, Module const *mod, method mth)
2054 mfp m = { mod, mth };
2059 service (HTTPRequest *http, Value &request, Value &response)
2061 char const *methodName = static_cast<char const *> (request["method"]);
2063 method_map::iterator mthit = methods.find (methodName);
2064 if (mthit != methods.end ())
2066 mfp m = mthit->second;
2067 Module *mod = new Module (*m.mod);
2069 (mod->*mth) (http, request, response);
2075 process (HTTPRequest *http, std::string &response_text, char const *request_text)
2079 Value request (objectValue);
2080 Value response (objectValue);
2084 response["error"] = Value(nullValue);
2085 response["result"] = Value(nullValue);
2087 parse_success = r.parse (request_text, request_text + strlen (request_text), request);
2089 response["id"] = request["id"];
2091 service (http, request, response);
2093 text = w.write (response);
2095 response_text = text.c_str ();
2102 MODULE_INIT(ModuleRpcJson)