title: bzip2: write ok, flush ok, read fail
body: <p>bzip2 1.0.6</p>
  
  <p>Task: compress network packets.
  Problem: bzip2 "BZ_FLUSH" is not working, only "BZ_FINISH" is working, but I need flush current data and keep stream for each connection, not separate stream for every packet.</p>
  
  <p>There is #if preprocessor tag in this code:
  "#if 0" (which is right now) makes bzip2 finish - and it's working;
  "#if 1" makes bzip2 flush - not working (forever stuck in read).</p>
  
  <pre><code>#include &lt;bzlib.h&gt;
  #include &lt;memory.h&gt;
  #include &lt;assert.h&gt;
  #include &lt;iostream&gt;
  using namespace std;
  
  int main()
  {
      typedef unsigned char U1;
      U1 temp[10000];
      size_t temp_count;
  
      U1 bbb[256];
      for ( size_t i=0; i&lt;sizeof(bbb); ++i )
          bbb[i] = i;
  
      {
          bz_stream s;
          memset(&amp;s,0,sizeof(s));
          BZ2_bzCompressInit(&amp;s,1,4,0);
          s.next_in = (char*)&amp;bbb[0];
          s.avail_in = sizeof(bbb);
          s.next_out = (char*)&amp;temp[0];
          s.avail_out = sizeof(temp);
          do
          {
              int res = BZ2_bzCompress(&amp;s,BZ_RUN);
              assert( res == BZ_RUN_OK );
              cout &lt;&lt; "s.avail_in=" &lt;&lt; s.avail_in &lt;&lt; endl;
          }
          while ( s.avail_in );
  #if 0
          do
          {
              int res = BZ2_bzCompress(&amp;s,BZ_FLUSH);
              cout &lt;&lt; "res=" &lt;&lt; res &lt;&lt; endl;
              cout &lt;&lt; "s.avail_in=" &lt;&lt; s.avail_in &lt;&lt; endl;
              if ( res == BZ_RUN_OK )
                  break;
              assert( res == BZ_FLUSH_OK );
          }
          while ( true );
  #else
          do
          {
              int res = BZ2_bzCompress(&amp;s,BZ_FINISH);
              cout &lt;&lt; "res=" &lt;&lt; res &lt;&lt; endl;
              cout &lt;&lt; "s.avail_in=" &lt;&lt; s.avail_in &lt;&lt; endl;
              if ( res == BZ_STREAM_END )
                  break;
              assert( res == BZ_FINISH_OK );
          }
          while ( true );
  #endif
          temp_count = sizeof(temp) - s.avail_out;
          BZ2_bzCompressEnd(&amp;s);
          cout &lt;&lt; "temp_count=" &lt;&lt; temp_count &lt;&lt; endl;
      }
  
      memset( &amp;bbb[0], 0, sizeof(bbb) );
  
      {
          bz_stream s;
          memset(&amp;s,0,sizeof(s));
          BZ2_bzDecompressInit(&amp;s,4,0);
          s.next_in = (char*)&amp;temp[0];
          s.avail_in = temp_count;
          s.next_out = (char*)&amp;bbb[0];
          s.avail_out = sizeof(bbb);
          do
          {
              cout &lt;&lt; "s.avail_in=" &lt;&lt; s.avail_in &lt;&lt; endl;
              int res = BZ2_bzDecompress(&amp;s);
              cout &lt;&lt; "res=" &lt;&lt; res &lt;&lt; endl;
              cout &lt;&lt; "s.avail_out=" &lt;&lt; s.avail_out &lt;&lt; endl;
              if( res == BZ_OK )
                  continue;
              assert( res == BZ_STREAM_END );
              assert( !s.avail_in );
              break;
          }
          while ( true );
          BZ2_bzDecompressEnd(&amp;s);
      }
  
      for ( size_t i=0; i&lt;sizeof(bbb); ++i )
          assert( bbb[i] == i );
  
      return 0;
  }
  </code></pre>