static Boolean ReadNextLine (FILE *f, CharPtr str, size_t maxsize) { Boolean done; Char ch; Int2 count; done = FALSE; if (f != NULL && str != NULL && maxsize > 0) { str [0] = '\0'; count = 0; ch = ReadNextChar (f); while (ch != '\n' && ch != '\r' && ch != '\0') { if (count < (Int2) maxsize && ch != '\0') { str [count] = ch; count++; } ch = ReadNextChar (f); } if (count <= (Int2) maxsize) { str [count] = '\0'; } done = (Boolean) (! feof (f)); } return done; }
static int GetNextInputChar( prompt_slot prompt ) /***********************************************/ { int c; c = ReadNextChar( prompt ); /* Redirect input to a response file; cannot be nested. */ if( c == '@' && !is_quoting ) { if( CmdFile->how == COMMANDLINE || CmdFile->how == INTERACTIVE ) { char fname[LINE_BUF_SIZE]; int oi; for( oi = 0; oi < sizeof( fname ) - 1; ) { c = ReadNextChar( prompt ); if( c == '"' ) is_quoting ^= true; /* Quit loop if not a valid filename character. */ if( (!is_quoting && (c == ',' || c == '+' || c == ';' || c == ' ')) || c == '/' || c < ' ' ) break; if( c != '"' ) { fname[oi++] = c; } } fname[oi] = '\0'; if( c > ' ' ) --CmdFile->current; /* Open the response file and read next character. */ StartNewFile( fname ); c = ReadNextChar( prompt ); } } return( c ); }
void BinaryBufferParser::ReadNextString(std::string& nextString,int stringSize) { if (!CanReadNextSizeofData(stringSize)) { return; } nextString.resize(stringSize); for (int i = 0; i < stringSize ; i++) { nextString[i] = ReadNextChar(); } }
std::string BinaryBufferParser::ReadNextString(int stringSize) { if (!CanReadNextSizeofData(stringSize)) { return ""; } std::string nextString; nextString.resize(stringSize); for (int i = 0; i < stringSize; i++) { nextString[i] = ReadNextChar(); } return nextString; }
tokens JSONScanner::Scan() { pTokenString = currentChar; while (currentChar < inputText + inputLen) { switch(ReadNextChar()) { case 0: //EOF currentChar--; return (pToken->tk = tkEOF); case '\t': case '\r': case '\n': case ' ': //WS - keep looping break; case '"': //check for string return ScanString(); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': //decimal digit starts a number { currentChar--; // we use StrToDbl() here for compat with the rest of the engine. StrToDbl() accept a larger syntax. // Verify first the JSON grammar. const char16* saveCurrentChar = currentChar; if(!IsJSONNumber()) { ThrowSyntaxError(JSERR_JsonBadNumber); } currentChar = saveCurrentChar; double val; const char16* end; val = Js::NumberUtilities::StrToDbl(currentChar, &end, scriptContext); if(currentChar == end) { ThrowSyntaxError(JSERR_JsonBadNumber); } AssertMsg(!Js::JavascriptNumber::IsNan(val), "Bad result from string to double conversion"); pToken->tk = tkFltCon; pToken->SetDouble(val, false); currentChar = end; return tkFltCon; } case ',': return (pToken->tk = tkComma); case ':': return (pToken->tk = tkColon); case '[': return (pToken->tk = tkLBrack); case ']': return (pToken->tk = tkRBrack); case '-': return (pToken->tk = tkSub); case 'n': //check for 'null' if (currentChar + 2 < inputText + inputLen && currentChar[0] == 'u' && currentChar[1] == 'l' && currentChar[2] == 'l') { currentChar += 3; return (pToken->tk = tkNULL); } ThrowSyntaxError(JSERR_JsonIllegalChar); case 't': //check for 'true' if (currentChar + 2 < inputText + inputLen && currentChar[0] == 'r' && currentChar[1] == 'u' && currentChar[2] == 'e') { currentChar += 3; return (pToken->tk = tkTRUE); } ThrowSyntaxError(JSERR_JsonIllegalChar); case 'f': //check for 'false' if (currentChar + 3 < inputText + inputLen && currentChar[0] == 'a' && currentChar[1] == 'l' && currentChar[2] == 's' && currentChar[3] == 'e') { currentChar += 4; return (pToken->tk = tkFALSE); } ThrowSyntaxError(JSERR_JsonIllegalChar); case '{': return (pToken->tk = tkLCurly); case '}': return (pToken->tk = tkRCurly); default: ThrowSyntaxError(JSERR_JsonIllegalChar); } } return (pToken->tk = tkEOF); }
tokens JSONScanner::ScanString() { char16 ch; this->currentIndex = 0; this->currentString = const_cast<char16*>(currentChar); bool endFound = false; bool isStringDirectInputTextMapped = true; LPCWSTR bulkStart = currentChar; uint bulkLength = 0; while (currentChar < inputText + inputLen) { ch = ReadNextChar(); int tempHex; if (ch == '"') { //end of the string endFound = true; break; } else if (ch <= 0x1F) { //JSON doesn't accept \u0000 - \u001f range, LS(\u2028) and PS(\u2029) are ok ThrowSyntaxError(JSERR_JsonIllegalChar); } else if ( 0 == ch ) { currentChar--; ThrowSyntaxError(JSERR_JsonNoStrEnd); } else if ('\\' == ch) { //JSON escape sequence in a string \", \/, \\, \b, \f, \n, \r, \t, unicode seq // unlikely V5.8 regular chars are not escaped, i.e '\g'' in a string is illegal not 'g' if (currentChar >= inputText + inputLen ) { ThrowSyntaxError(JSERR_JsonNoStrEnd); } ch = ReadNextChar(); switch (ch) { case 0: currentChar--; ThrowSyntaxError(JSERR_JsonNoStrEnd); case '"': case '/': case '\\': //keep ch break; case 'b': ch = 0x08; break; case 'f': ch = 0x0C; break; case 'n': ch = 0x0A; break; case 'r': ch = 0x0D; break; case 't': ch = 0x09; break; case 'u': { int chcode; // 4 hex digits if (currentChar + 3 >= inputText + inputLen) { //no room left for 4 hex chars ThrowSyntaxError(JSERR_JsonNoStrEnd); } if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex)) { ThrowSyntaxError(JSERR_JsonBadHexDigit); } chcode = tempHex * 0x1000; if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex)) { ThrowSyntaxError(JSERR_JsonBadHexDigit); } chcode += tempHex * 0x0100; if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex)) { ThrowSyntaxError(JSERR_JsonBadHexDigit); } chcode += tempHex * 0x0010; if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex)) { ThrowSyntaxError(JSERR_JsonBadHexDigit); } chcode += tempHex; AssertMsg(chcode == (chcode & 0xFFFF), "Bad unicode code"); ch = (char16)chcode; } break; default: // Any other '\o' is an error in JSON ThrowSyntaxError(JSERR_JsonIllegalChar); } // flush this->GetCurrentRangeCharacterPairList()->Add(RangeCharacterPair((uint)(bulkStart - inputText), bulkLength, ch)); uint oldIndex = currentIndex; currentIndex += bulkLength; currentIndex++; if (currentIndex < oldIndex) { // Overflow Js::Throw::OutOfMemory(); } // mark the mode as 'string transformed' (no direct mapping in inputText possible) isStringDirectInputTextMapped = false; // reset (to next char) bulkStart = currentChar; bulkLength = 0; } else { // continue bulkLength++; } } if (!endFound) { // no ending '"' found ThrowSyntaxError(JSERR_JsonNoStrEnd); } if (isStringDirectInputTextMapped == false) { // If the last bulk is not ended with an escape character, make sure that is // not built into the final unescaped string bool shouldSkipLastCharacter = false; if (bulkLength > 0) { shouldSkipLastCharacter = true; this->GetCurrentRangeCharacterPairList()->Add(RangeCharacterPair((uint)(bulkStart - inputText), bulkLength, _u('\0'))); uint oldIndex = currentIndex; currentIndex += bulkLength; if (currentIndex < oldIndex) { // Overflow Js::Throw::OutOfMemory(); } } this->BuildUnescapedString(shouldSkipLastCharacter); this->GetCurrentRangeCharacterPairList()->Clear(); this->currentString = this->stringBuffer; } else { // make currentIndex the length (w/o the \0) currentIndex = bulkLength; OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("ScanString(): direct-mapped string as '%.*s'\n"), GetCurrentStringLen(), GetCurrentString()); } return (pToken->tk = tkStrCon); }
bool JSONScanner::IsJSONNumber() { bool firstDigitIsAZero = false; if (PeekNextChar() == '0') { firstDigitIsAZero = true; currentChar++; } //partial verification of number JSON grammar. while (currentChar < inputText + inputLen) { switch(ReadNextChar()) { case 0: return false; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (firstDigitIsAZero) { return false; } break; case '.': { // at least one digit after '.' if(currentChar < inputText + inputLen) { char16 nch = ReadNextChar(); if('0' <= nch && nch <= '9') { return true; } else { return false; } } else { return false; } } //case 'E': //case 'e': // return true; default: return true; } firstDigitIsAZero = false; } return true; }