/* move idx to beginning of next word */ bool ParDoc::nextWord() { for (;idx<size; idx++) { switch (_chr[idx]) { case '\t': case '\n': case '\r': case ' ': eatWhitespace(); return (idx<size); case '\0': return false; default: continue; } } return false; }
void QHttpNetworkConnectionChannel::allDone() { #ifndef QT_NO_COMPRESS // expand the whole data. if (reply->d_func()->expectContent() && reply->d_func()->autoDecompress && !reply->d_func()->streamEnd) expand(true); // ### if expand returns false, its an error #endif // while handling 401 & 407, we might reset the status code, so save this. bool emitFinished = reply->d_func()->shouldEmitSignals(); handleStatus(); // ### at this point there should be no more data on the socket // close if server requested if (reply->d_func()->isConnectionCloseEnabled()) close(); // queue the finished signal, this is required since we might send new requests from // slot connected to it. The socket will not fire readyRead signal, if we are already // in the slot connected to readyRead if (emitFinished) QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection); // reset the reconnection attempts after we receive a complete reply. // in case of failures, each channel will attempt two reconnects before emitting error. reconnectAttempts = 2; detectPipeliningSupport(); // move next from pipeline to current request if (!alreadyPipelinedRequests.isEmpty()) { if (resendCurrent || reply->d_func()->isConnectionCloseEnabled() || socket->state() != QAbstractSocket::ConnectedState) { // move the pipelined ones back to the main queue requeueCurrentlyPipelinedRequests(); close(); } else { // there were requests pipelined in and we can continue HttpMessagePair messagePair = alreadyPipelinedRequests.takeFirst(); request = messagePair.first; reply = messagePair.second; state = QHttpNetworkConnectionChannel::ReadingState; resendCurrent = false; written = 0; // message body, excluding the header, irrelevant here bytesTotal = 0; // message body total, excluding the header, irrelevant here // pipeline even more connection->d_func()->fillPipeline(socket); // continue reading _q_receiveReply(); } } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) { eatWhitespace(); // this is weird. we had nothing pipelined but still bytes available. better close it. if (socket->bytesAvailable() > 0) close(); QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } else if (alreadyPipelinedRequests.isEmpty()) { QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } }
bool MenuConf::readItemNameIfPresent(FILE* f, Item* item) { eatWhitespace(f); if(! isAlpha(curChar)) { return true;//Name not present } if(! readToken(f, item->data->name, ItemData::NameSize)) { return false; } eatWhitespace(f); if(curChar != ':') { printf("%d, %d: Expected ':'\n", lineIndex, caret); return false; } nextChar(f); return true; }
static int Parse (FILE * fp, int (*sfunc) (char *), int (*pfunc) (char * option, char * value, int num_flags, char** flags)) { int c; c = eatWhitespace (fp); while ((c != EOF) && (c > 0)) { switch (c) { case '\n': /* blank line */ { c = eatWhitespace (fp); break; } case ';': /* comment line */ case '#': { c = eatComment (fp); break; } case '[': /* section header */ { if (Section (fp, sfunc) < 0) { return (-1); } c = eatWhitespace (fp); break; } default: /* parameter line */ { if (Parameter (fp, pfunc, c) < 0) return (-1); c = eatWhitespace (fp); } } } return 0; }
bool getToken(std::istream &is, std::string &token) { eatWhitespace(is); token.clear(); char c; while(is.good() && !isWhitespace(is.peek())) { c = is.get(); if (is.good()){ token += c; } } return token.size() > 0; }
bool MenuConf::readItemHotkeysIfPresent(FILE* f, Item* item) { eatWhitespace(f); if(curChar == ',') { nextChar(f); eatWhitespace(f); if(curChar != '[') { printf("%d, %d: Expected '['\n", lineIndex, caret); return false; } else { nextChar(f); while(true) { eatWhitespace(f); if(curChar == ']') { nextChar(f); return false; } if(curChar == '\n' || curChar == EOF) { printf("%d, %d: Expected hotkey or ']'\n", lineIndex, caret); return false; } if(item->data->hotkeys) { if(curChar != ',') { printf("%d, %d: Expected ','\n", lineIndex, caret); return false; } nextChar(f); } eatWhitespace(f); Hotkey* hotkey = new Hotkey(); if(readHotkey(f, hotkey->string, Hotkey::StringSize)) { addHotkey(item->data, hotkey); } } } } return true; }
/** * parse object name without colons */ Variant Json::parseObjectName(const std::string &json, int &index, bool &success, char limiter ) { std::string s; eatWhitespace(json, index); bool complete = false; int lastIndex = math::clamp<int>( index + 64, 0, json.size() ); for( int i=index; i < lastIndex; i++ ) { if( json[i+1] != limiter ) { s += json[ i ]; } else { s += json[ i ]; index = (i + 1); complete = true; break; } } std::string items("{}[],"); for( unsigned int i=0; i < s.size(); i++ ) { if( items.find( s[i] ) != std::string::npos ) { s = json.substr( std::max( 0, index-20 ), lastIndex ); complete = false; break; } } if( !complete ) { success = false; std::string advText = json.substr( std::max( 0, index - 60), 120 ); std::string errText = utils::format( 0xff, "Wrong symbol in object name \"%s\" at \n %s", s.c_str(), advText.c_str() ); return Variant( errText ); } return Variant(s); }
/* Parse out a single token */ int scene::getToken(char token[MAX_PARSER_TOKEN_LENGTH]) { int idx=0; assert (file != NULL); eatWhitespace(); if(parse_char == EOF) { token[0]='\0'; return 0; } while((!(isspace(parse_char))) && (parse_char != EOF)) { token[idx]=parse_char; idx++; parse_char = fgetc(file); } token[idx] = '\0'; return 1; }
/* the header looks like this: *--------- * P6 * # comments if you want to * width height * 255 *--------- * then follows RGBRGBRGBRGBRGB... */ struct Texture *viReadPPM(char *filename) { FILE *f; char ch; int width, height, colres; if(f=fopen(filename,"rb")) { char str[100]; struct Texture *tx; eatWhitespace(f); eatComments(f); eatWhitespace(f); fscanf(f,"%s",str); if(strcmp(str,"P6")!=0) { printf("Error: the texture image file must be of raw color PPM format,\n"); printf("i.e., it must have P6 in the header. File: %s\n",filename); exit(1); } eatWhitespace(f); eatComments(f); eatWhitespace(f); fscanf(f,"%d %d",&width,&height); if(width<=0 || height<=0) { printf("Error: width and height of the image must be greater than zero. File: %s\n",filename); exit(1); } eatWhitespace(f); eatComments(f); eatWhitespace(f); fscanf(f,"%d",&colres); if(colres!=255) { printf("Error: color resolution must be 255.File: %s\n",filename); return NULL; } /* gotta eat the newline too */ ch=0; while(ch!='\n') fscanf(f,"%c",&ch); tx=(struct Texture*)malloc(sizeof(struct Texture)); if(tx==NULL) { printf("Error: could not allocate memory for texture struct. File: %s\n",filename); return NULL; } tx->mWidth=width; tx->mHeight=height; tx->mRGB=(unsigned char*)malloc(3*width*height); if(tx->mRGB==NULL) { printf("Error: could not allocate memory for the pixels of the texture. File: %s\n",filename); exit(1); } if(fread(tx->mRGB,3*width*height,1,f)!=1) { printf("Error: could not read 3 x %d bytes of pixel info. File: %s\n",width*height,filename); return NULL; } fclose(f); return tx; } else { printf("Error: could not open %s.\n",filename); return NULL; } }
void read_gem_config_file() { FILE * configFile = fopen("gemConfig", "r"); char * c; char line[1024]; int len; line[sizeof(line)-1] = 0; if (!configFile) return; while (fgets(line, sizeof(line)-1, configFile)) { c = eatWhitespace(line); strToUpper(c); switch (*c) { case 'M': // Mode c = strchr(line, '='); strToUpper(c+1); gemRunMode = strstr(c, "EXHAUSTIVE") ? EXHAUSTIVE : SINGLE; break; case 'D': // Debug c = strchr(line, '='); strToUpper(c+1); if (c) { c = strstr(c, "ON"); if (!c) strstr(c, "1"); } gemDebugModeEnabled = (c != 0); if (gemDebugModeEnabled) { printf("GEM>> Debug Mode is ON\n"); } else { printf("GEM>> Debug Mode is OFF\n"); } break; case 'C': // Cached answers (dummy server) c = strchr(line, '='); strToUpper(c+1); if (c) { c = strstr(c, "ON"); if (!c) strstr(c, "1"); } gemUseDummyServer = (c != 0); break; case 'S': // Random Generator Seed c = strchr(line, '='); strToUpper(c+1); if (c) { gemSeedIsSet = sscanf(c+1, "%X", &gemSeedVal) > 0; } break; case 'A': // API Spec Path c = eatWhitespace(strchr(line, '=')+1); len = strlen(c); //apiSpecPath = malloc(len); apiSpecPath = malloc(len+1); strncpy(apiSpecPath, c, len); //apiSpecPath[len-1] = '\0'; apiSpecPath[len] = '\0'; if (len > 1 && apiSpecPath[len-1] == '\n') apiSpecPath[len-1] = '\0'; printf("API spec Path: `%s`\n", apiSpecPath); break; case 'G': // GEM (Racket) server path c = eatWhitespace(strchr(line, '=')+1); len = strlen(c); serverPath = malloc(len); strncpy(serverPath, c, len); serverPath[len-1] = '\0'; break; } } fclose(configFile); }
void QHttpNetworkConnectionChannel::allDone() { #ifndef QT_NO_COMPRESS // expand the whole data. if (reply->d_func()->expectContent() && reply->d_func()->autoDecompress && !reply->d_func()->streamEnd) expand(true); // ### if expand returns false, its an error #endif // while handling 401 & 407, we might reset the status code, so save this. bool emitFinished = reply->d_func()->shouldEmitSignals(); handleStatus(); // ### at this point there should be no more data on the socket // close if server requested bool connectionCloseEnabled = reply->d_func()->isConnectionCloseEnabled(); if (connectionCloseEnabled) close(); // queue the finished signal, this is required since we might send new requests from // slot connected to it. The socket will not fire readyRead signal, if we are already // in the slot connected to readyRead if (emitFinished) QMetaObject::invokeMethod(reply, "finished", Qt::QueuedConnection); // reset the reconnection attempts after we receive a complete reply. // in case of failures, each channel will attempt two reconnects before emitting error. reconnectAttempts = 2; detectPipeliningSupport(); // now the channel can be seen as free/idle again, all signal emissions for the reply have been done this->state = QHttpNetworkConnectionChannel::IdleState; // if it does not need to be sent again we can set it to 0 // the previous code did not do that and we had problems with accidental re-sending of a // finished request. // Note that this may trigger a segfault at some other point. But then we can fix the underlying // problem. if (!resendCurrent) { request = QHttpNetworkRequest(); reply = 0; } // move next from pipeline to current request if (!alreadyPipelinedRequests.isEmpty()) { if (resendCurrent || connectionCloseEnabled || socket->state() != QAbstractSocket::ConnectedState) { // move the pipelined ones back to the main queue requeueCurrentlyPipelinedRequests(); close(); } else { // there were requests pipelined in and we can continue HttpMessagePair messagePair = alreadyPipelinedRequests.takeFirst(); request = messagePair.first; reply = messagePair.second; state = QHttpNetworkConnectionChannel::ReadingState; resendCurrent = false; written = 0; // message body, excluding the header, irrelevant here bytesTotal = 0; // message body total, excluding the header, irrelevant here // pipeline even more connection->d_func()->fillPipeline(socket); // continue reading //_q_receiveReply(); // this was wrong, allDone gets called from that function anyway. } } else if (alreadyPipelinedRequests.isEmpty() && socket->bytesAvailable() > 0) { eatWhitespace(); // this is weird. we had nothing pipelined but still bytes available. better close it. if (socket->bytesAvailable() > 0) close(); QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } else if (alreadyPipelinedRequests.isEmpty()) { if (qobject_cast<QHttpNetworkConnection*>(connection)) QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } }
SExpression * Reader::read() { SExpression * ret = nil_symbol; ReaderChar val = eatWhitespace(); if (atEnd()) { return ret; } if (macroHint(val.chr)) { uint32_t val2 = peek().chr; uint64_t key2 = ((uint64_t)val.chr << 32) | val2; uint64_t key1 = ((uint64_t)val.chr << 32) | INVALID_CHAR; if (macros[key2]) { getChar(false); return macros[key2]->run(new List); } else if (macros[key1]) { return macros[key1]->run(new List); } else { printf("Couldn't find macro for [%c][%c]!\n", val.chr, val2); } } if (tokenType(val.chr) == TOKEN_QUOTE) { String * str = new String; ret = str; ret->begin_line = line; ret->begin_column = column; do { uint32_t val = getChar().chr; if (atEnd()) { printf("Got EOF in middle of string, %d\n", val); } if (tokenType(val) == TOKEN_QUOTE) { break; } str->append(val); } while (!atEnd()); ret->end_line = line; ret->end_column = column; } else if ( (tokenType(val.chr) == TOKEN_NUMERIC) || (tokenType(val.chr) == TOKEN_MINUS && tokenType(peek().chr) == TOKEN_NUMERIC) ) { bool is_minus = false; bool is_hex = false; int save_line = line; int save_column = column; if (tokenType(val.chr) == TOKEN_MINUS) { is_minus = true; val = getChar(); } if (val.chr == '0' && peek().chr == 'x') { is_hex = true; getChar(); } int64_t count_val = val.chr - '0'; do { val = getChar(); if (val.chr < '0' || val.chr > '9') { if (is_hex && (val.chr >= 'a' && val.chr <= 'f')) { } else { ret = new Number(is_minus ? -count_val : count_val); ret->begin_line = save_line; ret->begin_column = save_column; ret->end_line = line; ret->end_column = column; reject(val); break; } } if (is_hex) { if (val.chr >= 'a' && val.chr <= 'f') { val.chr -= ('a' - 10); } else { val.chr -= '0'; } count_val *= 16; count_val += val.chr; } else { val.chr -= '0'; count_val *= 10; count_val += val.chr; } if (atEnd()) { ret = new Number(is_minus ? -count_val : count_val); ret->begin_line = save_line; ret->begin_column = save_column; ret->end_line = line; ret->end_column = column; } } while (!atEnd()); } else if (tokenType(val.chr) == TOKEN_ALPHA) { String * str = new String; str->append(val.chr); Symbol * sym = new Symbol(str); ret = sym; ret->begin_line = line; ret->begin_column = column; do { ReaderChar val = getChar(); if (atEnd() || (tokenType(val.chr) != TOKEN_ALPHA && tokenType(val.chr) != TOKEN_MINUS && tokenType(val.chr) != TOKEN_NUMERIC)) { reject(val); break; } str->append(val.chr); } while (!atEnd()); ret->end_line = line; ret->end_column = column; } else if (tokenType(val.chr) == TOKEN_OPEN_BRACE) { List * list = new List; ret = list; ret->begin_line = line; ret->begin_column = column; do { ReaderChar next = eatWhitespace(); if (atEnd()) { printf("Got EOF in middle of list, %d\n", next.chr); break; } if (tokenType(next.chr) == TOKEN_CLOSE_BRACE) { break; } reject(next); SExpression * sep = read(); list->contents.push_back(sep); } while(!atEnd()); ret->end_line = line; ret->end_column = column; } else if (tokenType(val.chr) == TOKEN_COMMENT) { do { val = getChar(); } while (tokenType(val.chr) != TOKEN_NEWLINE && !atEnd()); } else { printf("Didn't expect %d %d!\n", val.chr, tokenType(val.chr)); } return ret; }
void QHttpNetworkConnectionChannel::_q_receiveReply() { Q_ASSERT(socket); if (!reply) { // heh, how should that happen! qWarning() << "QHttpNetworkConnectionChannel::_q_receiveReply() called without QHttpNetworkReply," << socket->bytesAvailable() << "bytes on socket."; close(); return; } // only run when the QHttpNetworkConnection is not currently being destructed, e.g. // this function is called from _q_disconnected which is called because // of ~QHttpNetworkConnectionPrivate if (!qobject_cast<QHttpNetworkConnection*>(connection)) { return; } qint64 bytes = 0; QAbstractSocket::SocketState socketState = socket->state(); // connection might be closed to signal the end of data if (socketState == QAbstractSocket::UnconnectedState) { if (socket->bytesAvailable() <= 0) { if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { // finish this reply. this case happens when the server did not send a content length reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; allDone(); return; } else { handleUnexpectedEOF(); return; } } else { // socket not connected but still bytes for reading.. just continue in this function } } // read loop for the response while (socket->bytesAvailable()) { QHttpNetworkReplyPrivate::ReplyState state = reply->d_func()->state; switch (state) { case QHttpNetworkReplyPrivate::NothingDoneState: { // only eat whitespace on the first call eatWhitespace(); state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState; // fallthrough } case QHttpNetworkReplyPrivate::ReadingStatusState: { qint64 statusBytes = reply->d_func()->readStatus(socket); if (statusBytes == -1) { // connection broke while reading status. also handled if later _q_disconnected is called handleUnexpectedEOF(); return; } bytes += statusBytes; lastStatus = reply->d_func()->statusCode; break; } case QHttpNetworkReplyPrivate::ReadingHeaderState: { QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); qint64 headerBytes = replyPrivate->readHeader(socket); if (headerBytes == -1) { // connection broke while reading headers. also handled if later _q_disconnected is called handleUnexpectedEOF(); return; } bytes += headerBytes; if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) { if (replyPrivate->isGzipped() && replyPrivate->autoDecompress) { // remove the Content-Length from header replyPrivate->removeAutoDecompressHeader(); } else { replyPrivate->autoDecompress = false; } if (replyPrivate->statusCode == 100) { replyPrivate->clearHttpLayerInformation(); replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState; break; // ignore } if (replyPrivate->shouldEmitSignals()) emit reply->headerChanged(); if (!replyPrivate->expectContent()) { replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState; allDone(); break; } } break; } case QHttpNetworkReplyPrivate::ReadingDataState: { QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); if (replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) { // We already have some HTTP body data. We don't read more from the socket until // this is fetched by QHttpNetworkAccessHttpBackend. If we would read more, // we could not limit our read buffer usage. // We only do this when shouldEmitSignals==true because our HTTP parsing // always needs to parse the 401/407 replies. Therefore they don't really obey // to the read buffer maximum size, but we don't care since they should be small. return; } if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress && replyPrivate->bodyLength > 0) { // bulk files like images should fulfill these properties and // we can therefore save on memory copying bytes = replyPrivate->readBodyFast(socket, &replyPrivate->responseData); replyPrivate->totalProgress += bytes; if (replyPrivate->shouldEmitSignals()) { QPointer<QHttpNetworkReply> replyPointer = reply; emit reply->readyRead(); // make sure that the reply is valid if (replyPointer.isNull()) return; emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength); // make sure that the reply is valid if (replyPointer.isNull()) return; } } else { // use the traditional slower reading (for compressed encoding, chunked encoding, // no content-length etc) QByteDataBuffer byteDatas; bytes = replyPrivate->readBody(socket, &byteDatas); if (bytes) { if (replyPrivate->autoDecompress) replyPrivate->appendCompressedReplyData(byteDatas); else replyPrivate->appendUncompressedReplyData(byteDatas); if (!replyPrivate->autoDecompress) { replyPrivate->totalProgress += bytes; if (replyPrivate->shouldEmitSignals()) { QPointer<QHttpNetworkReply> replyPointer = reply; // important: At the point of this readyRead(), the byteDatas list must be empty, // else implicit sharing will trigger memcpy when the user is reading data! emit reply->readyRead(); // make sure that the reply is valid if (replyPointer.isNull()) return; emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength); // make sure that the reply is valid if (replyPointer.isNull()) return; } } #ifndef QT_NO_COMPRESS else if (!expand(false)) { // expand a chunk if possible return; // ### expand failed } #endif } } // still in ReadingDataState? This function will be called again by the socket's readyRead if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) break; // everything done, fall through } case QHttpNetworkReplyPrivate::AllDoneState: allDone(); break; default: break; } } }
static int Section (FILE * fp, int (*sfunc) (char *)) { int p; p = eatWhitespace (fp); /* ** we've already got the '['. scan past initial ** white space */ char section[SECTION_LENGTH]; int section_length = 0; char section_finished = 0; while (!section_finished) { switch (p) { case ']' : { if (section_length == 0) { fprintf(stderr, "Empty section length\n"); return -1; break; } if (section_length == SECTION_LENGTH) { fprintf(stderr, "Section name too long\n"); return -1; } // Terminate the string section[section_length] = '\0'; section_length++; section_finished = 1; break; } case ' ' : case '\t' : { fprintf(stderr, "Unexpected whitespace in section name\n"); return -1; break; } case EOF : { fprintf(stderr, "Unexpected end of file\n"); return -1; break; } case '\n': { fprintf(stderr, "Unexpected end of file\n"); return -1; break; } default: { while (p != ']' && p != '\n' && p != ' ' && p != '\t' && p != EOF) { if (section_length == SECTION_LENGTH) { fprintf(stderr, "Section name too long\n"); } section[section_length] = p; section_length++; p = getc(fp); } // Maybe this is the end of name if (p == ' ' || p == '\t') { p = eatWhitespace(fp); } } } } /* fprintf(stderr, "[MCFG] Section -> '%s'\n", section); fprintf(stderr, "[MCFG] \n"); */ return sfunc(section); }
bool MenuConf::readItemCaption(FILE* f, Item* item) { eatWhitespace(f); return readQuotedString(f, item->data->caption, ItemData::CaptionSize); }
static int Parameter (FILE * fp, int (*pfunc) (char * option, char * value, int num_flags, char **flags), int c) { int option_length = 0; char option[OPTION_LENGTH]; int num_flags = 0; char _flags[MAX_FLAG_NUM][MAX_FLAG_LENGTH]; char *flags[MAX_FLAG_NUM]; { // Initialize the array of pointers with the static storage int i; for (i = 0; i < MAX_FLAG_NUM; i++) { flags[i] = _flags[i]; } } // First parse flags if any int p = c; // This is the beginning of a flag if (p == '{') { char flags_finished = 0; int current_flag_length = 0; char current_flag[MAX_FLAG_LENGTH]; // After '{' there may be blanks p = eatWhitespace(fp); while (!flags_finished) { switch (p) { case EOF : { fprintf(stderr, "Unexpected end of file while parsing parameter of configuration file\n"); return (-1); } case '}' : { // No more parameters flags_finished = 1; /* Fall-through! */ } case ',' : { if (current_flag_length == MAX_FLAG_LENGTH) { fprintf(stderr, "Flag too long\n"); return -1; } if (current_flag_length == 0 || (current_flag_length == 1 && current_flag[0] == '!')) { fprintf(stderr, "Empty flag\n"); return -1; } // Terminate the string current_flag[current_flag_length] = '\0'; current_flag_length++; if (num_flags == MAX_FLAG_NUM) { fprintf(stderr, "Too many flags\n"); return (-1); } strncpy(flags[num_flags], current_flag, current_flag_length); num_flags++; // Restart the flag current_flag_length = 0; // After a ',' or '}' we allow blanks p = eatWhitespace(fp); break; } case '\n': { fprintf(stderr, "Invalid newline in flags\n"); return -1; break; } case ' ': case '\t': { fprintf(stderr, "Invalid whitespace in flags\n"); return -1; break; } default: { if (p == '!') // Negation { if (current_flag_length == MAX_FLAG_LENGTH) { fprintf(stderr, "Flag too long\n"); return -1; } current_flag[current_flag_length] = p; current_flag_length++; p = eatWhitespace(fp); } // Advance as many as possible while (p != ' ' // Blank && p != '\t' // Blank && p != '\n' // newline && p != ',' // Comma && p != '}' // End of flags && p != '!' // Negation && p != EOF ) { if (current_flag_length == MAX_FLAG_LENGTH) { fprintf(stderr, "Flag too long\n"); return -1; } current_flag[current_flag_length] = p; current_flag_length++; p = getc(fp); } // Maybe this is the end of a flag if (p == ' ' || p == '\t') { p = eatWhitespace(fp); } break; } } } } // We allow this because it is more flexible when autogenerating the // configure if (p == '\n') { // Do not do anything but returning success return 0; } char option_finished = 0; while (!option_finished) { switch (p) { case EOF : { fprintf(stderr, "Unexpected end of file when parsing option\n"); return -1; break; } case '=' : { if (option_length == 0) { fprintf(stderr, "Empty option\n"); return -1; } if (option_length == OPTION_LENGTH) { fprintf(stderr, "Option too long\n"); return -1; } // Terminate the string option[option_length] = '\0'; option_length++; option_finished = 1; // Allow whitespaces after the finished option p = eatWhitespace(fp); break; } case '\n': { fprintf(stderr, "Unexpected end of line when parsing option\n"); return -1; break; } case ' ' : case '\t' : { fprintf(stderr, "Invalid whitespace when parsing option\n"); return -1; break; } default: { while (p != EOF && p != '=' && p != '\n' && p != ' ' && p != '\t') { if (option_length == OPTION_LENGTH) { fprintf(stderr, "Option too long\n"); return -1; } option[option_length] = p; option_length++; p = getc(fp); } // Maybe this is the end of the option if (p == ' ' || p == '\t') { p = eatWhitespace(fp); } break; } } } int value_length = 0; char value[VALUE_LENGTH]; // Get the rest of the line and trim at the same time // This is -1 because in empty strings there is no last non blank // but there will be '\0' so when incremented it will be 0 int last_nonblank = -1; while (p != '\n' && p != EOF) { if (value_length == VALUE_LENGTH) { fprintf(stderr, "Value for option too long\n"); return -1; } // Store if this is nonblank if (p != ' ' && p != '\t') { last_nonblank = value_length; } value[value_length] = p; value_length++; p = getc(fp); } // Terminate the string value[last_nonblank + 1] = '\0'; value_length = last_nonblank + 1; /* fprintf(stderr, "[MCFG] Option -> '%s'\n", option); fprintf(stderr, "[MCFG] Value -> '%s'\n", value); fprintf(stderr, "[MCFG] num_flags -> '%d'\n", num_flags); { int i; for (i = 0; i < num_flags; i++) { fprintf(stderr, "[MCFG] flags[%d] -> '%s'\n", i, flags[i]); } } fprintf(stderr, "[MCFG] \n"); */ return pfunc(option, value, num_flags, flags); }
void QHttpNetworkConnectionChannel::_q_receiveReply() { Q_ASSERT(socket); qint64 bytes = 0; QAbstractSocket::SocketState socketState = socket->state(); // connection might be closed to signal the end of data if (socketState == QAbstractSocket::UnconnectedState) { if (!socket->bytesAvailable()) { if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); } else { // try to reconnect/resend before sending an error. if (reconnectAttempts-- > 0) { closeAndResendCurrentRequest(); } else if (reply) { reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::RemoteHostClosedError, socket); emit reply->finishedWithError(QNetworkReply::RemoteHostClosedError, reply->d_func()->errorString); QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); } } } } // read loop for the response while (socket->bytesAvailable()) { QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState; switch (state) { case QHttpNetworkReplyPrivate::NothingDoneState: case QHttpNetworkReplyPrivate::ReadingStatusState: { eatWhitespace(); qint64 statusBytes = reply->d_func()->readStatus(socket); if (statusBytes == -1 && reconnectAttempts <= 0) { // too many errors reading/receiving/parsing the status, close the socket and emit error close(); reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::ProtocolFailure, socket); emit reply->finishedWithError(QNetworkReply::ProtocolFailure, reply->d_func()->errorString); QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); break; } else if (statusBytes == -1) { reconnectAttempts--; reply->d_func()->clear(); closeAndResendCurrentRequest(); break; } bytes += statusBytes; lastStatus = reply->d_func()->statusCode; break; } case QHttpNetworkReplyPrivate::ReadingHeaderState: { QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); bytes += replyPrivate->readHeader(socket); if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) { if (replyPrivate->isGzipped() && replyPrivate->autoDecompress) { // remove the Content-Length from header replyPrivate->removeAutoDecompressHeader(); } else { replyPrivate->autoDecompress = false; } if (replyPrivate->statusCode == 100) { replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState; break; // ignore } if (replyPrivate->shouldEmitSignals()) emit reply->headerChanged(); if (!replyPrivate->expectContent()) { replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState; this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); return; } } break; } case QHttpNetworkReplyPrivate::ReadingDataState: { QHttpNetworkReplyPrivate *replyPrivate = reply->d_func(); if (replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) { // We already have some HTTP body data. We don't read more from the socket until // this is fetched by QHttpNetworkAccessHttpBackend. If we would read more, // we could not limit our read buffer usage. // We only do this when shouldEmitSignals==true because our HTTP parsing // always needs to parse the 401/407 replies. Therefore they don't really obey // to the read buffer maximum size, but we don't care since they should be small. return; } if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress && replyPrivate->bodyLength > 0) { // bulk files like images should fulfill these properties and // we can therefore save on memory copying bytes = replyPrivate->readBodyFast(socket, &replyPrivate->responseData); replyPrivate->totalProgress += bytes; if (replyPrivate->shouldEmitSignals()) { QPointer<QHttpNetworkReply> replyPointer = reply; emit reply->readyRead(); // make sure that the reply is valid if (replyPointer.isNull()) return; emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength); // make sure that the reply is valid if (replyPointer.isNull()) return; } } else { // use the traditional slower reading (for compressed encoding, chunked encoding, // no content-length etc) QByteDataBuffer byteDatas; bytes = replyPrivate->readBody(socket, &byteDatas); if (bytes) { if (replyPrivate->autoDecompress) replyPrivate->appendCompressedReplyData(byteDatas); else replyPrivate->appendUncompressedReplyData(byteDatas); if (!replyPrivate->autoDecompress) { replyPrivate->totalProgress += bytes; if (replyPrivate->shouldEmitSignals()) { QPointer<QHttpNetworkReply> replyPointer = reply; // important: At the point of this readyRead(), the byteDatas list must be empty, // else implicit sharing will trigger memcpy when the user is reading data! emit reply->readyRead(); // make sure that the reply is valid if (replyPointer.isNull()) return; emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength); // make sure that the reply is valid if (replyPointer.isNull()) return; } } #ifndef QT_NO_COMPRESS else if (!expand(false)) { // expand a chunk if possible return; // ### expand failed } #endif } } if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) break; // everything done, fall through } case QHttpNetworkReplyPrivate::AllDoneState: this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); break; default: break; } } }