/* * 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. */ #include #include #include namespace apache { namespace thrift { namespace frozen { std::ostream& operator<<(std::ostream& os, DebugLine dl) { os << '\n'; for (int i = 0; i < dl.level; ++i) { os << ' ' << ' '; } return os; } std::ostream& operator<<(std::ostream& os, const LayoutBase& layout) { layout.print(os, 0); return os; } bool LayoutBase::resize(FieldPosition after, bool _inlined) { bool resized = false; inlined = (this->size == 0 && _inlined); if (!inlined) { if (static_cast(after.offset) > this->size) { this->size = after.offset; resized = true; } } if (static_cast(after.bitOffset) > this->bits) { this->bits = after.bitOffset; resized = true; } return resized; } void LayoutBase::print(std::ostream& os, int level) const { os << DebugLine(level); if (size) { os << size << " byte"; if (bits) { os << " (with " << bits << " bits)"; } } else if (bits) { os << bits << " bit"; } else { os << "empty"; } os << ' '; } void LayoutBase::clear() { size = 0; bits = 0; inlined = false; } void ByteRangeFreezer::doAppendBytes( byte* origin, size_t n, folly::MutableByteRange& range, size_t& distance, size_t alignment) { CHECK_LE(origin, write_.begin()); if (!n) { distance = 0; range.reset(nullptr, 0); return; } auto start = reinterpret_cast(write_.begin()); auto aligned = alignBy(start, alignment); auto padding = aligned - start; if (padding + n > write_.size()) { throw std::length_error("Insufficient buffer allocated"); } range.reset(write_.begin() + padding, n); write_.advance(padding + n); distance = range.begin() - origin; } namespace detail { FieldPosition BlockLayout::maximize() { FieldPosition pos = startFieldPosition(); FROZEN_MAXIMIZE_FIELD(mask); FROZEN_MAXIMIZE_FIELD(offset); return pos; } FieldPosition BlockLayout::layout( LayoutRoot& root, const T& x, LayoutPosition self) { FieldPosition pos = startFieldPosition(); FROZEN_LAYOUT_FIELD_REQ(mask); FROZEN_LAYOUT_FIELD_REQ(offset); return pos; } void BlockLayout::freeze( FreezeRoot& root, const T& x, FreezePosition self) const { FROZEN_FREEZE_FIELD_REQ(mask); FROZEN_FREEZE_FIELD_REQ(offset); } void BlockLayout::print(std::ostream& os, int level) const { LayoutBase::print(os, level); os << folly::demangle(type.name()); maskField.print(os, level + 1); offsetField.print(os, level + 1); } void BlockLayout::clear() { maskField.clear(); offsetField.clear(); } size_t BufferHelpers>::size( const std::unique_ptr& src) { return src != nullptr ? src->computeChainDataLength() : 0; } void BufferHelpers>::copyTo( const std::unique_ptr& src, folly::MutableByteRange dst) { if (src != nullptr) { folly::io::Cursor(src.get()).pull(dst.begin(), dst.size()); } } void BufferHelpers>::thawTo( folly::ByteRange src, std::unique_ptr& dst) { dst = folly::IOBuf::copyBuffer(src.begin(), src.size()); } size_t BufferHelpers::size(const folly::IOBuf& src) { return src.computeChainDataLength(); } void BufferHelpers::copyTo( const folly::IOBuf& src, folly::MutableByteRange dst) { folly::io::Cursor(&src).pull(dst.begin(), dst.size()); } void BufferHelpers::thawTo( folly::ByteRange src, folly::IOBuf& dst) { dst = folly::IOBuf(folly::IOBuf::COPY_BUFFER, src); } } // namespace detail } // namespace frozen } // namespace thrift } // namespace apache