| 6 | mWriteTo( mWriteTo ), mChunkNewBuffer( false ), mChunkEnded( false ) {} |
| 7 | |
| 8 | ios_size HttpStreamChunked::write( const char* data, ios_size size ) { |
| 9 | ios_size writeTotal = 0; |
| 10 | |
| 11 | // If the chunk reading ended we just add the buffer received as a header |
| 12 | // Otherwise we process the buffer data as chunk |
| 13 | if ( !mChunkEnded ) { |
| 14 | // Keep a chunk buffer until the end of chunk is found |
| 15 | mChunkBuffer.append( data, size ); |
| 16 | |
| 17 | // If the new chunk starts with \r\n and the last removed chunk |
| 18 | // did not contain the trailing \r\n, we remove it to detect |
| 19 | // correctly the next length data |
| 20 | if ( mChunkNewBuffer ) { |
| 21 | if ( mChunkBuffer.substr( 0, 2 ) == "\r\n" ) { |
| 22 | mChunkBuffer = mChunkBuffer.substr( 2 ); |
| 23 | } |
| 24 | |
| 25 | mChunkNewBuffer = false; |
| 26 | } |
| 27 | |
| 28 | bool retry; |
| 29 | |
| 30 | do { |
| 31 | retry = false; |
| 32 | |
| 33 | // Check for the first \r\n to find the end of the length definition |
| 34 | std::string::size_type lenEnd = mChunkBuffer.find( "\r\n" ); |
| 35 | |
| 36 | if ( lenEnd != std::string::npos ) { |
| 37 | std::string::size_type firstCharPos = lenEnd + 2; |
| 38 | Uint64 length; |
| 39 | |
| 40 | // Get the length of the chunk |
| 41 | bool res = String::fromString( length, mChunkBuffer.substr( 0, lenEnd ), 16 ); |
| 42 | |
| 43 | // If the length is solved... |
| 44 | if ( res ) { |
| 45 | // And it's bigger than 0, means that there are more chunks |
| 46 | if ( length > 0 ) { |
| 47 | // Check if the chunk buffer size at least equals to the length reported |
| 48 | if ( mChunkBuffer.size() - firstCharPos >= length ) { |
| 49 | // In that case write the chunk to the file buffer |
| 50 | writeTotal = mWriteTo.write( &mChunkBuffer[firstCharPos], length ); |
| 51 | |
| 52 | // And keep the remaining not completed chunk |
| 53 | mChunkBuffer = mChunkBuffer.substr( firstCharPos + length ); |
| 54 | |
| 55 | // Check if already have the \r\n of the next length in the buffer |
| 56 | if ( !mChunkBuffer.empty() ) { |
| 57 | std::size_t pos = 0; |
| 58 | |
| 59 | // Remove al the \r\n remaining |
| 60 | while ( pos < mChunkBuffer.size() && |
| 61 | 0 == strncmp( &mChunkBuffer[pos], "\r\n", 2 ) ) { |
| 62 | pos += 2; |
| 63 | } |
| 64 | |
| 65 | if ( pos > 0 ) { |
no test coverage detected