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);
86 response.headers.SetHeader("X-Powered-By", "m_rpc_json.so");
87 response.headers.SetHeader("Content-Type", "application/json; charset=iso-8859-1");
88 response.headers.SetHeader("Connection", "Keep-Alive");
89 Request req((char*)&response, (Module*)this, event->GetSource());
95 void Implements(char* List)
100 virtual ~ModuleRpcJson()
102 ServerInstance->UnpublishInterface("JSON-RPC", this);
105 virtual Version GetVersion()
107 return Version(0, 1, 0, 0, VF_VENDOR, API_VERSION);
113 ValueIteratorBase::ValueIteratorBase ()
118 ValueIteratorBase::ValueIteratorBase (const Value::ObjectValues::iterator ¤t)
124 ValueIteratorBase::deref () const
126 return current_->second;
131 ValueIteratorBase::increment ()
138 ValueIteratorBase::decrement ()
144 ValueIteratorBase::difference_type
145 ValueIteratorBase::computeDistance (const SelfType &other) const
147 return difference_type (std::distance (current_, other.current_));
152 ValueIteratorBase::isEqual (const SelfType &other) const
154 return current_ == other.current_;
159 ValueIteratorBase::copy (const SelfType &other)
161 current_ = other.current_;
166 ValueIteratorBase::key () const
168 const Value::CZString czstring = (*current_).first;
169 if (czstring.c_str ())
171 if (czstring.isStaticString ())
172 return Value (StaticString (czstring.c_str ()));
173 return Value (czstring.c_str ());
175 return Value (czstring.index ());
180 ValueIteratorBase::index () const
182 const Value::CZString czstring = (*current_).first;
183 if (!czstring.c_str ())
184 return czstring.index ();
185 return unsigned (-1);
190 ValueIteratorBase::memberName () const
192 char const *name = (*current_).first.c_str ();
193 return name ? name : "";
197 ValueConstIterator::ValueConstIterator ()
202 ValueConstIterator::ValueConstIterator (const Value::ObjectValues::iterator ¤t)
203 : ValueIteratorBase (current)
208 ValueConstIterator::operator = (const ValueIteratorBase &other)
215 ValueIterator::ValueIterator ()
220 ValueIterator::ValueIterator (const Value::ObjectValues::iterator ¤t)
221 : ValueIteratorBase (current)
225 ValueIterator::ValueIterator (const ValueConstIterator &other)
226 : ValueIteratorBase (other)
230 ValueIterator::ValueIterator (const ValueIterator &other)
231 : ValueIteratorBase (other)
236 ValueIterator::operator = (const SelfType &other)
246 in (char c, char c1, char c2, char c3, char c4)
248 return c == c1 || c == c2 || c == c3 || c == c4;
252 in (char c, char c1, char c2, char c3, char c4, char c5)
254 return c == c1 || c == c2 || c == c3 || c == c4 || c == c5;
263 Reader::parse (const std::string &document,
266 document_ = document;
267 char const *begin = document_.c_str ();
268 char const *end = begin + document_.length ();
269 return parse (begin, end, root);
273 Reader::parse (std::istream& sin,
277 std::getline (sin, doc, (char)EOF);
278 return parse (doc, root);
282 Reader::parse (char const *beginDoc, char const *endDOc,
291 while (!nodes_.empty ())
295 bool successful = readValue ();
306 while (token.type_ == tokenComment);
307 bool successful = true;
311 case tokenObjectBegin:
312 successful = readObject ();
314 case tokenArrayBegin:
315 successful = readArray ();
318 successful = decodeNumber (token);
321 successful = decodeString (token);
324 currentValue () = true;
327 currentValue () = false;
330 currentValue () = Value ();
333 return addError ("Syntax error: value, object or array expected.", token);
341 Reader::expectToken (TokenType type, Token &token, char const *message)
344 if (token.type_ != type)
345 return addError (message, token);
351 Reader::readToken (Token &token)
354 token.start_ = current_;
355 char c = getNextChar ();
360 token.type_ = tokenObjectBegin;
363 token.type_ = tokenObjectEnd;
366 token.type_ = tokenArrayBegin;
369 token.type_ = tokenArrayEnd;
372 token.type_ = tokenString;
380 case '0': case '1': case '2': case '3':
381 case '4': case '5': case '6': case '7':
385 token.type_ = tokenNumber;
389 token.type_ = tokenTrue;
390 ok = match ("rue", 3);
393 token.type_ = tokenFalse;
394 ok = match ("alse", 4);
397 token.type_ = tokenNull;
398 ok = match ("ull", 3);
401 token.type_ = tokenArraySeparator;
404 token.type_ = tokenMemberSeparator;
407 token.type_ = tokenEndOfStream;
414 token.type_ = tokenError;
415 token.end_ = current_;
421 Reader::skipSpaces ()
423 while (current_ != end_)
426 if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
435 Reader::match (Location pattern, int patternLength)
437 if (end_ - current_ < patternLength)
439 int index = patternLength;
441 if (current_[index] != pattern[index])
443 current_ += patternLength;
449 Reader::readNumber ()
451 while (current_ != end_)
453 if (!(*current_ >= '0' && *current_ <= '9') &&
454 !in (*current_, '.', 'e', 'E', '+', '-'))
461 Reader::readString ()
464 while (current_ != end_)
477 Reader::readObject ()
481 currentValue () = Value (objectValue);
482 while (readToken (tokenName))
484 if (tokenName.type_ == tokenObjectEnd && name.empty ()) // empty object
486 if (tokenName.type_ != tokenString)
490 if (!decodeString (tokenName, name))
491 return recoverFromError (tokenObjectEnd);
494 if (!readToken (colon) || colon.type_ != tokenMemberSeparator)
496 return addErrorAndRecover ("Missing ':' after object member name",
500 Value &value = currentValue ()[ name ];
501 nodes_.push (&value);
502 bool ok = readValue ();
504 if (!ok) // error already set
505 return recoverFromError (tokenObjectEnd);
508 if (!readToken (comma)
509 || (comma.type_ != tokenObjectEnd &&
510 comma.type_ != tokenArraySeparator))
512 return addErrorAndRecover ("Missing ',' or '}' in object declaration",
516 if (comma.type_ == tokenObjectEnd)
519 return addErrorAndRecover ("Missing '}' or object member name",
528 currentValue () = Value (arrayValue);
530 if (*current_ == ']') // empty array
533 readToken (endArray);
539 Value &value = currentValue ()[ index++ ];
540 nodes_.push (&value);
541 bool ok = readValue ();
543 if (!ok) // error already set
544 return recoverFromError (tokenArrayEnd);
547 if (!readToken (token)
548 || (token.type_ != tokenArraySeparator &&
549 token.type_ != tokenArrayEnd))
551 return addErrorAndRecover ("Missing ',' or ']' in array declaration",
555 if (token.type_ == tokenArrayEnd)
563 Reader::decodeNumber (Token &token)
565 bool isDouble = false;
566 for (Location inspect = token.start_; inspect != token.end_; ++inspect)
569 || in (*inspect, '.', 'e', 'E', '+')
570 || (*inspect == '-' && inspect != token.start_);
573 return decodeDouble (token);
574 Location current = token.start_;
575 bool isNegative = *current == '-';
578 unsigned threshold = (isNegative ? unsigned (-Value::minInt)
579 : Value::maxUInt) / 10;
581 while (current < token.end_)
584 if (c < '0' || c > '9')
585 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
586 if (value >= threshold)
587 return decodeDouble (token);
588 value = value * 10 + unsigned (c - '0');
591 currentValue () = -int (value);
592 else if (value <= unsigned (Value::maxInt))
593 currentValue () = int (value);
595 currentValue () = value;
601 Reader::decodeDouble (Token &token)
604 const int bufferSize = 32;
606 int length = int (token.end_ - token.start_);
607 if (length <= bufferSize)
609 char buffer[bufferSize];
610 memcpy (buffer, token.start_, length);
612 count = sscanf (buffer, "%lf", &value);
616 std::string buffer (token.start_, token.end_);
617 count = sscanf (buffer.c_str (), "%lf", &value);
621 return addError ("'" + std::string (token.start_, token.end_) + "' is not a number.", token);
622 currentValue () = value;
628 Reader::decodeString (Token &token)
631 if (!decodeString (token, decoded))
633 currentValue () = decoded;
639 Reader::decodeString (Token &token, std::string &decoded)
641 Location current = token.start_ + 1; // skip '"'
642 Location end = token.end_ - 1; // do not include '"'
643 decoded.reserve (long (end - current));
645 while (current != end)
648 if (expect_false (c == '"'))
650 else if (expect_false (c == '\\'))
652 if (expect_false (current == end))
653 return addError ("Empty escape sequence in string", token, current);
654 char escape = *current++;
659 case '\\': decoded += escape; break;
661 case 'b': decoded += '\010'; break;
662 case 't': decoded += '\011'; break;
663 case 'n': decoded += '\012'; break;
664 case 'f': decoded += '\014'; break;
665 case 'r': decoded += '\015'; break;
669 if (!decodeUnicodeEscapeSequence (token, current, end, unicode))
671 // @todo encode unicode as utf8.
672 // @todo remember to alter the writer too.
676 return addError ("Bad escape sequence in string", token, current);
690 Reader::decodeUnicodeEscapeSequence (Token &token,
695 if (end - current < 4)
696 return addError ("Bad unicode escape sequence in string: four digits expected.", token, current);
698 for (int index = 0; index < 4; ++index)
702 if (c >= '0' && c <= '9')
704 else if (c >= 'a' && c <= 'f')
705 unicode += c - 'a' + 10;
706 else if (c >= 'A' && c <= 'F')
707 unicode += c - 'A' + 10;
709 return addError ("Bad unicode escape sequence in string: hexadecimal digit expected.", token, current);
716 Reader::addError (const std::string &message,
722 info.message_ = message;
724 errors_.push_back (info);
730 Reader::recoverFromError (TokenType skipUntilToken)
732 int errorCount = int (errors_.size ());
736 if (!readToken (skip))
737 errors_.resize (errorCount); // discard errors caused by recovery
738 if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
741 errors_.resize (errorCount);
747 Reader::addErrorAndRecover (const std::string &message,
749 TokenType skipUntilToken)
751 addError (message, token);
752 return recoverFromError (skipUntilToken);
757 Reader::currentValue ()
759 return *(nodes_.top ());
764 Reader::getNextChar ()
766 if (current_ == end_)
773 Reader::getLocationLineAndColumn (Location location,
777 Location current = begin_;
778 Location lastLineStart = current;
780 while (current < location && current != end_)
785 if (*current == '\n')
787 lastLineStart = current;
792 lastLineStart = current;
796 // column & line start at 1
797 column = int (location - lastLineStart) + 1;
803 Reader::getLocationLineAndColumn (Location location) const
806 getLocationLineAndColumn (location, line, column);
807 char buffer[18+16+16+1];
808 sprintf (buffer, "Line %d, Column %d", line, column);
814 Reader::error_msgs () const
816 std::string formattedMessage;
817 for (Errors::const_iterator itError = errors_.begin ();
818 itError != errors_.end ();
821 const ErrorInfo &error = *itError;
822 formattedMessage += "* " + getLocationLineAndColumn (error.token_.start_) + "\n";
823 formattedMessage += " " + error.message_ + "\n";
825 formattedMessage += "See " + getLocationLineAndColumn (error.extra_) + " for detail.\n";
827 return formattedMessage;
834 unreachable_internal (char const *file, int line, char const *function)
837 snprintf (buf, 1024, "%s (%d) [%s] critical: Unreachable line reached.",
838 file, line, function);
840 throw std::runtime_error (buf);
844 throw_unless_internal (char const *file, int line, char const *function, char const *condition)
847 snprintf (buf, 1024, "%s (%d) [%s] critical: Assertion `%s' failed.",
848 file, line, function, condition);
850 throw std::runtime_error (buf);
854 throw_msg_unless_internal (char const *file, int line, char const *function, char const *message)
857 snprintf (buf, 1024, "%s (%d) [%s] critical: %s.",
858 file, line, function, message);
860 throw std::runtime_error (buf);
863 #define throw_unreachable unreachable_internal (__FILE__, __LINE__, CURFUNC)
864 #define throw_unless(condition) if (!expect_false (condition)) throw_unless_internal (__FILE__, __LINE__, CURFUNC, #condition)
865 #define throw_msg_unless(condition, message) if (!expect_false (condition)) throw_msg_unless_internal (__FILE__, __LINE__, CURFUNC, message)
867 const Value Value::null;
868 const int Value::minInt = int (~ (unsigned (-1)/2));
869 const int Value::maxInt = int (unsigned (-1)/2);
870 const unsigned Value::maxUInt = unsigned (-1);
872 ValueAllocator::~ValueAllocator ()
876 class DefaultValueAllocator : public ValueAllocator
879 virtual ~DefaultValueAllocator ()
883 virtual char *makeMemberName (char const *memberName)
885 return duplicateStringValue (memberName);
888 virtual void releaseMemberName (char *memberName)
890 releaseStringValue (memberName);
893 virtual char *duplicateStringValue (char const *value, unsigned length = unknown)
895 //@todo invesgate this old optimization
897 if (!value || value[0] == 0)
901 if (length == unknown)
902 length = (unsigned)strlen (value);
903 char *newString = static_cast<char *> (malloc (length + 1));
904 memcpy (newString, value, length);
905 newString[length] = 0;
909 virtual void releaseStringValue (char *value)
916 static ValueAllocator *&valueAllocator ()
918 static DefaultValueAllocator defaultAllocator;
919 static ValueAllocator *valueAllocator = &defaultAllocator;
920 return valueAllocator;
923 static struct DummyValueAllocatorInitializer {
924 DummyValueAllocatorInitializer ()
926 valueAllocator (); // ensure valueAllocator () statics are initialized before main ().
928 } dummyValueAllocatorInitializer;
932 Value::CZString::CZString (int index)
938 Value::CZString::CZString (char const *cstr, DuplicationPolicy allocate)
939 : cstr_ (allocate == duplicate ? valueAllocator()->makeMemberName (cstr)
945 Value::CZString::CZString (const CZString &other)
946 : cstr_ (other.index_ != noDuplication && other.cstr_ != 0
947 ? valueAllocator()->makeMemberName (other.cstr_)
949 , index_ (other.cstr_ ? (other.index_ == noDuplication ? noDuplication : duplicate)
954 Value::CZString::~CZString ()
956 if (cstr_ && index_ == duplicate)
957 valueAllocator()->releaseMemberName (const_cast<char *> (cstr_));
961 Value::CZString::swap (CZString &other)
963 std::swap (cstr_, other.cstr_);
964 std::swap (index_, other.index_);
968 Value::CZString::operator = (const CZString &other)
970 CZString temp (other);
976 Value::CZString::operator < (const CZString &other) const
979 return strcmp (cstr_, other.cstr_) < 0;
980 return index_ < other.index_;
984 Value::CZString::operator == (const CZString &other) const
987 return strcmp (cstr_, other.cstr_) == 0;
988 return index_ == other.index_;
993 Value::CZString::index () const
1000 Value::CZString::c_str () const
1006 Value::CZString::isStaticString () const
1008 return index_ == noDuplication;
1012 // class Value::Value
1014 Value::Value (ValueType type)
1034 value_.map_ = new ObjectValues ();
1037 value_.bool_ = false;
1045 Value::Value (int value)
1048 value_.int_ = value;
1052 Value::Value (unsigned value)
1055 value_.uint_ = value;
1058 Value::Value (double value)
1061 value_.real_ = value;
1064 Value::Value (char const *value)
1065 : type_ (stringValue)
1068 value_.string_ = valueAllocator()->duplicateStringValue (value);
1071 Value::Value (const std::string &value)
1072 : type_ (stringValue)
1075 value_.string_ = valueAllocator()->duplicateStringValue (value.c_str (), (unsigned)value.length ());
1078 Value::Value (const StaticString &value)
1079 : type_ (stringValue)
1080 , allocated_ (false)
1082 value_.string_ = const_cast<char *> (value.c_str ());
1086 Value::Value (bool value)
1087 : type_ (booleanValue)
1089 value_.bool_ = value;
1093 Value::Value (const Value &other)
1094 : type_ (other.type_)
1103 value_ = other.value_;
1106 if (other.value_.string_)
1108 value_.string_ = valueAllocator()->duplicateStringValue (other.value_.string_);
1116 value_.map_ = new ObjectValues (*other.value_.map_);
1136 valueAllocator()->releaseStringValue (value_.string_);
1148 Value::operator = (const Value &other)
1156 Value::swap (Value &other)
1158 ValueType temp = type_;
1159 type_ = other.type_;
1161 std::swap (value_, other.value_);
1162 int temp2 = allocated_;
1163 allocated_ = other.allocated_;
1164 other.allocated_ = temp2;
1168 Value::type () const
1174 Value::operator < (const Value &other) const
1176 int typeDelta = type_ - other.type_;
1178 return typeDelta < 0 ? true : false;
1184 return value_.int_ < other.value_.int_;
1186 return value_.uint_ < other.value_.uint_;
1188 return value_.real_ < other.value_.real_;
1190 return value_.bool_ < other.value_.bool_;
1192 return (value_.string_ == 0 && other.value_.string_)
1193 || (other.value_.string_
1195 && strcmp (value_.string_, other.value_.string_) < 0);
1199 int delta = int (value_.map_->size () - other.value_.map_->size ());
1202 return (*value_.map_) < (*other.value_.map_);
1207 return 0; // unreachable
1211 Value::operator <= (const Value &other) const
1213 return !(other > *this);
1217 Value::operator >= (const Value &other) const
1219 return !(*this < other);
1223 Value::operator > (const Value &other) const
1225 return other < *this;
1229 Value::operator == (const Value &other) const
1231 if (type_ != other.type_)
1239 return value_.int_ == other.value_.int_;
1241 return value_.uint_ == other.value_.uint_;
1243 return value_.real_ == other.value_.real_;
1245 return value_.bool_ == other.value_.bool_;
1247 return (value_.string_ == other.value_.string_)
1248 || (other.value_.string_
1250 && strcmp (value_.string_, other.value_.string_) == 0);
1253 return value_.map_->size () == other.value_.map_->size ()
1254 && (*value_.map_) == (*other.value_.map_);
1258 return 0; // unreachable
1262 Value::operator != (const Value &other) const
1264 return !(*this == other);
1267 Value::operator char const * () const
1269 throw_unless (type_ == stringValue);
1270 return value_.string_;
1274 Value::operator std::string () const
1281 return value_.string_ ? value_.string_ : "";
1283 return value_.bool_ ? "true" : "false";
1289 throw_msg_unless (false, "Type is not convertible to string");
1293 return ""; // unreachable
1296 Value::operator int () const
1305 throw_msg_unless (value_.uint_ < (unsigned)maxInt, "integer out of signed integer range");
1306 return value_.uint_;
1308 throw_msg_unless (value_.real_ >= minInt && value_.real_ <= maxInt, "Real out of signed integer range");
1309 return int (value_.real_);
1311 return value_.bool_ ? 1 : 0;
1315 throw_msg_unless (false, "Type is not convertible to int");
1319 return 0; // unreachable;
1322 Value::operator unsigned () const
1329 throw_msg_unless (value_.int_ >= 0, "Negative integer can not be converted to unsigned integer");
1332 return value_.uint_;
1334 throw_msg_unless (value_.real_ >= 0 && value_.real_ <= maxUInt, "Real out of unsigned integer range");
1335 return unsigned (value_.real_);
1337 return value_.bool_ ? 1 : 0;
1341 throw_msg_unless (false, "Type is not convertible to uint");
1345 return 0; // unreachable;
1348 Value::operator double () const
1357 return value_.uint_;
1359 return value_.real_;
1361 return value_.bool_ ? 1.0 : 0.0;
1365 throw_msg_unless (false, "Type is not convertible to double");
1369 return 0; // unreachable;
1372 Value::operator bool () const
1380 return value_.int_ != 0;
1382 return value_.real_ != 0.0;
1384 return value_.bool_;
1386 return value_.string_ && value_.string_[0] != 0;
1389 return value_.map_->size () != 0;
1393 return false; // unreachable;
1398 Value::isConvertibleTo (ValueType other) const
1405 return (other == nullValue && value_.int_ == 0)
1406 || other == intValue
1407 || (other == uintValue && value_.int_ >= 0)
1408 || other == realValue
1409 || other == stringValue
1410 || other == booleanValue;
1412 return (other == nullValue && value_.uint_ == 0)
1413 || (other == intValue && value_.uint_ <= (unsigned)maxInt)
1414 || other == uintValue
1415 || other == realValue
1416 || other == stringValue
1417 || other == booleanValue;
1419 return (other == nullValue && value_.real_ == 0.0)
1420 || (other == intValue && value_.real_ >= minInt && value_.real_ <= maxInt)
1421 || (other == uintValue && value_.real_ >= 0 && value_.real_ <= maxUInt)
1422 || other == realValue
1423 || other == stringValue
1424 || other == booleanValue;
1426 return (other == nullValue && value_.bool_ == false)
1427 || other == intValue
1428 || other == uintValue
1429 || other == realValue
1430 || other == stringValue
1431 || other == booleanValue;
1433 return other == stringValue
1434 || (other == nullValue && (!value_.string_ || value_.string_[0] == 0));
1436 return other == arrayValue
1437 || (other == nullValue && value_.map_->size () == 0);
1439 return other == objectValue
1440 || (other == nullValue && value_.map_->size () == 0);
1444 return false; // unreachable;
1448 /// Number of values in array or object
1450 Value::size () const
1461 case arrayValue: // size of the array is highest index + 1
1462 if (!value_.map_->empty ())
1464 ObjectValues::const_iterator itLast = value_.map_->end ();
1466 return itLast->first.index ()+1;
1470 return int (value_.map_->size ());
1474 return 0; // unreachable;
1479 Value::empty () const
1481 if (isNull () || isArray () || isObject ())
1482 return size () == 0u;
1489 Value::operator ! () const
1498 throw_unless (type_ == nullValue || type_ == arrayValue || type_ == objectValue);
1504 value_.map_->clear ();
1512 Value::resize (unsigned newSize)
1514 throw_unless (type_ == nullValue || type_ == arrayValue);
1515 if (type_ == nullValue)
1516 *this = Value (arrayValue);
1517 unsigned oldSize = size ();
1520 else if (newSize > oldSize)
1521 (*this)[ newSize - 1 ];
1524 for (unsigned index = newSize; index < oldSize; ++index)
1525 value_.map_->erase (index);
1526 throw_unless (size () == newSize);
1532 Value::operator [] (int index)
1534 return operator [] (static_cast<unsigned> (index));
1539 Value::operator [] (unsigned index)
1541 throw_unless (type_ == nullValue || type_ == arrayValue);
1542 if (type_ == nullValue)
1543 *this = Value (arrayValue);
1544 CZString key (index);
1545 ObjectValues::iterator it = value_.map_->lower_bound (key);
1546 if (it != value_.map_->end () && it->first == key)
1549 ObjectValues::value_type defaultValue (key, null);
1550 it = value_.map_->insert (it, defaultValue);
1556 Value::operator [] (int index) const
1558 return operator [] (static_cast<unsigned> (index));
1563 Value::operator [] (unsigned index) const
1565 throw_unless (type_ == nullValue || type_ == arrayValue);
1566 if (type_ == nullValue)
1568 CZString key (index);
1569 ObjectValues::const_iterator it = value_.map_->find (key);
1570 if (it == value_.map_->end ())
1577 Value::operator [] (char const *key)
1579 return resolveReference (key, false);
1584 Value::resolveReference (char const *key, bool isStatic)
1586 throw_unless (type_ == nullValue || type_ == objectValue);
1587 if (type_ == nullValue)
1588 *this = Value (objectValue);
1589 CZString actualKey (key, isStatic ? CZString::noDuplication
1590 : CZString::duplicateOnCopy);
1591 ObjectValues::iterator it = value_.map_->lower_bound (actualKey);
1592 if (it != value_.map_->end () && it->first == actualKey)
1595 ObjectValues::value_type defaultValue (actualKey, null);
1596 it = value_.map_->insert (it, defaultValue);
1597 Value &value = it->second;
1603 Value::get (int index, const Value &defaultValue) const
1605 return get (static_cast<unsigned> (index), defaultValue);
1610 Value::get (unsigned index, const Value &defaultValue) const
1612 const Value *value = &((*this)[index]);
1613 return value == &null ? defaultValue : *value;
1618 Value::isValidIndex (int index) const
1620 return isValidIndex (static_cast<unsigned> (index));
1625 Value::isValidIndex (unsigned index) const
1627 return index < size ();
1633 Value::operator [] (char const *key) const
1635 throw_unless (type_ == nullValue || type_ == objectValue);
1636 if (type_ == nullValue)
1638 CZString actualKey (key, CZString::noDuplication);
1639 ObjectValues::const_iterator it = value_.map_->find (actualKey);
1640 if (it == value_.map_->end ())
1647 Value::operator [] (const std::string &key)
1649 return (*this)[ key.c_str () ];
1654 Value::operator [] (const std::string &key) const
1656 return (*this)[ key.c_str () ];
1660 Value::operator [] (const StaticString &key)
1662 return resolveReference (key, true);
1667 Value::append (const Value &value)
1669 return (*this)[size ()] = value;
1674 Value::get (char const *key, const Value &defaultValue) const
1676 const Value *value = &((*this)[key]);
1677 return value == &null ? defaultValue : *value;
1682 Value::get (const std::string &key, const Value &defaultValue) const
1684 return get (key.c_str (), defaultValue);
1688 Value::removeMember (char const *key)
1690 throw_unless (type_ == nullValue || type_ == objectValue);
1691 if (type_ == nullValue)
1693 CZString actualKey (key, CZString::noDuplication);
1694 ObjectValues::iterator it = value_.map_->find (actualKey);
1695 if (it == value_.map_->end ())
1697 Value old (it->second);
1698 value_.map_->erase (it);
1703 Value::removeMember (const std::string &key)
1705 return removeMember (key.c_str ());
1709 Value::isMember (char const *key) const
1711 const Value *value = &((*this)[key]);
1712 return value != &null;
1717 Value::isMember (const std::string &key) const
1719 return isMember (key.c_str ());
1724 Value::getMemberNames () const
1726 throw_unless (type_ == nullValue || type_ == objectValue);
1727 if (type_ == nullValue)
1728 return Value::Members ();
1730 members.reserve (value_.map_->size ());
1731 ObjectValues::const_iterator it;
1732 ObjectValues::const_iterator itEnd = value_.map_->end ();
1733 for (it = value_.map_->begin (); it != itEnd; ++it)
1734 members.push_back (std::string (it->first.c_str()));
1739 Value::isNull () const
1741 return type_ == nullValue;
1746 Value::isBool () const
1748 return type_ == booleanValue;
1753 Value::isInt () const
1755 return type_ == intValue;
1760 Value::isUInt () const
1762 return type_ == uintValue;
1767 Value::isIntegral () const
1769 return type_ == intValue
1770 || type_ == uintValue
1771 || type_ == booleanValue;
1776 Value::isDouble () const
1778 return type_ == realValue;
1783 Value::isNumeric () const
1785 return isIntegral () || isDouble ();
1790 Value::isString () const
1792 return type_ == stringValue;
1797 Value::isArray () const
1799 return type_ == nullValue || type_ == arrayValue;
1804 Value::isObject () const
1806 return type_ == nullValue || type_ == objectValue;
1810 Value::const_iterator
1811 Value::begin () const
1818 return const_iterator (value_.map_->begin ());
1823 return const_iterator ();
1826 Value::const_iterator
1834 return const_iterator (value_.map_->end ());
1839 return const_iterator ();
1851 return iterator (value_.map_->begin ());
1867 return iterator (value_.map_->end ());
1878 static void uintToString (unsigned value,
1884 *--current = (value % 10) + '0';
1890 std::string valueToString (int value)
1893 char *current = buffer + sizeof (buffer);
1894 bool isNegative = value < 0;
1897 uintToString (unsigned (value), current);
1900 throw_unless (current >= buffer);
1905 std::string valueToString (unsigned value)
1908 char *current = buffer + sizeof (buffer);
1909 uintToString (value, current);
1910 throw_unless (current >= buffer);
1914 std::string valueToString (double value)
1917 sprintf (buffer, "%.16g", value);
1922 std::string valueToString (bool value)
1924 return value ? "true" : "false";
1927 std::string valueToQuotedString (char const *value)
1929 // Not sure how to handle unicode...
1930 if (std::strpbrk (value, "\"\\\b\f\n\r\t") == NULL)
1931 return std::string ("\"") + value + "\"";
1932 // We have to walk value and escape any special characters.
1933 // Appending to std::string is not efficient, but this should be rare.
1934 // (Note: forward slashes are *not* rare, but I am not escaping them.)
1935 unsigned maxsize = strlen (value) * 2 + 3; // allescaped+quotes+NULL
1937 result.reserve (maxsize); // to avoid lots of mallocs
1939 for (char const* c=value; *c != 0; ++c){
1963 // Even though \/ is considered a legal escape in JSON, a bare
1964 // slash is also legal, so I see no reason to escape it.
1965 // (I hope I am not misunderstanding something.)
1976 Writer::write (const Value &root)
1986 Writer::writeValue (const Value &value)
1988 switch (value.type ())
1991 document_ += "null";
1994 document_ += valueToString (static_cast<int> (value));
1997 document_ += valueToString (static_cast<unsigned> (value));
2000 document_ += valueToString (static_cast<double> (value));
2003 document_ += valueToQuotedString (static_cast<char const *> (value));
2006 document_ += valueToString (static_cast<bool> (value));
2011 int size = value.size ();
2012 for (int index = 0; index < size; ++index)
2016 writeValue (value[index]);
2023 Value::Members members (value.getMemberNames ());
2025 for (Value::Members::iterator it = members.begin ();
2026 it != members.end ();
2029 const std::string &name = *it;
2030 if (it != members.begin ())
2032 document_ += valueToQuotedString (name.c_str ());
2034 writeValue (value[name]);
2054 add_method (char *name, Module const *mod, method mth)
2056 mfp m = { mod, mth };
2061 service (HTTPRequest *http, Value &request, Value &response)
2063 char const *methodName = static_cast<char const *> (request["method"]);
2065 method_map::iterator mthit = methods.find (methodName);
2066 if (mthit != methods.end ())
2068 mfp m = mthit->second;
2069 Module *mod = new Module (*m.mod);
2071 (mod->*mth) (http, request, response);
2077 process (HTTPRequest *http, std::string &response_text, char const *request_text)
2081 Value request (objectValue);
2082 Value response (objectValue);
2086 response["error"] = Value(nullValue);
2087 response["result"] = Value(nullValue);
2089 parse_success = r.parse (request_text, request_text + strlen (request_text), request);
2091 response["id"] = request["id"];
2093 service (http, request, response);
2095 text = w.write (response);
2097 response_text = text.c_str ();
2104 MODULE_INIT(ModuleRpcJson)