www.pudn.com > simplec++codeforp2p.rar > stream.cpp


// ------------------------------------------------
// File : stream.cpp
// Date: 4-apr-2002
// Author: giles
// Desc:
//		Basic stream handling functions. 
//
// (c) 2002 peercast.org
// ------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// ------------------------------------------------


#include "stream.h"
#include "common.h"
#include "sys.h"


// --------------------------------------------------
void MemoryStream::convertFromBase64()
{       
	char *out = buf;
	char *in = buf;
	
	int rl=len;
    while(rl >= 4) 
	{
		out += String::base64WordToChars(out,in);
		in += 4;
        rl -= 4;
    }
    *out = 0;
	len = out-buf;
}
// -------------------------------------
void FileStream::openReadOnly(const char *fn)
{
	file = fopen(fn,"rb");

    if (!file)
    	throw StreamException("Unable to open file");
}
// -------------------------------------
void FileStream::openWriteReplace(const char *fn)
{
	file = fopen(fn,"wb");

	if (!file) 
    	throw StreamException("Unable to open file");
}
// -------------------------------------
void FileStream::openWriteAppend(const char *fn)
{
        file = fopen(fn,"ab");

        if (!file)
        	throw StreamException("Unable to open file");
}

// -------------------------------------
void FileStream::close()
{
	if (file)
	{
		fclose(file);
		file = NULL;
	}
}
// -------------------------------------
void FileStream::rewind()
{
	if (file)
		fseek(file,0,SEEK_SET);
}
// -------------------------------------
int FileStream::length()
{
	int len = 0;
	if (file)
	{
		int old = ftell(file);
		fseek(file,0,SEEK_END);
		len = ftell(file);
		fseek(file,old,SEEK_SET);

	}
	return len;
}

// -------------------------------------
bool FileStream::eof()
{
	if (file)
		return (feof(file)!=0);
	else
		return true;
}
// -------------------------------------
int FileStream::read(void *ptr, int len)
{
	if (!file)
		return 0;
	if (feof(file))
    	throw StreamException("End of file"); 
 
	int r = (int)fread(ptr,1,len,file);
 
	updateTotals(r, 0); 
    return r; 
}

// -------------------------------------
void FileStream::write(const void *ptr, int len)
{
	if (!file)
		return;
    fwrite(ptr,1,len,file); 
	updateTotals(0, len); 

}
// -------------------------------------
void FileStream::flush()
{
	if (!file)
		return;
    fflush(file);
} 
// ------------------------------------- 
int FileStream::pos() 
{ 
	if (!file) 
		return 0; 
    return ftell(file); 
} 
 
// ------------------------------------- 
void FileStream::seekTo(int pos) 
{ 
	if (!file) 
		return; 
	fseek(file,pos,SEEK_SET); 
} 
 
// ------------------------------------- 
void Stream::writeTo(Stream &out, int len) 
{ 
	char tmp[4096]; 
	while (len) 
	{ 
		int rlen = sizeof(tmp); 
		if (rlen > len) 
			rlen = len; 
 
		read(tmp,rlen); 
		out.write(tmp,rlen); 
 
		len-=rlen; 
	} 
} 
// ------------------------------------- 
int	Stream::writeUTF8(unsigned int code) 
{ 
	if (code < 0x80) 
	{ 
		writeChar(code); 
		return 1; 
	}else  
	if (code < 0x0800) 
	{ 
		writeChar(code>>6 | 0xC0); 
		writeChar(code & 0x3F | 0x80); 
		return 2; 
	}else if (code < 0x10000) 
	{ 
		writeChar(code>>12 | 0xE0); 
		writeChar(code>>6 & 0x3F | 0x80); 
		writeChar(code & 0x3F | 0x80); 
		return 3; 
	}else  
	{ 
		writeChar(code>>18 | 0xF0); 
		writeChar(code>>12 & 0x3F | 0x80); 
		writeChar(code>>6 & 0x3F | 0x80); 
		writeChar(code & 0x3F | 0x80); 
		return 4; 
	} 
		 
} 
 
// ------------------------------------- 
void Stream::skip(int len) 
{ 
	char tmp[4096]; 
	while (len) 
	{ 
		int rlen = sizeof(tmp); 
		if (rlen > len) 
			rlen = len; 
		read(tmp,rlen); 
		len-=rlen; 
	} 
 
} 


// -------------------------------------
void Stream::updateTotals(unsigned int in, unsigned int out)
{
	totalBytesIn += in;
	totalBytesOut += out;

	unsigned int tdiff = sys->getTime()-lastUpdate;
	if (tdiff >= 5)
	{
		bytesInPerSec = (totalBytesIn-lastBytesIn)/tdiff;
		bytesOutPerSec = (totalBytesOut-lastBytesOut)/tdiff;
		lastBytesIn = totalBytesIn;
		lastBytesOut = totalBytesOut;
		lastUpdate = sys->getTime();
	}
}
// -------------------------------------
int	Stream::readLine(char *in, int max)
{
    int i=0;
	max -= 2;

	while(max--)
    {                
    	char c;         
    	read(&c,1);
		if (c == '\n')
			break;
		if (c == '\r')
			continue;
        in[i++] = c;
    }
    in[i] = 0;
	return i;
}
// -------------------------------------
void Stream::write(const char *fmt,va_list ap)
{
	char tmp[4096];
	vsprintf(tmp,fmt,ap);
    write(tmp,strlen(tmp));
}
// -------------------------------------
void Stream::writeStringF(const char *fmt,...)
{
	va_list ap;
  	va_start(ap, fmt);
	write(fmt,ap);
   	va_end(ap);	
}
// ------------------------------------- 
void Stream::writeString(const char *str) 
{ 
	write(str,strlen(str)); 
} 
// -------------------------------------
void Stream::writeLineF(const char *fmt,...)
{
	va_list ap;
  	va_start(ap, fmt);

	write(fmt,ap);

	if (writeCRLF)
	    write("\r\n",2);
	else
		write("\n",1);

   	va_end(ap);	
}
 
// ------------------------------------- 
void Stream::writeLine(const char *str) 
{ 
	writeString(str); 
 
	if (writeCRLF) 
	    write("\r\n",2); 
	else 
		write("\n",1); 
} 

// -------------------------------------
int	Stream::readWord(char *in, int max)
{
	int i=0;
    while (!eof())
    {
        char c = readChar();

        if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n'))
        {
        	if (i)
            	break;		// stop reading
            else
	        	continue;	// skip whitespace
        }

    	if (i >= (max-1))
        	break;

        in[i++] = c;
    }

	in[i]=0;
    return i;
}


// --------------------------------------------------
int Stream::readBase64(char *p, int max)
{       
	char vals[4];

	int cnt=0;
	while (cnt < (max-4))
	{
		read(vals,4);
		int rl = String::base64WordToChars(p,vals);
		if (!rl)
			break;

		p+=rl;
		cnt+=rl;
	}
	*p = 0;
	return cnt;
}

 
// ------------------------------------- 
int Stream::readBits(int cnt) 
{ 
	int v = 0; 
 
	while (cnt) 
	{ 
		if (!bitsPos) 
			bitsBuffer = readChar(); 
 
		cnt--; 
 
		v |= (bitsBuffer&(1<<(7-bitsPos)))?(1<