⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 databuffer.cpp

📁 彩信浏览器
💻 CPP
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player 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 Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA/*  * @$Id: databuffer.cpp,v 1.41 2007/02/12 14:15:09 jackjansen Exp $  */#include "ambulant/net/databuffer.h"#include "ambulant/lib/logger.h"#ifndef AMBULANT_PLATFORM_WIN32#include <unistd.h>#endif//#define AM_DBG#ifndef AM_DBG#define AM_DBG if(0)#endif// Define this to put random garbage into newly allocated buffer space// and into buffer space that has been freed.#undef RANDOM_BYTES// ***********************************  C++  CODE  ***********************************// data_buffer//#define DEFAULT_MAX_BUF_SIZE 4096long int ambulant::net::databuffer::s_default_max_size = 1000000;long int ambulant::net::databuffer::s_default_max_unused_size = 1000000;using namespace ambulant;using namespace net;// Static methods:voiddatabuffer::default_max_size(int max_size){	s_default_max_size = max_size;}voiddatabuffer::default_max_unused_size(int max_unused_size){	s_default_max_unused_size = max_unused_size;}databuffer::databuffer(int max_size):	m_buffer(NULL),	m_reading(false),	m_writing(false),	m_old_buffer(NULL),	m_rear(0),	m_size(0),	m_max_size(max_size),	m_max_unused_size(s_default_max_unused_size),	m_used(0),	m_buffer_full(false){	AM_DBG lib::logger::get_logger()->debug("databuffer::databuffer() -> 0x%x", (void*)this);	if (m_max_size == 0) m_max_size = s_default_max_size;}booldatabuffer::buffer_full(){	m_lock.enter();	bool rv = m_buffer_full;	m_lock.leave();	return rv;}booldatabuffer::buffer_not_empty(){	m_lock.enter();	bool rv = (m_used > 0);	m_lock.leave();	return rv;}voiddatabuffer::set_max_size(int max_size){	m_lock.enter();	// Zero means: no limit, <0 means: default    if (max_size >= 0) {        m_max_size = max_size;    } else {        m_max_size = s_default_max_size;    }    m_buffer_full = (m_max_size > 0 && m_used > m_max_size);	if (m_buffer_full) lib::logger::get_logger()->debug("databuffer::set_max_size(0x%x, %d): buffer now full (used=%d)",		(void*)this, max_size, m_used);	m_lock.leave();}databuffer::~databuffer(){	m_lock.enter();	AM_DBG lib::logger::get_logger()->debug("databuffer::~databuffer(0x%x)", (void*)this);	assert(!m_reading);	assert(!m_writing);	if (m_buffer) {		free(m_buffer);        m_buffer = NULL;	}	if (m_old_buffer) {		free(m_old_buffer);		m_old_buffer = NULL;	}	m_lock.leave();}int databuffer::size() const{	const_cast<databuffer*>(this)->m_lock.enter();//XXXX	assert(!m_reading);	int rv = m_used;	assert(rv < 10000000); // TMP sanity check	const_cast<databuffer*>(this)->m_lock.leave();	return rv;}#ifndef AMBULANT_NO_IOSTREAMS_HEADERSvoid databuffer::dump(std::ostream& os, bool verbose) const{	unsigned long int i;	os << "BUFFER SIZE : " << m_size << " bytes" << std::endl;	os << "BYTES USED : " << m_used << " bytes" << std::endl;	os << "m_rear   : " << m_rear << std::endl;	if (verbose) {		if (m_buffer) {			for (i = m_rear;i < m_size;i++) {	   		os << m_buffer[i];	   		}		}	}  	os << std::endl;}#endifchar *databuffer::get_write_ptr(int sz){	m_lock.enter();	assert(!m_writing);	assert(sz > 0);	m_writing = true;		char *rv = NULL;	AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x).get_write_ptr(%d): start ", (void*)this, sz);	    if(!m_buffer_full) {			//AM_DBG lib::logger::get_logger()->debug("databuffer.get_write_ptr: returning m_front (%x)",m_buffer + m_size);			_grow(sz);			rv = m_buffer + m_size;		    } else {        lib::logger::get_logger()->trace("databuffer::databuffer::get_write_ptr : buffer full but still trying to obtain write pointer ");		rv = NULL;    }    m_lock.leave();	return rv;}voiddatabuffer::_grow(int sz){	assert(sz > 0);	if (m_reading && m_old_buffer == NULL) {		// We cannot realloc, the buffer is in use. Copy.		m_old_buffer = m_buffer;		m_buffer = (char*)malloc(m_size + sz);		if (m_buffer) memcpy(m_buffer, m_old_buffer, m_size);		AM_DBG lib::logger::get_logger()->debug("databuffer::get_write_ptr: buffer alloc/copy to from %d to %d bytes",m_size, m_size + sz);	} else {		m_buffer = (char*) realloc(m_buffer, m_size + sz);		AM_DBG lib::logger::get_logger()->debug("databuffer::get_write_ptr: buffer realloc to from %d to %d bytes",m_size, m_size + sz);	}	AM_DBG lib::logger::get_logger()->debug("databuffer::get_write_ptr: buffer realloc done (%x)",m_buffer);	if (!m_buffer) {		lib::logger::get_logger()->fatal("databuffer::get_write_ptr(size=%d): out of memory", m_size+sz);	}#ifdef RANDOM_BYTES	unsigned int i;	for(i=m_size; i<m_size+sz; i++) m_buffer[i] = (char) rand();#endif}void databuffer::pushdata(int sz){	m_lock.enter();	assert(m_writing);	m_writing = false;	AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x)::pushdata(%d) m_size=%d", (void*)this, sz, m_size);	if (m_buffer_full) {        lib::logger::get_logger()->trace("databuffer::databuffer::pushdata : buffer full but still trying to fill it");    }	// std::cout << sz << "\n";	assert(sz >= 0);	assert(m_size >= 0);		if (!m_reading) {		// If we have a read pointer outstanding we simply not realloc. It will		// happen the next time.		m_buffer = (char*) realloc(m_buffer, m_size + sz);	}	AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x)::pushdata(%d) realloc m_buffer=x%x, from %d bytes to %d bytes", (void*)this, sz, (void*) m_buffer, m_size, m_size + sz);	m_size += sz;	//AM_DBG lib::logger::get_logger()->debug("databuffer.pushdata:size = %d ",sz);	assert(m_size >= m_rear);	m_used = m_size - m_rear;	 if (!m_buffer && (sz > 0)) {		 lib::logger::get_logger()->fatal("databuffer::pushdata(size=%d): out of memory", m_size);		 abort();	 }	if(m_max_size > 0 && m_used > m_max_size) {		AM_DBG lib::logger::get_logger()->debug("databuffer.pushdata: buffer full [size = %d, max size = %d]",m_size, m_max_size);		m_buffer_full = true;	}	m_lock.leave();}char *databuffer::get_read_ptr(){	m_lock.enter();	char *rv = (m_buffer + m_rear);	AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x)::get_read_ptr(): returning 0x%x (m_size = %d)", (void*)this, (void*)rv, m_size);	assert(!m_reading);	m_reading = true;	m_lock.leave();	return rv;	}voiddatabuffer::readdone(int sz){	m_lock.enter();	assert(m_reading); // if this fails we have a readdone() without a prior get_read_ptr().	m_reading = false;	AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x)::readdone(%d)", (void*)this, sz);	assert((size_t)sz <= m_used);#ifdef RANDOM_BYTES	unsigned int i;	for(i=m_rear; i<m_rear+sz; i++) m_buffer[i] = (char) rand();#endif	m_rear += sz;	assert( m_size >= m_rear);	m_used = m_size - m_rear;	m_buffer_full = (m_max_size > 0 && m_used > m_max_size);		// If the writer needed more space while m_reading was true it will	// have left the old buffer for us to remove.	if (m_old_buffer) {		AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x)::readdone: free old buffer 0x%x", this, m_old_buffer);		free(m_old_buffer);		m_old_buffer = NULL;	}		// Free the unused space in the buffer if the buffer is either empty	// or underused. Skip this if there is a write outstanding, then it'll	// happen the next time around.	if (!m_writing && (m_used == 0 || (m_max_unused_size > 0 && m_rear > m_max_unused_size))) {		 AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x)::readdone(%d) resizing buffer (cur. size = %d)", (void*)this, sz, m_size);		 if (m_used) memcpy(m_buffer, m_buffer+m_rear, m_used);		 m_buffer = (char *)realloc(m_buffer, m_used);		 m_size = m_used;		 m_rear = 0;		 AM_DBG lib::logger::get_logger()->debug("databuffer(0x%x)::readdone(%d) (m_buffer=x%x) resized to %d",  (void*)this, (void*)m_buffer, m_size);		 if (m_buffer == NULL && m_used > 0) {			 lib::logger::get_logger()->fatal("databuffer::readdone(size=%d): out of memory", m_size);		 }	}	m_lock.leave();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -