Accept an incoming resource advertisement, instantiate a receiver-side Resource and register it with the link. Mirror Python Resource.py:167. Returns a Resource (or NONE on rejection / duplicate). */
| 58 | Returns a Resource (or NONE on rejection / duplicate). |
| 59 | */ |
| 60 | Resource Resource::accept(const Packet& advertisement_packet, Callbacks::concluded callback /*= nullptr*/, Callbacks::progress progress_callback /*= nullptr*/, const Bytes& request_id /*= {Bytes::NONE}*/) { |
| 61 | ResourceAdvertisement adv = ResourceAdvertisement::unpack(advertisement_packet.plaintext()); |
| 62 | if (!adv._h) { |
| 63 | DEBUG("Could not decode resource advertisement, dropping resource"); |
| 64 | return {Type::NONE}; |
| 65 | } |
| 66 | |
| 67 | // Allocate a receiver-side Resource via the minimal constructor. The |
| 68 | // per-advertisement fields below overwrite the constructor's defaults |
| 69 | // directly, so no fluent configuration is needed here. |
| 70 | Link link = advertisement_packet.link(); |
| 71 | Resource resource({Bytes::NONE}, link); |
| 72 | assert(resource._object); |
| 73 | |
| 74 | resource._object->_status = Type::Resource::TRANSFERRING; |
| 75 | resource._object->_flags = adv._f; |
| 76 | resource._object->_size = adv._t; |
| 77 | resource._object->_total_size = adv._d; |
| 78 | resource._object->_uncompressed_size = adv._d; |
| 79 | resource._object->_hash = adv._h; |
| 80 | resource._object->_original_hash = adv._o; |
| 81 | resource._object->_random_hash = adv._r; |
| 82 | resource._object->_hashmap_raw = adv._m; |
| 83 | resource._object->_encrypted = adv._e; |
| 84 | resource._object->_compressed = adv._c; |
| 85 | resource._object->_initiator = false; |
| 86 | resource._object->_callbacks._concluded = callback; |
| 87 | resource._object->_callbacks._progress = progress_callback; |
| 88 | resource._object->_total_parts = static_cast<uint32_t>((adv._t + resource._object->_sdu - 1) / resource._object->_sdu); |
| 89 | resource._object->_received_count = 0; |
| 90 | resource._object->_outstanding_parts = 0; |
| 91 | resource._object->_window = Type::Resource::WINDOW; |
| 92 | resource._object->_window_max = Type::Resource::WINDOW_MAX_SLOW; |
| 93 | resource._object->_window_min = Type::Resource::WINDOW_MIN; |
| 94 | resource._object->_window_flexibility = Type::Resource::WINDOW_FLEXIBILITY; |
| 95 | resource._object->_last_activity = Utilities::OS::time(); |
| 96 | resource._object->_started_transferring = resource._object->_last_activity; |
| 97 | resource._object->_advertisement_packet = advertisement_packet; |
| 98 | resource._object->_segment_index = adv._i; |
| 99 | resource._object->_total_segments = adv._l; |
| 100 | resource._object->_split = (adv._l > 1); |
| 101 | resource._object->_has_metadata = adv._x; |
| 102 | resource._object->_consecutive_completed_height = -1; |
| 103 | resource._object->_waiting_for_hmu = false; |
| 104 | resource._object->_receiving_part = false; |
| 105 | resource._object->_request_id = request_id; |
| 106 | // Mirror Python: the advertisement carries the request/response flags; |
| 107 | // these are used by Link::resource_concluded() to dispatch on completion. |
| 108 | resource._object->_is_response = adv._p; |
| 109 | |
| 110 | // Pre-allocate the parts buffer with empty slots; receive_part() fills |
| 111 | // each slot as the corresponding packet arrives. |
| 112 | resource._object->_parts.clear(); |
| 113 | resource._object->_parts.reserve(resource._object->_total_parts); |
| 114 | for (uint32_t i = 0; i < resource._object->_total_parts; ++i) { |
| 115 | resource._object->_parts.push_back({Type::NONE}); |
| 116 | } |
| 117 | // Hashmap holds N x MAPHASH_LEN bytes; pre-zero so missing entries are |
nothing calls this directly
no test coverage detected