Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
252enum expect_bits : unsigned {253EXP_OBJ_NAME = (1U << 0),254EXP_COLON = (1U << 1),255EXP_ARR_VALUE = (1U << 2),256EXP_VALUE = (1U << 3),257EXP_NOT_VALUE = (1U << 4),258};260#define expect(bit) (expectMask & (EXP_##bit))261#define setExpect(bit) (expectMask |= EXP_##bit)262#define clearExpect(bit) (expectMask &= ~EXP_##bit)264bool UniValue::read(std::string_view json)265{266UniValue parsed;267if (!parsed.read_impl(json)) {268setNull();269return false;270}271*this = std::move(parsed);272return true;273}275bool UniValue::read_impl(std::string_view str_in)276{277clear();279uint32_t expectMask = 0;280std::vector<UniValue*> stack;282std::string tokenVal;283unsigned int consumed;284enum jtokentype tok = JTOK_NONE;285enum jtokentype last_tok = JTOK_NONE;286const char* raw{str_in.data()};287const char* end{raw + str_in.size()};288do {289last_tok = tok;291tok = getJsonToken(tokenVal, consumed, raw, end);292if (tok == JTOK_NONE || tok == JTOK_ERR)293return false;294raw += consumed;296bool isValueOpen = jsonTokenIsValue(tok) ||297tok == JTOK_OBJ_OPEN || tok == JTOK_ARR_OPEN;299if (expect(VALUE)) {300if (!isValueOpen)301return false;302clearExpect(VALUE);304} else if (expect(ARR_VALUE)) {305bool isArrValue = isValueOpen || (tok == JTOK_ARR_CLOSE);306if (!isArrValue)307return false;309clearExpect(ARR_VALUE);311} else if (expect(OBJ_NAME)) {312bool isObjName = (tok == JTOK_OBJ_CLOSE || tok == JTOK_STRING);313if (!isObjName)314return false;316} else if (expect(COLON)) {317if (tok != JTOK_COLON)318return false;319clearExpect(COLON);321} else if (!expect(COLON) && (tok == JTOK_COLON)) {322return false;323}325if (expect(NOT_VALUE)) {326if (isValueOpen)327return false;328clearExpect(NOT_VALUE);329}331switch (tok) {333case JTOK_OBJ_OPEN:334case JTOK_ARR_OPEN: {335VType utyp = (tok == JTOK_OBJ_OPEN ? VOBJ : VARR);336if (!stack.size()) {337if (utyp == VOBJ)338setObject();339else340setArray();341stack.push_back(this);342} else {343UniValue tmpVal(utyp);344UniValue *top = stack.back();345top->values.push_back(tmpVal);347UniValue *newTop = &(top->values.back());348stack.push_back(newTop);349}351if (stack.size() > MAX_JSON_DEPTH)352return false;354if (utyp == VOBJ)355setExpect(OBJ_NAME);356else357setExpect(ARR_VALUE);358break;359}361case JTOK_OBJ_CLOSE:362case JTOK_ARR_CLOSE: {363if (!stack.size() || (last_tok == JTOK_COMMA))364return false;366VType utyp = (tok == JTOK_OBJ_CLOSE ? VOBJ : VARR);367UniValue *top = stack.back();368if (utyp != top->getType())369return false;371stack.pop_back();372clearExpect(OBJ_NAME);373setExpect(NOT_VALUE);374break;375}377case JTOK_COLON: {378if (!stack.size())379return false;381UniValue *top = stack.back();382if (top->getType() != VOBJ)383return false;385setExpect(VALUE);386break;387}389case JTOK_COMMA: {390if (!stack.size() ||391(last_tok == JTOK_COMMA) || (last_tok == JTOK_ARR_OPEN))392return false;394UniValue *top = stack.back();395if (top->getType() == VOBJ)396setExpect(OBJ_NAME);397else398setExpect(ARR_VALUE);399break;400}402case JTOK_KW_NULL:403case JTOK_KW_TRUE:404case JTOK_KW_FALSE: {405UniValue tmpVal;406switch (tok) {407case JTOK_KW_NULL:408// do nothing more409break;410case JTOK_KW_TRUE:411tmpVal.setBool(true);412break;413case JTOK_KW_FALSE:414tmpVal.setBool(false);415break;416default: /* impossible */ break;417}419if (!stack.size()) {420*this = tmpVal;421break;422}424UniValue *top = stack.back();425top->values.push_back(tmpVal);427setExpect(NOT_VALUE);428break;429}431case JTOK_NUMBER: {432UniValue tmpVal(VNUM, tokenVal);433if (!stack.size()) {434*this = tmpVal;435break;436}438UniValue *top = stack.back();439top->values.push_back(tmpVal);441setExpect(NOT_VALUE);442break;443}445case JTOK_STRING: {446if (expect(OBJ_NAME)) {447UniValue *top = stack.back();448top->keys.push_back(tokenVal);449clearExpect(OBJ_NAME);450setExpect(COLON);451} else {452UniValue tmpVal(VSTR, tokenVal);453if (!stack.size()) {454*this = tmpVal;455break;456}457UniValue *top = stack.back();458top->values.push_back(tmpVal);459}461setExpect(NOT_VALUE);462break;463}465default:466return false;467}468} while (!stack.empty ());470/* Check that nothing follows the initial construct (parsed above). */471tok = getJsonToken(tokenVal, consumed, raw, end);472if (tok != JTOK_NONE)473return false;475return true;476}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.