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);
}