1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors 2 // Licensed under the MIT License: 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a copy 5 // of this software and associated documentation files (the "Software"), to deal 6 // in the Software without restriction, including without limitation the rights 7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 // copies of the Software, and to permit persons to whom the Software is 9 // furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 // THE SOFTWARE. 21 22 #pragma once 23 24 #include "layout.h" 25 #include "list.h" 26 27 CAPNP_BEGIN_HEADER 28 29 namespace capnp { 30 namespace _ { // private 31 32 // PointerHelpers is a template class that assists in wrapping/unwrapping the low-level types in 33 // layout.h with the high-level public API and generated types. This way, the code generator 34 // and other templates do not have to specialize on each kind of pointer. 35 36 template <typename T> 37 struct PointerHelpers<T, Kind::STRUCT> { 38 static inline typename T::Reader get(PointerReader reader, const word* defaultValue = nullptr) { 39 return typename T::Reader(reader.getStruct(defaultValue)); 40 } 41 static inline typename T::Builder get(PointerBuilder builder, 42 const word* defaultValue = nullptr) { 43 return typename T::Builder(builder.getStruct(structSize<T>(), defaultValue)); 44 } 45 static inline void set(PointerBuilder builder, typename T::Reader value) { 46 builder.setStruct(value._reader); 47 } 48 static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { 49 builder.setStruct(value._reader, true); 50 } 51 static inline typename T::Builder init(PointerBuilder builder) { 52 return typename T::Builder(builder.initStruct(structSize<T>())); 53 } 54 static inline void adopt(PointerBuilder builder, Orphan<T>&& value) { 55 builder.adopt(kj::mv(value.builder)); 56 } 57 static inline Orphan<T> disown(PointerBuilder builder) { 58 return Orphan<T>(builder.disown()); 59 } 60 static inline _::StructReader getInternalReader(const typename T::Reader& reader) { 61 return reader._reader; 62 } 63 static inline _::StructBuilder getInternalBuilder(typename T::Builder&& builder) { 64 return builder._builder; 65 } 66 }; 67 68 template <typename T> 69 struct PointerHelpers<List<T>, Kind::LIST> { 70 static inline typename List<T>::Reader get(PointerReader reader, 71 const word* defaultValue = nullptr) { 72 return typename List<T>::Reader(List<T>::getFromPointer(reader, defaultValue)); 73 } 74 static inline typename List<T>::Builder get(PointerBuilder builder, 75 const word* defaultValue = nullptr) { 76 return typename List<T>::Builder(List<T>::getFromPointer(builder, defaultValue)); 77 } 78 static inline void set(PointerBuilder builder, typename List<T>::Reader value) { 79 builder.setList(value.reader); 80 } 81 static inline void setCanonical(PointerBuilder builder, typename List<T>::Reader value) { 82 builder.setList(value.reader, true); 83 } 84 static void set(PointerBuilder builder, kj::ArrayPtr<const ReaderFor<T>> value) { 85 auto l = init(builder, value.size()); 86 uint i = 0; 87 for (auto& element: value) { 88 l.set(i++, element); 89 } 90 } 91 static inline typename List<T>::Builder init(PointerBuilder builder, uint size) { 92 return typename List<T>::Builder(List<T>::initPointer(builder, size)); 93 } 94 static inline void adopt(PointerBuilder builder, Orphan<List<T>>&& value) { 95 builder.adopt(kj::mv(value.builder)); 96 } 97 static inline Orphan<List<T>> disown(PointerBuilder builder) { 98 return Orphan<List<T>>(builder.disown()); 99 } 100 static inline _::ListReader getInternalReader(const typename List<T>::Reader& reader) { 101 return reader.reader; 102 } 103 static inline _::ListBuilder getInternalBuilder(typename List<T>::Builder&& builder) { 104 return builder.builder; 105 } 106 }; 107 108 template <typename T> 109 struct PointerHelpers<T, Kind::BLOB> { 110 static inline typename T::Reader get(PointerReader reader, 111 const void* defaultValue = nullptr, 112 uint defaultBytes = 0) { 113 return reader.getBlob<T>(defaultValue, bounded(defaultBytes) * BYTES); 114 } 115 static inline typename T::Builder get(PointerBuilder builder, 116 const void* defaultValue = nullptr, 117 uint defaultBytes = 0) { 118 return builder.getBlob<T>(defaultValue, bounded(defaultBytes) * BYTES); 119 } 120 static inline void set(PointerBuilder builder, typename T::Reader value) { 121 builder.setBlob<T>(value); 122 } 123 static inline void setCanonical(PointerBuilder builder, typename T::Reader value) { 124 builder.setBlob<T>(value); 125 } 126 static inline typename T::Builder init(PointerBuilder builder, uint size) { 127 return builder.initBlob<T>(bounded(size) * BYTES); 128 } 129 static inline void adopt(PointerBuilder builder, Orphan<T>&& value) { 130 builder.adopt(kj::mv(value.builder)); 131 } 132 static inline Orphan<T> disown(PointerBuilder builder) { 133 return Orphan<T>(builder.disown()); 134 } 135 }; 136 137 struct UncheckedMessage { 138 typedef const word* Reader; 139 }; 140 141 template <> struct Kind_<UncheckedMessage> { static constexpr Kind kind = Kind::OTHER; }; 142 143 template <> 144 struct PointerHelpers<UncheckedMessage> { 145 // Reads an AnyPointer field as an unchecked message pointer. Requires that the containing 146 // message is itself unchecked. This hack is currently private. It is used to locate default 147 // values within encoded schemas. 148 149 static inline const word* get(PointerReader reader) { 150 return reader.getUnchecked(); 151 } 152 }; 153 154 } // namespace _ (private) 155 } // namespace capnp 156 157 CAPNP_END_HEADER 158