/** * DataBlock.cpp * This file is part of the YATE Project http://YATE.null.ro * * Yet Another Telephony Engine - a fully featured software PBX and IVR * Copyright (C) 2004, 2005 Null Team * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "yateclass.h" #include #include extern "C" { #include "tables/all.h" } using namespace TelEngine; static DataBlock s_empty; const DataBlock& DataBlock::empty() { return s_empty; } DataBlock::DataBlock() : m_data(0), m_length(0) { } DataBlock::DataBlock(const DataBlock& value) : m_data(0), m_length(0) { assign(value.data(),value.length()); } DataBlock::DataBlock(void* value, unsigned int len, bool copyData) : m_data(0), m_length(0) { assign(value,len,copyData); } DataBlock::~DataBlock() { clear(); } void* DataBlock::getObject(const String& name) const { if (name == "DataBlock") return const_cast(this); return GenObject::getObject(name); } void DataBlock::clear(bool deleteData) { m_length = 0; if (m_data) { void *data = m_data; m_data = 0; if (deleteData) ::free(data); } } DataBlock& DataBlock::assign(void* value, unsigned int len, bool copyData) { if ((value != m_data) || (len != m_length)) { void *odata = m_data; m_length = 0; m_data = 0; if (len) { if (copyData) { void *data = ::malloc(len); if (data) { if (value) ::memcpy(data,value,len); else ::memset(data,0,len); m_data = data; } else Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",len); } else m_data = value; if (m_data) m_length = len; } if (odata && (odata != m_data)) ::free(odata); } return *this; } void DataBlock::truncate(unsigned int len) { if (!len) clear(); else if (len < m_length) assign(m_data,len); } void DataBlock::cut(int len) { if (!len) return; int ofs = 0; if (len < 0) ofs = len = -len; if ((unsigned)len >= m_length) { clear(); return; } assign(ofs+(char *)m_data,m_length - len); } DataBlock& DataBlock::operator=(const DataBlock& value) { assign(value.data(),value.length()); return *this; } void DataBlock::append(const DataBlock& value) { if (m_length) { if (value.length()) { unsigned int len = m_length+value.length(); void *data = ::malloc(len); if (data) { ::memcpy(data,m_data,m_length); ::memcpy(m_length+(char*)data,value.data(),value.length()); assign(data,len,false); } else Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",len); } } else assign(value.data(),value.length()); } void DataBlock::append(const String& value) { if (m_length) { if (value.length()) { unsigned int len = m_length+value.length(); void *data = ::malloc(len); if (data) { ::memcpy(data,m_data,m_length); ::memcpy(m_length+(char*)data,value.safe(),value.length()); assign(data,len,false); } else Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",len); } } else assign((void*)value.c_str(),value.length()); } void DataBlock::insert(const DataBlock& value) { unsigned int vl = value.length(); if (m_length) { if (vl) { unsigned int len = m_length+vl; void *data = ::malloc(len); if (data) { ::memcpy(data,value.data(),vl); ::memcpy(vl+(char*)data,m_data,m_length); assign(data,len,false); } else Debug("DataBlock",DebugFail,"malloc(%d) returned NULL!",len); } } else assign(value.data(),vl); } bool DataBlock::convert(const DataBlock& src, const String& sFormat, const String& dFormat, unsigned maxlen) { if (sFormat == dFormat) { operator=(src); return true; } unsigned sl = 0, dl = 0; void *ctable = 0; if (sFormat == "slin") { sl = 2; dl = 1; if (dFormat == "alaw") ctable = s2a; else if (dFormat == "mulaw") ctable = s2u; } else if (sFormat == "alaw") { sl = 1; if (dFormat == "mulaw") { dl = 1; ctable = a2u; } else if (dFormat == "slin") { dl = 2; ctable = a2s; } } else if (sFormat == "mulaw") { sl = 1; if (dFormat == "alaw") { dl = 1; ctable = u2a; } else if (dFormat == "slin") { dl = 2; ctable = u2s; } } clear(); if (!ctable) return false; unsigned len = src.length(); if (maxlen && (maxlen < len)) len = maxlen; len /= sl; if (!len) return true; assign(0,len*dl); if ((sl == 1) && (dl == 1)) { unsigned char *s = (unsigned char *) src.data(); unsigned char *d = (unsigned char *) data(); unsigned char *c = (unsigned char *) ctable; while (len--) *d++ = c[*s++]; } else if ((sl == 1) && (dl == 2)) { unsigned char *s = (unsigned char *) src.data(); unsigned short *d = (unsigned short *) data(); unsigned short *c = (unsigned short *) ctable; while (len--) *d++ = c[*s++]; } else if ((sl == 2) && (dl == 1)) { unsigned short *s = (unsigned short *) src.data(); unsigned char *d = (unsigned char *) data(); unsigned char *c = (unsigned char *) ctable; while (len--) *d++ = c[*s++]; } return true; } /* vi: set ts=8 sw=4 sts=4 noet: */