forked from jkcoxson/idevice
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtcp_callback_feeder.cpp
More file actions
118 lines (103 loc) · 3.28 KB
/
Copy pathtcp_callback_feeder.cpp
File metadata and controls
118 lines (103 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Jackson Coxson
#include <idevice++/bindings.hpp>
#include <idevice++/tcp_object_stack.hpp>
namespace IdeviceFFI {
// ---------- TcpFeeder ----------
bool TcpObjectStackFeeder::write(const uint8_t* data, std::size_t len, FfiError& err) const {
if (IdeviceFfiError* e = ::idevice_tcp_feed_object_write(h_, data, len)) {
err = FfiError(e);
return false;
}
return true;
}
// ---------- TcpEater ----------
bool TcpObjectStackEater::read(OwnedBuffer& out, FfiError& err) const {
uint8_t* ptr = nullptr;
std::size_t len = 0;
if (IdeviceFfiError* e = ::idevice_tcp_eat_object_read(h_, &ptr, &len)) {
err = FfiError(e);
return false;
}
// Success: adopt the buffer (freed via idevice_data_free in OwnedBuffer dtor)
out.adopt(ptr, len);
return true;
}
// ---------- TcpStackFromCallback ----------
Result<TcpObjectStack, FfiError> TcpObjectStack::create(const std::string& our_ip,
const std::string& their_ip) {
::TcpFeedObject* feeder_h = nullptr;
::TcpEatObject* eater_h = nullptr;
::AdapterHandle* adapter_h = nullptr;
FfiError e(::idevice_tcp_stack_into_sync_objects(
our_ip.c_str(), their_ip.c_str(), &feeder_h, &eater_h, &adapter_h));
if (e) {
return Err(e);
}
auto impl = std::make_unique<Impl>();
impl->feeder = TcpObjectStackFeeder(feeder_h);
impl->eater = TcpObjectStackEater(eater_h);
impl->adapter = Adapter::adopt(adapter_h);
TcpObjectStack out;
out.impl_ = std::move(impl);
return Ok(std::move(out));
}
TcpObjectStackFeeder& TcpObjectStack::feeder() {
return impl_->feeder;
}
const TcpObjectStackFeeder& TcpObjectStack::feeder() const {
return impl_->feeder;
}
TcpObjectStackEater& TcpObjectStack::eater() {
return impl_->eater;
}
const TcpObjectStackEater& TcpObjectStack::eater() const {
return impl_->eater;
}
Adapter& TcpObjectStack::adapter() {
if (!impl_ || impl_->adapter.is_some()) {
static Adapter* never = nullptr;
return *never;
}
return (impl_->adapter.unwrap());
}
const Adapter& TcpObjectStack::adapter() const {
if (!impl_ || impl_->adapter.is_none()) {
static Adapter* never = nullptr;
return *never;
}
return (impl_->adapter.unwrap());
}
// ---------- Release APIs ----------
Option<TcpObjectStackFeeder> TcpObjectStack::release_feeder() {
if (!impl_) {
return None;
}
auto has = impl_->feeder.raw() != nullptr;
if (!has) {
return None;
}
TcpObjectStackFeeder out = std::move(impl_->feeder);
// impl_->feeder is now empty (h_ == nullptr) thanks to move
return Some(std::move(out));
}
Option<TcpObjectStackEater> TcpObjectStack::release_eater() {
if (!impl_) {
return None;
}
auto has = impl_->eater.raw() != nullptr;
if (!has) {
return None;
}
TcpObjectStackEater out = std::move(impl_->eater);
return Some(std::move(out));
}
Option<Adapter> TcpObjectStack::release_adapter() {
if (!impl_ || impl_->adapter.is_none()) {
return None;
}
// Move out and clear our optional
auto out = std::move((impl_->adapter.unwrap()));
impl_->adapter.reset();
return Some(std::move(out));
}
} // namespace IdeviceFFI