vm/vmcore/include/ExpandableMemBlock.h (76 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _MEM_BLOCK_H_
#define _MEM_BLOCK_H_
#include "port_malloc.h"
class ExpandableMemBlock
{
public:
ExpandableMemBlock(long nBlockLen = 2000, long nInc = 1000)
: m_nBlockLen(nBlockLen), m_nCurPos(0), m_nInc(nInc){
assert(nInc > 0);
m_pBlock = STD_MALLOC(m_nBlockLen);
assert(m_pBlock);
}
~ExpandableMemBlock(){
if(m_pBlock)
STD_FREE(m_pBlock);
}
void AppendBlock(const char *szBlock, long nLen = -1){
if(!szBlock)return;
if(nLen <= 0)nLen = (long) strlen(szBlock);
if(!nLen)return;
long nOweSpace = (m_nCurPos + nLen) - m_nBlockLen;
if(nOweSpace >= 0){ //change > 0 to >= 0, prevents assert in m_free(m_pBlock)
m_nBlockLen += (nOweSpace / m_nInc + 1)*m_nInc;
m_pBlock = STD_REALLOC(m_pBlock, m_nBlockLen);
assert(m_pBlock);
}
//memmove((char*)m_pBlock + m_nCurPos, szBlock, nLen);
memcpy((char*)m_pBlock + m_nCurPos, szBlock, nLen);
m_nCurPos += nLen;
}
void AppendFormatBlock(const char *szfmt, ... ){
va_list arg;
//char *buf = (char*)calloc(1024, 1);
char buf[1024];
va_start( arg, szfmt );
vsprintf(buf, szfmt, arg );
va_end( arg );
AppendBlock(buf);
//m_free(buf);
}
void SetIncrement(long nInc){
assert(nInc > 0);
m_nInc = nInc;
}
void SetCurrentPos(long nPos){
assert((nPos >= 0) && (nPos < m_nBlockLen));
m_nCurPos = nPos;
}
long GetCurrentPos(){
return m_nCurPos;
}
const void *AccessBlock(){
return m_pBlock;
}
const char *toString(){
*((char*)m_pBlock + m_nCurPos) = '\0';
return (const char*)m_pBlock;
}
void EnsureCapacity(long capacity){
long nOweSpace = capacity - m_nBlockLen;
if(nOweSpace >= 0){ //change > 0 to >= 0, prevents assert in m_free(m_pBlock)
m_nBlockLen += (nOweSpace / m_nInc + 1)*m_nInc;
m_pBlock = STD_REALLOC(m_pBlock, m_nBlockLen);
assert(m_pBlock);
}
}
void CopyTo(ExpandableMemBlock &mb, long len = -1){
if(len == -1)
len = m_nBlockLen;
mb.SetCurrentPos(0);
mb.AppendBlock((char*)m_pBlock, len);
}
protected:
void *m_pBlock;
long m_nBlockLen;
long m_nCurPos;
long m_nInc;
};
#endif /* _MEM_BLOCK_H_ */