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 ServerInstance->PublishInterface("JSON-RPC", this);
58 json::rpc::add_method ("system.listMethods", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::system_list_methods);
59 json::rpc::add_method ("ircd.moduleVersion", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::MthModuleVersion);
62 void OnEvent(Event* event)
64 std::stringstream data("");
66 if (event->GetEventID() == "httpd_url")
68 HTTPRequest* http = (HTTPRequest*)event->GetData();
70 if (http->GetURI() == "/jsonrpc" && http->GetType() == "POST")
74 std::string response_text;
75 json::rpc::process (http, response_text, http->GetPostData().c_str());
76 data << response_text;
78 catch (std::runtime_error &)
80 data << "{ \"result\": \"JSON Fault\", \"error\": \"Invalid RPC call\", \"id\": 1}";
83 /* Send the document back to m_httpd */
84 HTTPDocument response(http->sock, &data, 200, "X-Powered-By: m_rpc_json.so\r\n"
85 "Content-Type: application/json; charset=iso-8859-1\r\n");
86 Request req((char*)&response, (Module*)this, event->GetSource());
92 void Implements(char* List)
97 virtual ~ModuleRpcJson()
99 ServerInstance->UnpublishInterface("JSON-RPC", this);
102 virtual Version GetVersion()
104 return Version(0, 1, 0, 0, VF_VENDOR, API_VERSION);
109 unreachable_internal (char const *file, int line, char const *function)
112 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
113 file, line, function);
115 throw std::runtime_error (buf);
119 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
122 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
123 file, line, function, condition);
125 throw std::runtime_error (buf);
129 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
132 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
133 file, line, function, message);
135 throw std::runtime_error (buf);
141 ValueIteratorBase::ValueIteratorBase ()
146 ValueIteratorBase::ValueIteratorBase (const Value::ObjectValues::iterator ¤t)
152 ValueIteratorBase::deref () const
154 return current_->second;
159 ValueIteratorBase::increment ()
166 ValueIteratorBase::decrement ()
172 ValueIteratorBase::difference_type
173 ValueIteratorBase::computeDistance (const SelfType &other) const
175 return difference_type (std::distance (current_, other.current_));
180 ValueIteratorBase::isEqual (const SelfType &other) const
182 return current_ == other.current_;
187 ValueIteratorBase::copy (const SelfType &other)
189 current_ = other.current_;
194 ValueIteratorBase::key () const
196 const Value::CZString czstring = (*current_).first;
197 if (czstring.c_str ())
199 if (czstring.isStaticString ())
200 return Value (StaticString (czstring.c_str ()));
201 return Value (czstring.c_str ());
203 return Value (czstring.index ());
208 ValueIteratorBase::index () const
210 const Value::CZString czstring = (*current_).first;
211 if (!czstring.c_str ())
212 return czstring.index ();
213 return unsigned (-1);
218 ValueIteratorBase::memberName () const
220 char const *name = (*current_).first.c_str ();
221 return name ? name : "";
225 ValueConstIterator::ValueConstIterator ()
230 ValueConstIterator::ValueConstIterator (const Value::ObjectValues::iterator ¤t)
231 : ValueIteratorBase (current)
236 ValueConstIterator::operator = (const ValueIteratorBase &other)
243 ValueIterator::ValueIterator ()
248 ValueIterator::ValueIterator (const Value::ObjectValues::iterator ¤t)
249 : ValueIteratorBase (current)
253 ValueIterator::ValueIterator (const ValueConstIterator &other)
254 : ValueIteratorBase (other)
258 ValueIterator::ValueIterator (const ValueIterator &other)
259 : ValueIteratorBase (other)
264 ValueIterator::operator = (const SelfType &other)
274 in (char c, char c1, char c2, char c3, char c4)
276 return c == c1 || c == c2 || c == c3 || c == c4;
280 in (char c, char c1, char c2, char c3, char c4, char c5)
282 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
291 Reader::parse (const std::string &document,
294 document_ = document;
295 char const *begin = document_.c_str ();
296 char const *end = begin + document_.length ();
297 return parse (begin, end, root);
301 Reader::parse (std::istream& sin,
305 std::getline (sin, doc, (char)EOF);
306 return parse (doc, root);
310 Reader::parse (char const *beginDoc, char const *endDOc,
319 while (!nodes_.empty ())
323 bool successful = readValue ();
334 while (token.type_ == tokenComment);
335 bool successful = true;
339 case tokenObjectBegin:
340 successful = readObject ();
342 case tokenArrayBegin:
343 successful = readArray ();
346 successful = decodeNumber (token);
349 successful = decodeString (token);
352 currentValue () = true;
355 currentValue () = false;
358 currentValue () = Value ();
361 return addError ("Syntax error: value, object or array expected.", token);
369 Reader::expectToken (TokenType type, Token &token, char const *message)
372 if (token.type_ != type)
373 return addError (message, token);
379 Reader::readToken (Token &token)
382 token.start_ = current_;
383 char c = getNextChar ();
388 token.type_ = tokenObjectBegin;
391 token.type_ = tokenObjectEnd;
394 token.type_ = tokenArrayBegin;
397 token.type_ = tokenArrayEnd;
400 token.type_ = tokenString;
408 case '0': case '1': case '2': case '3':
409 case '4': case '5': case '6': case '7':
413 token.type_ = tokenNumber;
417 token.type_ = tokenTrue;
418 ok = match ("rue", 3);
421 token.type_ = tokenFalse;
422 ok = match ("alse", 4);
425 token.type_ = tokenNull;
426 ok = match ("ull", 3);
429 token.type_ = tokenArraySeparator;
432 token.type_ = tokenMemberSeparator;
435 token.type_ = tokenEndOfStream;
442 token.type_ = tokenError;
443 token.end_ = current_;
449 Reader::skipSpaces ()
451 while (current_ != end_)
454 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
463 Reader::match (Location pattern, int patternLength)
465 if (end_ - current_ < patternLength)
467 int index = patternLength;
469 if (current_[index] != pattern[index])
471 current_ += patternLength;
477 Reader::readNumber ()
479 while (current_ != end_)
481 if (!(*current_ >= '0' && *current_ <= '9') &&
482 !in (*current_, '.', 'e', 'E', '+', '-'))
489 Reader::readString ()
492 while (current_ != end_)
505 Reader::readObject ()
509 currentValue () = Value (objectValue);
510 while (readToken (tokenName))
512 if (tokenName.type_ == tokenObjectEnd && name.empty ()) // empty object
514 if (tokenName.type_ != tokenString)
518 if (!decodeString (tokenName, name))
519 return recoverFromError (tokenObjectEnd);
522 if (!readToken (colon) || colon.type_ != tokenMemberSeparator)
524 return addErrorAndRecover ("Missing ':' after object member name",
528 Value &value = currentValue ()[ name ];
529 nodes_.push (&value);
530 bool ok = readValue ();
532 if (!ok) // error already set
533 return recoverFromError (tokenObjectEnd);
536 if (!readToken (comma)
537 || (comma.type_ != tokenObjectEnd &&
538 comma.type_ != tokenArraySeparator))
540 return addErrorAndRecover ("Missing ',' or '}' in object declaration",
544 if (comma.type_ == tokenObjectEnd)
547 return addErrorAndRecover ("Missing '}' or object member name",
556 currentValue () = Value (arrayValue);
558 if (*current_ == ']') // empty array
561 readToken (endArray);
567 Value &value = currentValue ()[ index++ ];
568 nodes_.push (&value);
569 bool ok = readValue ();
571 if (!ok) // error already set
572 return recoverFromError (tokenArrayEnd);
575 if (!readToken (token)
576 || (token.type_ != tokenArraySeparator &&
577 token.type_ != tokenArrayEnd))
579 return addErrorAndRecover ("Missing ',' or ']' in array declaration",
583 if (token.type_ == tokenArrayEnd)
591 Reader::decodeNumber (Token &token)
593 bool isDouble = false;
594 for (Location inspect = token.start_; inspect != token.end_; ++inspect)
597 || in (*inspect, '.', 'e', 'E', '+')
598 || (*inspect == '-' && inspect != token.start_);
601 return decodeDouble (token);
602 Location current = token.start_;
603 bool isNegative = *current == '-';
606 unsigned threshold = (isNegative ? unsigned (-Value::minInt)
607 : Value::maxUInt) / 10;
609 while (current < token.end_)
612 if (c < '0' || c > '9')
613 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
614 if (value >= threshold)
615 return decodeDouble (token);
616 value = value * 10 + unsigned (c - '0');
619 currentValue () = -int (value);
620 else if (value <= unsigned (Value::maxInt))
621 currentValue () = int (value);
623 currentValue () = value;
629 Reader::decodeDouble (Token &token)
632 const int bufferSize = 32;
634 int length = int (token.end_ - token.start_);
635 if (length <= bufferSize)
637 char buffer[bufferSize];
638 memcpy (buffer, token.start_, length);
640 count = sscanf (buffer, "%lf", &value);
644 std::string buffer (token.start_, token.end_);
645 count = sscanf (buffer.c_str (), "%lf", &value);
649 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
650 currentValue () = value;
656 Reader::decodeString (Token &token)
659 if (!decodeString (token, decoded))
661 currentValue () = decoded;
667 Reader::decodeString (Token &token, std::string &decoded)
669 Location current = token.start_ + 1; // skip '"'
670 Location end = token.end_ - 1; // do not include '"'
671 decoded.reserve (long (end - current));
673 while (current != end)
676 if (expect_false (c == '"'))
678 else if (expect_false (c == '\\'))
680 if (expect_false (current == end))
681 return addError ("Empty escape sequence in string", token, current);
682 char escape = *current++;
687 case '\\': decoded += escape; break;
689 case 'b': decoded += '\010'; break;
690 case 't': decoded += '\011'; break;
691 case 'n': decoded += '\012'; break;
692 case 'f': decoded += '\014'; break;
693 case 'r': decoded += '\015'; break;
697 if (!decodeUnicodeEscapeSequence (token, current, end, unicode))
699 // @todo encode unicode as utf8.
700 // @todo remember to alter the writer too.
704 return addError ("Bad escape sequence in string", token, current);
718 Reader::decodeUnicodeEscapeSequence (Token &token,
723 if (end - current < 4)
724 return addError ("Bad unicode escape sequence in string: four digits expected.", token, current);
726 for (int index = 0; index < 4; ++index)
730 if (c >= '0' && c <= '9')
732 else if (c >= 'a' && c <= 'f')
733 unicode += c - 'a' + 10;
734 else if (c >= 'A' && c <= 'F')
735 unicode += c - 'A' + 10;
737 return addError ("Bad unicode escape sequence in string: hexadecimal digit expected.", token, current);
744 Reader::addError (const std::string &message,
750 info.message_ = message;
752 errors_.push_back (info);
758 Reader::recoverFromError (TokenType skipUntilToken)
760 int errorCount = int (errors_.size ());
764 if (!readToken (skip))
765 errors_.resize (errorCount); // discard errors caused by recovery
766 if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
769 errors_.resize (errorCount);
775 Reader::addErrorAndRecover (const std::string &message,
777 TokenType skipUntilToken)
779 addError (message, token);
780 return recoverFromError (skipUntilToken);
785 Reader::currentValue ()
787 return *(nodes_.top ());
792 Reader::getNextChar ()
794 if (current_ == end_)
801 Reader::getLocationLineAndColumn (Location location,
805 Location current = begin_;
806 Location lastLineStart = current;
808 while (current < location && current != end_)
813 if (*current == '\n')
815 lastLineStart = current;
820 lastLineStart = current;
824 // column & line start at 1
825 column = int (location - lastLineStart) + 1;
831 Reader::getLocationLineAndColumn (Location location) const
834 getLocationLineAndColumn (location, line, column);
835 char buffer[18+16+16+1];
836 sprintf (buffer, "Line %d, Column %d", line, column);
842 Reader::error_msgs () const
844 std::string formattedMessage;
845 for (Errors::const_iterator itError = errors_.begin ();
846 itError != errors_.end ();
849 const ErrorInfo &error = *itError;
850 formattedMessage += "* " + getLocationLineAndColumn (error.token_.start_) + "\n";
851 formattedMessage += " " + error.message_ + "\n";
853 formattedMessage += "See " + getLocationLineAndColumn (error.extra_) + " for detail.\n";
855 return formattedMessage;
862 unreachable_internal (char const *file, int line, char const *function)
865 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
866 file, line, function);
868 throw std::runtime_error (buf);
872 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
875 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
876 file, line, function, condition);
878 throw std::runtime_error (buf);
882 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
885 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
886 file, line, function, message);
888 throw std::runtime_error (buf);
891 const Value Value::null;
892 const int Value::minInt = int (~ (unsigned (-1)/2));
893 const int Value::maxInt = int (unsigned (-1)/2);
894 const unsigned Value::maxUInt = unsigned (-1);
896 ValueAllocator::~ValueAllocator ()
900 class DefaultValueAllocator : public ValueAllocator
903 virtual ~DefaultValueAllocator ()
907 virtual char *makeMemberName (char const *memberName)
909 return duplicateStringValue (memberName);
912 virtual void releaseMemberName (char *memberName)
914 releaseStringValue (memberName);
917 virtual char *duplicateStringValue (char const *value, unsigned length = unknown)
919 //@todo invesgate this old optimization
921 if (!value || value[0] == 0)
925 if (length == unknown)
926 length = (unsigned)strlen (value);
927 char *newString = static_cast<char *> (malloc (length + 1));
928 memcpy (newString, value, length);
929 newString[length] = 0;
933 virtual void releaseStringValue (char *value)
940 static ValueAllocator *&valueAllocator ()
942 static DefaultValueAllocator defaultAllocator;
943 static ValueAllocator *valueAllocator = &defaultAllocator;
944 return valueAllocator;
947 static struct DummyValueAllocatorInitializer {
948 DummyValueAllocatorInitializer ()
950 valueAllocator (); // ensure valueAllocator () statics are initialized before main ().
952 } dummyValueAllocatorInitializer;
956 Value::CZString::CZString (int index)
962 Value::CZString::CZString (char const *cstr, DuplicationPolicy allocate)
963 : cstr_ (allocate == duplicate ? valueAllocator()->makeMemberName (cstr)
969 Value::CZString::CZString (const CZString &other)
970 : cstr_ (other.index_ != noDuplication && other.cstr_ != 0
971 ? valueAllocator()->makeMemberName (other.cstr_)
973 , index_ (other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
978 Value::CZString::~CZString ()
980 if (cstr_ && index_ == duplicate)
981 valueAllocator()->releaseMemberName (const_cast<char *> (cstr_));
985 Value::CZString::swap (CZString &other)
987 std::swap (cstr_, other.cstr_);
988 std::swap (index_, other.index_);
992 Value::CZString::operator = (const CZString &other)
994 CZString temp (other);
1000 Value::CZString::operator < (const CZString &other) const
1003 return strcmp (cstr_, other.cstr_) < 0;
1004 return index_ < other.index_;
1008 Value::CZString::operator == (const CZString &other) const
1011 return strcmp (cstr_, other.cstr_) == 0;
1012 return index_ == other.index_;
1017 Value::CZString::index () const
1024 Value::CZString::c_str () const
1030 Value::CZString::isStaticString () const
1032 return index_ == noDuplication;
1036 // class Value::Value
1038 Value::Value (ValueType type)
1058 value_.map_ = new ObjectValues ();
1061 value_.bool_ = false;
1069 Value::Value (int value)
1072 value_.int_ = value;
1076 Value::Value (unsigned value)
1079 value_.uint_ = value;
1082 Value::Value (double value)
1085 value_.real_ = value;
1088 Value::Value (char const *value)
1089 : type_ (stringValue)
1092 value_.string_ = valueAllocator()->duplicateStringValue (value);
1095 Value::Value (const std::string &value)
1096 : type_ (stringValue)
1099 value_.string_ = valueAllocator()->duplicateStringValue (value.c_str (), (unsigned)value.length ());
1102 Value::Value (const StaticString &value)
1103 : type_ (stringValue)
1104 , allocated_ (false)
1106 value_.string_ = const_cast<char *> (value.c_str ());
1110 Value::Value (bool value)
1111 : type_ (booleanValue)
1113 value_.bool_ = value;
1117 Value::Value (const Value &other)
1118 : type_ (other.type_)
1127 value_ = other.value_;
1130 if (other.value_.string_)
1132 value_.string_ = valueAllocator()->duplicateStringValue (other.value_.string_);
1140 value_.map_ = new ObjectValues (*other.value_.map_);
1160 valueAllocator()->releaseStringValue (value_.string_);
1172 Value::operator = (const Value &other)
1180 Value::swap (Value &other)
1182 ValueType temp = type_;
1183 type_ = other.type_;
1185 std::swap (value_, other.value_);
1186 int temp2 = allocated_;
1187 allocated_ = other.allocated_;
1188 other.allocated_ = temp2;
1192 Value::type () const
1198 Value::operator < (const Value &other) const
1200 int typeDelta = type_ - other.type_;
1202 return typeDelta < 0 ? true : false;
1208 return value_.int_ < other.value_.int_;
1210 return value_.uint_ < other.value_.uint_;
1212 return value_.real_ < other.value_.real_;
1214 return value_.bool_ < other.value_.bool_;
1216 return (value_.string_ == 0 && other.value_.string_)
1217 || (other.value_.string_
1219 && strcmp (value_.string_, other.value_.string_) < 0);
1223 int delta = int (value_.map_->size () - other.value_.map_->size ());
1226 return (*value_.map_) < (*other.value_.map_);
1231 return 0; // unreachable
1235 Value::operator <= (const Value &other) const
1237 return !(other > *this);
1241 Value::operator >= (const Value &other) const
1243 return !(*this < other);
1247 Value::operator > (const Value &other) const
1249 return other < *this;
1253 Value::operator == (const Value &other) const
1255 if (type_ != other.type_)
1263 return value_.int_ == other.value_.int_;
1265 return value_.uint_ == other.value_.uint_;
1267 return value_.real_ == other.value_.real_;
1269 return value_.bool_ == other.value_.bool_;
1271 return (value_.string_ == other.value_.string_)
1272 || (other.value_.string_
1274 && strcmp (value_.string_, other.value_.string_) == 0);
1277 return value_.map_->size () == other.value_.map_->size ()
1278 && (*value_.map_) == (*other.value_.map_);
1282 return 0; // unreachable
1286 Value::operator != (const Value &other) const
1288 return !(*this == other);
1291 Value::operator char const * () const
1293 throw_unless (type_ == stringValue);
1294 return value_.string_;
1298 Value::operator std::string () const
1305 return value_.string_ ? value_.string_ : "";
1307 return value_.bool_ ? "true" : "false";
1313 throw_msg_unless (false, "Type is not convertible to string");
1317 return ""; // unreachable
1320 Value::operator int () const
1329 throw_msg_unless (value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
1330 return value_.uint_;
1332 throw_msg_unless (value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
1333 return int (value_.real_);
1335 return value_.bool_ ? 1 : 0;
1339 throw_msg_unless (false, "Type is not convertible to int");
1343 return 0; // unreachable;
1346 Value::operator unsigned () const
1353 throw_msg_unless (value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
1356 return value_.uint_;
1358 throw_msg_unless (value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
1359 return unsigned (value_.real_);
1361 return value_.bool_ ? 1 : 0;
1365 throw_msg_unless (false, "Type is not convertible to uint");
1369 return 0; // unreachable;
1372 Value::operator double () const
1381 return value_.uint_;
1383 return value_.real_;
1385 return value_.bool_ ? 1.0 : 0.0;
1389 throw_msg_unless (false, "Type is not convertible to double");
1393 return 0; // unreachable;
1396 Value::operator bool () const
1404 return value_.int_ != 0;
1406 return value_.real_ != 0.0;
1408 return value_.bool_;
1410 return value_.string_ && value_.string_[0] != 0;
1413 return value_.map_->size () != 0;
1417 return false; // unreachable;
1422 Value::isConvertibleTo (ValueType other) const
1429 return (other == nullValue && value_.int_ == 0)
1430 || other == intValue
1431 || (other == uintValue && value_.int_ >= 0)
1432 || other == realValue
1433 || other == stringValue
1434 || other == booleanValue;
1436 return (other == nullValue && value_.uint_ == 0)
1437 || (other == intValue && value_.uint_ <= (unsigned)maxInt)
1438 || other == uintValue
1439 || other == realValue
1440 || other == stringValue
1441 || other == booleanValue;
1443 return (other == nullValue && value_.real_ == 0.0)
1444 || (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt)
1445 || (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt)
1446 || other == realValue
1447 || other == stringValue
1448 || other == booleanValue;
1450 return (other == nullValue && value_.bool_ == false)
1451 || other == intValue
1452 || other == uintValue
1453 || other == realValue
1454 || other == stringValue
1455 || other == booleanValue;
1457 return other == stringValue
1458 || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
1460 return other == arrayValue
1461 || (other == nullValue && value_.map_->size () == 0);
1463 return other == objectValue
1464 || (other == nullValue && value_.map_->size () == 0);
1468 return false; // unreachable;
1472 /// Number of values in array or object
1474 Value::size () const
1485 case arrayValue: // size of the array is highest index + 1
1486 if (!value_.map_->empty ())
1488 ObjectValues::const_iterator itLast = value_.map_->end ();
1490 return itLast->first.index ()+1;
1494 return int (value_.map_->size ());
1498 return 0; // unreachable;
1503 Value::empty () const
1505 if (isNull () || isArray () || isObject ())
1506 return size () == 0u;
1513 Value::operator ! () const
1522 throw_unless (type_ == nullValue || type_ == arrayValue || type_ == objectValue);
1528 value_.map_->clear ();
1536 Value::resize (unsigned newSize)
1538 throw_unless (type_ == nullValue || type_ == arrayValue);
1539 if (type_ == nullValue)
1540 *this = Value (arrayValue);
1541 unsigned oldSize = size ();
1544 else if (newSize > oldSize)
1545 (*this)[ newSize - 1 ];
1548 for (unsigned index = newSize; index < oldSize; ++index)
1549 value_.map_->erase (index);
1550 throw_unless (size () == newSize);
1556 Value::operator [] (int index)
1558 return operator [] (static_cast<unsigned> (index));
1563 Value::operator [] (unsigned index)
1565 throw_unless (type_ == nullValue || type_ == arrayValue);
1566 if (type_ == nullValue)
1567 *this = Value (arrayValue);
1568 CZString key (index);
1569 ObjectValues::iterator it = value_.map_->lower_bound (key);
1570 if (it != value_.map_->end () && it->first == key)
1573 ObjectValues::value_type defaultValue (key, null);
1574 it = value_.map_->insert (it, defaultValue);
1580 Value::operator [] (int index) const
1582 return operator [] (static_cast<unsigned> (index));
1587 Value::operator [] (unsigned index) const
1589 throw_unless (type_ == nullValue || type_ == arrayValue);
1590 if (type_ == nullValue)
1592 CZString key (index);
1593 ObjectValues::const_iterator it = value_.map_->find (key);
1594 if (it == value_.map_->end ())
1601 Value::operator [] (char const *key)
1603 return resolveReference (key, false);
1608 Value::resolveReference (char const *key, bool isStatic)
1610 throw_unless (type_ == nullValue || type_ == objectValue);
1611 if (type_ == nullValue)
1612 *this = Value (objectValue);
1613 CZString actualKey (key, isStatic ? CZString::noDuplication
1614 : CZString::duplicateOnCopy);
1615 ObjectValues::iterator it = value_.map_->lower_bound (actualKey);
1616 if (it != value_.map_->end () && it->first == actualKey)
1619 ObjectValues::value_type defaultValue (actualKey, null);
1620 it = value_.map_->insert (it, defaultValue);
1621 Value &value = it->second;
1627 Value::get (int index, const Value &defaultValue) const
1629 return get (static_cast<unsigned> (index), defaultValue);
1634 Value::get (unsigned index, const Value &defaultValue) const
1636 const Value *value = &((*this)[index]);
1637 return value == &null ? defaultValue : *value;
1642 Value::isValidIndex (int index) const
1644 return isValidIndex (static_cast<unsigned> (index));
1649 Value::isValidIndex (unsigned index) const
1651 return index < size ();
1657 Value::operator [] (char const *key) const
1659 throw_unless (type_ == nullValue || type_ == objectValue);
1660 if (type_ == nullValue)
1662 CZString actualKey (key, CZString::noDuplication);
1663 ObjectValues::const_iterator it = value_.map_->find (actualKey);
1664 if (it == value_.map_->end ())
1671 Value::operator [] (const std::string &key)
1673 return (*this)[ key.c_str () ];
1678 Value::operator [] (const std::string &key) const
1680 return (*this)[ key.c_str () ];
1684 Value::operator [] (const StaticString &key)
1686 return resolveReference (key, true);
1691 Value::append (const Value &value)
1693 return (*this)[size ()] = value;
1698 Value::get (char const *key, const Value &defaultValue) const
1700 const Value *value = &((*this)[key]);
1701 return value == &null ? defaultValue : *value;
1706 Value::get (const std::string &key, const Value &defaultValue) const
1708 return get (key.c_str (), defaultValue);
1712 Value::removeMember (char const *key)
1714 throw_unless (type_ == nullValue || type_ == objectValue);
1715 if (type_ == nullValue)
1717 CZString actualKey (key, CZString::noDuplication);
1718 ObjectValues::iterator it = value_.map_->find (actualKey);
1719 if (it == value_.map_->end ())
1721 Value old (it->second);
1722 value_.map_->erase (it);
1727 Value::removeMember (const std::string &key)
1729 return removeMember (key.c_str ());
1733 Value::isMember (char const *key) const
1735 const Value *value = &((*this)[key]);
1736 return value != &null;
1741 Value::isMember (const std::string &key) const
1743 return isMember (key.c_str ());
1748 Value::getMemberNames () const
1750 throw_unless (type_ == nullValue || type_ == objectValue);
1751 if (type_ == nullValue)
1752 return Value::Members ();
1754 members.reserve (value_.map_->size ());
1755 ObjectValues::const_iterator it;
1756 ObjectValues::const_iterator itEnd = value_.map_->end ();
1757 for (it = value_.map_->begin (); it != itEnd; ++it)
1758 members.push_back (std::string (it->first.c_str()));
1763 Value::isNull () const
1765 return type_ == nullValue;
1770 Value::isBool () const
1772 return type_ == booleanValue;
1777 Value::isInt () const
1779 return type_ == intValue;
1784 Value::isUInt () const
1786 return type_ == uintValue;
1791 Value::isIntegral () const
1793 return type_ == intValue
1794 || type_ == uintValue
1795 || type_ == booleanValue;
1800 Value::isDouble () const
1802 return type_ == realValue;
1807 Value::isNumeric () const
1809 return isIntegral () || isDouble ();
1814 Value::isString () const
1816 return type_ == stringValue;
1821 Value::isArray () const
1823 return type_ == nullValue || type_ == arrayValue;
1828 Value::isObject () const
1830 return type_ == nullValue || type_ == objectValue;
1834 Value::const_iterator
1835 Value::begin () const
1842 return const_iterator (value_.map_->begin ());
1847 return const_iterator ();
1850 Value::const_iterator
1858 return const_iterator (value_.map_->end ());
1863 return const_iterator ();
1875 return iterator (value_.map_->begin ());
1891 return iterator (value_.map_->end ());
1902 static void uintToString (unsigned value,
1908 *--current = (value % 10) + '0';
1914 std::string valueToString (int value)
1917 char *current = buffer + sizeof (buffer);
1918 bool isNegative = value < 0;
1921 uintToString (unsigned (value), current);
1924 throw_unless (current >= buffer);
1929 std::string valueToString (unsigned value)
1932 char *current = buffer + sizeof (buffer);
1933 uintToString (value, current);
1934 throw_unless (current >= buffer);
1938 std::string valueToString (double value)
1941 sprintf (buffer, "%.16g", value);
1946 std::string valueToString (bool value)
1948 return value ? "true" : "false";
1951 std::string valueToQuotedString (char const *value)
1953 // Not sure how to handle unicode...
1954 if (std::strpbrk (value, "\"\\\b\f\n\r\t") == NULL)
1955 return std::string ("\"") + value + "\"";
1956 // We have to walk value and escape any special characters.
1957 // Appending to std::string is not efficient, but this should be rare.
1958 // (Note: forward slashes are *not* rare, but I am not escaping them.)
1959 unsigned maxsize = strlen (value) * 2 + 3; // allescaped+quotes+NULL
1961 result.reserve (maxsize); // to avoid lots of mallocs
1963 for (char const* c=value; *c != 0; ++c){
1987 // Even though \/ is considered a legal escape in JSON, a bare
1988 // slash is also legal, so I see no reason to escape it.
1989 // (I hope I am not misunderstanding something.)
2000 Writer::write (const Value &root)
2010 Writer::writeValue (const Value &value)
2012 switch (value.type ())
2015 document_ += "null";
2018 document_ += valueToString (static_cast<int> (value));
2021 document_ += valueToString (static_cast<unsigned> (value));
2024 document_ += valueToString (static_cast<double> (value));
2027 document_ += valueToQuotedString (static_cast<char const *> (value));
2030 document_ += valueToString (static_cast<bool> (value));
2035 int size = value.size ();
2036 for (int index = 0; index < size; ++index)
2040 writeValue (value[index]);
2047 Value::Members members (value.getMemberNames ());
2049 for (Value::Members::iterator it = members.begin ();
2050 it != members.end ();
2053 const std::string &name = *it;
2054 if (it != members.begin ())
2056 document_ += valueToQuotedString (name.c_str ());
2058 writeValue (value[name]);
2078 add_method (char *name, Module const *mod, method mth)
2080 mfp m = { mod, mth };
2085 service (HTTPRequest *http, Value &request, Value &response)
2087 char const *methodName = static_cast<char const *> (request["method"]);
2089 method_map::iterator mthit = methods.find (methodName);
2090 if (mthit != methods.end ())
2092 mfp m = mthit->second;
2093 Module *mod = new Module (*m.mod);
2095 (mod->*mth) (http, request, response);
2101 process (HTTPRequest *http, std::string &response_text, char const *request_text)
2105 Value request (objectValue);
2106 Value response (objectValue);
2110 parse_success = r.parse (request_text, request_text + strlen (request_text), request);
2112 service (http, request, response);
2114 text = w.write (response);
2116 response_text = text.c_str ();
2123 MODULE_INIT(ModuleRpcJson)