// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors // Licensed under the MIT License: // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #pragma once #include "layout.h" #include "list.h" CAPNP_BEGIN_HEADER namespace capnp { namespace _ { // private // PointerHelpers is a template class that assists in wrapping/unwrapping the low-level types in // layout.h with the high-level public API and generated types. This way, the code generator // and other templates do not have to specialize on each kind of pointer. template struct PointerHelpers { static inline typename T::Reader get(PointerReader reader, const word* defaultValue = nullptr) { return typename T::Reader(reader.getStruct(defaultValue)); } static inline typename T::Builder get(PointerBuilder builder, const word* defaultValue = nullptr) { return typename T::Builder(builder.getStruct(structSize(), defaultValue)); } static inline void set(PointerBuilder builder, typename T::Reader value) { builder.setStruct(value._reader); } static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { builder.setStruct(value._reader, true); } static inline typename T::Builder init(PointerBuilder builder) { return typename T::Builder(builder.initStruct(structSize())); } static inline void adopt(PointerBuilder builder, Orphan&& value) { builder.adopt(kj::mv(value.builder)); } static inline Orphan disown(PointerBuilder builder) { return Orphan(builder.disown()); } static inline _::StructReader getInternalReader(const typename T::Reader& reader) { return reader._reader; } static inline _::StructBuilder getInternalBuilder(typename T::Builder&& builder) { return builder._builder; } }; template struct PointerHelpers, Kind::LIST> { static inline typename List::Reader get(PointerReader reader, const word* defaultValue = nullptr) { return typename List::Reader(List::getFromPointer(reader, defaultValue)); } static inline typename List::Builder get(PointerBuilder builder, const word* defaultValue = nullptr) { return typename List::Builder(List::getFromPointer(builder, defaultValue)); } static inline void set(PointerBuilder builder, typename List::Reader value) { builder.setList(value.reader); } static inline void setCanonical(PointerBuilder builder, typename List::Reader value) { builder.setList(value.reader, true); } static void set(PointerBuilder builder, kj::ArrayPtr> value) { auto l = init(builder, value.size()); uint i = 0; for (auto& element: value) { l.set(i++, element); } } static inline typename List::Builder init(PointerBuilder builder, uint size) { return typename List::Builder(List::initPointer(builder, size)); } static inline void adopt(PointerBuilder builder, Orphan>&& value) { builder.adopt(kj::mv(value.builder)); } static inline Orphan> disown(PointerBuilder builder) { return Orphan>(builder.disown()); } static inline _::ListReader getInternalReader(const typename List::Reader& reader) { return reader.reader; } static inline _::ListBuilder getInternalBuilder(typename List::Builder&& builder) { return builder.builder; } }; template struct PointerHelpers { static inline typename T::Reader get(PointerReader reader, const void* defaultValue = nullptr, uint defaultBytes = 0) { return reader.getBlob(defaultValue, bounded(defaultBytes) * BYTES); } static inline typename T::Builder get(PointerBuilder builder, const void* defaultValue = nullptr, uint defaultBytes = 0) { return builder.getBlob(defaultValue, bounded(defaultBytes) * BYTES); } static inline void set(PointerBuilder builder, typename T::Reader value) { builder.setBlob(value); } static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { builder.setBlob(value); } static inline typename T::Builder init(PointerBuilder builder, uint size) { return builder.initBlob(bounded(size) * BYTES); } static inline void adopt(PointerBuilder builder, Orphan&& value) { builder.adopt(kj::mv(value.builder)); } static inline Orphan disown(PointerBuilder builder) { return Orphan(builder.disown()); } }; struct UncheckedMessage { typedef const word* Reader; }; template <> struct Kind_ { static constexpr Kind kind = Kind::OTHER; }; template <> struct PointerHelpers { // Reads an AnyPointer field as an unchecked message pointer. Requires that the containing // message is itself unchecked. This hack is currently private. It is used to locate default // values within encoded schemas. static inline const word* get(PointerReader reader) { return reader.getUnchecked(); } }; } // namespace _ (private) } // namespace capnp CAPNP_END_HEADER