/** * Can be called after last byte is sent to finish up, on the off chance we did not * end with a valid trailer */ int mpp_finish(parse_ctx *ctx) { ctx->data_buffer[ctx->data_pos] = 0; // fprintf(stdout, "finish leftover[%s]\n", ctx->data_buffer); if (ctx->reading_meta == 0 && ctx->reading_unknown == 0) { flush_data_buffer(ctx); flush_unknown_buffer(ctx); return -1; } else if (ctx->reading_meta == 0 && ctx->reading_data == 1) { flush_data_buffer(ctx); return -1; } else { return 0; } }
//----------------------------------------------------------------------------- // name: fwrite() // desc: ... //----------------------------------------------------------------------------- size_t XWriteThread::fwrite(const void * ptr, size_t size, size_t nitems, FILE * stream) { if(stream != m_stream) flush_data_buffer(); // TODO: overflow detection if(m_data_buffer->put((char*)ptr, size*nitems) == 0) { EM_log(CK_LOG_SEVERE, "XWriteThread::fwrite: data buffer overflow"); } m_bytes_in_buffer += size*nitems; m_stream = stream; if(m_bytes_in_buffer >= PRODUCER_BUFFER_SIZE) flush_data_buffer(); return nitems; }
//----------------------------------------------------------------------------- // name: fclose() // desc: ... //----------------------------------------------------------------------------- int XWriteThread::fclose(FILE *stream) { flush_data_buffer(); Message msg; msg.file = stream; msg.operation = Message::CLOSE; m_msg_buffer->put(msg); return 0; }
//----------------------------------------------------------------------------- // name: fseek() // desc: ... //----------------------------------------------------------------------------- int XWriteThread::fseek(FILE *stream, long offset, int whence) { flush_data_buffer(); Message msg; msg.file = stream; msg.operation = Message::SEEK; msg.seek.offset = offset; msg.seek.whence = whence; m_msg_buffer->put(msg); return 0; }
int mpp_process_char(parse_ctx *ctx, char c) { // trap errors first if (ctx->meta_pos >= META_BUFFER_SIZE - 1 || ctx->data_pos >= DATA_BUFFER_SIZE - 1 || ctx->unknown_pos >= UNKNOWN_BUFFER_SIZE - 1) { // fprintf(stdout, "Buffer limit reached meta[%d] data[%d] unknown[%d]\n", ctx->meta_pos, ctx->data_pos, ctx->unknown_pos); return 1; } // discard leading new lines if ( ctx->reading_meta == 0 && ctx->reading_data == 0 && ctx->reading_unknown == 0 ) { if ( c == '\n' || c == '\r' ) { return 0; } else { // fprintf(stdout, "Started parse of data\n"); ctx->reading_meta = 1; ctx->meta_buffer[ctx->meta_pos] = c; ctx->meta_pos++; return 0; } } // hit a new line char if ( c == '\n' ) { // fprintf(stdout, "newline\n"); if ( ctx->reading_meta == 1 ) { if ( ctx->last_was_newline == 1 ) { // fprintf(stdout, "\n double newline end of meta \n\n"); ctx->last_was_newline = 0; ctx->reading_meta = 0; ctx->reading_data = 1; discard_meta(ctx); } else { ctx->meta_buffer[ctx->meta_pos] = 0; process_meta_newline(ctx); ctx->last_was_newline = 1; } return 0; } else if ( ctx->reading_unknown == 1 ) { // fprintf(stdout, "newline in unknown_state always wrong [%d]\n", c); ctx->unknown_buffer[ctx->unknown_pos] = c; ctx->unknown_pos++; flush_data_buffer(ctx); flush_unknown_buffer(ctx); ctx->reading_unknown = 0; ctx->reading_data = 1; return 0; } else if ( ctx->reading_data == 1 ) { // fprintf(stdout, "enter unknown state\n"); ctx->data_buffer[ctx->data_pos] = c; ctx->data_pos++; ctx->reading_unknown = 1 ; return 0; } return -1; //bug } if ( c == '\r' ) { if ( ctx->reading_meta == 1 ) { return 0; } } // any other char c ctx->last_was_newline = 0; if ( ctx->reading_unknown == 1 ) { // fprintf(stdout, "reading_unkown"); int ret = match_boundary(ctx, c); if ( ret == 0 ) { // matching ctx->unknown_buffer[ctx->unknown_pos] = c; ctx->unknown_pos++; return 0; } else if ( ret == 1 ) { // full match // fprintf(stdout, "Match!\n"); // discard CRLF we added, this works for only LF provided there was not a natural CR first (spec requries CRLF anyway) if (ctx->data_buffer[ctx->data_pos -1] == '\n') ctx->data_pos--; if (ctx->data_buffer[ctx->data_pos -1] == '\r') ctx->data_pos--; ctx->data_buffer[ctx->data_pos] = 0; // string terminate (not needed except for debug) int ret = flush_data_buffer(ctx); ctx->unknown_buffer[0] = 0; ctx->unknown_pos = 0; ctx->reading_file = 0; ctx->reading_unknown = 0; ctx->reading_data = 0; ctx->reading_meta = 1; return ret; } else { // fprintf(stdout, "False alarm!!\n"); ctx->unknown_buffer[ctx->unknown_pos] = c; ctx->unknown_pos++; int ret = flush_data_buffer(ctx); flush_unknown_buffer(ctx); ctx->reading_unknown = 0; return ret; } } // fill the buffers else if (ctx->reading_meta == 1) { // fprintf(stdout, "filling meta [%d]\n" , ctx->meta_pos); ctx->meta_buffer[ctx->meta_pos] = c; ctx->meta_pos++; return 0; } else if (ctx->reading_data == 1) { int ret = 0; if (ctx->data_pos == DATA_BUFFER_SIZE - 2) { // -2 for CRLF that can end up in the data_buffer // flush the data_buffer, it is full ret = flush_data_buffer(ctx); } ctx->data_buffer[ctx->data_pos] = c; ctx->data_pos++; return ret; } else { // fprintf(stdout, "bug\n"); return -2; } }