| /* |
| * |
| * 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. |
| * |
| */ |
| #include "DataBuilder.h" |
| #include "CharSequence.h" |
| #include "qpid/log/Statement.h" |
| #include "qpid/types/encodings.h" |
| |
| namespace qpid { |
| namespace amqp { |
| |
| void DataBuilder::onNull(const Descriptor*) |
| { |
| handle(qpid::types::Variant()); |
| } |
| void DataBuilder::onBoolean(bool v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onUByte(uint8_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onUShort(uint16_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onUInt(uint32_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onULong(uint64_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onByte(int8_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onShort(int16_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onInt(int32_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onLong(int64_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onFloat(float v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onDouble(double v, const Descriptor*) |
| { |
| handle(v); |
| } |
| void DataBuilder::onUuid(const CharSequence& v, const Descriptor*) |
| { |
| if (v.size == qpid::types::Uuid::SIZE) { |
| handle(qpid::types::Uuid(v.data)); |
| } |
| } |
| void DataBuilder::onTimestamp(int64_t v, const Descriptor*) |
| { |
| handle(v); |
| } |
| |
| void DataBuilder::handle(const qpid::types::Variant& v) |
| { |
| switch (nested.top()->getType()) { |
| case qpid::types::VAR_MAP: |
| nested.push(&nested.top()->asMap()[v.asString()]); |
| break; |
| case qpid::types::VAR_LIST: |
| nested.top()->asList().push_back(v); |
| break; |
| default: |
| *(nested.top()) = v; |
| nested.pop(); |
| break; |
| } |
| } |
| |
| void DataBuilder::onBinary(const CharSequence& v, const Descriptor*) |
| { |
| onString(std::string(v.data, v.size), qpid::types::encodings::BINARY); |
| } |
| void DataBuilder::onString(const CharSequence& v, const Descriptor*) |
| { |
| onString(std::string(v.data, v.size), qpid::types::encodings::UTF8); |
| } |
| void DataBuilder::onSymbol(const CharSequence& v, const Descriptor*) |
| { |
| onString(std::string(v.data, v.size), qpid::types::encodings::ASCII); |
| } |
| |
| void DataBuilder::onString(const std::string& value, const std::string& encoding) |
| { |
| switch (nested.top()->getType()) { |
| case qpid::types::VAR_MAP: |
| nested.push(&nested.top()->asMap()[value]); |
| break; |
| case qpid::types::VAR_LIST: |
| nested.top()->asList().push_back(qpid::types::Variant(value)); |
| nested.top()->asList().back().setEncoding(encoding); |
| break; |
| default: |
| qpid::types::Variant& v = *(nested.top()); |
| v = value; |
| v.setEncoding(encoding); |
| nested.pop(); |
| break; |
| } |
| } |
| |
| bool DataBuilder::proceed() |
| { |
| return !nested.empty(); |
| } |
| |
| bool DataBuilder::nest(const qpid::types::Variant& n) |
| { |
| switch (nested.top()->getType()) { |
| case qpid::types::VAR_MAP: |
| if (nested.size() > 1 || nested.top()->asMap().size() > 0) { |
| QPID_LOG(error, QPID_MSG("Expecting map key; got " << n << " " << *(nested.top()))); |
| } |
| break; |
| case qpid::types::VAR_LIST: |
| nested.top()->asList().push_back(n); |
| nested.push(&nested.top()->asList().back()); |
| break; |
| default: |
| qpid::types::Variant& value = *(nested.top()); |
| value = n; |
| nested.pop(); |
| nested.push(&value); |
| break; |
| } |
| return true; |
| } |
| |
| bool DataBuilder::onStartList(uint32_t, const CharSequence&, const CharSequence&, const Descriptor*) |
| { |
| return nest(qpid::types::Variant::List()); |
| } |
| void DataBuilder::onEndList(uint32_t /*count*/, const Descriptor*) |
| { |
| nested.pop(); |
| } |
| bool DataBuilder::onStartMap(uint32_t /*count*/, const CharSequence&, const CharSequence&, const Descriptor*) |
| { |
| return nest(qpid::types::Variant::Map()); |
| } |
| void DataBuilder::onEndMap(uint32_t /*count*/, const Descriptor*) |
| { |
| nested.pop(); |
| } |
| bool DataBuilder::onStartArray(uint32_t count, const CharSequence&, const Constructor&, const Descriptor*) |
| { |
| return onStartList(count, CharSequence::create(), CharSequence::create(), 0); |
| } |
| void DataBuilder::onEndArray(uint32_t count, const Descriptor*) |
| { |
| onEndList(count, 0); |
| } |
| qpid::types::Variant& DataBuilder::getValue() |
| { |
| return base; |
| } |
| DataBuilder::DataBuilder(qpid::types::Variant v) : base(v) |
| { |
| nested.push(&base); |
| } |
| DataBuilder::~DataBuilder() {} |
| }} // namespace qpid::amqp |