本文整理汇总了C++中Document::FindMember方法的典型用法代码示例。如果您正苦于以下问题:C++ Document::FindMember方法的具体用法?C++ Document::FindMember怎么用?C++ Document::FindMember使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Document
的用法示例。
在下文中一共展示了Document::FindMember方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SetTitleInfo
/// <summary>
/// PlayFab Title cannot be created from SDK tests, so you must provide your titleId to run unit tests.
/// (Also, we don't want lots of excess unused titles)
/// </summary>
bool SetTitleInfo(Document &testInputs)
{
CCLOG("%s", "SetTitleInfo");
// Parse all the inputs
auto end = testInputs.MemberEnd();
auto each = testInputs.FindMember("titleId");
if (each != end) PlayFabSettings::titleId = each->value.GetString(); else return false;
each = testInputs.FindMember("developerSecretKey");
if (each != end) PlayFabSettings::developerSecretKey = each->value.GetString(); else return false;
string blah;
each = testInputs.FindMember("titleCanUpdateSettings");
if (each != end) blah = each->value.GetString(); else return false;
TITLE_CAN_UPDATE_SETTINGS = (blah.compare("true") == 0 || blah.compare("True") == 0 || blah.compare("TRUE") == 0);
each = testInputs.FindMember("userName");
if (each != end) USER_NAME = each->value.GetString(); else return false;
each = testInputs.FindMember("userEmail");
if (each != end) USER_EMAIL = each->value.GetString(); else return false;
each = testInputs.FindMember("userPassword");
if (each != end) USER_PASSWORD = each->value.GetString(); else return false;
each = testInputs.FindMember("characterName");
if (each != end) CHAR_NAME = each->value.GetString(); else return false;
// Verify all the inputs won't cause crashes in the tests
return !PlayFabSettings::titleId.empty()
&& !PlayFabSettings::developerSecretKey.empty()
&& !USER_NAME.empty()
&& !USER_EMAIL.empty()
&& !USER_PASSWORD.empty()
&& !CHAR_NAME.empty();
}
示例2: writer
// Issue 226: Value of string type should not point to NULL
TEST(Document, AssertAcceptInvalidNameType) {
Document doc;
doc.SetObject();
doc.AddMember("a", 0, doc.GetAllocator());
doc.FindMember("a")->name.SetNull(); // Change name to non-string type.
OutputStringStream os;
Writer<OutputStringStream> writer(os);
ASSERT_THROW(doc.Accept(writer), AssertException);
}
示例3: processWebMessages
void GameShow::processWebMessages()
{
Document* document = pGameController->socketServer()->getNextIncomingMessage();
if(0 != document){
// cout << "Got document " << document;
string message = document->FindMember("message")->value.GetString();
// cout << "Got message " << document;
if(message.compare("get_buttons") == 0){
pGameController->sendWebMessage(pGameController->buttonController()->getInfoString());
}else if(message.compare("get_lamps") == 0){
pGameController->sendWebMessage(pGameController->lampController()->getInfoString());
}else if(message.compare("get_coils") == 0){
pGameController->sendWebMessage(pGameController->coilController()->getInfoString());
}else if(message.compare("set_lamp_state") == 0){
string name = document->FindMember("name")->value.GetString();
LampState state = (LampState)document->FindMember("value")->value.GetInt();
pGameController->lampController()->setLampState(name, state);
}else if(message.compare("set_coil_state") == 0){
string name = document->FindMember("name")->value.GetString();
int state = document->FindMember("value")->value.GetInt();
pGameController->coilController()->setCoilState(name, state);
}else if(message.compare("set_button_state") == 0){
string name = document->FindMember("name")->value.GetString();
int state = document->FindMember("value")->value.GetInt();
pGameController->buttonController()->overrideButtonState(name, state);
}else if(message.compare("get_game_states") == 0){ //note the plural S
pGameState->sendAllStatesToWeb();
}else if(message.compare("get_game_state") == 0){
pGameState->sendToWeb();
}else if(message.compare("set_game_state") == 0){
string state = document->FindMember("value")->value.GetString();
setGameState(state);
}
//I don't like this here.
delete(document);
}
}
示例4:
Config::ElementGroupType
getAllElementGroups(const Document& doc, const std::vector<SvgElement>& all_elements_)
{
const auto element_groups_it = doc.FindMember("element_groups");
assert(element_groups_it != doc.MemberEnd());
assert(element_groups_it->value.IsArray());
const auto raw_array_of_groups = element_groups_it->value.GetArray();
Config::ElementGroupType all_element_groups;
all_element_groups.set_empty_key(std::string{""});
for (const auto& raw_single_group: raw_array_of_groups)
{
assert(raw_single_group.IsObject());
const auto& single_group = raw_single_group.GetObject();
//group name
const auto group_name_it = single_group.FindMember("name");
assert(group_name_it != single_group.MemberEnd());
assert(group_name_it->value.IsString());
const auto group_name = std::string {group_name_it->value.GetString(), group_name_it->value.GetStringLength()};
//all the elements that are part of the group
std::vector<std::string> single_group_members;
const auto raw_single_group_members = single_group.FindMember("elements");
assert(raw_single_group_members != single_group.MemberEnd());
assert(raw_single_group_members->value.IsArray());
const auto raw_array_of_group_members = raw_single_group_members->value.GetArray();
for (const auto& raw_single_group_element : raw_array_of_group_members)
{
assert(raw_single_group_element.IsString());
single_group_members.emplace_back(std::string{raw_single_group_element.GetString(),
raw_single_group_element.GetStringLength()});
}
all_element_groups[group_name] = std::move(single_group_members);
}
for (auto& array_name_pair : all_element_groups)
{
auto& element_vector = array_name_pair.second;
std::sort(std::begin(element_vector), std::end(element_vector));
}
// TODO: this line is for debug purposes, should be removed
std::cout << all_elements_;
return all_element_groups;
}
示例5: getAllElements
Config::ElementContainerType getAllElements(const Document& doc)
{
// load elements
const auto elements_it = doc.FindMember("elements");
assert(elements_it != doc.MemberEnd());
assert(elements_it->value.IsArray());
std::vector<SvgElement> all_elements;
const auto raw_elements = elements_it->value.GetArray();;
for (SizeType i = 0; i < raw_elements.Size(); ++i)
{
const Value& singleElement = raw_elements[i];
assert(singleElement.IsString());
all_elements.emplace_back(SvgElement{singleElement.GetString()});
}
std::sort(std::begin(all_elements), std::end(all_elements));
return all_elements;
}
示例6: SetTitleInfo
/// <summary>
/// PlayFab Title cannot be created from SDK tests, so you must provide your titleId to run unit tests.
/// (Also, we don't want lots of excess unused titles)
/// </summary>
static void SetTitleInfo(Document &testInputs)
{
// Parse all the inputs
auto end = testInputs.MemberEnd();
auto each = testInputs.FindMember("titleId");
if (each != end) playFabSettings->titleId = each->value.GetString();
string blah;
each = testInputs.FindMember("titleCanUpdateSettings");
if (each != end) blah = each->value.GetString();
TITLE_CAN_UPDATE_SETTINGS = (blah.compare("true") == 0 || blah.compare("True") == 0 || blah.compare("TRUE") == 0);
each = testInputs.FindMember("userName");
if (each != end) userName = each->value.GetString();
each = testInputs.FindMember("userEmail");
if (each != end) userEmail = each->value.GetString();
each = testInputs.FindMember("userPassword");
if (each != end) userPassword = each->value.GetString();
each = testInputs.FindMember("characterName");
if (each != end) characterName = each->value.GetString();
}
示例7: main
int main(int, char*[]) {
////////////////////////////////////////////////////////////////////////////
// 1. Parse a JSON text string to a document.
const char json[] = " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ";
printf("Original JSON:\n %s\n", json);
Document document; // Default template parameter uses UTF8 and MemoryPoolAllocator.
#if 0
// "normal" parsing, decode strings to new buffers. Can use other input stream via ParseStream().
if (document.Parse(json).HasParseError())
return 1;
#else
// In-situ parsing, decode strings directly in the source string. Source must be string.
char buffer[sizeof(json)];
memcpy(buffer, json, sizeof(json));
if (document.ParseInsitu(buffer).HasParseError())
return 1;
#endif
printf("\nParsing to document succeeded.\n");
////////////////////////////////////////////////////////////////////////////
// 2. Access values in document.
printf("\nAccess values in document:\n");
assert(document.IsObject()); // Document is a JSON value represents the root of DOM. Root can be either an object or array.
assert(document.HasMember("hello"));
assert(document["hello"].IsString());
printf("hello = %s\n", document["hello"].GetString());
// Since version 0.2, you can use single lookup to check the existing of member and its value:
Value::MemberIterator hello = document.FindMember("hello");
assert(hello != document.MemberEnd());
assert(hello->value.IsString());
assert(strcmp("world", hello->value.GetString()) == 0);
(void)hello;
assert(document["t"].IsBool()); // JSON true/false are bool. Can also uses more specific function IsTrue().
printf("t = %s\n", document["t"].GetBool() ? "true" : "false");
assert(document["f"].IsBool());
printf("f = %s\n", document["f"].GetBool() ? "true" : "false");
printf("n = %s\n", document["n"].IsNull() ? "null" : "?");
assert(document["i"].IsNumber()); // Number is a JSON type, but C++ needs more specific type.
assert(document["i"].IsInt()); // In this case, IsUint()/IsInt64()/IsUInt64() also return true.
printf("i = %d\n", document["i"].GetInt()); // Alternative (int)document["i"]
assert(document["pi"].IsNumber());
assert(document["pi"].IsDouble());
printf("pi = %g\n", document["pi"].GetDouble());
{
const Value& a = document["a"]; // Using a reference for consecutive access is handy and faster.
assert(a.IsArray());
for (SizeType i = 0; i < a.Size(); i++) // rapidjson uses SizeType instead of size_t.
printf("a[%d] = %d\n", i, a[i].GetInt());
int y = a[0].GetInt();
(void)y;
// Iterating array with iterators
printf("a = ");
for (Value::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
printf("%d ", itr->GetInt());
printf("\n");
}
// Iterating object members
static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };
for (Value::ConstMemberIterator itr = document.MemberBegin(); itr != document.MemberEnd(); ++itr)
printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]);
////////////////////////////////////////////////////////////////////////////
// 3. Modify values in document.
// Change i to a bigger number
{
uint64_t f20 = 1; // compute factorial of 20
for (uint64_t j = 1; j <= 20; j++)
f20 *= j;
document["i"] = f20; // Alternate form: document["i"].SetUint64(f20)
assert(!document["i"].IsInt()); // No longer can be cast as int or uint.
}
// Adding values to array.
{
Value& a = document["a"]; // This time we uses non-const reference.
Document::AllocatorType& allocator = document.GetAllocator();
for (int i = 5; i <= 10; i++)
a.PushBack(i, allocator); // May look a bit strange, allocator is needed for potentially realloc. We normally uses the document's.
// Fluent API
a.PushBack("Lua", allocator).PushBack("Mio", allocator);
}
//.........这里部分代码省略.........
示例8: aggregate
//.........这里部分代码省略.........
FILE* input = fopen(filename.data(), "r");
{
// Read file line by line
CompressedFileReader reader(input);
char* line = nullptr;
int nb_line = 0;
while ((line = reader.nextLine()) != nullptr) {
nb_line++;
// Find tab
char* tab = strchr(line, '\t');
if (!tab) {
fprintf(stderr, "No tab on line %i\n", nb_line);
continue;
}
// Set tab = \0 creating two C-strings
*tab = '\0';
char* uuid = line;
char* json = tab + 1;
UNUSED(uuid);
// Parse the JSON line
Document d;
d.Parse<0>(json);
// Check that we have an object
if (!d.IsObject()) {
fprintf(stderr, "JSON root is not an object on line %i\n", nb_line);
continue;
}
// Find the info field
Value::Member* infoField = d.FindMember("info");
if (!infoField || !infoField->value.IsObject()) {
fprintf(stderr, "'info' in payload isn't an object, line %i\n", nb_line);
continue;
}
Value& info = infoField->value;
// Find OS, osVersion, arch and revision
Value::Member* osField = info.FindMember("OS");
Value::Member* osVerField = info.FindMember("version");
Value::Member* archField = info.FindMember("arch");
Value::Member* revField = info.FindMember("revision");
if (!osField || !osField->value.IsString()) {
fprintf(stderr, "'OS' in 'info' isn't a string\n");
continue;
}
if (!osVerField || !(osVerField->value.IsString() ||
osVerField->value.IsNumber())) {
fprintf(stderr, "'version' in 'info' isn't a string or number\n");
continue;
}
if (!archField || !archField->value.IsString()) {
fprintf(stderr, "'arch' in 'info' isn't a string\n");
continue;
}
InternedString revision;
if (revField) {
if (!revField->value.IsString()) {
fprintf(stderr, "'revision' in 'info' isn't a string\n");
continue;
}
// Get InternedString for revision
revision = Aggregate::internRevisionString(revField->value.GetString());
示例9: DecodeRequest
bool PlayFabRequestHandler::DecodeRequest(int httpStatus, HttpRequest* request, void* userData, PlayFabBaseModel& outResult, PlayFabError& outError)
{
std::string response = request->GetReponse();
Document rawResult;
rawResult.Parse<0>(response.c_str());
// Check for bad responses
if (response.length() == 0 // Null response
|| rawResult.GetParseError() != NULL) // Non-Json response
{
// If we get here, we failed to connect meaningfully to the server - Assume a timeout
outError.HttpCode = 408;
outError.ErrorCode = PlayFabErrorConnectionTimeout;
// For text returns, use the non-json response if possible, else default to no response
outError.ErrorName = outError.ErrorMessage = outError.HttpStatus = response.length() == 0 ? "Request Timeout or null response" : response;
return false;
}
// Check if the returned json indicates an error
const Value::Member* errorCodeJson = rawResult.FindMember("errorCode");
if (errorCodeJson != NULL)
{
// There was an error, BUMMER
if (!errorCodeJson->value.IsNumber())
{
// unexpected json formatting - If we get here, we failed to connect meaningfully to the server - Assume a timeout
outError.HttpCode = 408;
outError.ErrorCode = PlayFabErrorConnectionTimeout;
// For text returns, use the non-json response if possible, else default to no response
outError.ErrorName = outError.ErrorMessage = outError.HttpStatus = response.length() == 0 ? "Request Timeout or null response" : response;
return false;
}
// TODO: what happens when the error is not in the enum?
outError.ErrorCode = static_cast<PlayFabErrorCode>(errorCodeJson->value.GetInt());
const Value::Member* codeJson = rawResult.FindMember("code");
if (codeJson != NULL && codeJson->value.IsNumber())
outError.HttpCode = codeJson->value.GetInt();
const Value::Member* statusJson = rawResult.FindMember("status");
if (statusJson != NULL && statusJson->value.IsString())
outError.HttpStatus = statusJson->value.GetString();
const Value::Member* errorNameJson = rawResult.FindMember("error");
if (errorNameJson != NULL && errorNameJson->value.IsString())
outError.ErrorName = errorNameJson->value.GetString();
const Value::Member* errorMessageJson = rawResult.FindMember("errorMessage");
if (errorMessageJson != NULL && errorMessageJson->value.IsString())
outError.ErrorMessage = errorMessageJson->value.GetString();
const Value::Member* errorDetailsJson = rawResult.FindMember("errorDetails");
if (errorDetailsJson != NULL && errorDetailsJson->value.IsObject())
{
const Value& errorDetailsObj = errorDetailsJson->value;
for (Value::ConstMemberIterator itr = errorDetailsObj.MemberBegin(); itr != errorDetailsObj.MemberEnd(); ++itr)
{
if (itr->name.IsString() && itr->value.IsArray())
{
const Value& errorList = itr->value;
for (Value::ConstValueIterator erroListIter = errorList.Begin(); erroListIter != errorList.End(); ++erroListIter)
outError.ErrorDetails.insert(std::pair<std::string, std::string>(itr->name.GetString(), erroListIter->GetString()));
}
}
}
// We encountered no errors parsing the error
return false;
}
const Value::Member* data = rawResult.FindMember("data");
if (data == NULL || !data->value.IsObject())
return false;
return outResult.readFromValue(data->value);
}
示例10: NodeBtHandler
//.........这里部分代码省略.........
cout << refreshRateCounter << endl;
} // BT Publisher kısmının sonu
// Sunucu tarafından gönderilen Matlab komutlarına Subscribe olunuyor
else
{
status = serverReqReader->take(serverReqSeq,
infoSeq,
LENGTH_UNLIMITED,
ANY_SAMPLE_STATE,
ANY_VIEW_STATE,
ANY_INSTANCE_STATE);
checkStatus(status, "severReqDataReader::read");
for (DDS::ULong j = 0; j < serverReqSeq.length(); j++)
{
if(infoSeq[j].valid_data)
{
cout << "=== [Subscriber] message received :" << endl;
cout << " Received Request Message : "
<< serverReqSeq[j].request << endl;
cout << " Received RequestID : \""
<< serverReqSeq[j].requestID << "\"" << endl;
// Rapidjson yapılandırıcısı yaratılıyor
Document d;
if(d.Parse(serverReqSeq[j].request).HasParseError())
cout << " Parsing Error!" << endl;
StringBuffer nodeIdBuffer;
Writer<StringBuffer> nodeIdWriter(nodeIdBuffer);
d["NodeID"].Accept(nodeIdWriter);
string tempNodeId = nodeIdBuffer.GetString();
// Subscribe olunan mesajın düğüme ait olup olmadığı kontrol ediliyor
if (tempNodeId == "\"SensDug13\"")
{
StringBuffer buffer;
Value::ConstMemberIterator itr = d.FindMember("SetRefreshRate");
// Ref Rate komutunun gelip gelmediği kontrol ediliyor
if(itr != d.MemberEnd())
{
string refreshRateString;
int refreshRateInt;
// Document formatındaki JSON mesajı StrinBuffer'a dönüştürülüyor
Writer<StringBuffer> writer(buffer);
d["SetRefreshRate"].Accept(writer);
refreshRateString = buffer.GetString();
// Gelen mesajda fazladan çift tırnak ile bulunuyor
// Örneğin, ""15""
// Bu yüzden ilk son karakterler kırpılıyor
refreshRateString =
refreshRateString.substr(1, refreshRateString.size()-1);
// Refresh rate değeri stringden integera çevriliyor
refreshRateInt = atoi(refreshRateString.c_str());
refreshRate = refreshRateInt;
timelimit.setMaxDuration(std::chrono::milliseconds
(refreshRate*1000));
}
}
else
cout << "Invalid NodeID!" << endl;
}
}
status = serverReqReader->return_loan(serverReqSeq, infoSeq);
checkStatus(status, "ServerReqDataReader::return_loan");
refreshRateCounter++;
cout << refreshRateCounter << endl;
} // Matlab komutuna Subscribe olma kısmının sonu
// Terminalde akacak olan çıktıları dah gözle görülebilir bir şekilde
// yazdırmak için koyulmuştur
FakeDelay();
}
// Hafıza temizle işlemleri gerçekleştiriliyor
mgrBtPub.deleteWriter();
mgrBtPub.deletePublisher();
mgrBtPub.deleteTopic();
mgrBtPub.deleteParticipant();
mgrReqSub.deleteReader();
mgrReqSub.deleteSubscriber();
mgrReqSub.deleteTopic();
mgrReqSub.deleteParticipant();
return 0;
}
示例11: NodeWifiHandler
//.........这里部分代码省略.........
checkStatus(status, "severReqDataReader::take");
// isDataReceived değişkeni bir kontrol değişkeni olup, Matlab komut
// bilgisini içeren mesaja Subscribe olunduysa true, olunmadıysa false
// değerini tutar
bool isDataReceived = false;
for (DDS::ULong j = 0; j < serverReqSeq.length(); j++)
{
if(infoSeq[j].valid_data)
{
cout << "=== [Subscriber] message received :" << endl;
cout << " Received Request Message : "
<< serverReqSeq[j].request << endl;
cout << " Received RequestID : \""
<< serverReqSeq[j].requestID << "\"" << endl;
// Rapidjson yapılandırıcısı yaratılıyor
Document d;
if(d.Parse(serverReqSeq[j].request).HasParseError())
cout << " Parsing Error!" << endl;
StringBuffer nodeIdBuffer;
Writer<StringBuffer> nodeIdWriter(nodeIdBuffer);
d["NodeID"].Accept(nodeIdWriter);
string tempNodeId = nodeIdBuffer.GetString();
// Subscribe olunan mesajın düğüme ait olup olmadığı kontrol ediliyor
if (tempNodeId == "\"SensDug13\"")
{
StringBuffer buffer;
// Reset komutunun gelip gelmediği kontrol ediliyor.
Value::ConstMemberIterator itr = d.FindMember("Reset");
if(itr != d.MemberEnd())
{
// Resetin değeri falsedan trueya çevriliyor
Value& s = d["Reset"];
s.SetBool(true);
// Document formatındaki JSON mesajı StrinBuffer'a dönüştürülüyor
Writer<StringBuffer> writer(buffer);
d.Accept(writer);
cout << " Request Message is modified to : "
<< buffer.GetString() << endl;
// Publish edilecek Response mesajı hazırlanıyor
string str = buffer.GetString();
str.append("\n");
serverReq->request = DDS::string_dup(str.c_str());
serverReq->requestID = serverReqSeq[j].requestID;
if(!isDataReceived && status == DDS::RETCODE_OK)
{
// Response mesajı gönderiliyor
ReturnCode_t tempStatus = serverReqWriter->write(
*serverReq, DDS::HANDLE_NIL);
checkStatus(tempStatus, "severReqDataReader::write");
isDataReceived = true;
cout << " Response Request Message is sent : "
<< serverReq->request << endl;
cout << " Response RequestID is sent : \""
<< serverReq->requestID << "\"" << endl;
示例12: Refresh
AbstractWorkSource::Events AbstractWorkSource::Refresh(bool canRead, bool canWrite) {
// This is public and due to TCP async connect nature, we cannot assume we're ready to go so shortcircuit if still waiting.
if(!stratum) return Events();
// As a start, dispatch my data to the server. It is required to do this first as we need to
// initiate connection with a mining.subscribe. Each tick, we send as many bytes as we can until
// write buffer is exhausted.
const time_t PREV_WORK_STAMP(stratum->LastNotifyTimestamp());
if(stratum->pending.size() && canWrite) {
asizei count = 1;
while(count && stratum->pending.size()) {
StratumState::Blob &msg(stratum->pending.front());
auto sent(Send(msg.data + msg.sent, msg.total - msg.sent));
if(sent.first == false) {
Events ohno;
ohno.connFailed = true;
return ohno;
}
count = sent.second;
msg.sent += count;
if(msg.sent == msg.total) {
#if STRATUM_DUMPTRAFFIC
stratumDump<<">>sent to server:"<<std::endl;
for(asizei i = 0; i < msg.total; i++) stratumDump<<msg.data[i];
stratumDump<<std::endl;
#endif
stratum->pending.pop();
}
}
}
Events ret;
if(canRead == false) return ret; // sends are still considered nops, as they don't really change the hi-level state
auto received(Receive(recvBuffer.NextBytes(), recvBuffer.Remaining()));
if(received.first == false) {
ret.connFailed = true;
return ret;
}
else if(received.second == 0) return ret;
ret.bytesReceived += received.second;
recvBuffer.used += received.second;
if(recvBuffer.Full()) recvBuffer.Grow();
using namespace rapidjson;
Document object;
char *pos = recvBuffer.data.get();
char *lastEndl = nullptr;
const auto prevDiff(GetCurrentDiff());
const auto prevJob(stratum->GetCurrentJob());
while(pos < recvBuffer.NextBytes()) {
char *limit = std::find(pos, recvBuffer.NextBytes(), '\n');
if(limit >= recvBuffer.NextBytes()) pos = limit;
else { // I process one line at time
#if STRATUM_DUMPTRAFFIC
stratumDump<<">>from server:";
for(asizei i = 0; pos + i < limit; i++) stratumDump<<pos[i];
stratumDump<<std::endl;
#endif
lastEndl = limit;
ScopedFuncCall restoreChar([limit]() { *limit = '\n'; }); // not really necessary but I like the idea
*limit = 0;
object.ParseInsitu(pos);
const Value::ConstMemberIterator &id(object.FindMember("id"));
const Value::ConstMemberIterator &method(object.FindMember("method"));
// There was a time in which stratum had "notifications" and "requests". They were the same thing basically but requests had an id
// to be used for confirmations. Besides some idiot wanted to use 0 as an ID, P2Pool servers always attach an ID even to notifications,
// which is a less brain-damaged thing but still mandated some changes here.
std::string idstr;
aulong idvalue = 0;
if(id != object.MemberEnd()) {
switch(id->value.GetType()) {
case kNumberType: {
if(id->value.IsUint()) idvalue = id->value.GetUint();
else if(id->value.IsInt()) idvalue = id->value.GetInt();
else if(id->value.IsUint64()) idvalue = id->value.GetUint64();
else if(id->value.IsInt64()) idvalue = id->value.GetInt64();
idstr = std::to_string(idvalue);
break;
}
case kStringType:
idstr.assign(id->value.GetString(), id->value.GetStringLength());
for(size_t check = 0; check < idstr.length(); check++) {
char c = idstr[check];
if(c < '0' || c > '9') throw std::exception("All my ids are naturals>0, this should be a natural>0 number!");
}
idvalue = strtoul(idstr.c_str(), NULL, 10);
break;
}
}
/* If you read the minimalistic documentation of stratum you get the idea you can trust on some things.
No, you don't. The only real thing you can do is figure out if something is a request from the server or a reply. */
if(method != object.MemberEnd() && method->value.IsString()) {
if(method->value.GetString()) MangleMessageFromServer(idstr, method->value.GetString(), object["params"]);
}
else { // I consider it a reply. Then it has .result or .error... MAYBE. P2Pool for example sends .result=.error=null as AUTH replies to say it doesn't care about who's logging in!
MangleReplyFromServer(idvalue, object["result"], object["error"]);
}
pos = lastEndl + 1;
}
}
if(lastEndl) { // at least a line has been mangled
//.........这里部分代码省略.........