[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [dferry] serialization: Arguments::Writer: make it copyable.
From:       Andreas Hartmetz <ahartmetz () gmail ! com>
Date:       2016-10-12 0:57:07
Message-ID: E1bu7r1-0007PZ-Ud () code ! kde ! org
[Download RAW message or body]

Git commit 911771aff15536d0881fb14b8fdbbdf10f2d5b2d by Andreas Hartmetz.
Committed on 11/10/2016 at 22:08.
Pushed by ahartmetz into branch 'master'.

Arguments::Writer: make it copyable.

Not that useful normally, but QDBusArgument unfortunately must
be copyable in any state.
Only a tiny fraction of copied data needs to be fixed up due to
the change to store variant signatures "inline" in m_data, and
the resulting ability to use positions relative to m_data for
signatures, which works best in that constellation anyway.

M  +74   -0    serialization/arguments.cpp
M  +3    -2    serialization/arguments.h

http://commits.kde.org/dferry/911771aff15536d0881fb14b8fdbbdf10f2d5b2d

diff --git a/serialization/arguments.cpp b/serialization/arguments.cpp
index d6f3cad..7efe905 100644
--- a/serialization/arguments.cpp
+++ b/serialization/arguments.cpp
@@ -163,6 +163,9 @@ public:
         m_elements.reserve(16);
     }
 
+    Private(const Private &other);
+    void operator=(const Private &other);
+
     void reserveData(uint32 size)
     {
         if (likely(size <= m_dataCapacity)) {
@@ -1725,6 +1728,51 @@ Arguments::IoState Arguments::Reader::currentAggregate() const
     return d->m_aggregateStack.back().aggregateType;
 }
 
+Arguments::Writer::Private::Private(const Private &other)
+{
+    *this = other;
+}
+
+void Arguments::Writer::Private::operator=(const Private &other)
+{
+    if (&other == this) {
+        assert(false); // if this happens, the (internal) caller did something wrong
+        return;
+    }
+
+    m_dataElementsCountBeforeNilArray = other.m_dataElementsCountBeforeNilArray;
+    m_dataPositionBeforeNilArray = other.m_dataPositionBeforeNilArray;
+
+    // Arguments m_args can only be default initialized empty or moved-from, in both cases
+    // copying it is okay and fairly cheap.
+    m_args = other.m_args;
+
+    m_nesting = other.m_nesting;
+    m_signature.ptr = other.m_signature.ptr; // ### still needs adjustment, done after allocating m_data
+    m_signature.length = other.m_signature.length;
+    m_signaturePosition = other.m_signaturePosition;
+    m_variantSignaturesWastedSpace = other.m_variantSignaturesWastedSpace;
+
+    m_dataCapacity = other.m_dataCapacity;
+    m_dataPosition = other.m_dataPosition;
+    // handle *m_data and the data it's pointing to
+    if (m_dataCapacity == InitialDataCapacity) {
+        m_data = m_initialDataBuffer;
+    } else {
+        m_data = reinterpret_cast<byte *>(malloc(m_dataCapacity));
+    }
+    memcpy(m_data, other.m_data, m_dataPosition);
+    m_signature.ptr += m_data - other.m_data;
+
+    m_nilArrayNesting = other.m_nilArrayNesting;
+    m_error = other.m_error;
+
+    m_variantSignatures = other.m_variantSignatures;
+
+    m_aggregateStack = other.m_aggregateStack;
+    m_elements = other.m_elements;
+}
+
 Arguments::Writer::Writer()
    : d(new(allocCaches.writerPrivate.allocate()) Private),
      m_state(AnyData)
@@ -1751,6 +1799,32 @@ void Arguments::Writer::operator=(Writer &&other)
     other.d = nullptr;
 }
 
+Arguments::Writer::Writer(const Writer &other)
+   : d(nullptr),
+     m_state(other.m_state),
+     m_u(other.m_u)
+{
+    if (other.d) {
+        d = new Private(*other.d);
+    }
+
+}
+
+void Arguments::Writer::operator=(const Writer &other)
+{
+    if (&other == this) {
+        return;
+    }
+    m_state = other.m_state;
+    m_u = other.m_u;
+    if (d && other.d) {
+        *d = *other.d;
+    } else {
+        Writer temp(other);
+        std::swap(d, temp.d);
+    }
+}
+
 Arguments::Writer::~Writer()
 {
     if (d->m_data != d->m_initialDataBuffer) {
diff --git a/serialization/arguments.h b/serialization/arguments.h
index 5ba00f2..d557c8a 100644
--- a/serialization/arguments.h
+++ b/serialization/arguments.h
@@ -275,8 +275,9 @@ public:
         explicit Writer();
         Writer(Writer &&other);
         void operator=(Writer &&other);
-        Writer(const Writer &other) = delete;
-        void operator=(const Writer &other) = delete;
+        // TODO unit-test copy and assignment
+        Writer(const Writer &other);
+        void operator=(const Writer &other);
 
         ~Writer();
 

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic