summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-09-17 13:54:40 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-09-17 13:54:40 +0300
commit1bc0b0657cdc9fc9c092896a7f893bca0c50c4ea (patch)
tree09920e1526f5a54325d12f9f0b5af36370896fb5 /src
parent0c63ec79606a42d944aeed0fd52596c55d6a0768 (diff)
MBinBuffer made a bit smarter to allow the decent people to return it from functions
Diffstat (limited to 'src')
-rw-r--r--src/mir_core/src/binbuffer.cpp129
-rw-r--r--src/mir_core/src/mir_core.def2
2 files changed, 106 insertions, 25 deletions
diff --git a/src/mir_core/src/binbuffer.cpp b/src/mir_core/src/binbuffer.cpp
index e5aef775bd..d558dcc7b7 100644
--- a/src/mir_core/src/binbuffer.cpp
+++ b/src/mir_core/src/binbuffer.cpp
@@ -17,15 +17,81 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-MBinBuffer::MBinBuffer() :
- m_buf(nullptr),
- m_len(0)
+struct BufImpl
{
+ uint32_t size, lockCount;
+
+ BufImpl* alloc(size_t newSize)
+ {
+ bool bEmpty = (this == nullptr);
+ auto *res = (BufImpl *)mir_realloc(this, newSize + sizeof(BufImpl));
+ if (bEmpty) {
+ res->lockCount = 1;
+ res->size = 0;
+ }
+ return res;
+ }
+
+ BufImpl* realloc(size_t newSize)
+ {
+ bool bEmpty;
+ newSize += sizeof(BufImpl);
+ if (this != nullptr) {
+ newSize += size;
+ bEmpty = false;
+ }
+ else bEmpty = true;
+
+ auto *res = (BufImpl *)mir_realloc(this, newSize);
+ if (bEmpty) {
+ res->lockCount = 1;
+ res->size = 0;
+ }
+ return res;
+ }
+
+ void free()
+ {
+ if (this == nullptr)
+ return;
+
+ if (lockCount == 1)
+ mir_free(this);
+ else
+ lockCount--;
+ }
+};
+
+__forceinline BufImpl* ptr2buf(char *p)
+{
+ return (p == nullptr) ? nullptr : (BufImpl*)p-1;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+MBinBuffer::MBinBuffer()
+{}
+
+MBinBuffer::MBinBuffer(const MBinBuffer &orig)
+{
+ ptr2buf(m_buf)->free();
+
+ BufImpl *p = ptr2buf(m_buf = orig.m_buf);
+ if (p)
+ p->lockCount++;
+}
+
+MBinBuffer::MBinBuffer(size_t preAlloc)
+{
+ BufImpl *p = (BufImpl *)mir_alloc(sizeof(BufImpl) + preAlloc);
+ p->lockCount = 1;
+ p->size = (unsigned)preAlloc;
+ m_buf = (char*)(p + 1);
}
MBinBuffer::~MBinBuffer()
{
- mir_free(m_buf);
+ ptr2buf(m_buf)->free();
}
void MBinBuffer::append(const void *pBuf, size_t bufLen)
@@ -33,12 +99,13 @@ void MBinBuffer::append(const void *pBuf, size_t bufLen)
if (pBuf == nullptr || bufLen == 0)
return;
- m_buf = (char*)mir_realloc(m_buf, bufLen + m_len);
- if (m_buf) {
- memcpy(m_buf + m_len, pBuf, bufLen);
- m_len += bufLen;
+ BufImpl *p = ptr2buf(m_buf)->realloc(bufLen);
+ if (p) {
+ m_buf = (char*)(p + 1);
+ memcpy(m_buf + p->size, pBuf, bufLen);
+ p->size += (unsigned)bufLen;
}
- else m_len = 0;
+ else m_buf = nullptr;
}
void MBinBuffer::appendBefore(const void *pBuf, size_t bufLen)
@@ -46,13 +113,14 @@ void MBinBuffer::appendBefore(const void *pBuf, size_t bufLen)
if (pBuf == nullptr || bufLen == 0)
return;
- m_buf = (char*)mir_realloc(m_buf, bufLen + m_len);
- if (m_buf) {
- memmove(m_buf + bufLen, m_buf, m_len);
+ BufImpl *p = ptr2buf(m_buf)->realloc(bufLen);
+ if (p) {
+ m_buf = (char *)(p + 1);
+ memmove(m_buf + bufLen, m_buf, p->size);
memcpy(m_buf, pBuf, bufLen);
- m_len += bufLen;
+ p->size += (unsigned)bufLen;
}
- else m_len = 0;
+ else m_buf = nullptr;
}
void MBinBuffer::assign(const void *pBuf, size_t bufLen)
@@ -60,25 +128,36 @@ void MBinBuffer::assign(const void *pBuf, size_t bufLen)
if (pBuf == nullptr || bufLen == 0)
return;
- m_buf = (char *)mir_realloc(m_buf, bufLen);
- if (m_buf) {
+ BufImpl *p = ptr2buf(m_buf)->alloc(bufLen);
+ if (p) {
+ p->size = (unsigned)bufLen;
+ m_buf = (char *)(p + 1);
memcpy(m_buf, pBuf, bufLen);
- m_len = bufLen;
}
- else m_len = 0;
+ else m_buf = nullptr;
+}
+
+size_t MBinBuffer::length() const
+{
+ BufImpl *p = ptr2buf(m_buf);
+ return (p) ? p->size : 0;
}
void MBinBuffer::remove(size_t sz)
{
- if (sz > m_len)
- m_len = sz;
+ BufImpl *p = ptr2buf(m_buf);
+ if (!p)
+ return;
+
+ if (sz > p->size)
+ sz = p->size;
- if (m_len == sz) {
- m_len = 0;
- mir_free(m_buf); m_buf = nullptr;
+ if (p->size == sz) {
+ p->free();
+ m_buf = nullptr;
}
else {
- memmove(m_buf, m_buf + sz, m_len - sz);
- m_len -= sz;
+ memmove(m_buf, m_buf + sz, p->size - sz);
+ p->size -= (unsigned)sz;
}
}
diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def
index 9409e6d133..619b069b3a 100644
--- a/src/mir_core/src/mir_core.def
+++ b/src/mir_core/src/mir_core.def
@@ -1541,3 +1541,5 @@ Miranda_WaitOnHandle @1760
Miranda_WaitOnHandleEx @1761
_Utils_CorrectFontSize@4 @1762 NONAME
?OnResize@CDlgBase@@MAEXXZ @1763 NONAME
+??0MBinBuffer@@QAE@ABV0@@Z @1764 NONAME
+??0MBinBuffer@@QAE@I@Z @1765 NONAME