Merge lp:~jamesh/go-unityscopes/go-1.6-compat into lp:go-unityscopes/v2
- go-1.6-compat
- Merge into v2
Proposed by
James Henstridge
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | dobey | ||||
Approved revision: | 84 | ||||
Merged at revision: | 74 | ||||
Proposed branch: | lp:~jamesh/go-unityscopes/go-1.6-compat | ||||
Merge into: | lp:go-unityscopes/v2 | ||||
Diff against target: |
851 lines (+176/-121) 22 files modified
activationresponse.cpp (+5/-5) activationresponse.go (+1/-1) childscope.cpp (+3/-4) childscope.go (+2/-3) column_layout.cpp (+3/-9) column_layout.go (+1/-6) department.cpp (+7/-13) department.go (+12/-4) helpers.cpp (+15/-3) helpers.go (+49/-0) helpers.h (+5/-1) metadata.cpp (+7/-8) metadata.go (+7/-7) query.cpp (+3/-3) query.go (+5/-5) reply.cpp (+8/-10) reply.go (+6/-7) result.cpp (+2/-2) result.go (+2/-3) shim.cpp (+3/-2) shim.h (+29/-24) unityscope.go (+1/-1) |
||||
To merge this branch: | bzr merge lp:~jamesh/go-unityscopes/go-1.6-compat | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
dobey (community) | Approve | ||
Review via email: mp+292117@code.launchpad.net |
Commit message
Description of the change
Update code to work with Go 1.6's new cgo pointer handling rules:
http://
Without these changes, it is necessary to run scopes using GODEBUG=cgocheck=0 if they are compiled on Xenial.
The changes make sure we never pass pointers to C that point at memory containing other pointers to Go allocated memory. So rather than passing a pointer to the Go string header to pass a string without copying it, we now pass a pointer to the string data plus the length (packed together in a struct).
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'activationresponse.cpp' |
2 | --- activationresponse.cpp 2016-02-03 07:17:04 +0000 |
3 | +++ activationresponse.cpp 2016-04-18 08:45:48 +0000 |
4 | @@ -9,8 +9,10 @@ |
5 | extern "C" { |
6 | #include "_cgo_export.h" |
7 | } |
8 | +#include "helpers.h" |
9 | |
10 | using namespace unity::scopes; |
11 | +using namespace gounityscopes::internal; |
12 | |
13 | void activation_response_init_status(_ActivationResponse *response, int status) { |
14 | *reinterpret_cast<ActivationResponse*>(response) = |
15 | @@ -27,13 +29,11 @@ |
16 | ActivationResponse(*reinterpret_cast<Result*>(result)); |
17 | } |
18 | |
19 | -void activation_response_init_update_preview(_ActivationResponse *response, void *gostring_array, int count, char **error) { |
20 | +void activation_response_init_update_preview(_ActivationResponse *response, const StrData widget_list, char **error) { |
21 | try { |
22 | - GoString *widget_data = static_cast<GoString*>(gostring_array); |
23 | PreviewWidgetList widgets; |
24 | - for (int i = 0; i < count; i++) { |
25 | - widgets.push_back(PreviewWidget(std::string( |
26 | - widget_data[i].p, widget_data[i].n))); |
27 | + for (const auto &data : split_strings(widget_list)) { |
28 | + widgets.push_back(PreviewWidget(data)); |
29 | } |
30 | *reinterpret_cast<ActivationResponse*>(response) = |
31 | ActivationResponse(widgets); |
32 | |
33 | === modified file 'activationresponse.go' |
34 | --- activationresponse.go 2015-10-20 05:43:00 +0000 |
35 | +++ activationresponse.go 2016-04-18 08:45:48 +0000 |
36 | @@ -90,7 +90,7 @@ |
37 | widgetData[i] = string(data) |
38 | } |
39 | var errorString *C.char |
40 | - C.activation_response_init_update_preview(responsePtr, unsafe.Pointer(&widgetData[0]), C.int(len(widgetData)), &errorString) |
41 | + C.activation_response_init_update_preview(responsePtr, joinedStrData(widgetData), &errorString) |
42 | if err := checkError(errorString); err != nil { |
43 | return err |
44 | } |
45 | |
46 | === modified file 'childscope.cpp' |
47 | --- childscope.cpp 2015-06-09 15:03:05 +0000 |
48 | +++ childscope.cpp 2016-04-18 08:45:48 +0000 |
49 | @@ -11,13 +11,12 @@ |
50 | using namespace unity::scopes; |
51 | using namespace gounityscopes::internal; |
52 | |
53 | -_ChildScope *new_child_scope(void *id, _ScopeMetadata *metadata, int enabled, void *gostring_array, int count) { |
54 | +_ChildScope *new_child_scope(const StrData id, _ScopeMetadata *metadata, int enabled, const StrData keyword_list) { |
55 | ScopeMetadata *api_metadata = reinterpret_cast<ScopeMetadata *>(metadata); |
56 | |
57 | - GoString *keyword_data = static_cast<GoString*>(gostring_array); |
58 | std::set<std::string> keywords; |
59 | - for (int i = 0; i < count; i++) { |
60 | - keywords.emplace(std::string(keyword_data[i].p, keyword_data[i].n)); |
61 | + for (auto &k : split_strings(keyword_list)) { |
62 | + keywords.emplace(std::move(k)); |
63 | } |
64 | |
65 | return reinterpret_cast<_ChildScope *>(new ChildScope(from_gostring(id), *api_metadata, enabled, keywords)); |
66 | |
67 | === modified file 'childscope.go' |
68 | --- childscope.go 2015-05-21 19:22:44 +0000 |
69 | +++ childscope.go 2016-04-18 08:45:48 +0000 |
70 | @@ -34,11 +34,10 @@ |
71 | } else { |
72 | cEnabled = 0 |
73 | } |
74 | - return makeChildScope(C.new_child_scope(unsafe.Pointer(&id), |
75 | + return makeChildScope(C.new_child_scope(strData(id), |
76 | (*C._ScopeMetadata)(metadata.m), |
77 | cEnabled, |
78 | - unsafe.Pointer(&keywords[0]), |
79 | - C.int(len(keywords)))) |
80 | + joinedStrData(keywords))) |
81 | } |
82 | |
83 | // Id returns the identifier of the child scope |
84 | |
85 | === modified file 'column_layout.cpp' |
86 | --- column_layout.cpp 2015-03-05 14:59:18 +0000 |
87 | +++ column_layout.cpp 2016-04-18 08:45:48 +0000 |
88 | @@ -23,16 +23,10 @@ |
89 | return reinterpret_cast<_ColumnLayout*>(new ColumnLayout(num_columns)); |
90 | } |
91 | |
92 | -void column_layout_add_column(_ColumnLayout *layout, void *gostring_array_widgets, int nb_widgets, char **error) { |
93 | - GoString *widget_data = static_cast<GoString*>(gostring_array_widgets); |
94 | - |
95 | - std::vector<std::string> api_widgets; |
96 | - // convert to std::string |
97 | - for (auto i = 0; i < nb_widgets; ++i) { |
98 | - api_widgets.push_back(std::string(widget_data[i].p, widget_data[i].n)); |
99 | - } |
100 | +void column_layout_add_column(_ColumnLayout *layout, const StrData widget_list, char **error) { |
101 | + std::vector<std::string> widgets = split_strings(widget_list); |
102 | try { |
103 | - reinterpret_cast<ColumnLayout*>(layout)->add_column(api_widgets); |
104 | + reinterpret_cast<ColumnLayout*>(layout)->add_column(widgets); |
105 | } catch(unity::LogicException & e) { |
106 | *error = strdup(e.what()); |
107 | } |
108 | |
109 | === modified file 'column_layout.go' |
110 | --- column_layout.go 2015-03-23 11:16:52 +0000 |
111 | +++ column_layout.go 2016-04-18 08:45:48 +0000 |
112 | @@ -6,7 +6,6 @@ |
113 | import ( |
114 | "encoding/json" |
115 | "runtime" |
116 | - "unsafe" |
117 | ) |
118 | |
119 | // ColumnLayout is used represent different representations of a widget. |
120 | @@ -41,11 +40,7 @@ |
121 | // AddColumn method. |
122 | func (layout *ColumnLayout) AddColumn(widgetIds ...string) error { |
123 | var errorString *C.char |
124 | - var ptr_columns unsafe.Pointer |
125 | - if len(widgetIds) > 0 { |
126 | - ptr_columns = unsafe.Pointer(&widgetIds[0]) |
127 | - } |
128 | - C.column_layout_add_column(layout.c, ptr_columns, C.int(len(widgetIds)), &errorString) |
129 | + C.column_layout_add_column(layout.c, joinedStrData(widgetIds), &errorString) |
130 | |
131 | return checkError(errorString) |
132 | } |
133 | |
134 | === modified file 'department.cpp' |
135 | --- department.cpp 2015-03-05 14:59:18 +0000 |
136 | +++ department.cpp 2016-04-18 08:45:48 +0000 |
137 | @@ -19,17 +19,11 @@ |
138 | init_ptr<Department>(dest, dept); |
139 | } |
140 | |
141 | -void new_department(void *dept_id, _CannedQuery *query, void *label, SharedPtrData dept, char **error) { |
142 | +void new_department(const StrData dept_id, _CannedQuery *query, const StrData label, SharedPtrData dept, char **error) { |
143 | try { |
144 | - Department::UPtr d; |
145 | - if(dept_id) { |
146 | - d = Department::create(from_gostring(dept_id), |
147 | - *reinterpret_cast<CannedQuery*>(query), |
148 | - from_gostring(label)); |
149 | - } else { |
150 | - d = Department::create(*reinterpret_cast<CannedQuery*>(query), |
151 | - from_gostring(label)); |
152 | - } |
153 | + auto d = Department::create(from_gostring(dept_id), |
154 | + *reinterpret_cast<CannedQuery*>(query), |
155 | + from_gostring(label)); |
156 | init_ptr<Department>(dept, std::move(d)); |
157 | } catch (const std::exception &e) { |
158 | *error = strdup(e.what()); |
159 | @@ -44,7 +38,7 @@ |
160 | get_ptr<Department>(dept)->add_subdepartment(get_ptr<Department>(child)); |
161 | } |
162 | |
163 | -void department_set_alternate_label(SharedPtrData dept, void *label) { |
164 | +void department_set_alternate_label(SharedPtrData dept, const StrData label) { |
165 | get_ptr<Department>(dept)->set_alternate_label(from_gostring(label)); |
166 | } |
167 | |
168 | @@ -80,10 +74,10 @@ |
169 | return ret_data; |
170 | } |
171 | |
172 | -void department_set_subdepartments(SharedPtrData dept, SharedPtrData **subdepartments, int nb_subdepartments) { |
173 | +void department_set_subdepartments(SharedPtrData dept, SharedPtrData *subdepartments, int nb_subdepartments) { |
174 | DepartmentList api_depts; |
175 | for(auto i = 0; i < nb_subdepartments; i++) { |
176 | - api_depts.push_back(get_ptr<Department>(*subdepartments[i])); |
177 | + api_depts.push_back(get_ptr<Department>(subdepartments[i])); |
178 | } |
179 | get_ptr<Department>(dept)->set_subdepartments(api_depts); |
180 | } |
181 | |
182 | === modified file 'department.go' |
183 | --- department.go 2015-04-07 07:36:43 +0000 |
184 | +++ department.go 2016-04-18 08:45:48 +0000 |
185 | @@ -24,7 +24,7 @@ |
186 | func NewDepartment(departmentID string, query *CannedQuery, label string) (*Department, error) { |
187 | dept := makeDepartment() |
188 | var errorString *C.char |
189 | - C.new_department(unsafe.Pointer(&departmentID), query.q, unsafe.Pointer(&label), &dept.d[0], &errorString) |
190 | + C.new_department(strData(departmentID), query.q, strData(label), &dept.d[0], &errorString) |
191 | |
192 | if err := checkError(errorString); err != nil { |
193 | return nil, err |
194 | @@ -70,7 +70,7 @@ |
195 | // The alternate label only needs to be provided for the current |
196 | // department. |
197 | func (dept *Department) SetAlternateLabel(label string) { |
198 | - C.department_set_alternate_label(&dept.d[0], unsafe.Pointer(&label)) |
199 | + C.department_set_alternate_label(&dept.d[0], strData(label)) |
200 | } |
201 | |
202 | // AlternateLabel gets the alternate label for this department. |
203 | @@ -126,9 +126,17 @@ |
204 | |
205 | // SetSubdepartments sets sub-departments of this department. |
206 | func (dept *Department) SetSubdepartments(subdepartments []*Department) { |
207 | - api_depts := make([]*C.SharedPtrData, len(subdepartments)) |
208 | + // This technically breaks C++ shared_ptr rules because we are |
209 | + // making a copy of the shared_ptr that doesn't own a |
210 | + // reference. |
211 | + // |
212 | + // However, we know the copy won't be destroyed on the C++ |
213 | + // side, and we hold references to the underlying Deparment |
214 | + // objects, preventing them from being cleaned up while the |
215 | + // shared_ptr copies are in scope. |
216 | + api_depts := make([]C.SharedPtrData, len(subdepartments)) |
217 | for i := 0; i < len(subdepartments); i++ { |
218 | - api_depts[i] = &subdepartments[i].d |
219 | + api_depts[i] = subdepartments[i].d |
220 | } |
221 | if len(subdepartments) > 0 { |
222 | C.department_set_subdepartments(&dept.d[0], &api_depts[0], C.int(len(subdepartments))) |
223 | |
224 | === modified file 'helpers.cpp' |
225 | --- helpers.cpp 2015-02-26 10:39:56 +0000 |
226 | +++ helpers.cpp 2016-04-18 08:45:48 +0000 |
227 | @@ -10,9 +10,21 @@ |
228 | namespace gounityscopes { |
229 | namespace internal { |
230 | |
231 | -std::string from_gostring(void *str) { |
232 | - GoString *s = static_cast<GoString*>(str); |
233 | - return std::string(s->p, s->n); |
234 | +std::string from_gostring(const StrData str) { |
235 | + return std::string(str.data, str.length); |
236 | +} |
237 | + |
238 | +std::vector<std::string> split_strings(const StrData str) { |
239 | + std::vector<std::string> list; |
240 | + const char *s = str.data; |
241 | + // str contains a sequence of nul-terminated strings concatenated together. |
242 | + for (const char *p = str.data; p != str.data + str.length; ++p) { |
243 | + if (*p == '\0') { |
244 | + list.push_back(s); |
245 | + s = p + 1; |
246 | + } |
247 | + } |
248 | + return list; |
249 | } |
250 | |
251 | void *as_bytes(const std::string &str, int *length) { |
252 | |
253 | === added file 'helpers.go' |
254 | --- helpers.go 1970-01-01 00:00:00 +0000 |
255 | +++ helpers.go 2016-04-18 08:45:48 +0000 |
256 | @@ -0,0 +1,49 @@ |
257 | +package scopes |
258 | + |
259 | +// #include <stdlib.h> |
260 | +// #include "shim.h" |
261 | +import "C" |
262 | +import ( |
263 | + "reflect" |
264 | + "unsafe" |
265 | +) |
266 | + |
267 | +// strData transforms a string to a form that can be passed to cgo |
268 | +// without copying data. |
269 | +func strData(s string) C.StrData { |
270 | + h := (*reflect.StringHeader)(unsafe.Pointer(&s)) |
271 | + return C.StrData{ |
272 | + data: (*C.char)(unsafe.Pointer(h.Data)), |
273 | + length: C.long(len(s)), |
274 | + } |
275 | +} |
276 | + |
277 | +// byteData transforms a byte array into the same format strData() produces. |
278 | +func byteData(b []byte) C.StrData { |
279 | + if len(b) == 0 { |
280 | + return C.StrData{ |
281 | + data: nil, |
282 | + length: 0, |
283 | + } |
284 | + } |
285 | + return C.StrData{ |
286 | + data: (*C.char)(unsafe.Pointer(&b[0])), |
287 | + length: C.long(len(b)), |
288 | + } |
289 | +} |
290 | + |
291 | + |
292 | +func joinedStrData(a []string) C.StrData { |
293 | + total := 0 |
294 | + for _, s := range a { |
295 | + total += len(s) + 1 |
296 | + } |
297 | + buf := make([]byte, total) |
298 | + i := 0 |
299 | + for _, s := range a { |
300 | + copy(buf[i:i+len(s)], s) |
301 | + buf[i+len(s)] = 0 |
302 | + i += len(s) + 1 |
303 | + } |
304 | + return byteData(buf) |
305 | +} |
306 | |
307 | === modified file 'helpers.h' |
308 | --- helpers.h 2015-02-26 10:39:56 +0000 |
309 | +++ helpers.h 2016-04-18 08:45:48 +0000 |
310 | @@ -2,11 +2,15 @@ |
311 | #define UNITYSCOPE_HELPERS_H |
312 | |
313 | #include <string> |
314 | +#include <vector> |
315 | + |
316 | +typedef struct StrData StrData; |
317 | |
318 | namespace gounityscopes { |
319 | namespace internal { |
320 | |
321 | -std::string from_gostring(void *str); |
322 | +std::string from_gostring(const StrData str); |
323 | +std::vector<std::string> split_strings(const StrData str); |
324 | void *as_bytes(const std::string &str, int *length); |
325 | |
326 | } |
327 | |
328 | === modified file 'metadata.cpp' |
329 | --- metadata.cpp 2015-05-21 12:21:03 +0000 |
330 | +++ metadata.cpp 2016-04-18 08:45:48 +0000 |
331 | @@ -16,7 +16,7 @@ |
332 | using namespace gounityscopes::internal; |
333 | |
334 | /* SearchMetadata objects */ |
335 | -_SearchMetadata *new_search_metadata(int cardinality, void *locale, void *form_factor) { |
336 | +_SearchMetadata *new_search_metadata(int cardinality, const StrData locale, const StrData form_factor) { |
337 | return reinterpret_cast<_SearchMetadata*>(new SearchMetadata(cardinality, |
338 | from_gostring(locale), |
339 | from_gostring(form_factor))); |
340 | @@ -88,12 +88,11 @@ |
341 | } |
342 | } |
343 | |
344 | -void search_metadata_set_aggregated_keywords(_SearchMetadata *metadata, void *gostring_array, int count, char **error) { |
345 | +void search_metadata_set_aggregated_keywords(_SearchMetadata *metadata, const StrData keyword_list, char **error) { |
346 | try { |
347 | - GoString *keyword_data = static_cast<GoString*>(gostring_array); |
348 | std::set<std::string> keywords; |
349 | - for (int i = 0; i < count; i++) { |
350 | - keywords.emplace(std::string(keyword_data[i].p, keyword_data[i].n)); |
351 | + for (auto &k : split_strings(keyword_list)) { |
352 | + keywords.emplace(std::move(k)); |
353 | } |
354 | reinterpret_cast<SearchMetadata*>(metadata)->set_aggregated_keywords(keywords); |
355 | } catch (const std::exception & e) { |
356 | @@ -115,7 +114,7 @@ |
357 | |
358 | |
359 | /* ActionMetadata objects */ |
360 | -_ActionMetadata *new_action_metadata(void *locale, void *form_factor) { |
361 | +_ActionMetadata *new_action_metadata(const StrData locale, const StrData form_factor) { |
362 | return reinterpret_cast<_ActionMetadata*>(new ActionMetadata(from_gostring(locale), |
363 | from_gostring(form_factor))); |
364 | } |
365 | @@ -138,7 +137,7 @@ |
366 | } |
367 | } |
368 | |
369 | -void action_metadata_set_hint(_ActionMetadata *metadata, void *key, char *json_data, int json_data_length, char **error) { |
370 | +void action_metadata_set_hint(_ActionMetadata *metadata, const StrData key, char *json_data, int json_data_length, char **error) { |
371 | try { |
372 | Variant value = Variant::deserialize_json(std::string(json_data, json_data_length)); |
373 | reinterpret_cast<ActionMetadata*>(metadata)->set_hint(from_gostring(key), value); |
374 | @@ -147,7 +146,7 @@ |
375 | } |
376 | } |
377 | |
378 | -void *action_metadata_get_hint(_ActionMetadata *metadata, void *key, int *data_length, char **error) { |
379 | +void *action_metadata_get_hint(_ActionMetadata *metadata, const StrData key, int *data_length, char **error) { |
380 | try { |
381 | ActionMetadata const*api_metadata = reinterpret_cast<ActionMetadata const*>(metadata); |
382 | Variant value = (*api_metadata)[from_gostring(key)]; |
383 | |
384 | === modified file 'metadata.go' |
385 | --- metadata.go 2015-05-21 14:58:07 +0000 |
386 | +++ metadata.go 2016-04-18 08:45:48 +0000 |
387 | @@ -71,8 +71,8 @@ |
388 | // form_factor |
389 | func NewSearchMetadata(cardinality int, locale, form_factor string) *SearchMetadata { |
390 | return makeSearchMetadata(C.new_search_metadata(C.int(cardinality), |
391 | - unsafe.Pointer(&locale), |
392 | - unsafe.Pointer(&form_factor))) |
393 | + strData(locale), |
394 | + strData(form_factor))) |
395 | } |
396 | |
397 | // Cardinality returns the desired number of results for the search request. |
398 | @@ -134,7 +134,7 @@ |
399 | |
400 | func (metadata *SearchMetadata) SetAggregatedKeywords(keywords []string) error { |
401 | var errorString *C.char |
402 | - C.search_metadata_set_aggregated_keywords((*C._SearchMetadata)(metadata.m), unsafe.Pointer(&keywords[0]), C.int(len(keywords)), &errorString) |
403 | + C.search_metadata_set_aggregated_keywords((*C._SearchMetadata)(metadata.m), joinedStrData(keywords), &errorString) |
404 | return checkError(errorString) |
405 | } |
406 | |
407 | @@ -171,8 +171,8 @@ |
408 | // NewActionMetadata creates a new ActionMetadata with the given locale and |
409 | // form_factor |
410 | func NewActionMetadata(locale, form_factor string) *ActionMetadata { |
411 | - return makeActionMetadata(C.new_action_metadata(unsafe.Pointer(&locale), |
412 | - unsafe.Pointer(&form_factor))) |
413 | + return makeActionMetadata(C.new_action_metadata(strData(locale), |
414 | + strData(form_factor))) |
415 | } |
416 | |
417 | func makeActionMetadata(m *C._ActionMetadata) *ActionMetadata { |
418 | @@ -211,7 +211,7 @@ |
419 | return err |
420 | } |
421 | var errorString *C.char |
422 | - C.action_metadata_set_hint((*C._ActionMetadata)(metadata.m), unsafe.Pointer(&key), (*C.char)(unsafe.Pointer(&data[0])), C.int(len(data)), &errorString) |
423 | + C.action_metadata_set_hint((*C._ActionMetadata)(metadata.m), strData(key), (*C.char)(unsafe.Pointer(&data[0])), C.int(len(data)), &errorString) |
424 | return checkError(errorString) |
425 | } |
426 | |
427 | @@ -220,7 +220,7 @@ |
428 | func (metadata *ActionMetadata) Hint(key string, value interface{}) error { |
429 | var dataLength C.int |
430 | var errorString *C.char |
431 | - scopeData := C.action_metadata_get_hint((*C._ActionMetadata)(metadata.m), unsafe.Pointer(&key), &dataLength, &errorString) |
432 | + scopeData := C.action_metadata_get_hint((*C._ActionMetadata)(metadata.m), strData(key), &dataLength, &errorString) |
433 | if dataLength > 0 && errorString == nil { |
434 | defer C.free(scopeData) |
435 | return json.Unmarshal(C.GoBytes(scopeData, dataLength), value) |
436 | |
437 | === modified file 'query.cpp' |
438 | --- query.cpp 2015-02-28 00:44:27 +0000 |
439 | +++ query.cpp 2016-04-18 08:45:48 +0000 |
440 | @@ -15,7 +15,7 @@ |
441 | delete reinterpret_cast<CannedQuery*>(query); |
442 | } |
443 | |
444 | -_CannedQuery *new_canned_query(void *scope_id, void *query_str, void *department_id) { |
445 | +_CannedQuery *new_canned_query(const StrData scope_id, const StrData query_str, const StrData department_id) { |
446 | return reinterpret_cast<_CannedQuery*>( |
447 | new CannedQuery(from_gostring(scope_id), |
448 | from_gostring(query_str), |
449 | @@ -45,11 +45,11 @@ |
450 | return strdup(reinterpret_cast<CannedQuery*>(query)->query_string().c_str()); |
451 | } |
452 | |
453 | -void canned_query_set_department_id(_CannedQuery *query, void *department_id) { |
454 | +void canned_query_set_department_id(_CannedQuery *query, const StrData department_id) { |
455 | reinterpret_cast<CannedQuery*>(query)->set_department_id(from_gostring(department_id)); |
456 | } |
457 | |
458 | -void canned_query_set_query_string(_CannedQuery *query, void *query_str) { |
459 | +void canned_query_set_query_string(_CannedQuery *query, const StrData query_str) { |
460 | reinterpret_cast<CannedQuery*>(query)->set_query_string(from_gostring(query_str)); |
461 | } |
462 | |
463 | |
464 | === modified file 'query.go' |
465 | --- query.go 2015-02-28 00:44:27 +0000 |
466 | +++ query.go 2016-04-18 08:45:48 +0000 |
467 | @@ -32,9 +32,9 @@ |
468 | // query string and department ID. |
469 | func NewCannedQuery(scopeID, queryString, departmentID string) *CannedQuery { |
470 | return makeCannedQuery(C.new_canned_query( |
471 | - unsafe.Pointer(&scopeID), |
472 | - unsafe.Pointer(&queryString), |
473 | - unsafe.Pointer(&departmentID))) |
474 | + strData(scopeID), |
475 | + strData(queryString), |
476 | + strData(departmentID))) |
477 | } |
478 | |
479 | // ScopeID returns the scope ID for this canned query. |
480 | @@ -72,12 +72,12 @@ |
481 | |
482 | // SetDepartmentID changes the department ID for this canned query. |
483 | func (query *CannedQuery) SetDepartmentID(departmentID string) { |
484 | - C.canned_query_set_department_id(query.q, unsafe.Pointer(&departmentID)) |
485 | + C.canned_query_set_department_id(query.q, strData(departmentID)) |
486 | } |
487 | |
488 | // SetQueryString changes the query string for this canned query. |
489 | func (query *CannedQuery) SetQueryString(queryString string) { |
490 | - C.canned_query_set_query_string(query.q, unsafe.Pointer(&queryString)) |
491 | + C.canned_query_set_query_string(query.q, strData(queryString)) |
492 | } |
493 | |
494 | // ToURI formats the canned query as a URI. |
495 | |
496 | === modified file 'reply.cpp' |
497 | --- reply.cpp 2015-03-25 07:46:21 +0000 |
498 | +++ reply.cpp 2016-04-18 08:45:48 +0000 |
499 | @@ -28,12 +28,12 @@ |
500 | get_ptr<SearchReply>(reply)->finished(); |
501 | } |
502 | |
503 | -void search_reply_error(SharedPtrData reply, void *err_string) { |
504 | +void search_reply_error(SharedPtrData reply, const StrData err_string) { |
505 | get_ptr<SearchReply>(reply)->error(std::make_exception_ptr( |
506 | std::runtime_error(from_gostring(err_string)))); |
507 | } |
508 | |
509 | -void search_reply_register_category(SharedPtrData reply, void *id, void *title, void *icon, void *cat_template, SharedPtrData category) { |
510 | +void search_reply_register_category(SharedPtrData reply, const StrData id, const StrData title, const StrData icon, const StrData cat_template, SharedPtrData category) { |
511 | CategoryRenderer renderer; |
512 | std::string renderer_template = from_gostring(cat_template); |
513 | if (!renderer_template.empty()) { |
514 | @@ -55,7 +55,7 @@ |
515 | } |
516 | } |
517 | |
518 | -void search_reply_push_filters(SharedPtrData reply, void *filters_json, void *filter_state_json, char **error) { |
519 | +void search_reply_push_filters(SharedPtrData reply, const StrData filters_json, const StrData filter_state_json, char **error) { |
520 | #if UNITY_SCOPES_VERSION_MAJOR == 0 && (UNITY_SCOPES_VERSION_MINOR < 6 || (UNITY_SCOPES_VERSION_MINOR == 6 && UNITY_SCOPES_VERSION_MICRO < 10)) |
521 | std::string errorMessage = "SearchReply.PushFilters() is only available when compiled against libunity-scopes >= 0.6.10"; |
522 | *error = strdup(errorMessage.c_str()); |
523 | @@ -89,18 +89,16 @@ |
524 | get_ptr<PreviewReply>(reply)->finished(); |
525 | } |
526 | |
527 | -void preview_reply_error(SharedPtrData reply, void *err_string) { |
528 | +void preview_reply_error(SharedPtrData reply, const StrData err_string) { |
529 | get_ptr<PreviewReply>(reply)->error(std::make_exception_ptr( |
530 | std::runtime_error(from_gostring(err_string)))); |
531 | } |
532 | |
533 | -void preview_reply_push_widgets(SharedPtrData reply, void *gostring_array, int count, char **error) { |
534 | +void preview_reply_push_widgets(SharedPtrData reply, const StrData widget_list, char **error) { |
535 | try { |
536 | - GoString *widget_data = static_cast<GoString*>(gostring_array); |
537 | PreviewWidgetList widgets; |
538 | - for (int i = 0; i < count; i++) { |
539 | - widgets.push_back(PreviewWidget(std::string( |
540 | - widget_data[i].p, widget_data[i].n))); |
541 | + for (const auto &w : split_strings(widget_list)) { |
542 | + widgets.push_back(PreviewWidget(w)); |
543 | } |
544 | get_ptr<PreviewReply>(reply)->push(widgets); |
545 | } catch (const std::exception &e) { |
546 | @@ -108,7 +106,7 @@ |
547 | } |
548 | } |
549 | |
550 | -void preview_reply_push_attr(SharedPtrData reply, void *key, void *json_value, char **error) { |
551 | +void preview_reply_push_attr(SharedPtrData reply, const StrData key, const StrData json_value, char **error) { |
552 | try { |
553 | Variant value = Variant::deserialize_json(from_gostring(json_value)); |
554 | get_ptr<PreviewReply>(reply)->push(from_gostring(key), value); |
555 | |
556 | === modified file 'reply.go' |
557 | --- reply.go 2015-03-25 08:14:19 +0000 |
558 | +++ reply.go 2016-04-18 08:45:48 +0000 |
559 | @@ -6,7 +6,6 @@ |
560 | import ( |
561 | "encoding/json" |
562 | "runtime" |
563 | - "unsafe" |
564 | ) |
565 | |
566 | // SearchReply is used to send results of search queries to the client. |
567 | @@ -41,7 +40,7 @@ |
568 | // with an error. |
569 | func (reply *SearchReply) Error(err error) { |
570 | errString := err.Error() |
571 | - C.search_reply_error(&reply.r[0], unsafe.Pointer(&errString)) |
572 | + C.search_reply_error(&reply.r[0], strData(errString)) |
573 | } |
574 | |
575 | // RegisterCategory registers a new results category with the client. |
576 | @@ -56,7 +55,7 @@ |
577 | func (reply *SearchReply) RegisterCategory(id, title, icon, template string) *Category { |
578 | cat := new(Category) |
579 | runtime.SetFinalizer(cat, finalizeCategory) |
580 | - C.search_reply_register_category(&reply.r[0], unsafe.Pointer(&id), unsafe.Pointer(&title), unsafe.Pointer(&icon), unsafe.Pointer(&template), &cat.c[0]) |
581 | + C.search_reply_register_category(&reply.r[0], strData(id), strData(title), strData(icon), strData(template), &cat.c[0]) |
582 | return cat |
583 | } |
584 | |
585 | @@ -95,7 +94,7 @@ |
586 | return err |
587 | } |
588 | var errorString *C.char |
589 | - C.search_reply_push_filters(&reply.r[0], unsafe.Pointer(&filtersJson), unsafe.Pointer(&stateJson), &errorString) |
590 | + C.search_reply_push_filters(&reply.r[0], strData(filtersJson), strData(stateJson), &errorString) |
591 | return checkError(errorString) |
592 | } |
593 | |
594 | @@ -131,7 +130,7 @@ |
595 | // with an error. |
596 | func (reply *PreviewReply) Error(err error) { |
597 | errString := err.Error() |
598 | - C.preview_reply_error(&reply.r[0], unsafe.Pointer(&errString)) |
599 | + C.preview_reply_error(&reply.r[0], strData(errString)) |
600 | } |
601 | |
602 | // PushWidgets sends one or more preview widgets to the client. |
603 | @@ -145,7 +144,7 @@ |
604 | widget_data[i] = string(data) |
605 | } |
606 | var errorString *C.char |
607 | - C.preview_reply_push_widgets(&reply.r[0], unsafe.Pointer(&widget_data[0]), C.int(len(widget_data)), &errorString) |
608 | + C.preview_reply_push_widgets(&reply.r[0], joinedStrData(widget_data), &errorString) |
609 | return checkError(errorString) |
610 | } |
611 | |
612 | @@ -162,7 +161,7 @@ |
613 | } |
614 | json_value := string(data) |
615 | var errorString *C.char |
616 | - C.preview_reply_push_attr(&reply.r[0], unsafe.Pointer(&attr), unsafe.Pointer(&json_value), &errorString) |
617 | + C.preview_reply_push_attr(&reply.r[0], strData(attr), strData(json_value), &errorString) |
618 | return checkError(errorString) |
619 | } |
620 | |
621 | |
622 | === modified file 'result.cpp' |
623 | --- result.cpp 2015-03-02 05:43:42 +0000 |
624 | +++ result.cpp 2016-04-18 08:45:48 +0000 |
625 | @@ -23,7 +23,7 @@ |
626 | delete reinterpret_cast<Result*>(res); |
627 | } |
628 | |
629 | -void *result_get_attr(_Result *res, void *attr, int *length, char **error) { |
630 | +void *result_get_attr(_Result *res, const StrData attr, int *length, char **error) { |
631 | std::string json_data; |
632 | try { |
633 | Variant v = reinterpret_cast<Result*>(res)->value(from_gostring(attr)); |
634 | @@ -35,7 +35,7 @@ |
635 | return as_bytes(json_data, length); |
636 | } |
637 | |
638 | -void result_set_attr(_Result *res, void *attr, void *json_value, char **error) { |
639 | +void result_set_attr(_Result *res, const StrData attr, const StrData json_value, char **error) { |
640 | try { |
641 | Variant v = Variant::deserialize_json(from_gostring(json_value)); |
642 | (*reinterpret_cast<Result*>(res))[from_gostring(attr)] = v; |
643 | |
644 | === modified file 'result.go' |
645 | --- result.go 2015-03-23 11:16:52 +0000 |
646 | +++ result.go 2016-04-18 08:45:48 +0000 |
647 | @@ -6,7 +6,6 @@ |
648 | import ( |
649 | "encoding/json" |
650 | "runtime" |
651 | - "unsafe" |
652 | ) |
653 | |
654 | // Result represents a result from the scope |
655 | @@ -39,7 +38,7 @@ |
656 | length C.int |
657 | errorString *C.char |
658 | ) |
659 | - data := C.result_get_attr(res.result, unsafe.Pointer(&attr), &length, &errorString) |
660 | + data := C.result_get_attr(res.result, strData(attr), &length, &errorString) |
661 | if err := checkError(errorString); err != nil { |
662 | return err |
663 | } |
664 | @@ -59,7 +58,7 @@ |
665 | stringValue := string(data) |
666 | |
667 | var errorString *C.char |
668 | - C.result_set_attr(res.result, unsafe.Pointer(&attr), unsafe.Pointer(&stringValue), &errorString) |
669 | + C.result_set_attr(res.result, strData(attr), strData(stringValue), &errorString) |
670 | return checkError(errorString) |
671 | } |
672 | |
673 | |
674 | === modified file 'shim.cpp' |
675 | --- shim.cpp 2015-05-21 16:26:12 +0000 |
676 | +++ shim.cpp 2016-04-18 08:45:48 +0000 |
677 | @@ -14,8 +14,9 @@ |
678 | using namespace unity::scopes; |
679 | using namespace gounityscopes::internal; |
680 | |
681 | -void run_scope(void *scope_name, void *runtime_config, void *scope_config, |
682 | - void *pointer_to_iface, char **error) { |
683 | +void run_scope(const StrData scope_name, const StrData runtime_config, |
684 | + const StrData scope_config, void *pointer_to_iface, |
685 | + char **error) { |
686 | try { |
687 | auto runtime = Runtime::create_scope_runtime( |
688 | from_gostring(scope_name), from_gostring(runtime_config)); |
689 | |
690 | === modified file 'shim.h' |
691 | --- shim.h 2015-10-20 05:34:29 +0000 |
692 | +++ shim.h 2016-04-18 08:45:48 +0000 |
693 | @@ -11,6 +11,11 @@ |
694 | |
695 | typedef uintptr_t SharedPtrData[2]; |
696 | |
697 | +typedef struct StrData { |
698 | + char *data; |
699 | + long length; |
700 | +} StrData; |
701 | + |
702 | typedef struct _CannedQuery _CannedQuery; |
703 | typedef struct _Result _Result; |
704 | typedef struct _Result _CategorisedResult; |
705 | @@ -25,8 +30,8 @@ |
706 | |
707 | typedef struct _ActivationResponse _ActivationResponse; |
708 | |
709 | -void run_scope(void *scope_name, void *runtime_config, |
710 | - void *scope_config, void *pointer_to_iface, |
711 | +void run_scope(const StrData scope_name, const StrData runtime_config, |
712 | + const StrData scope_config, void *pointer_to_iface, |
713 | char **error); |
714 | |
715 | /* ScopeBase objects */ |
716 | @@ -38,7 +43,7 @@ |
717 | _ChildScope **list_child_scopes(_ScopeBase *scope, int *n_scopes); |
718 | |
719 | /* ChildScope objects */ |
720 | -_ChildScope *new_child_scope(void *id, _ScopeMetadata *metadata, int enabled, void *gostring_array, int count); |
721 | +_ChildScope *new_child_scope(const StrData id, _ScopeMetadata *metadata, int enabled, const StrData keyword_list); |
722 | void destroy_child_scope(_ChildScope *childscope); |
723 | char *child_scope_get_id(_ChildScope *childscope); |
724 | void set_child_scopes_list(void *child_scopes_list, _ChildScope **source_child_scopes, int length); |
725 | @@ -48,31 +53,31 @@ |
726 | void destroy_search_reply_ptr(SharedPtrData data); |
727 | |
728 | void search_reply_finished(SharedPtrData reply); |
729 | -void search_reply_error(SharedPtrData reply, void *err_string); |
730 | -void search_reply_register_category(SharedPtrData reply, void *id, void *title, void *icon, void *cat_template, SharedPtrData category); |
731 | +void search_reply_error(SharedPtrData reply, const StrData err_string); |
732 | +void search_reply_register_category(SharedPtrData reply, const StrData id, const StrData title, const StrData icon, const StrData cat_template, SharedPtrData category); |
733 | void search_reply_register_departments(SharedPtrData reply, SharedPtrData dept); |
734 | void search_reply_push(SharedPtrData reply, _CategorisedResult *result, char **error); |
735 | -void search_reply_push_filters(SharedPtrData reply, void *filters_json, void *filter_state_json, char **error); |
736 | +void search_reply_push_filters(SharedPtrData reply, const StrData filters_json, const StrData filter_state_json, char **error); |
737 | |
738 | /* PreviewReply objects */ |
739 | void init_preview_reply_ptr(SharedPtrData dest, SharedPtrData src); |
740 | void destroy_preview_reply_ptr(SharedPtrData data); |
741 | |
742 | void preview_reply_finished(SharedPtrData reply); |
743 | -void preview_reply_error(SharedPtrData reply, void *err_string); |
744 | -void preview_reply_push_widgets(SharedPtrData reply, void *gostring_array, int count, char **error); |
745 | -void preview_reply_push_attr(SharedPtrData reply, void *key, void *json_value, char **error); |
746 | +void preview_reply_error(SharedPtrData reply, const StrData err_string); |
747 | +void preview_reply_push_widgets(SharedPtrData reply, const StrData widget_list, char **error); |
748 | +void preview_reply_push_attr(SharedPtrData reply, const StrData key, const StrData json_value, char **error); |
749 | void preview_reply_register_layout(SharedPtrData reply, _ColumnLayout **layout, int n_items, char **error); |
750 | |
751 | /* CannedQuery objects */ |
752 | void destroy_canned_query(_CannedQuery *query); |
753 | -_CannedQuery *new_canned_query(void *scope_id, void *query_str, void *department_id); |
754 | +_CannedQuery *new_canned_query(const StrData scope_id, const StrData query_str, const StrData department_id); |
755 | char *canned_query_get_scope_id(_CannedQuery *query); |
756 | char *canned_query_get_department_id(_CannedQuery *query); |
757 | char *canned_query_get_query_string(_CannedQuery *query); |
758 | void *canned_query_get_filter_state(_CannedQuery *query, int *length); |
759 | -void canned_query_set_department_id(_CannedQuery *query, void *department_id); |
760 | -void canned_query_set_query_string(_CannedQuery *query, void *query_str); |
761 | +void canned_query_set_department_id(_CannedQuery *query, const StrData department_id); |
762 | +void canned_query_set_query_string(_CannedQuery *query, const StrData query_str); |
763 | char *canned_query_to_uri(_CannedQuery *query); |
764 | |
765 | /* Category objects */ |
766 | @@ -83,16 +88,16 @@ |
767 | void destroy_result(_Result *res); |
768 | |
769 | /* Result objects */ |
770 | -void *result_get_attr(_Result *res, void *attr, int *length, char **error); |
771 | -void result_set_attr(_Result *res, void *attr, void *json_value, char **error); |
772 | +void *result_get_attr(_Result *res, const StrData attr, int *length, char **error); |
773 | +void result_set_attr(_Result *res, const StrData attr, const StrData json_value, char **error); |
774 | void result_set_intercept_activation(_Result *res); |
775 | |
776 | /* Department objects */ |
777 | void init_department_ptr(SharedPtrData dest, SharedPtrData src); |
778 | -void new_department(void *deptt_id, _CannedQuery *query, void *label, SharedPtrData dept, char **error); |
779 | +void new_department(const StrData deptt_id, _CannedQuery *query, const StrData label, SharedPtrData dept, char **error); |
780 | void destroy_department_ptr(SharedPtrData data); |
781 | void department_add_subdepartment(SharedPtrData dept, SharedPtrData child); |
782 | -void department_set_alternate_label(SharedPtrData dept, void *label); |
783 | +void department_set_alternate_label(SharedPtrData dept, const StrData label); |
784 | char *department_get_alternate_label(SharedPtrData dept); |
785 | char *department_get_id(SharedPtrData dept); |
786 | char *department_get_label(SharedPtrData dept); |
787 | @@ -100,7 +105,7 @@ |
788 | int department_has_subdepartments(SharedPtrData dept); |
789 | //void department_get_subdepartments(SharedPtrData dept, SharedPtrData **ret_data); |
790 | SharedPtrData * department_get_subdepartments(SharedPtrData dept, int *n_subdepts); |
791 | -void department_set_subdepartments(SharedPtrData dept, SharedPtrData **subdepartments, int nb_subdepartments); |
792 | +void department_set_subdepartments(SharedPtrData dept, SharedPtrData *subdepartments, int nb_subdepartments); |
793 | _CannedQuery * department_get_query(SharedPtrData dept); |
794 | |
795 | /* QueryMetadata objects */ |
796 | @@ -110,22 +115,22 @@ |
797 | int query_metadata_get_internet_connectivity(_QueryMetadata *metadata); |
798 | |
799 | /* SearchMetadata objects */ |
800 | -_SearchMetadata *new_search_metadata(int cardinality, void *locale, void *form_factor); |
801 | +_SearchMetadata *new_search_metadata(int cardinality, const StrData locale, const StrData form_factor); |
802 | void destroy_search_metadata(_SearchMetadata *metadata); |
803 | int search_metadata_get_cardinality(_SearchMetadata *metadata); |
804 | void *search_metadata_get_location(_SearchMetadata *metadata, int *length); |
805 | void search_metadata_set_location(_SearchMetadata *metadata, char *json_data, int json_data_length, char **error); |
806 | -void search_metadata_set_aggregated_keywords(_SearchMetadata *metadata, void *gostring_array, int count, char **error); |
807 | +void search_metadata_set_aggregated_keywords(_SearchMetadata *metadata, const StrData keyword_list, char **error); |
808 | void *search_metadata_get_aggregated_keywords(_SearchMetadata *metadata, int *length); |
809 | int search_metadata_is_aggregated(_SearchMetadata *metadata); |
810 | |
811 | /* ActionMetadata objects */ |
812 | -_ActionMetadata *new_action_metadata(void *locale, void *form_factor); |
813 | +_ActionMetadata *new_action_metadata(const StrData locale, const StrData form_factor); |
814 | void destroy_action_metadata(_ActionMetadata *metadata); |
815 | void *action_metadata_get_scope_data(_ActionMetadata *metadata, int *data_length); |
816 | void action_metadata_set_scope_data(_ActionMetadata *metadata, char *json_data, int json_data_length, char **error); |
817 | -void action_metadata_set_hint(_ActionMetadata *metadata, void *key, char *json_data, int json_data_length, char **error); |
818 | -void *action_metadata_get_hint(_ActionMetadata *metadata, void *key, int *data_length, char **error); |
819 | +void action_metadata_set_hint(_ActionMetadata *metadata, const StrData key, char *json_data, int json_data_length, char **error); |
820 | +void *action_metadata_get_hint(_ActionMetadata *metadata, const StrData key, int *data_length, char **error); |
821 | void *action_metadata_get_hints(_ActionMetadata *metadata, int *length); |
822 | |
823 | /* ScopeMetadata objects */ |
824 | @@ -136,13 +141,13 @@ |
825 | void activation_response_init_status(_ActivationResponse *response, int status); |
826 | void activation_response_init_query(_ActivationResponse *response, _CannedQuery *query); |
827 | void activation_response_init_update_result(_ActivationResponse *response, _Result *result); |
828 | -void activation_response_init_update_preview(_ActivationResponse *response, void *gostring_array, int count, char **error); |
829 | +void activation_response_init_update_preview(_ActivationResponse *response, const StrData widget_list, char **error); |
830 | void activation_response_set_scope_data(_ActivationResponse *response, char *json_data, int json_data_length, char **error); |
831 | |
832 | /* ColumnLayout objects */ |
833 | _ColumnLayout *new_column_layout(int num_columns); |
834 | void destroy_column_layout(_ColumnLayout *layout); |
835 | -void column_layout_add_column(_ColumnLayout *layout, void *gostring_array_widgets, int nb_widgets, char **error); |
836 | +void column_layout_add_column(_ColumnLayout *layout, const StrData widget_list, char **error); |
837 | int column_layout_number_of_columns(_ColumnLayout *layout); |
838 | int column_layout_size(_ColumnLayout *layout); |
839 | void *column_layout_column(_ColumnLayout *layout, int column, int *n_items, char **error); |
840 | |
841 | === modified file 'unityscope.go' |
842 | --- unityscope.go 2015-06-09 15:03:05 +0000 |
843 | +++ unityscope.go 2016-04-18 08:45:48 +0000 |
844 | @@ -254,7 +254,7 @@ |
845 | scopeId := base[:len(base)-len(".ini")] |
846 | |
847 | var errorString *C.char |
848 | - C.run_scope(unsafe.Pointer(&scopeId), unsafe.Pointer(runtimeConfig), unsafe.Pointer(scopeConfig), unsafe.Pointer(&scope), &errorString) |
849 | + C.run_scope(strData(scopeId), strData(*runtimeConfig), strData(*scopeConfig), unsafe.Pointer(&scope), &errorString) |
850 | return checkError(errorString) |
851 | } |
852 |
Why has this been sitting here for six months without review? :(
We need this landed to get go scopes working on xenial for the coming unity8 snap.