37 #ifdef DABC_EXTRA_CHECKS
38 DebugObject(
"Memory",
this, 1);
45 #ifdef DABC_EXTRA_CHECKS
46 DebugObject(
"Memory",
this, -1);
68 #ifdef DABC_EXTRA_CHECKS
69 DebugObject(
"Buffer",
this, -1);
87 return dynamic_cast<MemoryPool*
> (GetObject()->fPool());
94 for (
unsigned n=0;n<NumSegments();n++)
112 if (len == totalsize)
return;
114 unsigned nseg(0), npos(0);
115 Locate(len, nseg, npos);
117 if (nseg >= NumSegments())
121 GetObject()->fSegm[nseg].datasize = npos;
127 if (nseg<NumSegments()) {
134 GetObject()->fNumSegments = nseg;
143 if (len>=GetTotalSize()) {
148 unsigned nseg(0), npos(0);
149 Locate(len, nseg, npos);
151 if (nseg >= NumSegments())
157 if (PoolPtr()) PoolPtr()->DecreaseSegmRefs(Segments(), nseg);
159 for (
unsigned n=0;n<NumSegments()-nseg;n++)
160 GetObject()->fSegm[n].copy_from(GetObject()->fSegm + n + nseg);
162 GetObject()->fNumSegments -= nseg;
166 GetObject()->fSegm[0].datasize -= npos;
167 GetObject()->fSegm[0].buffer = (
char*) (GetObject()->fSegm[0].buffer) + npos;
179 while ((curr < p) && (seg_indx<NumSegments())) {
180 if (curr + SegmentSize(seg_indx) <= p) {
181 curr += SegmentSize(seg_indx);
186 seg_shift = p - curr;
196 if (
null())
return res;
198 if (PoolPtr()) PoolPtr()->IncreaseSegmRefs(Segments(), NumSegments());
202 res.
GetObject()->fPool = GetObject()->fPool;
206 res.
GetObject()->fNumSegments = NumSegments();
208 for (
unsigned n=0;n<NumSegments();n++)
209 res.
GetObject()->fSegm[n].copy_from(GetObject()->fSegm + n);
217 return Insert(GetTotalSize(), src, moverefs);
222 return Insert(0, src, moverefs);
241 if ((PoolPtr()!=0) && (src.
PoolPtr()!=PoolPtr())) {
256 unsigned tgtseg(0), tgtpos(0);
258 Locate(pos, tgtseg, tgtpos);
260 unsigned numrequired = NumSegments() + ownbuf.
NumSegments();
261 if (tgtpos>0) numrequired++;
263 if (numrequired > GetObject()->fCapacity)
269 for (
unsigned n=NumSegments(); n>tgtseg + (tgtpos>0 ? 1 : 0); ) {
274 segm[n + numrequired - NumSegments()] = segm[n];
284 segm[tgtseg + n + (tgtpos>0 ? 1 : 0)].copy_from(&(srcsegm[n]));
289 if(PoolPtr()) PoolPtr()->IncreaseSegmRefs(segm + tgtseg, 1);
293 segm[seg2].
id = segm[tgtseg].
id;
295 segm[seg2].
buffer = (
char*) segm[tgtseg].buffer + tgtpos;
299 DOUT0(
"split segment %u on two parts, second is in %u", tgtseg, seg2);
303 GetObject()->fNumSegments = numrequired;
305 if (PoolPtr() && (ownbuf.
PoolPtr() == PoolPtr())) {
321 if (
null())
return sbuf;
323 DOUT0(
"Num segments = %u", NumSegments());
325 for (
unsigned nseg=0; nseg<NumSegments(); nseg++) {
326 DOUT0(
"Segm %u = %p %u", nseg, SegmentPtr(nseg), SegmentSize(nseg));
327 sbuf.append((
const char*)SegmentPtr(nseg), SegmentSize(nseg));
353 if (ptr.fullsize()<len)
return res;
355 while (!allowsegmented && (len > ptr.rawsize())) {
356 ptr.shift(ptr.rawsize());
357 if (ptr.fullsize() < len)
break;
360 if (ptr.fullsize() < len)
return res;
362 unsigned firstseg(0), lastseg(0);
366 while ((len>0) && (ptr.fSegm<NumSegments())) {
367 unsigned partlen(len);
368 if (partlen>ptr.rawsize()) partlen = ptr.rawsize();
369 if (partlen==0)
break;
372 firstptr = ptr.ptr();
374 firstseg = ptr.fSegm;
385 EOUT(
"Internal problem - not full length covered");
399 for (
unsigned n=firstseg;n<=lastseg;n++) {
410 res.
GetObject()->fNumSegments = lastseg - firstseg + 1;
421 return CreateBuffer(malloc(sz), sz,
true);
432 }
else if (makecopy) {
433 void *newptr = malloc(size);
435 EOUT(
"Failed to allocate buffer of size %u", size);
438 memcpy(newptr, ptr, size);
444 res.
GetObject()->fSegm[0].buffer = (
void*) ptr;
445 res.
GetObject()->fSegm[0].datasize = size;
454 if (!
null() && (pool!=0))
455 return pool->
IsSingleSegmRefs(GetObject()->fSegm, GetObject()->fNumSegments);
468 void* area = malloc(obj_size);
Container for data, referenced by Buffer class.
MemSegment * fSegm
array of segments
unsigned fNumSegments
number of entries in segments list
virtual ~BufferContainer()
Reference fPool
reference on the memory pool (or other object, containing memory)
unsigned fCapacity
capacity of segments list
Reference on memory from memory pool.
Buffer Duplicate() const
Duplicates instance of Buffer with new segments list independent from source.
unsigned NumSegments() const
Returns number of segment in buffer.
bool Insert(BufferSize_t pos, Buffer &src, bool moverefs=true)
Insert content of buffer at specified position.
bool Append(Buffer &src, bool moverefs=true)
Append content of provided buffer.
void AllocateContainer(unsigned capacity)
BufferSize_t CopyTo(void *ptr, BufferSize_t len) const
Copy content into provided raw buffer.
void CutFromBegin(BufferSize_t len)
Remove part of buffer from the beginning.
void SetTotalSize(BufferSize_t len)
Set total length of the buffer to specified value Size cannot be bigger than original size of the buf...
BufferSize_t CopyFrom(const Buffer &srcbuf, BufferSize_t len=0)
Copy content from source buffer.
BufferSize_t GetTotalSize() const
Return total size of all buffer segments.
MemoryPool * PoolPtr() const
MemSegment * Segments() const
Buffer GetNextPart(Pointer &ptr, BufferSize_t len, bool allowsegmented=true)
Returns reference on the part of the memory, referenced by the object.
std::string AsStdString()
Convert content of the buffer into std::string.
BufferSize_t CopyFromStr(const char *src, unsigned len=0)
Copy data from string.
bool Prepend(Buffer &src, bool moverefs=true)
Prepend content of provided buffer.
bool CanSafelyChange() const
Returns true when user can modify buffer content without any doubts.
Reference GetPool() const
Returns reference on the pool, in user code MemoryPoolRef can be used like dabc::Buffer buf = Recv();...
static Buffer CreateBuffer(BufferSize_t sz)
This static method create independent buffer for any other memory pools Therefore it can be used in s...
void SetTypeId(unsigned tid)
void Locate(BufferSize_t p, unsigned &seg_indx, unsigned &seg_shift) const
Helper class to release memory, allocated independently from memory pool Object will be deleted (with...
MemoryContainer(void *ptr=0)
virtual ~MemoryContainer()
void IncreaseSegmRefs(MemSegment *segm, unsigned num)
Method increases ref.counuters of all segments.
bool IsSingleSegmRefs(MemSegment *segm, unsigned num)
Return true when all segments has refcnt==1.
void DecreaseSegmRefs(MemSegment *segm, unsigned num)
Decrease references of specified segments.
Base class for most of the DABC classes.
@ flAutoDestroy
object will be automatically destroyed when no references exists, normally set in constructor,...
Manipulator with dabc::Buffer class.
BufferSize_t copyfrom(const Pointer &src, BufferSize_t sz=0)
Returns actual size copied.
BufferSize_t copyto(void *tgt, BufferSize_t sz) const
BufferSize_t copyfromstr(const char *str, unsigned len=0)
Reference on the arbitrary object
void Release()
Releases reference on the object.
Object * GetObject() const
Return pointer on the object.
bool null() const
Returns true if reference contains nullptr.
const BufferSize_t BufferSizeError
std::string format(const char *fmt,...)
Structure with descriptor of single memory segment.
unsigned id
id of the buffer
void * buffer
pointer on the beginning of buffer (must be in the area of id)
unsigned datasize
length of data
void copy_from(MemSegment *src)