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 * ---------------------------------------------------
21 #include "inspsocket.h"
25 /* $ModDesc: Provides a JSON-RPC interface for modules using m_httpd.so */
27 class ModuleRpcJson : public Module
29 void MthModuleVersion (HTTPRequest *http, json::Value &request, json::Value &response)
31 Version v = this->GetVersion();
32 std::string result = ConvToStr(v.Major) + "." + ConvToStr(v.Minor) + "." + ConvToStr(v.Revision) + "." + ConvToStr(v.Build);
33 response["result"] = result;
36 void system_list_methods (HTTPRequest *http, json::Value &request, json::Value &response)
39 json::Value method_list (json::arrayValue);
41 json::rpc::method_map::iterator it;
42 for (it = json::rpc::methods.begin(); it != json::rpc::methods.end(); ++it)
44 method_list[i] = json::Value (it->first);
48 response["result"] = method_list;
52 ModuleRpcJson(InspIRCd* Me) : Module(Me)
54 ServerInstance->PublishInterface("JSON-RPC", this);
55 json::rpc::add_method ("system.listMethods", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::system_list_methods);
56 json::rpc::add_method ("ircd.moduleVersion", (Module *)this, (void (Module::*)(HTTPRequest*, json::Value&, json::Value&))&ModuleRpcJson::MthModuleVersion);
59 void OnEvent(Event* event)
61 std::stringstream data("");
63 if (event->GetEventID() == "httpd_url")
65 HTTPRequest* http = (HTTPRequest*)event->GetData();
67 if (http->GetURI() == "/jsonrpc" && http->GetType() == "POST")
71 std::string response_text;
72 json::rpc::process (http, response_text, http->GetPostData().c_str());
73 data << response_text;
75 catch (std::runtime_error &)
77 data << "{ \"result\": \"JSON Fault\", \"error\": \"Invalid RPC call\", \"id\": 1}";
80 /* Send the document back to m_httpd */
81 HTTPDocument response(http->sock, &data, 200);
82 response.headers.SetHeader("X-Powered-By", "m_rpc_json.so");
83 response.headers.SetHeader("Content-Type", "application/json; charset=iso-8859-1");
84 response.headers.SetHeader("Connection", "Keep-Alive");
85 Request req((char*)&response, (Module*)this, event->GetSource());
91 void Implements(char* List)
96 virtual ~ModuleRpcJson()
98 ServerInstance->UnpublishInterface("JSON-RPC", this);
101 virtual Version GetVersion()
103 return Version(0, 1, 0, 0, VF_VENDOR, API_VERSION);
109 ValueIteratorBase::ValueIteratorBase ()
114 ValueIteratorBase::ValueIteratorBase (const Value::ObjectValues::iterator ¤t)
120 ValueIteratorBase::deref () const
122 return current_->second;
127 ValueIteratorBase::increment ()
134 ValueIteratorBase::decrement ()
140 ValueIteratorBase::difference_type
141 ValueIteratorBase::computeDistance (const SelfType &other) const
143 return difference_type (std::distance (current_, other.current_));
148 ValueIteratorBase::isEqual (const SelfType &other) const
150 return current_ == other.current_;
155 ValueIteratorBase::copy (const SelfType &other)
157 current_ = other.current_;
162 ValueIteratorBase::key () const
164 const Value::CZString czstring = (*current_).first;
165 if (czstring.c_str ())
167 if (czstring.isStaticString ())
168 return Value (StaticString (czstring.c_str ()));
169 return Value (czstring.c_str ());
171 return Value (czstring.index ());
176 ValueIteratorBase::index () const
178 const Value::CZString czstring = (*current_).first;
179 if (!czstring.c_str ())
180 return czstring.index ();
181 return unsigned (-1);
186 ValueIteratorBase::memberName () const
188 char const *name = (*current_).first.c_str ();
189 return name ? name : "";
193 ValueConstIterator::ValueConstIterator ()
198 ValueConstIterator::ValueConstIterator (const Value::ObjectValues::iterator ¤t)
199 : ValueIteratorBase (current)
204 ValueConstIterator::operator = (const ValueIteratorBase &other)
211 ValueIterator::ValueIterator ()
216 ValueIterator::ValueIterator (const Value::ObjectValues::iterator ¤t)
217 : ValueIteratorBase (current)
221 ValueIterator::ValueIterator (const ValueConstIterator &other)
222 : ValueIteratorBase (other)
226 ValueIterator::ValueIterator (const ValueIterator &other)
227 : ValueIteratorBase (other)
232 ValueIterator::operator = (const SelfType &other)
242 in (char c, char c1, char c2, char c3, char c4)
244 return c == c1 || c == c2 || c == c3 || c == c4;
248 in (char c, char c1, char c2, char c3, char c4, char c5)
250 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
259 Reader::parse (const std::string &document,
262 document_ = document;
263 char const *begin = document_.c_str ();
264 char const *end = begin + document_.length ();
265 return parse (begin, end, root);
269 Reader::parse (std::istream& sin,
273 std::getline (sin, doc, (char)EOF);
274 return parse (doc, root);
278 Reader::parse (char const *beginDoc, char const *endDOc,
287 while (!nodes_.empty ())
291 bool successful = readValue ();
302 while (token.type_ == tokenComment);
303 bool successful = true;
307 case tokenObjectBegin:
308 successful = readObject ();
310 case tokenArrayBegin:
311 successful = readArray ();
314 successful = decodeNumber (token);
317 successful = decodeString (token);
320 currentValue () = true;
323 currentValue () = false;
326 currentValue () = Value ();
329 return addError ("Syntax error: value, object or array expected.", token);
337 Reader::expectToken (TokenType type, Token &token, char const *message)
340 if (token.type_ != type)
341 return addError (message, token);
347 Reader::readToken (Token &token)
350 token.start_ = current_;
351 char c = getNextChar ();
356 token.type_ = tokenObjectBegin;
359 token.type_ = tokenObjectEnd;
362 token.type_ = tokenArrayBegin;
365 token.type_ = tokenArrayEnd;
368 token.type_ = tokenString;
376 case '0': case '1': case '2': case '3':
377 case '4': case '5': case '6': case '7':
381 token.type_ = tokenNumber;
385 token.type_ = tokenTrue;
386 ok = match ("rue", 3);
389 token.type_ = tokenFalse;
390 ok = match ("alse", 4);
393 token.type_ = tokenNull;
394 ok = match ("ull", 3);
397 token.type_ = tokenArraySeparator;
400 token.type_ = tokenMemberSeparator;
403 token.type_ = tokenEndOfStream;
410 token.type_ = tokenError;
411 token.end_ = current_;
417 Reader::skipSpaces ()
419 while (current_ != end_)
422 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
431 Reader::match (Location pattern, int patternLength)
433 if (end_ - current_ < patternLength)
435 int index = patternLength;
437 if (current_[index] != pattern[index])
439 current_ += patternLength;
445 Reader::readNumber ()
447 while (current_ != end_)
449 if (!(*current_ >= '0' && *current_ <= '9') &&
450 !in (*current_, '.', 'e', 'E', '+', '-'))
457 Reader::readString ()
460 while (current_ != end_)
473 Reader::readObject ()
477 currentValue () = Value (objectValue);
478 while (readToken (tokenName))
480 if (tokenName.type_ == tokenObjectEnd && name.empty ()) // empty object
482 if (tokenName.type_ != tokenString)
486 if (!decodeString (tokenName, name))
487 return recoverFromError (tokenObjectEnd);
490 if (!readToken (colon) || colon.type_ != tokenMemberSeparator)
492 return addErrorAndRecover ("Missing ':' after object member name",
496 Value &value = currentValue ()[ name ];
497 nodes_.push (&value);
498 bool ok = readValue ();
500 if (!ok) // error already set
501 return recoverFromError (tokenObjectEnd);
504 if (!readToken (comma)
505 || (comma.type_ != tokenObjectEnd &&
506 comma.type_ != tokenArraySeparator))
508 return addErrorAndRecover ("Missing ',' or '}' in object declaration",
512 if (comma.type_ == tokenObjectEnd)
515 return addErrorAndRecover ("Missing '}' or object member name",
524 currentValue () = Value (arrayValue);
526 if (*current_ == ']') // empty array
529 readToken (endArray);
535 Value &value = currentValue ()[ index++ ];
536 nodes_.push (&value);
537 bool ok = readValue ();
539 if (!ok) // error already set
540 return recoverFromError (tokenArrayEnd);
543 if (!readToken (token)
544 || (token.type_ != tokenArraySeparator &&
545 token.type_ != tokenArrayEnd))
547 return addErrorAndRecover ("Missing ',' or ']' in array declaration",
551 if (token.type_ == tokenArrayEnd)
559 Reader::decodeNumber (Token &token)
561 bool isDouble = false;
562 for (Location inspect = token.start_; inspect != token.end_; ++inspect)
565 || in (*inspect, '.', 'e', 'E', '+')
566 || (*inspect == '-' && inspect != token.start_);
569 return decodeDouble (token);
570 Location current = token.start_;
571 bool isNegative = *current == '-';
574 unsigned threshold = (isNegative ? unsigned (-Value::minInt)
575 : Value::maxUInt) / 10;
577 while (current < token.end_)
580 if (c < '0' || c > '9')
581 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
582 if (value >= threshold)
583 return decodeDouble (token);
584 value = value * 10 + unsigned (c - '0');
587 currentValue () = -int (value);
588 else if (value <= unsigned (Value::maxInt))
589 currentValue () = int (value);
591 currentValue () = value;
597 Reader::decodeDouble (Token &token)
600 const int bufferSize = 32;
602 int length = int (token.end_ - token.start_);
603 if (length <= bufferSize)
605 char buffer[bufferSize];
606 memcpy (buffer, token.start_, length);
608 count = sscanf (buffer, "%lf", &value);
612 std::string buffer (token.start_, token.end_);
613 count = sscanf (buffer.c_str (), "%lf", &value);
617 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
618 currentValue () = value;
624 Reader::decodeString (Token &token)
627 if (!decodeString (token, decoded))
629 currentValue () = decoded;
635 Reader::decodeString (Token &token, std::string &decoded)
637 Location current = token.start_ + 1; // skip '"'
638 Location end = token.end_ - 1; // do not include '"'
639 decoded.reserve (long (end - current));
641 while (current != end)
644 if (expect_false (c == '"'))
646 else if (expect_false (c == '\\'))
648 if (expect_false (current == end))
649 return addError ("Empty escape sequence in string", token, current);
650 char escape = *current++;
655 case '\\': decoded += escape; break;
657 case 'b': decoded += '\010'; break;
658 case 't': decoded += '\011'; break;
659 case 'n': decoded += '\012'; break;
660 case 'f': decoded += '\014'; break;
661 case 'r': decoded += '\015'; break;
665 if (!decodeUnicodeEscapeSequence (token, current, end, unicode))
667 // @todo encode unicode as utf8.
668 // @todo remember to alter the writer too.
672 return addError ("Bad escape sequence in string", token, current);
686 Reader::decodeUnicodeEscapeSequence (Token &token,
691 if (end - current < 4)
692 return addError ("Bad unicode escape sequence in string: four digits expected.", token, current);
694 for (int index = 0; index < 4; ++index)
698 if (c >= '0' && c <= '9')
700 else if (c >= 'a' && c <= 'f')
701 unicode += c - 'a' + 10;
702 else if (c >= 'A' && c <= 'F')
703 unicode += c - 'A' + 10;
705 return addError ("Bad unicode escape sequence in string: hexadecimal digit expected.", token, current);
712 Reader::addError (const std::string &message,
718 info.message_ = message;
720 errors_.push_back (info);
726 Reader::recoverFromError (TokenType skipUntilToken)
728 int errorCount = int (errors_.size ());
732 if (!readToken (skip))
733 errors_.resize (errorCount); // discard errors caused by recovery
734 if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
737 errors_.resize (errorCount);
743 Reader::addErrorAndRecover (const std::string &message,
745 TokenType skipUntilToken)
747 addError (message, token);
748 return recoverFromError (skipUntilToken);
753 Reader::currentValue ()
755 return *(nodes_.top ());
760 Reader::getNextChar ()
762 if (current_ == end_)
769 Reader::getLocationLineAndColumn (Location location,
773 Location current = begin_;
774 Location lastLineStart = current;
776 while (current < location && current != end_)
781 if (*current == '\n')
783 lastLineStart = current;
788 lastLineStart = current;
792 // column & line start at 1
793 column = int (location - lastLineStart) + 1;
799 Reader::getLocationLineAndColumn (Location location) const
802 getLocationLineAndColumn (location, line, column);
803 char buffer[18+16+16+1];
804 sprintf (buffer, "Line %d, Column %d", line, column);
810 Reader::error_msgs () const
812 std::string formattedMessage;
813 for (Errors::const_iterator itError = errors_.begin ();
814 itError != errors_.end ();
817 const ErrorInfo &error = *itError;
818 formattedMessage += "* " + getLocationLineAndColumn (error.token_.start_) + "\n";
819 formattedMessage += " " + error.message_ + "\n";
821 formattedMessage += "See " + getLocationLineAndColumn (error.extra_) + " for detail.\n";
823 return formattedMessage;
830 unreachable_internal (char const *file, int line, char const *function)
833 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
834 file, line, function);
836 throw std::runtime_error (buf);
840 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
843 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
844 file, line, function, condition);
846 throw std::runtime_error (buf);
850 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
853 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
854 file, line, function, message);
856 throw std::runtime_error (buf);
859 #define throw_unreachable unreachable_internal (__FILE__, __LINE__, CURFUNC)
860 #define throw_unless(condition) if (!expect_false (condition)) throw_unless_internal (__FILE__, __LINE__, CURFUNC, #condition)
861 #define throw_msg_unless(condition, message) if (!expect_false (condition)) throw_msg_unless_internal (__FILE__, __LINE__, CURFUNC, message)
863 const Value Value::null;
864 const int Value::minInt = int (~ (unsigned (-1)/2));
865 const int Value::maxInt = int (unsigned (-1)/2);
866 const unsigned Value::maxUInt = unsigned (-1);
868 ValueAllocator::~ValueAllocator ()
872 class DefaultValueAllocator : public ValueAllocator
875 virtual ~DefaultValueAllocator ()
879 virtual char *makeMemberName (char const *memberName)
881 return duplicateStringValue (memberName);
884 virtual void releaseMemberName (char *memberName)
886 releaseStringValue (memberName);
889 virtual char *duplicateStringValue (char const *value, unsigned length = unknown)
891 //@todo invesgate this old optimization
893 if (!value || value[0] == 0)
897 if (length == unknown)
898 length = (unsigned)strlen (value);
899 char *newString = static_cast<char *> (malloc (length + 1));
900 memcpy (newString, value, length);
901 newString[length] = 0;
905 virtual void releaseStringValue (char *value)
912 static ValueAllocator *&valueAllocator ()
914 static DefaultValueAllocator defaultAllocator;
915 static ValueAllocator *valueAllocator = &defaultAllocator;
916 return valueAllocator;
919 static struct DummyValueAllocatorInitializer {
920 DummyValueAllocatorInitializer ()
922 valueAllocator (); // ensure valueAllocator () statics are initialized before main ().
924 } dummyValueAllocatorInitializer;
928 Value::CZString::CZString (int index)
934 Value::CZString::CZString (char const *cstr, DuplicationPolicy allocate)
935 : cstr_ (allocate == duplicate ? valueAllocator()->makeMemberName (cstr)
941 Value::CZString::CZString (const CZString &other)
942 : cstr_ (other.index_ != noDuplication && other.cstr_ != 0
943 ? valueAllocator()->makeMemberName (other.cstr_)
945 , index_ (other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
950 Value::CZString::~CZString ()
952 if (cstr_ && index_ == duplicate)
953 valueAllocator()->releaseMemberName (const_cast<char *> (cstr_));
957 Value::CZString::swap (CZString &other)
959 std::swap (cstr_, other.cstr_);
960 std::swap (index_, other.index_);
964 Value::CZString::operator = (const CZString &other)
966 CZString temp (other);
972 Value::CZString::operator < (const CZString &other) const
975 return strcmp (cstr_, other.cstr_) < 0;
976 return index_ < other.index_;
980 Value::CZString::operator == (const CZString &other) const
983 return strcmp (cstr_, other.cstr_) == 0;
984 return index_ == other.index_;
989 Value::CZString::index () const
996 Value::CZString::c_str () const
1002 Value::CZString::isStaticString () const
1004 return index_ == noDuplication;
1008 // class Value::Value
1010 Value::Value (ValueType type)
1030 value_.map_ = new ObjectValues ();
1033 value_.bool_ = false;
1041 Value::Value (int value)
1044 value_.int_ = value;
1048 Value::Value (unsigned value)
1051 value_.uint_ = value;
1054 Value::Value (double value)
1057 value_.real_ = value;
1060 Value::Value (char const *value)
1061 : type_ (stringValue)
1064 value_.string_ = valueAllocator()->duplicateStringValue (value);
1067 Value::Value (const std::string &value)
1068 : type_ (stringValue)
1071 value_.string_ = valueAllocator()->duplicateStringValue (value.c_str (), (unsigned)value.length ());
1074 Value::Value (const StaticString &value)
1075 : type_ (stringValue)
1076 , allocated_ (false)
1078 value_.string_ = const_cast<char *> (value.c_str ());
1082 Value::Value (bool value)
1083 : type_ (booleanValue)
1085 value_.bool_ = value;
1089 Value::Value (const Value &other)
1090 : type_ (other.type_)
1099 value_ = other.value_;
1102 if (other.value_.string_)
1104 value_.string_ = valueAllocator()->duplicateStringValue (other.value_.string_);
1112 value_.map_ = new ObjectValues (*other.value_.map_);
1132 valueAllocator()->releaseStringValue (value_.string_);
1144 Value::operator = (const Value &other)
1152 Value::swap (Value &other)
1154 ValueType temp = type_;
1155 type_ = other.type_;
1157 std::swap (value_, other.value_);
1158 int temp2 = allocated_;
1159 allocated_ = other.allocated_;
1160 other.allocated_ = temp2;
1164 Value::type () const
1170 Value::operator < (const Value &other) const
1172 int typeDelta = type_ - other.type_;
1174 return typeDelta < 0 ? true : false;
1180 return value_.int_ < other.value_.int_;
1182 return value_.uint_ < other.value_.uint_;
1184 return value_.real_ < other.value_.real_;
1186 return value_.bool_ < other.value_.bool_;
1188 return (value_.string_ == 0 && other.value_.string_)
1189 || (other.value_.string_
1191 && strcmp (value_.string_, other.value_.string_) < 0);
1195 int delta = int (value_.map_->size () - other.value_.map_->size ());
1198 return (*value_.map_) < (*other.value_.map_);
1203 return 0; // unreachable
1207 Value::operator <= (const Value &other) const
1209 return !(other > *this);
1213 Value::operator >= (const Value &other) const
1215 return !(*this < other);
1219 Value::operator > (const Value &other) const
1221 return other < *this;
1225 Value::operator == (const Value &other) const
1227 if (type_ != other.type_)
1235 return value_.int_ == other.value_.int_;
1237 return value_.uint_ == other.value_.uint_;
1239 return value_.real_ == other.value_.real_;
1241 return value_.bool_ == other.value_.bool_;
1243 return (value_.string_ == other.value_.string_)
1244 || (other.value_.string_
1246 && strcmp (value_.string_, other.value_.string_) == 0);
1249 return value_.map_->size () == other.value_.map_->size ()
1250 && (*value_.map_) == (*other.value_.map_);
1254 return 0; // unreachable
1258 Value::operator != (const Value &other) const
1260 return !(*this == other);
1263 Value::operator char const * () const
1265 throw_unless (type_ == stringValue);
1266 return value_.string_;
1270 Value::operator std::string () const
1277 return value_.string_ ? value_.string_ : "";
1279 return value_.bool_ ? "true" : "false";
1285 throw_msg_unless (false, "Type is not convertible to string");
1289 return ""; // unreachable
1292 Value::operator int () const
1301 throw_msg_unless (value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
1302 return value_.uint_;
1304 throw_msg_unless (value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
1305 return int (value_.real_);
1307 return value_.bool_ ? 1 : 0;
1311 throw_msg_unless (false, "Type is not convertible to int");
1315 return 0; // unreachable;
1318 Value::operator unsigned () const
1325 throw_msg_unless (value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
1328 return value_.uint_;
1330 throw_msg_unless (value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
1331 return unsigned (value_.real_);
1333 return value_.bool_ ? 1 : 0;
1337 throw_msg_unless (false, "Type is not convertible to uint");
1341 return 0; // unreachable;
1344 Value::operator double () const
1353 return value_.uint_;
1355 return value_.real_;
1357 return value_.bool_ ? 1.0 : 0.0;
1361 throw_msg_unless (false, "Type is not convertible to double");
1365 return 0; // unreachable;
1368 Value::operator bool () const
1376 return value_.int_ != 0;
1378 return value_.real_ != 0.0;
1380 return value_.bool_;
1382 return value_.string_ && value_.string_[0] != 0;
1385 return value_.map_->size () != 0;
1389 return false; // unreachable;
1394 Value::isConvertibleTo (ValueType other) const
1401 return (other == nullValue && value_.int_ == 0)
1402 || other == intValue
1403 || (other == uintValue && value_.int_ >= 0)
1404 || other == realValue
1405 || other == stringValue
1406 || other == booleanValue;
1408 return (other == nullValue && value_.uint_ == 0)
1409 || (other == intValue && value_.uint_ <= (unsigned)maxInt)
1410 || other == uintValue
1411 || other == realValue
1412 || other == stringValue
1413 || other == booleanValue;
1415 return (other == nullValue && value_.real_ == 0.0)
1416 || (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt)
1417 || (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt)
1418 || other == realValue
1419 || other == stringValue
1420 || other == booleanValue;
1422 return (other == nullValue && value_.bool_ == false)
1423 || other == intValue
1424 || other == uintValue
1425 || other == realValue
1426 || other == stringValue
1427 || other == booleanValue;
1429 return other == stringValue
1430 || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
1432 return other == arrayValue
1433 || (other == nullValue && value_.map_->size () == 0);
1435 return other == objectValue
1436 || (other == nullValue && value_.map_->size () == 0);
1440 return false; // unreachable;
1444 /// Number of values in array or object
1446 Value::size () const
1457 case arrayValue: // size of the array is highest index + 1
1458 if (!value_.map_->empty ())
1460 ObjectValues::const_iterator itLast = value_.map_->end ();
1462 return itLast->first.index ()+1;
1466 return int (value_.map_->size ());
1470 return 0; // unreachable;
1475 Value::empty () const
1477 if (isNull () || isArray () || isObject ())
1478 return size () == 0u;
1485 Value::operator ! () const
1494 throw_unless (type_ == nullValue || type_ == arrayValue || type_ == objectValue);
1500 value_.map_->clear ();
1508 Value::resize (unsigned newSize)
1510 throw_unless (type_ == nullValue || type_ == arrayValue);
1511 if (type_ == nullValue)
1512 *this = Value (arrayValue);
1513 unsigned oldSize = size ();
1516 else if (newSize > oldSize)
1517 (*this)[ newSize - 1 ];
1520 for (unsigned index = newSize; index < oldSize; ++index)
1521 value_.map_->erase (index);
1522 throw_unless (size () == newSize);
1528 Value::operator [] (int index)
1530 return operator [] (static_cast<unsigned> (index));
1535 Value::operator [] (unsigned index)
1537 throw_unless (type_ == nullValue || type_ == arrayValue);
1538 if (type_ == nullValue)
1539 *this = Value (arrayValue);
1540 CZString key (index);
1541 ObjectValues::iterator it = value_.map_->lower_bound (key);
1542 if (it != value_.map_->end () && it->first == key)
1545 ObjectValues::value_type defaultValue (key, null);
1546 it = value_.map_->insert (it, defaultValue);
1552 Value::operator [] (int index) const
1554 return operator [] (static_cast<unsigned> (index));
1559 Value::operator [] (unsigned index) const
1561 throw_unless (type_ == nullValue || type_ == arrayValue);
1562 if (type_ == nullValue)
1564 CZString key (index);
1565 ObjectValues::const_iterator it = value_.map_->find (key);
1566 if (it == value_.map_->end ())
1573 Value::operator [] (char const *key)
1575 return resolveReference (key, false);
1580 Value::resolveReference (char const *key, bool isStatic)
1582 throw_unless (type_ == nullValue || type_ == objectValue);
1583 if (type_ == nullValue)
1584 *this = Value (objectValue);
1585 CZString actualKey (key, isStatic ? CZString::noDuplication
1586 : CZString::duplicateOnCopy);
1587 ObjectValues::iterator it = value_.map_->lower_bound (actualKey);
1588 if (it != value_.map_->end () && it->first == actualKey)
1591 ObjectValues::value_type defaultValue (actualKey, null);
1592 it = value_.map_->insert (it, defaultValue);
1593 Value &value = it->second;
1599 Value::get (int index, const Value &defaultValue) const
1601 return get (static_cast<unsigned> (index), defaultValue);
1606 Value::get (unsigned index, const Value &defaultValue) const
1608 const Value *value = &((*this)[index]);
1609 return value == &null ? defaultValue : *value;
1614 Value::isValidIndex (int index) const
1616 return isValidIndex (static_cast<unsigned> (index));
1621 Value::isValidIndex (unsigned index) const
1623 return index < size ();
1629 Value::operator [] (char const *key) const
1631 throw_unless (type_ == nullValue || type_ == objectValue);
1632 if (type_ == nullValue)
1634 CZString actualKey (key, CZString::noDuplication);
1635 ObjectValues::const_iterator it = value_.map_->find (actualKey);
1636 if (it == value_.map_->end ())
1643 Value::operator [] (const std::string &key)
1645 return (*this)[ key.c_str () ];
1650 Value::operator [] (const std::string &key) const
1652 return (*this)[ key.c_str () ];
1656 Value::operator [] (const StaticString &key)
1658 return resolveReference (key, true);
1663 Value::append (const Value &value)
1665 return (*this)[size ()] = value;
1670 Value::get (char const *key, const Value &defaultValue) const
1672 const Value *value = &((*this)[key]);
1673 return value == &null ? defaultValue : *value;
1678 Value::get (const std::string &key, const Value &defaultValue) const
1680 return get (key.c_str (), defaultValue);
1684 Value::removeMember (char const *key)
1686 throw_unless (type_ == nullValue || type_ == objectValue);
1687 if (type_ == nullValue)
1689 CZString actualKey (key, CZString::noDuplication);
1690 ObjectValues::iterator it = value_.map_->find (actualKey);
1691 if (it == value_.map_->end ())
1693 Value old (it->second);
1694 value_.map_->erase (it);
1699 Value::removeMember (const std::string &key)
1701 return removeMember (key.c_str ());
1705 Value::isMember (char const *key) const
1707 const Value *value = &((*this)[key]);
1708 return value != &null;
1713 Value::isMember (const std::string &key) const
1715 return isMember (key.c_str ());
1720 Value::getMemberNames () const
1722 throw_unless (type_ == nullValue || type_ == objectValue);
1723 if (type_ == nullValue)
1724 return Value::Members ();
1726 members.reserve (value_.map_->size ());
1727 ObjectValues::const_iterator it;
1728 ObjectValues::const_iterator itEnd = value_.map_->end ();
1729 for (it = value_.map_->begin (); it != itEnd; ++it)
1730 members.push_back (std::string (it->first.c_str()));
1735 Value::isNull () const
1737 return type_ == nullValue;
1742 Value::isBool () const
1744 return type_ == booleanValue;
1749 Value::isInt () const
1751 return type_ == intValue;
1756 Value::isUInt () const
1758 return type_ == uintValue;
1763 Value::isIntegral () const
1765 return type_ == intValue
1766 || type_ == uintValue
1767 || type_ == booleanValue;
1772 Value::isDouble () const
1774 return type_ == realValue;
1779 Value::isNumeric () const
1781 return isIntegral () || isDouble ();
1786 Value::isString () const
1788 return type_ == stringValue;
1793 Value::isArray () const
1795 return type_ == nullValue || type_ == arrayValue;
1800 Value::isObject () const
1802 return type_ == nullValue || type_ == objectValue;
1806 Value::const_iterator
1807 Value::begin () const
1814 return const_iterator (value_.map_->begin ());
1819 return const_iterator ();
1822 Value::const_iterator
1830 return const_iterator (value_.map_->end ());
1835 return const_iterator ();
1847 return iterator (value_.map_->begin ());
1863 return iterator (value_.map_->end ());
1874 static void uintToString (unsigned value,
1880 *--current = (value % 10) + '0';
1886 std::string valueToString (int value)
1889 char *current = buffer + sizeof (buffer);
1890 bool isNegative = value < 0;
1893 uintToString (unsigned (value), current);
1896 throw_unless (current >= buffer);
1901 std::string valueToString (unsigned value)
1904 char *current = buffer + sizeof (buffer);
1905 uintToString (value, current);
1906 throw_unless (current >= buffer);
1910 std::string valueToString (double value)
1913 sprintf (buffer, "%.16g", value);
1918 std::string valueToString (bool value)
1920 return value ? "true" : "false";
1923 std::string valueToQuotedString (char const *value)
1925 // Not sure how to handle unicode...
1926 if (std::strpbrk (value, "\"\\\b\f\n\r\t") == NULL)
1927 return std::string ("\"") + value + "\"";
1928 // We have to walk value and escape any special characters.
1929 // Appending to std::string is not efficient, but this should be rare.
1930 // (Note: forward slashes are *not* rare, but I am not escaping them.)
1931 unsigned maxsize = strlen (value) * 2 + 3; // allescaped+quotes+NULL
1933 result.reserve (maxsize); // to avoid lots of mallocs
1935 for (char const* c=value; *c != 0; ++c){
1959 // Even though \/ is considered a legal escape in JSON, a bare
1960 // slash is also legal, so I see no reason to escape it.
1961 // (I hope I am not misunderstanding something.)
1972 Writer::write (const Value &root)
1982 Writer::writeValue (const Value &value)
1984 switch (value.type ())
1987 document_ += "null";
1990 document_ += valueToString (static_cast<int> (value));
1993 document_ += valueToString (static_cast<unsigned> (value));
1996 document_ += valueToString (static_cast<double> (value));
1999 document_ += valueToQuotedString (static_cast<char const *> (value));
2002 document_ += valueToString (static_cast<bool> (value));
2007 int size = value.size ();
2008 for (int index = 0; index < size; ++index)
2012 writeValue (value[index]);
2019 Value::Members members (value.getMemberNames ());
2021 for (Value::Members::iterator it = members.begin ();
2022 it != members.end ();
2025 const std::string &name = *it;
2026 if (it != members.begin ())
2028 document_ += valueToQuotedString (name.c_str ());
2030 writeValue (value[name]);
2050 add_method (char *name, Module const *mod, method mth)
2052 mfp m = { mod, mth };
2057 service (HTTPRequest *http, Value &request, Value &response)
2059 char const *methodName = static_cast<char const *> (request["method"]);
2061 method_map::iterator mthit = methods.find (methodName);
2062 if (mthit != methods.end ())
2064 mfp m = mthit->second;
2065 Module *mod = new Module (*m.mod);
2067 (mod->*mth) (http, request, response);
2073 process (HTTPRequest *http, std::string &response_text, char const *request_text)
2077 Value request (objectValue);
2078 Value response (objectValue);
2082 response["error"] = Value(nullValue);
2083 response["result"] = Value(nullValue);
2085 parse_success = r.parse (request_text, request_text + strlen (request_text), request);
2087 response["id"] = request["id"];
2089 service (http, request, response);
2091 text = w.write (response);
2093 response_text = text.c_str ();
2100 MODULE_INIT(ModuleRpcJson)