Commit b86ef7b3 authored by Vitaly Takmazov's avatar Vitaly Takmazov

Switch twitter backend to jsoncpp too

parent 88574150
......@@ -6,7 +6,7 @@ find_package(CURL)
if(CURL_FOUND)
message(STATUS "Using curl ${CURL_VERSION_STRING}: ${CURL_INCLUDE_DIRS} ${CURL_LIBRARIES}")
include_directories (${CURL_INCLUDE_DIRS})
include_directories (${CURL_INCLUDE_DIRS} ${JSONCPP_INCLUDE_DIRS})
target_link_libraries(spectrum2_twitter_backend transport ${CURL_LIBRARIES} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
else()
message(FATAL_ERROR "curl not found")
......
......@@ -49,88 +49,88 @@ static std::string toIsoTime(std::string in) {
return ss.str();
}
EmbeddedStatus getEmbeddedStatus(const rapidjson::Value &element)
EmbeddedStatus getEmbeddedStatus(const Json::Value &element)
{
EmbeddedStatus status;
if(!element.IsObject()) {
if(!element.isObject()) {
LOG4CXX_ERROR(logger, "Not a status element!");
return status;
}
status.setCreationTime( toIsoTime ( std::string( element[TwitterReponseTypes::created_at.c_str()].GetString() ) ) );
status.setID( stringOf( element[TwitterReponseTypes::id.c_str()].GetInt64() ) );
status.setTweet( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ), getUrlEntities(element) ) );
status.setTruncated( element[TwitterReponseTypes::truncated.c_str()].GetBool());
status.setReplyToStatusID( element[TwitterReponseTypes::in_reply_to_status_id.c_str()].IsNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_status_id.c_str()].GetInt64()) );
status.setReplyToUserID( element[TwitterReponseTypes::in_reply_to_user_id.c_str()].IsNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_user_id.c_str()].GetInt64()) );
status.setReplyToScreenName( element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].IsNull() ?
"" : std::string(element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].GetString()) );
status.setRetweetCount( element[TwitterReponseTypes::retweet_count.c_str()].GetInt64() );
status.setFavorited( element[TwitterReponseTypes::favorited.c_str()].GetBool() );
status.setRetweeted( element[TwitterReponseTypes::retweeted.c_str()].GetBool());
status.setCreationTime( toIsoTime ( element[TwitterReponseTypes::created_at.c_str()].asString() ) );
status.setID( stringOf( element[TwitterReponseTypes::id.c_str()].asInt64() ) );
status.setTweet( unescape ( element[TwitterReponseTypes::text.c_str()].asString(), getUrlEntities(element) ) );
status.setTruncated( element[TwitterReponseTypes::truncated.c_str()].asBool());
status.setReplyToStatusID( element[TwitterReponseTypes::in_reply_to_status_id.c_str()].isNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_status_id.c_str()].asInt64()) );
status.setReplyToUserID( element[TwitterReponseTypes::in_reply_to_user_id.c_str()].isNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_user_id.c_str()].asInt64()) );
status.setReplyToScreenName( element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].isNull() ?
"" : element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].asString() );
status.setRetweetCount( element[TwitterReponseTypes::retweet_count.c_str()].asInt64() );
status.setFavorited( element[TwitterReponseTypes::favorited.c_str()].asBool() );
status.setRetweeted( element[TwitterReponseTypes::retweeted.c_str()].asBool());
return status;
}
User getUser(const rapidjson::Value &element)
User getUser(const Json::Value &element)
{
User user;
if(!element.IsObject()) {
if(!element.isObject()) {
LOG4CXX_ERROR(logger, "Not a user element!");
return user;
}
user.setUserID( stringOf( element[TwitterReponseTypes::id.c_str()].GetInt64() ) );
user.setScreenName( tolowercase( std::string( element[TwitterReponseTypes::screen_name.c_str()].GetString() ) ) );
user.setUserName( std::string( element[TwitterReponseTypes::name.c_str()].GetString() ) );
user.setProfileImgURL( std::string( element[TwitterReponseTypes::profile_image_url.c_str()].GetString() ) );
user.setNumberOfTweets( element[TwitterReponseTypes::statuses_count.c_str()].GetInt64() );
if(element[TwitterReponseTypes::status.c_str()].IsObject())
user.setUserID( stringOf( element[TwitterReponseTypes::id.c_str()].asInt64() ) );
user.setScreenName( tolowercase( element[TwitterReponseTypes::screen_name.c_str()].asString() ) );
user.setUserName( element[TwitterReponseTypes::name.c_str()].asString() );
user.setProfileImgURL( element[TwitterReponseTypes::profile_image_url.c_str()].asString() );
user.setNumberOfTweets( element[TwitterReponseTypes::statuses_count.c_str()].asInt64() );
if(element[TwitterReponseTypes::status.c_str()].isObject())
user.setLastStatus(getEmbeddedStatus(element[TwitterReponseTypes::status.c_str()]));
return user;
}
Status getStatus(const rapidjson::Value &element)
Status getStatus(const Json::Value &element)
{
Status status;
status.setCreationTime( toIsoTime ( std::string( element[TwitterReponseTypes::created_at.c_str()].GetString() ) ) );
status.setID( stringOf( element[TwitterReponseTypes::id.c_str()].GetInt64() ));
status.setTweet( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ), getUrlEntities(element) ) );
status.setTruncated( element[TwitterReponseTypes::truncated.c_str()].GetBool());
status.setReplyToStatusID( element[TwitterReponseTypes::in_reply_to_status_id.c_str()].IsNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_status_id.c_str()].GetInt64()) );
status.setReplyToUserID( element[TwitterReponseTypes::in_reply_to_user_id.c_str()].IsNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_user_id.c_str()].GetInt64()) );
status.setReplyToScreenName( element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].IsNull() ?
"" : std::string(element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].GetString()) );
status.setCreationTime( toIsoTime ( element[TwitterReponseTypes::created_at.c_str()].asString() ) );
status.setID( stringOf( element[TwitterReponseTypes::id.c_str()].asInt64() ));
status.setTweet( unescape ( element[TwitterReponseTypes::text.c_str()].asString(), getUrlEntities(element) ) );
status.setTruncated( element[TwitterReponseTypes::truncated.c_str()].asBool());
status.setReplyToStatusID( element[TwitterReponseTypes::in_reply_to_status_id.c_str()].isNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_status_id.c_str()].asInt64()) );
status.setReplyToUserID( element[TwitterReponseTypes::in_reply_to_user_id.c_str()].isNull() ?
"" : stringOf(element[TwitterReponseTypes::in_reply_to_user_id.c_str()].asInt64()) );
status.setReplyToScreenName( element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].isNull() ?
"" : element[TwitterReponseTypes::in_reply_to_screen_name.c_str()].asString() );
status.setUserData( getUser(element[TwitterReponseTypes::user.c_str()]) );
status.setRetweetCount( element[TwitterReponseTypes::retweet_count.c_str()].GetInt64() );
status.setFavorited( element[TwitterReponseTypes::favorited.c_str()].GetBool() );
status.setRetweeted( element[TwitterReponseTypes::retweeted.c_str()].GetBool());
const rapidjson::Value &rt = element[TwitterReponseTypes::retweeted_status.c_str()];
if (rt.IsObject()) {
status.setTweet(unescape( std::string( rt[TwitterReponseTypes::text.c_str()].GetString()) + " (RT by @" + status.getUserData().getScreenName() + ")"
status.setRetweetCount( element[TwitterReponseTypes::retweet_count.c_str()].asInt64() );
status.setFavorited( element[TwitterReponseTypes::favorited.c_str()].asBool() );
status.setRetweeted( element[TwitterReponseTypes::retweeted.c_str()].asBool());
const Json::Value &rt = element[TwitterReponseTypes::retweeted_status.c_str()];
if (rt.isObject()) {
status.setTweet(unescape( rt[TwitterReponseTypes::text.c_str()].asString() + " (RT by @" + status.getUserData().getScreenName() + ")"
, getUrlEntities(element)) );
status.setRetweetID( stringOf(rt[TwitterReponseTypes::id.c_str()].GetInt64()) );
status.setCreationTime( toIsoTime ( std::string (rt[TwitterReponseTypes::created_at.c_str()].GetString() ) ) );
status.setRetweetID( stringOf(rt[TwitterReponseTypes::id.c_str()].asInt64()) );
status.setCreationTime( toIsoTime ( rt[TwitterReponseTypes::created_at.c_str()].asString() ) );
status.setUserData( getUser ( rt[TwitterReponseTypes::user.c_str()]) );
}
return status;
}
DirectMessage getDirectMessage(const rapidjson::Value &element)
DirectMessage getDirectMessage(const Json::Value &element)
{
DirectMessage DM;
DM.setCreationTime( toIsoTime ( std::string( element[TwitterReponseTypes::created_at.c_str()].GetString() ) ) );
DM.setID( stringOf( element[TwitterReponseTypes::id.c_str()].GetInt64() ) );
DM.setMessage( unescape ( std::string( element[TwitterReponseTypes::text.c_str()].GetString() ), getUrlEntities(element) ) );
DM.setSenderID( stringOf( element[TwitterReponseTypes::sender_id.c_str()].GetInt64()) );
DM.setRecipientID( stringOf( element[TwitterReponseTypes::recipient_id.c_str()].GetInt64() ) );
DM.setSenderScreenName( std::string( element[TwitterReponseTypes::sender_screen_name.c_str()].GetString() ) );
DM.setRecipientScreenName( std::string( element[TwitterReponseTypes::recipient_screen_name.c_str()].GetString() ) );
DM.setCreationTime( toIsoTime ( element[TwitterReponseTypes::created_at.c_str()].asString() ) );
DM.setID( stringOf( element[TwitterReponseTypes::id.c_str()].asInt64() ) );
DM.setMessage( unescape ( element[TwitterReponseTypes::text.c_str()].asString(), getUrlEntities(element) ) );
DM.setSenderID( stringOf( element[TwitterReponseTypes::sender_id.c_str()].asInt64()) );
DM.setRecipientID( stringOf( element[TwitterReponseTypes::recipient_id.c_str()].asInt64() ) );
DM.setSenderScreenName( element[TwitterReponseTypes::sender_screen_name.c_str()].asString() );
DM.setRecipientScreenName( element[TwitterReponseTypes::recipient_screen_name.c_str()].asString() );
DM.setSenderData( getUser(element[TwitterReponseTypes::sender.c_str()] ));
DM.setRecipientData( getUser(element[TwitterReponseTypes::recipient.c_str()]) );
return DM;
......@@ -139,21 +139,22 @@ DirectMessage getDirectMessage(const rapidjson::Value &element)
std::vector<Status> getTimeline(std::string &json)
{
std::vector<Status> statuses;
rapidjson::Document rootElement;
Json::Value rootElement;
Json::Reader reader;
if(rootElement.Parse<0>(json.c_str()).HasParseError()) {
if(!reader.parse(json.c_str(), rootElement)){
LOG4CXX_ERROR(logger, "Error while parsing JSON");
LOG4CXX_ERROR(logger, json);
return statuses;
}
if(!rootElement.IsArray()) {
if(!rootElement.isArray()) {
LOG4CXX_ERROR(logger, "JSON doesn't correspond to timeline:");
LOG4CXX_ERROR(logger, json);
return statuses;
}
for(rapidjson::SizeType i = 0; i < rootElement.Size(); i++) {
for(Json::Value::ArrayIndex i = 0; i < rootElement.size(); i++) {
statuses.push_back(getStatus(rootElement[i]));
}
return statuses;
......@@ -162,22 +163,22 @@ std::vector<Status> getTimeline(std::string &json)
std::vector<DirectMessage> getDirectMessages(std::string &json)
{
std::vector<DirectMessage> DMs;
rapidjson::Document rootElement;
Json::Value rootElement;
Json::Reader reader;
if(rootElement.Parse<0>(json.c_str()).HasParseError()) {
if(!reader.parse(json.c_str(), rootElement)) {
LOG4CXX_ERROR(logger, "Error while parsing JSON");
LOG4CXX_ERROR(logger, json);
return DMs;
}
if(!rootElement.IsArray()) {
if(!rootElement.isArray()) {
LOG4CXX_ERROR(logger, "JSON doesn't correspond to direct messages:");
LOG4CXX_ERROR(logger, json);
return DMs;
}
for(rapidjson::SizeType i = 0; i < rootElement.Size(); i++) {
for(Json::Value::ArrayIndex i = 0; i < rootElement.size(); i++) {
DMs.push_back(getDirectMessage(rootElement[i]));
}
return DMs;
......@@ -186,22 +187,22 @@ std::vector<DirectMessage> getDirectMessages(std::string &json)
std::vector<User> getUsers(std::string &json)
{
std::vector<User> users;
rapidjson::Document rootElement;
Json::Value rootElement;
Json::Reader reader;
if(rootElement.Parse<0>(json.c_str()).HasParseError()) {
if(!reader.parse(json.c_str(), rootElement)) {
LOG4CXX_ERROR(logger, "Error while parsing JSON");
LOG4CXX_ERROR(logger, json);
return users;
}
if(!rootElement.IsArray()) {
if(!rootElement.isArray()) {
LOG4CXX_ERROR(logger, "JSON doesn't correspond to user list:");
LOG4CXX_ERROR(logger, json);
return users;
}
for(rapidjson::SizeType i = 0; i < rootElement.Size(); i++) {
for(Json::Value::ArrayIndex i = 0; i < rootElement.size(); i++) {
users.push_back(getUser(rootElement[i]));
}
return users;
......@@ -210,15 +211,16 @@ std::vector<User> getUsers(std::string &json)
User getUser(std::string &json)
{
User user;
rapidjson::Document rootElement;
Json::Value rootElement;
Json::Reader reader;
if(rootElement.Parse<0>(json.c_str()).HasParseError()) {
if(!reader.parse(json.c_str(), rootElement)) {
LOG4CXX_ERROR(logger, "Error while parsing JSON");
LOG4CXX_ERROR(logger, json);
return user;
}
if(!rootElement.IsObject()) {
if(!rootElement.isObject()) {
LOG4CXX_ERROR(logger, "JSON doesn't correspond to user object");
LOG4CXX_ERROR(logger, json);
return user;
......@@ -230,24 +232,25 @@ User getUser(std::string &json)
std::vector<std::string> getIDs(std::string &json)
{
std::vector<std::string> IDs;
rapidjson::Document rootElement;
Json::Value rootElement;
Json::Reader reader;
if(rootElement.Parse<0>(json.c_str()).HasParseError()) {
if(!reader.parse(json.c_str(), rootElement)) {
LOG4CXX_ERROR(logger, "Error while parsing JSON");
LOG4CXX_ERROR(logger, json);
return IDs;
}
if(!rootElement.IsObject()) {
if(!rootElement.isObject()) {
LOG4CXX_ERROR(logger, "JSON doesn't correspond to id_list");
LOG4CXX_ERROR(logger, json);
return IDs;
}
const rapidjson::Value & ids = rootElement[TwitterReponseTypes::ids.c_str()];
const Json::Value & ids = rootElement[TwitterReponseTypes::ids.c_str()];
for(unsigned i=0 ; i<ids.Size() ; i++) {
IDs.push_back(stringOf( ids[i].GetInt64()) );
for(Json::Value::ArrayIndex i=0 ; i<ids.size() ; i++) {
IDs.push_back(stringOf( ids[i].asInt64()) );
}
return IDs;
}
......@@ -257,18 +260,19 @@ Error getErrorMessage(std::string &json)
std::string error = "";
std::string code = "0";
Error resp;
rapidjson::Document rootElement;
Json::Value rootElement;
Json::Reader reader;
if(rootElement.Parse<0>(json.c_str()).HasParseError()) {
if(!reader.parse(json.c_str(), rootElement)) {
LOG4CXX_ERROR(logger, "Error while parsing JSON");
LOG4CXX_ERROR(logger, json);
return resp;
}
if (rootElement.IsObject()) {
if (!rootElement["errors"].IsNull()) {
const rapidjson::Value &errorElement = rootElement["errors"][0u]; // first error
error = std::string(errorElement["message"].GetString());
code = stringOf(errorElement["code"].GetInt64());
if (rootElement.isObject()) {
if (!rootElement["errors"].isNull()) {
const Json::Value &errorElement = rootElement["errors"][0u]; // first error
error = errorElement["message"].asString();
code = stringOf(errorElement["code"].asInt64());
resp.setCode(code);
resp.setMessage(error);
}
......@@ -277,18 +281,18 @@ Error getErrorMessage(std::string &json)
return resp;
}
std::vector<UrlEntity> getUrlEntities(const rapidjson::Value &element)
std::vector<UrlEntity> getUrlEntities(const Json::Value &element)
{
std::vector<UrlEntity> url_entities;
const rapidjson::Value &entities = element["entities"];
const Json::Value &entities = element["entities"];
if (entities.IsObject()) {
const rapidjson::Value &urls = entities["urls"];
if (urls.IsArray()) {
for (rapidjson::SizeType i = 0; i < urls.Size(); i++) {
UrlEntity entity(urls[i]["url"].GetString(), urls[i]["expanded_url"].GetString());
if (entities.isObject()) {
const Json::Value &urls = entities["urls"];
if (urls.isArray()) {
for (Json::Value::ArrayIndex i = 0; i < urls.size(); i++) {
UrlEntity entity(urls[i]["url"].asString(), urls[i]["expanded_url"].asString());
url_entities.push_back(entity);
}
}
......
#ifndef TWITTERRESPOSNSEPARSER_H
#define TWITTERRESPOSNSEPARSER_H
#include "rapidjson/document.h"
#include <json/json.h>
#include <iostream>
#include <vector>
#include <string>
......@@ -234,8 +235,8 @@ std::vector<User> getUsers(std::string &xml);
User getUser(std::string &xml);
Error getErrorMessage(std::string &xml);
std::vector<UrlEntity> getUrlEntities(const rapidjson::Value &element);
Status getStatus(const rapidjson::Value &element);
DirectMessage getDirectMessage(const rapidjson::Value &element);
User getUser(const rapidjson::Value &element);
std::vector<UrlEntity> getUrlEntities(const Json::Value &element);
Status getStatus(const Json::Value &element);
DirectMessage getDirectMessage(const Json::Value &element);
User getUser(const Json::Value &element);
#endif
This diff is collapsed.
#ifndef RAPIDJSON_FILESTREAM_H_
#define RAPIDJSON_FILESTREAM_H_
#include <cstdio>
namespace rapidjson {
//! Wrapper of C file stream for input or output.
/*!
This simple wrapper does not check the validity of the stream.
\implements Stream
*/
class FileStream {
public:
typedef char Ch; //!< Character type. Only support char.
FileStream(FILE* fp) : fp_(fp), count_(0) { Read(); }
char Peek() const { return current_; }
char Take() { char c = current_; Read(); return c; }
size_t Tell() const { return count_; }
void Put(char c) { fputc(c, fp_); }
// Not implemented
char* PutBegin() { return 0; }
size_t PutEnd(char*) { return 0; }
private:
void Read() {
RAPIDJSON_ASSERT(fp_ != 0);
int c = fgetc(fp_);
if (c != EOF) {
current_ = (char)c;
count_++;
}
else
current_ = '\0';
}
FILE* fp_;
char current_;
size_t count_;
};
} // namespace rapidjson
#endif // RAPIDJSON_FILESTREAM_H_
#ifndef RAPIDJSON_POW10_
#define RAPIDJSON_POW10_
namespace rapidjson {
namespace internal {
//! Computes integer powers of 10 in double (10.0^n).
/*! This function uses lookup table for fast and accurate results.
\param n positive/negative exponent. Must <= 308.
\return 10.0^n
*/
inline double Pow10(int n) {
static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes
1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300,
1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280,
1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260,
1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240,
1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220,
1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200,
1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180,
1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160,
1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140,
1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120,
1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100,
1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80,
1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60,
1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40,
1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20,
1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e+0,
1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
};
RAPIDJSON_ASSERT(n <= 308);
return n < -308 ? 0.0 : e[n + 308];
}
} // namespace internal
} // namespace rapidjson
#endif // RAPIDJSON_POW10_
#ifndef RAPIDJSON_INTERNAL_STACK_H_
#define RAPIDJSON_INTERNAL_STACK_H_
namespace rapidjson {
namespace internal {
///////////////////////////////////////////////////////////////////////////////
// Stack
//! A type-unsafe stack for storing different types of data.
/*! \tparam Allocator Allocator for allocating stack memory.
*/
template <typename Allocator>
class Stack {
public:
Stack(Allocator* allocator, size_t stack_capacity) : allocator_(allocator), own_allocator_(0), stack_(0), stack_top_(0), stack_end_(0), stack_capacity_(stack_capacity) {
RAPIDJSON_ASSERT(stack_capacity_ > 0);
if (!allocator_)
own_allocator_ = allocator_ = new Allocator();
stack_top_ = stack_ = (char*)allocator_->Malloc(stack_capacity_);
stack_end_ = stack_ + stack_capacity_;
}
~Stack() {
Allocator::Free(stack_);
delete own_allocator_; // Only delete if it is owned by the stack
}
void Clear() { /*stack_top_ = 0;*/ stack_top_ = stack_; }
template<typename T>
T* Push(size_t count = 1) {
// Expand the stack if needed
if (stack_top_ + sizeof(T) * count >= stack_end_) {
size_t new_capacity = stack_capacity_ * 2;
size_t size = GetSize();
size_t new_size = GetSize() + sizeof(T) * count;
if (new_capacity < new_size)
new_capacity = new_size;
stack_ = (char*)allocator_->Realloc(stack_, stack_capacity_, new_capacity);
stack_capacity_ = new_capacity;
stack_top_ = stack_ + size;
stack_end_ = stack_ + stack_capacity_;
}
T* ret = (T*)stack_top_;
stack_top_ += sizeof(T) * count;
return ret;
}
template<typename T>
T* Pop(size_t count) {
RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
stack_top_ -= count * sizeof(T);
return (T*)stack_top_;
}
template<typename T>
T* Top() {
RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
return (T*)(stack_top_ - sizeof(T));
}
template<typename T>
T* Bottom() { return (T*)stack_; }
Allocator& GetAllocator() { return *allocator_; }
size_t GetSize() const { return stack_top_ - stack_; }
size_t GetCapacity() const { return stack_capacity_; }
private:
Allocator* allocator_;
Allocator* own_allocator_;
char *stack_;
char *stack_top_;
char *stack_end_;
size_t stack_capacity_;
};
} // namespace internal
} // namespace rapidjson
#endif // RAPIDJSON_STACK_H_
#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
#define RAPIDJSON_INTERNAL_STRFUNC_H_
namespace rapidjson {
namespace internal {
//! Custom strlen() which works on different character types.
/*! \tparam Ch Character type (e.g. char, wchar_t, short)
\param s Null-terminated input string.
\return Number of characters in the string.
\note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
*/
template <typename Ch>
inline SizeType StrLen(const Ch* s) {
const Ch* p = s;
while (*p != '\0')
++p;
return SizeType(p - s);
}
} // namespace internal
} // namespace rapidjson
#endif // RAPIDJSON_INTERNAL_STRFUNC_H_