Logo Search packages:      
Sourcecode: sam2p version File versions

void FlateStoreEncode::vi_write ( char const *  buf,
slen_t  len 
) [virtual]

vi_write() must be called with positive slen_t for normal writing, and vi_write(?,0); must be called to signal EOF. After that, it is prohibited to call vi_write() either way.

Implements Encoder.

Definition at line 392 of file encoder.cpp.

References abuf, abuflen, s1, and GenBuffer::Writable::vi_write().

                                                          {
  register s_t sold;
  register char const*p=buf; char const*pend=p+len;
  (void)sold;
  if (len==0) { /* EOF: flush and send trailer */
    /* Dat: Last block has to be written even if it's empty. */
    if (!had_header) { out.vi_write("\x78\x01", 2); had_header=true; }
    abuf[0]=(char)1; /* Last, stored block with padding */
    abuf[1]=abuflen; abuf[2]=abuflen>>8;
    abuf[3]=~(abuflen); abuf[4]=~(abuflen>>8);
    out.vi_write(abuf, abuflen+5);
    if (s1>=65521) s1-=65521;
    if (s2>=65521) s2-=65521;
    unsigned char trailer[4];
    trailer[0]=s2>>8; trailer[1]=s2&255; trailer[2]=s1>>8; trailer[3]=s1&255;
    out.vi_write((char const*)trailer,4);
    out.vi_write(0,0); /* Signal EOF */
    return;
  }
  /* From rfc1950.txt:
           Adler-32 is composed of two sums accumulated per byte: s1 is
           the sum of all bytes, s2 is the sum of all s1 values. Both sums
           are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
           Adler-32 checksum is stored as s2*65536 + s1 in most-
           significant-byte first (network) order.
  */
  /* Update Adler-32 checksum */
  while (p!=pend) {
    #if SIZEOF_INT>2
      if ((s1+=*(unsigned char const*)p)>=65521) s1-=65521;
      if ((s2+=s1)>=65521) s2-=65521;
    #elif SIZEOF_SHORT==2
      sold=s1;
      if ((s1+=*(unsigned char const*)p))<sold) s1+=15; /* 15==65536-21 */
      sold=s2;
      s2=(s2+s1)&0xffff;
      if ((s2+=s1)<sold) s2+=15;
    #else
      /* vvv 0xffff is needed since unsigned short may be > 0..65535 */
      sold=s1;
      s1=(s1+*(unsigned char const*)p)&0xffff;
      if (s1<sold) s1+=15; /* 15==65536-21 */
      sold=s2;
      s2=(s2+s1)&0xffff;
      if (s2<sold) s2+=15;
    #endif
    p++;
  }
  // fprintf(stderr, "len=%u\n", len);
  unsigned abufleft;
  while ((abufleft=ABUFSIZE-abuflen)<len) {
    // putchar('.');
    // fprintf(stderr, "ABUFSIZE=%u abuflen=%u\n", ABUFSIZE, abuflen);
    memcpy(abuf+abuflen+5, buf, abufleft);
    abuf[0]=0; /* Stored block with padding */
    abuf[1]=(char)ABUFSIZE; abuf[2]=(char)(ABUFSIZE>>8);
    abuf[3]=(char)~(ABUFSIZE); abuf[4]=(char)~(ABUFSIZE>>8);
    if (!had_header) { out.vi_write("\x78\x01", 2); had_header=true; }
    /* fprintf(stderr,"%02x %02x", abuf[1], abuf[2]); */
    out.vi_write(abuf, ABUFSIZE+5); /* emit next stored block with header */
    abuflen=0;
    len-=abufleft;
    buf+=abufleft;
  }
  // putchar('X');
  memcpy(abuf+abuflen+5, buf, len);
  abuflen+=len;
  /* Now abuf is possibly full. That is intentional, so we will be able to
   * emit a full last block instead of an empty one.
   */
}


Generated by  Doxygen 1.6.0   Back to index