Branch data Line data Source code
1 : : /* 2 : : * Copyright (C) 2026 by Thun Lu. All rights reserved. 3 : : * Author: Thun Lu <thun.lu@zohomail.cn> 4 : : * Repo: https://github.com/thun-res/vlink 5 : : * _ __ __ _ __ 6 : : * | | / / / / (_) ____ / /__ 7 : : * | | / / / / / / / __ \ / //_/ 8 : : * | |/ / / /___ / / / / / / / ,< 9 : : * |___/ /_____/ /_/ /_/ /_/ /_/|_| 10 : : * 11 : : * Licensed under the Apache License, Version 2.0 (the "License"); 12 : : * you may not use this file except in compliance with the License. 13 : : * You may obtain a copy of the License at 14 : : * 15 : : * http://www.apache.org/licenses/LICENSE-2.0 16 : : * 17 : : * Unless required by applicable law or agreed to in writing, software 18 : : * distributed under the License is distributed on an "AS IS" BASIS, 19 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 : : * See the License for the specific language governing permissions and 21 : : * limitations under the License. 22 : : */ 23 : : 24 : : #include "./extension/dynamic_data.h" 25 : : 26 : : #include <cstring> 27 : : #include <string_view> 28 : : #include <utility> 29 : : 30 : : namespace vlink { 31 : : 32 : : // DynamicData 33 : 84 : DynamicData::DynamicData() = default; 34 : : 35 : 2 : DynamicData::DynamicData(const DynamicData& target) : data_(target.data_) { refresh_type_view(target.type_.size()); } 36 : : 37 : 2 : DynamicData::DynamicData(DynamicData&& target) noexcept : data_(std::move(target.data_)) { 38 : 2 : refresh_type_view(target.type_.size()); 39 : 2 : target.type_ = std::string_view(); 40 : 2 : } 41 : : 42 : 16 : DynamicData& DynamicData::operator=(const DynamicData& target) { 43 [ + + ]: 16 : if VUNLIKELY (this == &target) { 44 : 1 : return *this; 45 : : } 46 : : 47 : 15 : data_ = target.data_; 48 : 15 : refresh_type_view(target.type_.size()); 49 : 15 : return *this; 50 : : } 51 : : 52 : 2 : DynamicData& DynamicData::operator=(DynamicData&& target) noexcept { 53 [ + + ]: 2 : if VUNLIKELY (this == &target) { 54 : 1 : return *this; 55 : : } 56 : : 57 : 1 : const auto type_size = target.type_.size(); 58 : 1 : data_ = std::move(target.data_); 59 : 1 : refresh_type_view(type_size); 60 : 1 : target.type_ = std::string_view(); 61 : 1 : return *this; 62 : : } 63 : : 64 : 3 : const Bytes& DynamicData::get_data() const { return data_; } 65 : : 66 : 17 : const std::string_view& DynamicData::get_type() const { return type_; } 67 : : 68 : 12 : bool DynamicData::is_empty() const { return data_.empty(); } 69 : : 70 [ + + + - ]: 10 : bool DynamicData::operator==(const DynamicData& target) const { return data_ == target.data_ && type_ == target.type_; } 71 : : 72 : 4 : bool DynamicData::operator!=(const DynamicData& target) const { return !(*this == target); } 73 : : 74 : 25 : bool DynamicData::operator<<(const Bytes& bytes) noexcept { 75 [ + + - + : 25 : if VUNLIKELY (bytes.size() < get_offset() || bytes.data() == nullptr) { + + ] 76 : 5 : return false; 77 : : } 78 : : 79 : 20 : auto next_data = Bytes::deep_copy(bytes.data() + get_offset(), bytes.size() - get_offset(), get_offset()); 80 : : 81 [ - + ]: 20 : if VUNLIKELY (next_data.real_data() == nullptr) { 82 : 0 : return false; 83 : : } 84 : : 85 : 20 : std::memcpy(next_data.real_data(), bytes.data(), get_offset()); 86 : 20 : const char* type_s = reinterpret_cast<const char*>(next_data.real_data()); 87 : 20 : const auto* type_end = static_cast<const char*>(std::memchr(type_s, '\0', get_offset())); 88 : : 89 [ + + ]: 20 : if VUNLIKELY (type_end == nullptr) { 90 : 1 : return false; 91 : : } 92 : : 93 : 19 : const auto type_size = static_cast<size_t>(type_end - type_s); 94 : 19 : data_ = std::move(next_data); 95 : 19 : refresh_type_view(type_size); 96 : : 97 : 19 : return true; 98 : 20 : } 99 : : 100 : 18 : bool DynamicData::operator>>(Bytes& bytes) const noexcept { 101 [ + + - + : 18 : if VUNLIKELY (data_.empty() || data_.offset() == 0 || !data_.is_owner()) { + + - + + + ] 102 : 1 : return false; 103 : : } 104 : : 105 : 17 : bytes = Bytes::shallow_copy(data_.real_data(), data_.real_size()); 106 : : 107 : 17 : return true; 108 : : } 109 : : 110 : 39 : void DynamicData::refresh_type_view(size_t type_size) noexcept { 111 [ + + - + : 39 : if VUNLIKELY (type_size == 0 || type_size >= get_offset() || data_.real_data() == nullptr || + + - + + + - + + + ] 112 : : data_.offset() < get_offset()) { 113 : 3 : type_ = std::string_view(); 114 : 3 : return; 115 : : } 116 : : 117 : 36 : type_ = std::string_view(reinterpret_cast<const char*>(data_.real_data()), type_size); 118 : : } 119 : : 120 : : } // namespace vlink