checksum() private method

private checksum ( ) : void
return void
Esempio n. 1
0
        public int pageseek(Page og)
        {
            int page = returned;
            int next;
            int bytes = fill - returned;

            if (headerbytes == 0)
            {
                int _headerbytes, i;
                if (bytes < 27)
                {
                    return(0);                         // not enough for a header
                }
                /* verify capture pattern */
                //!!!!!!!!!!!
                if (data[page] != 'O' || data[page + 1] != 'g' || data[page + 2] != 'g' || data[page + 3] != 'S')
                {
                    headerbytes = 0;
                    bodybytes   = 0;

                    // search for possible capture
                    next = 0;
                    for (int ii = 0; ii < bytes - 1; ii++)
                    {
                        if (data[page + 1 + ii] == 'O')
                        {
                            next = page + 1 + ii; break;
                        }
                    }
                    //next=memchr(page+1,'O',bytes-1);
                    if (next == 0)
                    {
                        next = fill;
                    }

                    returned = next;
                    return(-(next - page));
                }
                _headerbytes = (data[page + 26] & 0xff) + 27;
                if (bytes < _headerbytes)
                {
                    return(0);                                   // not enough for header + seg table
                }
                // count up body length in the segment table

                for (i = 0; i < (data[page + 26] & 0xff); i++)
                {
                    bodybytes += (data[page + 27 + i] & 0xff);
                }
                headerbytes = _headerbytes;
            }

            if (bodybytes + headerbytes > bytes)
            {
                return(0);
            }

            // The whole test page is buffered.  Verify the checksum
            lock (chksum)
            {
                // Grab the checksum bytes, set the header field to zero

                Array.Copy(data, page + 22, chksum, 0, 4);
                data[page + 22] = 0;
                data[page + 23] = 0;
                data[page + 24] = 0;
                data[page + 25] = 0;

                // set up a temp page struct and recompute the checksum
                Page log = pageseek_p;
                log.header_base = data;
                log.header      = page;
                log.header_len  = headerbytes;

                log.body_base = data;
                log.body      = page + headerbytes;
                log.body_len  = bodybytes;
                log.checksum();

                // Compare
                if (chksum[0] != data[page + 22] ||
                    chksum[1] != data[page + 23] ||
                    chksum[2] != data[page + 24] ||
                    chksum[3] != data[page + 25])
                {
                    // D'oh.  Mismatch! Corrupt page (or miscapture and not a page at all)
                    // replace the computed checksum with the one actually read in
                    Array.Copy(chksum, 0, data, page + 22, 4);
                    // Bad checksum. Lose sync */

                    headerbytes = 0;
                    bodybytes   = 0;
                    // search for possible capture
                    next = 0;
                    for (int ii = 0; ii < bytes - 1; ii++)
                    {
                        if (data[page + 1 + ii] == 'O')
                        {
                            next = page + 1 + ii; break;
                        }
                    }
                    //next=memchr(page+1,'O',bytes-1);
                    if (next == 0)
                    {
                        next = fill;
                    }
                    returned = next;
                    return(-(next - page));
                }
            }

            // yes, have a whole page all ready to go
            {
                page = returned;

                if (og != null)
                {
                    og.header_base = data;
                    og.header      = page;
                    og.header_len  = headerbytes;
                    og.body_base   = data;
                    og.body        = page + headerbytes;
                    og.body_len    = bodybytes;
                }

                unsynced    = 0;
                returned   += (bytes = headerbytes + bodybytes);
                headerbytes = 0;
                bodybytes   = 0;
                return(bytes);
            }
        }
Esempio n. 2
0
        /* This will flush remaining packets into a page (returning nonzero),
               even if there is not enough data to trigger a flush normally
               (undersized page). If there are no packets or partial packets to
               flush, ogg_stream_flush returns 0.  Note that ogg_stream_flush will
               try to flush a normal sized page like ogg_stream_pageout; a call to
               ogg_stream_flush does not gurantee that all packets have flushed.
               Only a return value of 0 from ogg_stream_flush indicates all packet
               data is flushed into pages.

               ogg_stream_page will flush the last page in a stream even if it's
               undersized; you almost certainly want to use ogg_stream_pageout
               (and *not* ogg_stream_flush) unless you need to flush an undersized
               page in the middle of a stream for some reason. */
        public int flush(Page og)
        {
            //System.out.println(this+" ---body_returned: "+body_returned);

            int i;
            int vals=0;
            int maxvals=(lacing_fill>255?255:lacing_fill);
            int bytes=0;
            int acc=0;
            long granule_pos=granule_vals[0];

            if(maxvals==0)return(0);

            /* construct a page */
            /* decide how many segments to include */

            /* If this is the initial header case, the first page must only include
                   the initial header packet */
            if(b_o_s==0)
            {  /* 'initial header page' case */
                granule_pos=0;
                for(vals=0;vals<maxvals;vals++)
                {
                    if((lacing_vals[vals]&0x0ff)<255)
                    {
                        vals++;
                        break;
                    }
                }
            }
            else
            {
                for(vals=0;vals<maxvals;vals++)
                {
                    if(acc>4096)break;
                    acc+=(lacing_vals[vals]&0x0ff);
                    granule_pos=granule_vals[vals];
                }
            }

            /* construct the header in temp storage */

            String oggs_str = "OggS";
            Encoding AE = Encoding.UTF8;
            byte[] oggs_byt = AE.GetBytes(oggs_str);
            Array.Copy(oggs_byt, 0, header, 0, oggs_byt.Length);

            /* stream structure version */
            header[4]=0x00;

            /* continued packet flag? */
            header[5]=0x00;
            if((lacing_vals[0]&0x100)==0)header[5]|=0x01;
            /* first page flag? */
            if(b_o_s==0) header[5]|=0x02;
            /* last page flag? */
            if(e_o_s!=0 && lacing_fill==vals) header[5]|=0x04;
            b_o_s=1;

            /* 64 bits of PCM position */
            for(i=6;i<14;i++)
            {
                header[i]=(byte)granule_pos;
                granule_pos>>=8;
            }

            /* 32 bits of stream serial number */
            {
            int _serialno=serialno;
            for(i=14;i<18;i++)
            {
                header[i]=(byte)_serialno;
                _serialno>>=8;
            }
            }

            /* 32 bits of page counter (we have both counter and page header
                   because this val can roll over) */
            if(pageno==-1)pageno=0;       /* because someone called
                     stream_reset; this would be a
                     strange thing to do in an
                     encode stream, but it has
                     plausible uses */
            {
            int _pageno=pageno++;
            for(i=18;i<22;i++)
            {
                header[i]=(byte)_pageno;
                _pageno>>=8;
            }
            }

            /* zero for computation; filled in later */
            header[22]=0;
            header[23]=0;
            header[24]=0;
            header[25]=0;

            /* segment table */
            header[26]=(byte)vals;
            for(i=0;i<vals;i++)
            {
                header[i+27]=(byte)lacing_vals[i];
                bytes+=(header[i+27]&0xff);
            }

            /* set pointers in the ogg_page struct */
            og.header_base=header;
            og.header=0;
            og.header_len=header_fill=vals+27;
            og.body_base=body_data;
            og.body=body_returned;
            og.body_len=bytes;

            /* advance the lacing data and set the body_returned pointer */

            lacing_fill-=vals;
            Array.Copy(lacing_vals, vals, lacing_vals, 0, lacing_fill*4);
            Array.Copy(granule_vals, vals, granule_vals, 0, lacing_fill*8);
            body_returned+=bytes;

            /* calculate the checksum */

            og.checksum();

            /* done */
            return(1);
        }
Esempio n. 3
0
        /* This will flush remaining packets into a page (returning nonzero),
         *         even if there is not enough data to trigger a flush normally
         *         (undersized page). If there are no packets or partial packets to
         *         flush, ogg_stream_flush returns 0.  Note that ogg_stream_flush will
         *         try to flush a normal sized page like ogg_stream_pageout; a call to
         *         ogg_stream_flush does not gurantee that all packets have flushed.
         *         Only a return value of 0 from ogg_stream_flush indicates all packet
         *         data is flushed into pages.
         *
         *         ogg_stream_page will flush the last page in a stream even if it's
         *         undersized; you almost certainly want to use ogg_stream_pageout
         *         (and *not* ogg_stream_flush) unless you need to flush an undersized
         *         page in the middle of a stream for some reason. */

        public int flush(Page og)
        {
            //System.out.println(this+" ---body_returned: "+body_returned);

            int  i;
            int  vals        = 0;
            int  maxvals     = (lacing_fill > 255?255:lacing_fill);
            int  bytes       = 0;
            int  acc         = 0;
            long granule_pos = granule_vals[0];

            if (maxvals == 0)
            {
                return(0);
            }

            /* construct a page */
            /* decide how many segments to include */

            /* If this is the initial header case, the first page must only include
             *         the initial header packet */
            if (b_o_s == 0)
            {              /* 'initial header page' case */
                granule_pos = 0;
                for (vals = 0; vals < maxvals; vals++)
                {
                    if ((lacing_vals[vals] & 0x0ff) < 255)
                    {
                        vals++;
                        break;
                    }
                }
            }
            else
            {
                for (vals = 0; vals < maxvals; vals++)
                {
                    if (acc > 4096)
                    {
                        break;
                    }
                    acc        += (lacing_vals[vals] & 0x0ff);
                    granule_pos = granule_vals[vals];
                }
            }

            /* construct the header in temp storage */

            String   oggs_str = "OggS";
            Encoding AE       = Encoding.UTF8;

            byte[] oggs_byt = AE.GetBytes(oggs_str);
            Array.Copy(oggs_byt, 0, header, 0, oggs_byt.Length);

            /* stream structure version */
            header[4] = 0x00;

            /* continued packet flag? */
            header[5] = 0x00;
            if ((lacing_vals[0] & 0x100) == 0)
            {
                header[5] |= 0x01;
            }
            /* first page flag? */
            if (b_o_s == 0)
            {
                header[5] |= 0x02;
            }
            /* last page flag? */
            if (e_o_s != 0 && lacing_fill == vals)
            {
                header[5] |= 0x04;
            }
            b_o_s = 1;

            /* 64 bits of PCM position */
            for (i = 6; i < 14; i++)
            {
                header[i]     = (byte)granule_pos;
                granule_pos >>= 8;
            }

            /* 32 bits of stream serial number */
            {
                int _serialno = serialno;
                for (i = 14; i < 18; i++)
                {
                    header[i]   = (byte)_serialno;
                    _serialno >>= 8;
                }
            }

            /* 32 bits of page counter (we have both counter and page header
             *         because this val can roll over) */
            if (pageno == -1)
            {
                pageno = 0;                           /* because someone called
                                                       * stream_reset; this would be a
                                                       * strange thing to do in an
                                                       * encode stream, but it has
                                                       * plausible uses */
            }
            {
                int _pageno = pageno++;
                for (i = 18; i < 22; i++)
                {
                    header[i] = (byte)_pageno;
                    _pageno >>= 8;
                }
            }

            /* zero for computation; filled in later */
            header[22] = 0;
            header[23] = 0;
            header[24] = 0;
            header[25] = 0;

            /* segment table */
            header[26] = (byte)vals;
            for (i = 0; i < vals; i++)
            {
                header[i + 27] = (byte)lacing_vals[i];
                bytes         += (header[i + 27] & 0xff);
            }

            /* set pointers in the ogg_page struct */
            og.header_base = header;
            og.header      = 0;
            og.header_len  = header_fill = vals + 27;
            og.body_base   = body_data;
            og.body        = body_returned;
            og.body_len    = bytes;

            /* advance the lacing data and set the body_returned pointer */

            lacing_fill -= vals;
            Array.Copy(lacing_vals, vals, lacing_vals, 0, lacing_fill * 4);
            Array.Copy(granule_vals, vals, granule_vals, 0, lacing_fill * 8);
            body_returned += bytes;

            /* calculate the checksum */

            og.checksum();

            /* done */
            return(1);
        }