/* ** CPQDIF_S_Chunk class. A stream I/O implementing which supports "chunks." ** This will allow a PQDIF file to be embedded in a database binary field, ** for example. ** -------------------------------------------------------------------------- ** ** File name: $Workfile: str_chnk.cpp $ ** Last modified: $Modtime: 10/11/01 12:48p $ ** Last modified by: $Author: Tomm $ ** ** VCS archive path: $Archive: /ElectrotekLibs/Borland/PQDIFlib/str_chnk.cpp $ ** VCS revision: $Revision: 7 $ */ #include "PQDIF_classes.h" // Construction // ============ CPQDIF_S_Chunk::CPQDIF_S_Chunk() { m_chunkRead = NULL; m_sizeChunkRead = 0; m_chunkWrite.SetSize( 0, 64 ); m_posChunk = 0; } CPQDIF_S_Chunk::~CPQDIF_S_Chunk() { // Nothing to delete } bool CPQDIF_S_Chunk::SetInput( BYTE * chunk, long size ) { bool status = FALSE; if( chunk && size > 0 ) { m_chunkRead = chunk; m_sizeChunkRead = size; status = TRUE; } else { m_chunkRead = NULL; m_sizeChunkRead = 0; } return status; } bool CPQDIF_S_Chunk::GetOutputSize( long& size ) { bool status = FALSE; size = m_chunkWrite.GetSize(); status = TRUE; return status; } bool CPQDIF_S_Chunk::GetOutput( BYTE * chunk, long maxSize ) { bool status = FALSE; long sizeActual; if( chunk && maxSize > 0 ) { sizeActual = min( maxSize, (long) m_chunkWrite.GetSize() ); memcpy( chunk, (BYTE *) m_chunkWrite.GetData(), sizeActual ); status = TRUE; } return status; } bool CPQDIF_S_Chunk::SeekPos( int pos ) { bool status = FALSE; m_posChunk = pos; status = TRUE; return status; } bool CPQDIF_S_Chunk::SeekEnd( void ) { bool status = FALSE; // Are we in read mode? if( m_chunkRead ) { m_posChunk = m_sizeChunkRead; status = TRUE; } else { // Nope, write mode. m_posChunk = m_chunkWrite.GetSize(); status = TRUE; } return status; } bool CPQDIF_S_Chunk::GetPos( int& pos ) { bool status = false; pos = m_posChunk; status = true; return status; } BYTE * CPQDIF_S_Chunk::ReadBlock( long size, int& actualSize ) { BYTE * buffRet = NULL; long sizeAvailable; long sizeRead; bool status = FALSE; // Init sizeRead = 0; // Clear buffers m_buffRead.SetSize( 0 ); m_posRead = 0; m_buffWrite.SetSize( 0 ); m_posWrite = 0; // Do we have a valid chunk to read? if( m_chunkRead && m_sizeChunkRead > 0 && m_posChunk >= 0 ) { // Attempt to read the block sizeAvailable = m_sizeChunkRead - m_posChunk; if( sizeAvailable > size ) { sizeRead = size; } else { sizeRead = sizeAvailable; } // Did we get anything? // (If not, we are at the end of the chunk and will return NULL.) if( sizeRead > 0 ) { // Size the buffer first & then copy the block m_buffRead.SetSize( sizeRead ); memcpy( m_buffRead.GetData(), m_chunkRead+m_posChunk, sizeRead ); // Increment past the part we just read. m_posChunk += sizeRead; // We got the block -- now decode it. status = ExecuteProcessorDecode(); if( status ) { // Pass back the decoded buffer buffRet = m_buffWrite.GetData(); actualSize = (long) m_buffWrite.GetSize(); } } } return buffRet; } bool CPQDIF_S_Chunk::WriteBlock( int &sizeActual ) { bool status = FALSE; BYTE * pdataChunk; // Init m_buffWrite.SetSize( 0 ); m_posWrite = 0; sizeActual = 0; // Encode the block status = ExecuteProcessorEncode(); if( status ) { // The write buffer should contain the output sizeActual = m_buffWrite.GetSize(); if( sizeActual > 0 ) { // Force the position to the end of the chunk... // and resize the write chunk. m_posChunk = m_chunkWrite.GetSize(); m_chunkWrite.SetSize( m_posChunk + sizeActual ); // Find where this block goes pdataChunk = (BYTE *) m_buffWrite.GetData(); pdataChunk += m_posChunk; // Copy over the block memcpy( pdataChunk, (BYTE *) m_buffWrite.GetData(), sizeActual ); m_posChunk += sizeActual; status = TRUE; } } return status; }