Merge lp:~jamesh/go-unityscopes/go-1.6-compat into lp:go-unityscopes/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
Reviewer Review Type Date Requested Status
dobey (community) Approve
Review via email: mp+292117@code.launchpad.net

Description of the change

Update code to work with Go 1.6's new cgo pointer handling rules:

http://tip.golang.org/cmd/cgo/#hdr-Passing_pointers

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.
Revision history for this message
dobey (dobey) wrote :

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.

review: Approve

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

Subscribers

People subscribed via source and target branches

to all changes: