-
Notifications
You must be signed in to change notification settings - Fork 11
/
main.cpp
143 lines (107 loc) · 3.1 KB
/
main.cpp
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// This example shows client-side usage from C++
#include <stdio.h>
#include <string.h>
#include "bindings.h"
#include <vector>
int trim(char *str);
template<typename T>
void use_kvstore(T& obj);
template<typename T>
void kvdump(T& obj);
int main() {
char name[256];
printf("Enter name of the plugin library [plugin_lib]:\n");
fgets(name, sizeof(name), stdin);
int len = trim(name);
PluginInner obj;
int ret;
// Load the plugin, ret is 0 on success.
if (ret = load_plugin(len > 0 ? name : "plugin_lib", &obj)) {
printf("Failed to load plugin (%d)!\n", ret);
return 1;
}
// In this block we only use borrowed features.
// After the block `borrowed` will be freed.
{
printf("%p %p\n", obj.container.instance.instance, obj.container.instance.drop_fn);
// While `borrowed` exists, `obj` should never be used.
auto borrowed = obj.borrow_features();
printf("%p %p\n", borrowed.container.instance.instance, borrowed.container.instance.drop_fn);
// print_self is part of MainFeature, and always exists.
borrowed.print_self();
// These are optional features we check to see if they exist.
if (borrowed.vtbl_keyvaluestore != nullptr) {
printf("Using borrowed kvstore:\n");
use_kvstore(borrowed);
}
if (borrowed.vtbl_keyvaluedumper != nullptr) {
printf("Dumping borrowed kvstore:\n");
kvdump(borrowed);
}
printf("Borrowed done.\n");
}
// In this block we convert the object into features.
// `obj` becomes unusable, `owned` is the one to be used.
// After the block `owned` gets freed, and so should the library.
{
printf("%p %p\n", obj.container.instance.instance, obj.container.instance.drop_fn);
auto owned = std::move(obj).into_features();
owned.print_self();
if (owned.vtbl_keyvaluestore != nullptr) {
printf("Using owned kvstore:\n");
use_kvstore(owned);
}
if (owned.vtbl_keyvaluedumper != nullptr) {
printf("Dumping owned kvstore:\n");
kvdump(owned);
}
}
return 0;
}
int trim(char *str) {
int len = strlen(str);
for (int i = 0; i < 2; i++) {
char c = str[--len];
if (c == '\n' || c == '\r') {
str[len] = '\0';
} else {
len++;
break;
}
}
return len;
}
template<typename T>
void use_kvstore(T& obj) {
char key[256];
printf("Enter key:\n");
fgets(key, sizeof(key), stdin);
trim(key);
// CSliceRef gets constructed instead of key
printf("Cur val: %zu\n", obj.get_key_value(key));
size_t new_val = 0;
printf("Enter value:\n");
scanf("%zu", &new_val);
char nl[2];
fgets(nl, sizeof(nl), stdin);
// CSliceRef gets constructed instead of key
obj.write_key_value(key, new_val);
}
template<typename T>
void kvdump(T& obj) {
// This lambda gets converted into callback.
// We could also collect the values into a
// vector, by passing through its pointer.
obj.dump_key_values([](KeyValue kv) {
fwrite(kv._0.data, sizeof(char), kv._0.len, stdout);
printf(" : %zu\n", kv._1);
return true;
});
std::vector<int> ints;
for (int i = 0; i < 32; i++) {
ints.push_back(i * i);
}
// In C++17 we do not have to supply the vector type,
// but here its sadly necessary.
obj.print_ints(CPPIterator<std::vector<int>>(ints));
}