[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [dferry] /: Allow to restart an array / dict as empty if not yet written to.
From: Andreas Hartmetz <ahartmetz () gmail ! com>
Date: 2016-11-04 23:33:44
Message-ID: E1c2nzU-0004G9-Un () code ! kde ! org
[Download RAW message or body]
Git commit 71b024e3cddec25750592df20eee2315f981a771 by Andreas Hartmetz.
Committed on 28/10/2016 at 18:21.
Pushed by ahartmetz into branch 'master'.
Allow to restart an array / dict as empty if not yet written to.
This is needed in client code where the number of elements is not
known at the time beginArray/Dict() is called, but there is
enough information for a late fix-up. As happens to be the case
in QtDBus.
This is just a little hack to solve a specific problem and should
not be the first choice when writing possibly empty arrays.
M +32 -7 serialization/arguments.cpp
M +3 -2 serialization/arguments.h
M +1 -0 util/error.h
http://commits.kde.org/dferry/71b024e3cddec25750592df20eee2315f981a771
diff --git a/serialization/arguments.cpp b/serialization/arguments.cpp
index 8bd2ffd..0e87009 100644
--- a/serialization/arguments.cpp
+++ b/serialization/arguments.cpp
@@ -2228,9 +2228,34 @@ void Arguments::Writer::advanceState(cstring \
signatureFragment, IoState newState m_state = AnyData;
}
-void Arguments::Writer::beginArrayOrDict(bool isDict, bool isEmpty)
+void Arguments::Writer::beginArrayOrDict(IoState beginWhat, ArrayOption option)
{
- isEmpty = isEmpty || d->m_nilArrayNesting;
+ assert(beginWhat == BeginArray || beginWhat == BeginDict);
+ if (unlikely(option == RestartEmptyArrayToWriteTypes)) {
+ if (!d->m_aggregateStack.empty()) {
+ Private::AggregateInfo &aggregateInfo = d->m_aggregateStack.back();
+ if (aggregateInfo.aggregateType == beginWhat) {
+ // No writes to the array or dict may have occurred yet
+ if (d->m_signature.length == aggregateInfo.arr.containedTypeBegin) {
+ // Fix up state as if beginArray/Dict() had been called with \
WriteTypesOfEmptyArray + // in the first place. After that small \
fixup we're done and return. + // The code is a slightly modified \
version of code below under: if (isEmpty) { + if \
(!d->m_nilArrayNesting) { + d->m_nilArrayNesting = 1;
+ d->m_dataElementsCountBeforeNilArray = d->m_elements.size() \
+ 1; + d->m_dataPositionBeforeNilArray = d->m_dataPosition;
+ } else {
+ // The array may be implicitly nil (so our poor API client \
doesn't notice) because + // an array below in the aggregate \
stack is nil, so just allow this as a no-op. + }
+ return;
+ }
+ }
+ }
+ VALID_IF(false, Error::InvalidStateToRestartEmptyArray);
+ }
+
+ const bool isEmpty = (option != NonEmptyArray) || d->m_nilArrayNesting;
if (isEmpty) {
if (!d->m_nilArrayNesting++) {
// For simplictiy and performance in the fast path, we keep storing the \
data chunks and any @@ -2241,16 +2266,16 @@ void \
Arguments::Writer::beginArrayOrDict(bool isDict, bool isEmpty) \
d->m_dataPositionBeforeNilArray = d->m_dataPosition; }
}
- if (isDict) {
- advanceState(cstring("a{", strlen("a{")), BeginDict);
+ if (beginWhat == BeginArray) {
+ advanceState(cstring("a", strlen("a")), beginWhat);
} else {
- advanceState(cstring("a", strlen("a")), BeginArray);
+ advanceState(cstring("a{", strlen("a{")), beginWhat);
}
}
void Arguments::Writer::beginArray(ArrayOption option)
{
- beginArrayOrDict(false, option == WriteTypesOfEmptyArray);
+ beginArrayOrDict(BeginArray, option);
}
void Arguments::Writer::endArray()
@@ -2260,7 +2285,7 @@ void Arguments::Writer::endArray()
void Arguments::Writer::beginDict(ArrayOption option)
{
- beginArrayOrDict(true, option == WriteTypesOfEmptyArray);
+ beginArrayOrDict(BeginDict, option);
}
void Arguments::Writer::endDict()
diff --git a/serialization/arguments.h b/serialization/arguments.h
index 5eb6087..4081e26 100644
--- a/serialization/arguments.h
+++ b/serialization/arguments.h
@@ -296,7 +296,8 @@ public:
enum ArrayOption
{
NonEmptyArray = 0,
- WriteTypesOfEmptyArray
+ WriteTypesOfEmptyArray,
+ RestartEmptyArrayToWriteTypes
};
void beginArray(ArrayOption option = NonEmptyArray);
@@ -340,7 +341,7 @@ public:
void doWritePrimitiveType(uint32 alignAndSize);
void doWriteString(uint32 lengthPrefixSize);
void advanceState(cstring signatureFragment, IoState newState);
- void beginArrayOrDict(bool isDict, bool isEmpty);
+ void beginArrayOrDict(IoState beginWhat, ArrayOption option);
void finishInternal();
Private *d;
diff --git a/util/error.h b/util/error.h
index 38c283d..247da72 100644
--- a/util/error.h
+++ b/util/error.h
@@ -72,6 +72,7 @@ public:
CannotEndArrayOrDictHere,
TooFewTypesInArrayOrDict,
ExtraIterationInEmptyArray,
+ InvalidStateToRestartEmptyArray,
InvalidKeyTypeInDict,
GreaterTwoTypesInDict,
ArrayOrDictTooLong,
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic