| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed 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. |
| */ |
| |
| #ifndef GAPII_ENCODE_CONVERTERS_H |
| #define GAPII_ENCODE_CONVERTERS_H |
| |
| #include "slice.h" |
| |
| #include <gapic/coder/memory.h> |
| #include <gapic/scratch_allocator.h> |
| |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include <string> |
| #include <unordered_map> |
| |
| namespace gapii { |
| |
| template<typename Out, typename In> |
| struct EncoderConverter {}; |
| |
| |
| // Passthrough: T -> T |
| template<typename T> |
| struct EncoderConverter<T, T> { |
| static inline T convert(const T& in, gapic::ScratchAllocator& alloc) { return in; } |
| }; |
| |
| // Passthrough: T* -> T* |
| template<typename T> |
| struct EncoderConverter<T*, T*> { |
| static inline T* convert(const T* in, gapic::ScratchAllocator& alloc) { return in; } |
| }; |
| |
| // Passthrough: void* -> coder::T__P |
| template<typename Out> |
| struct EncoderConverter<Out, void*> { |
| static inline Out convert(void* in, gapic::ScratchAllocator& alloc) { |
| uint32_t poolID = 0; // TODO: Support non-application pools? |
| uint64_t address = reinterpret_cast<uintptr_t>(in); |
| return Out(address, poolID); |
| } |
| }; |
| |
| // T* -> coder::T__P |
| template<typename Out, typename T> |
| struct EncoderConverter<Out, T*> { |
| static inline Out convert(T* in, gapic::ScratchAllocator& alloc) { |
| return EncoderConverter<Out, void*>::convert(in, alloc); |
| } |
| }; |
| |
| // std::string -> const char* |
| template<> |
| struct EncoderConverter<const char*, std::string> { |
| static inline const char* convert(const std::string& in, gapic::ScratchAllocator& alloc) { |
| char* buf = alloc.create<char>(in.size() + 1); |
| strncpy(buf, in.c_str(), in.size() + 1); |
| return buf; |
| } |
| }; |
| |
| // std::shared_ptr<T> -> coder::T* |
| template<typename T> |
| struct EncoderConverter<typename T::CoderType*, std::shared_ptr<T>> { |
| typedef typename T::CoderType* Out; |
| static inline Out convert(const std::shared_ptr<T>& in, gapic::ScratchAllocator& alloc) { |
| return alloc.make<typename T::CoderType>(in->encodeable(alloc)); |
| } |
| }; |
| |
| // T -> coder::T |
| template<typename T> |
| struct EncoderConverter<typename T::CoderType, T> { |
| static inline typename T::CoderType convert(const T& in, gapic::ScratchAllocator& alloc) { |
| return in.encodeable(alloc); |
| } |
| }; |
| |
| // gapii::Slice<T> -> coder::T__S |
| template<typename Out, typename T> |
| struct EncoderConverter< Out, gapii::Slice<T> > { |
| static inline Out convert(const gapii::Slice<T>& in, gapic::ScratchAllocator& alloc) { |
| uint32_t poolID = 0; // TODO: Support non-application pools? |
| uint64_t base = reinterpret_cast<uintptr_t>(in.begin()); |
| uint64_t root = base; // TODO: Track root. |
| return Out(gapic::coder::memory::SliceInfo(root, base, in.count(), poolID)); |
| } |
| }; |
| |
| // gapic::StaticArray<T, N> -> coder::T |
| template<typename Out, typename T, int N> |
| struct EncoderConverter< Out, gapic::StaticArray<T, N> > { |
| static inline Out convert(const gapic::StaticArray<T, N>& in, gapic::ScratchAllocator& alloc) { |
| return Out(in); |
| } |
| }; |
| |
| // std::unordered_map<KeyIn, ValueIn> -> gapic::Map<KeyOut, ValueOut> |
| template<typename KeyOut, typename ValueOut, typename KeyIn, typename ValueIn> |
| struct EncoderConverter< gapic::Map<KeyOut, ValueOut>, std::unordered_map<KeyIn, ValueIn> > { |
| typedef gapic::Map<KeyOut, ValueOut> Out; |
| typedef std::unordered_map<KeyIn, ValueIn> In; |
| |
| static inline Out convert(const In& in, gapic::ScratchAllocator& alloc) { |
| Out out = alloc.map<KeyOut, ValueOut>(in.size()); |
| for (auto it : in) { |
| KeyOut key = EncoderConverter<KeyOut, KeyIn>::convert(it.first, alloc); |
| ValueOut value = EncoderConverter<ValueOut, ValueIn>::convert(it.second, alloc); |
| out.set(key, value); |
| } |
| return out; |
| } |
| }; |
| |
| // gapic::StaticArray<ElIn, N> -> gapic::StaticArray<ElOut, N> |
| template<typename ElOut, typename ElIn, int N> |
| struct EncoderConverter< gapic::StaticArray<ElOut, N>, gapic::StaticArray<ElIn, N> > { |
| static inline gapic::StaticArray<ElOut, N> convert(const gapic::StaticArray<ElIn, N>& in, gapic::ScratchAllocator& alloc) { |
| gapic::StaticArray<ElOut, N> out; |
| for (size_t i = 0; i < N; ++i) { |
| out[i] = EncoderConverter<ElOut, ElIn>::convert(in[i], alloc); |
| } |
| return out; |
| } |
| }; |
| |
| template <typename Out, typename In> |
| inline Out toEncoder(const In& in, gapic::ScratchAllocator& alloc) { |
| return EncoderConverter<Out, In>::convert(in, alloc); |
| } |
| |
| } // namespace gapii |
| |
| #endif // GAPII_ENCODE_CONVERTERS_H |