/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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. */ namespace folly { class IOBuf; } namespace apache { namespace thrift { namespace frozen { namespace detail { template struct BufferHelpers { typedef typename T::value_type Item; static_assert( std::is_arithmetic::value || std::is_enum::value, "String storage requires simple item types"); static size_t size(const T& src) { return src.size(); } static void copyTo(const T& src, folly::Range dst) { std::copy(src.begin(), src.end(), reinterpret_cast(dst.begin())); } static void thawTo(folly::Range src, T& dst) { dst.assign(src.begin(), src.end()); } }; template <> struct BufferHelpers> { typedef uint8_t Item; static size_t size(const std::unique_ptr& src); static void copyTo( const std::unique_ptr& src, folly::MutableByteRange dst); static void thawTo(folly::ByteRange src, std::unique_ptr& dst); }; template <> struct BufferHelpers { typedef uint8_t Item; static size_t size(const folly::IOBuf& src); static void copyTo(const folly::IOBuf& src, folly::MutableByteRange dst); static void thawTo(folly::ByteRange src, folly::IOBuf& dst); }; /** * for contiguous, blittable ranges */ template struct StringLayout : public LayoutBase { typedef LayoutBase Base; typedef BufferHelpers Helper; typedef typename Helper::Item Item; Field distanceField; Field countField; StringLayout() : LayoutBase(typeid(T)), distanceField(1, "distance"), countField(2, "count") {} FieldPosition maximize() { FieldPosition pos = startFieldPosition(); FROZEN_MAXIMIZE_FIELD(distance); FROZEN_MAXIMIZE_FIELD(count); return pos; } FieldPosition layout(LayoutRoot& root, const T& o, LayoutPosition self) { FieldPosition pos = startFieldPosition(); size_t n = Helper::size(o); if (!n) { return pos; } size_t dist = root.layoutBytesDistance(self.start, n * sizeof(Item), alignof(Item)); pos = root.layoutField(self, pos, distanceField, dist); pos = root.layoutField(self, pos, countField, n); return pos; } void freeze(FreezeRoot& root, const T& o, FreezePosition self) const { size_t n = Helper::size(o); folly::MutableByteRange range; size_t dist; root.appendBytes(self.start, n * sizeof(Item), range, dist, alignof(Item)); root.freezeField(self, distanceField, dist); root.freezeField(self, countField, n); folly::Range target(reinterpret_cast(range.begin()), n); Helper::copyTo(o, target); } void thaw(ViewPosition self, T& out) const { Helper::thawTo(view(self), out); } typedef folly::Range View; View view(ViewPosition self) const { View range; size_t dist, n; thawField(self, countField, n); if (n) { thawField(self, distanceField, dist); const byte* read = self.start + dist; range.reset(reinterpret_cast(read), n); } return range; } void print(std::ostream& os, int level) const override { LayoutBase::print(os, level); os << "string of " << folly::demangle(type.name()); distanceField.print(os, level + 1); countField.print(os, level + 1); } void clear() final { LayoutBase::clear(); distanceField.clear(); countField.clear(); } FROZEN_SAVE_INLINE(FROZEN_SAVE_FIELD(distance) FROZEN_SAVE_FIELD(count)) FROZEN_LOAD_INLINE(FROZEN_LOAD_FIELD(distance, 1) FROZEN_LOAD_FIELD(count, 2)) static size_t hash(const View& v) { return folly::hash::fnv64_buf(v.begin(), sizeof(Item) * v.size()); } }; } // namespace detail template struct Layout::value>::type> : apache::thrift::frozen::detail::StringLayout< typename std::decay::type> {}; } // namespace frozen } // namespace thrift } // namespace apache THRIFT_DECLARE_TRAIT(IsString, std::string) THRIFT_DECLARE_TRAIT(IsString, folly::fbstring) THRIFT_DECLARE_TRAIT(IsString, std::unique_ptr) THRIFT_DECLARE_TRAIT(IsString, folly::IOBuf)