/// at most dwMinInBufferSize bytes must be decoded, except for the last bytes in stream void ZipArchiveFile::FillOutBuffer(DWORD dwMinInBufferSize) { std::vector<BYTE> vecTempOutBuffer; while (m_vecOutBuffer.size() < dwMinInBufferSize) { FillInputBuffer(); // check input buffer if (m_bEndOfInputStream && m_vecInBuffer.empty()) { // can't uncompress without data in input buffer m_bEndOfOutputStream = true; return; } // uncompress size_t uiUnusedInBytes = 0; { DWORD dwBytesToUncompress = dwMinInBufferSize - m_vecOutBuffer.size(); // ensure minimum number of bytes to produce dwBytesToUncompress = std::max(dwBytesToUncompress, DWORD(256)); bool bRet = m_decompressor.Uncompress( &m_vecInBuffer[0], m_vecInBuffer.size(), uiUnusedInBytes, vecTempOutBuffer, dwBytesToUncompress); //ATLTRACE(_T("Uncompress(): input %u bytes, output %u bytes, consumed %u input bytes\n"), // m_vecInBuffer.size(), // vecTempOutBuffer.size(), // m_vecInBuffer.size() - uiUnusedInBytes); if (!bRet && vecTempOutBuffer.empty()) { m_bEndOfOutputStream = true; return; } } // append to out buffer if (!vecTempOutBuffer.empty()) { m_vecOutBuffer.insert(m_vecOutBuffer.end(), vecTempOutBuffer.begin(), vecTempOutBuffer.end()); vecTempOutBuffer.clear(); } // move unused in bytes to front of buffer if (uiUnusedInBytes > 0) { size_t uiDecompressed = m_vecInBuffer.size() - uiUnusedInBytes; if (uiDecompressed > 0) m_vecInBuffer.erase(m_vecInBuffer.begin(), m_vecInBuffer.begin() + uiDecompressed); } else m_vecInBuffer.clear(); } }
// Handles skiped bytes. void SkipInputData(j_decompress_ptr cinfo, long num_bytes) { if(num_bytes > 0) { while(num_bytes > (long)cinfo->src->bytes_in_buffer) { num_bytes -= (long)cinfo->src->bytes_in_buffer; FillInputBuffer(cinfo); } cinfo->src->next_input_byte += (size_t)num_bytes; cinfo->src->bytes_in_buffer -= (size_t)num_bytes; } }
//------------------------------------------------------------------------- void CFKFileJpg::SkipInputData( j_decompress_ptr p_pInfo, long p_lNumBytes ) { CFKFileJpg* pSource = ( CFKFileJpg* )p_pInfo->src; if( p_lNumBytes > 0 ) { while( p_lNumBytes > ( long )pSource->bytes_in_buffer ) { p_lNumBytes -= ( long )pSource->bytes_in_buffer; FillInputBuffer( p_pInfo ); } pSource->next_input_byte += (size_t)p_lNumBytes; pSource->bytes_in_buffer -= (size_t)p_lNumBytes; } }
void XMLReader::FillOutputBuffer() { if (mOutputStart > mOutputBuffer) { size_t len = mOutputEnd - mOutputStart; std::memmove(mOutputBuffer, mOutputStart, len * sizeof(*mOutputBuffer)); mOutputEnd = mOutputBuffer + len; mOutputStart = mOutputBuffer; } size_t remainingCapacity = mOutputBuffer + kOutputBufferCount - mOutputEnd; if (remainingCapacity > 0) { FillInputBuffer(); if (mInputEnd > mInputStart) { mConverter.Convert(const_cast<const char * &>(mInputStart), mInputEnd, mOutputEnd, mOutputBuffer + kOutputBufferCount); } } }
// Returns true if a node was read successfully, false on EOF bool XMLReader::ReadInternal() { switch (mNodeType) { case kNone: FillInputBuffer(); if ((mInputEnd - mInputStart) >= 2) { uint16_t x = (uint16_t(mInputBuffer[0]) << 8) | mInputBuffer[1]; switch (x) { case 0xFEFF: case 0x003C: mConverter.Reset(TextEncoding::UTF16BE()); break; case 0xFFFE: case 0x3C00: mConverter.Reset(TextEncoding::UTF16LE()); break; } } mNodeType = kDocument; return true; case kDocument: // An XML document can start with: // document ::= prolog element Misc* // prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? // XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' // Misc ::= Comment | PI | S // doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>' // Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->' // PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>' // S ::= (#x20 | #x9 | #xD | #xA)+ // If the XML file starts with a byte order mark, throw it away. // The earlier code for the kNone case has already used it to // set the default encoding. ParseChar(UnicodeChar(0xFEFF)); if (BufferStartsWith("<?xml")) { if (! ParseXmlDeclaration()) return false; UnicodeString encodingName = GetAttribute("encoding"); if (encodingName.empty()) return true; TextEncoding newEncoding = TextEncoding::WebCharset(encodingName.c_str()); if (newEncoding == mConverter.GetSourceEncoding()) return true; // The encoding in the XML declaration is different from the one // we assumed, so we have to reset all the input buffering and // re-parse the XmlDeclaration. mConverter.Reset(newEncoding); mInput.Restart(); mInputStart = mInputEnd = mInputBuffer; mOutputStart = mOutputEnd = mOutputBuffer; ParseChar(UnicodeChar(0xFEFF)); return ParseXmlDeclaration(); } else if (StartsWithWhitespace()) return ParseRequiredWhitespace(); //else if (BufferStartsWith("<!--")) return ParseComment(); //else if (BufferStartsWith("<?")) return ParseProcessingInstruction(); //else if (BufferStartsWith("<!DOCTYPE")) return ParseDocumentType(); else if (BufferStartsWith("<")) return ParseElement(); else return false; case kXmlDeclaration: case kElement: case kEndElement: case kText: case kWhitespace: if (BufferStartsWith("</")) return ParseEndElement(); else if (BufferStartsWith("<")) return ParseElement(); else return ParseText(); } return false; }
ULONGLONG ZipArchiveFile::Seek(LONGLONG llOffset, ESeekOrigin origin) { if (AtEndOfStream()) { // seek beyond end of file return m_uiUncompressedSize; } // calc new position ULONGLONG ullNewPos = m_ullCurrentPos; switch (origin) { case seekBegin: ullNewPos = llOffset; break; case seekCurrent: ullNewPos += llOffset; case seekEnd: ullNewPos = ULONGLONG(m_uiUncompressedSize) - llOffset; break; default: ATLASSERT(false); break; } if (ullNewPos >= m_uiUncompressedSize) { // just seeked to end of file Close(); return m_uiUncompressedSize; } // could be converted into rewind + forward skip if (ullNewPos < m_ullCurrentPos) throw Exception(_T("zip file archive stream can't be seeked backwards"), __FILE__, __LINE__); ULONGLONG ullBytesToSkip = ullNewPos - m_ullCurrentPos; if (ullBytesToSkip == 0) return m_ullCurrentPos; // skip over bytes do { // consume out buffer if (ullBytesToSkip < m_vecOutBuffer.size()) { m_vecOutBuffer.erase(m_vecOutBuffer.begin(), m_vecOutBuffer.begin() + static_cast<size_t>(ullBytesToSkip)); ullBytesToSkip = 0; } else if (ullBytesToSkip == m_vecOutBuffer.size()) { m_vecOutBuffer.clear(); ullBytesToSkip = 0; } else { // more than enough in buffer ullBytesToSkip -= m_vecOutBuffer.size(); m_vecOutBuffer.clear(); } // when not enough, decode more input if (ullBytesToSkip > 0) { FillInputBuffer(); // read in at most 16k at a time DWORD dwBytesToRead = static_cast<DWORD>(std::min<ULONGLONG>(ullBytesToSkip, c_dwSkipBufferSize)); FillOutBuffer(dwBytesToRead); } } while (ullBytesToSkip > 0); m_ullCurrentPos = ullNewPos; return m_ullCurrentPos; }