44
44
#include <wchar.h>
45
45
46
46
/* GNU / LibUSB */
47
- #include "libusb.h"
48
- #include "iconv.h"
47
+ #include <libusb.h>
48
+ #ifndef __ANDROID__
49
+ #include <iconv.h>
50
+ #endif
49
51
50
52
#include "hidapi.h"
51
53
54
+ #ifdef __ANDROID__
55
+
56
+ /* Barrier implementation because Android/Bionic don't have pthread_barrier.
57
+ This implementation came from Brent Priddy and was posted on
58
+ StackOverflow. It is used with his permission. */
59
+ typedef int pthread_barrierattr_t ;
60
+ typedef struct pthread_barrier {
61
+ pthread_mutex_t mutex ;
62
+ pthread_cond_t cond ;
63
+ int count ;
64
+ int trip_count ;
65
+ } pthread_barrier_t ;
66
+
67
+ static int pthread_barrier_init (pthread_barrier_t * barrier , const pthread_barrierattr_t * attr , unsigned int count )
68
+ {
69
+ if (count == 0 ) {
70
+ errno = EINVAL ;
71
+ return -1 ;
72
+ }
73
+
74
+ if (pthread_mutex_init (& barrier -> mutex , 0 ) < 0 ) {
75
+ return -1 ;
76
+ }
77
+ if (pthread_cond_init (& barrier -> cond , 0 ) < 0 ) {
78
+ pthread_mutex_destroy (& barrier -> mutex );
79
+ return -1 ;
80
+ }
81
+ barrier -> trip_count = count ;
82
+ barrier -> count = 0 ;
83
+
84
+ return 0 ;
85
+ }
86
+
87
+ static int pthread_barrier_destroy (pthread_barrier_t * barrier )
88
+ {
89
+ pthread_cond_destroy (& barrier -> cond );
90
+ pthread_mutex_destroy (& barrier -> mutex );
91
+ return 0 ;
92
+ }
93
+
94
+ static int pthread_barrier_wait (pthread_barrier_t * barrier )
95
+ {
96
+ pthread_mutex_lock (& barrier -> mutex );
97
+ ++ (barrier -> count );
98
+ if (barrier -> count >= barrier -> trip_count )
99
+ {
100
+ barrier -> count = 0 ;
101
+ pthread_cond_broadcast (& barrier -> cond );
102
+ pthread_mutex_unlock (& barrier -> mutex );
103
+ return 1 ;
104
+ }
105
+ else
106
+ {
107
+ pthread_cond_wait (& barrier -> cond , & (barrier -> mutex ));
108
+ pthread_mutex_unlock (& barrier -> mutex );
109
+ return 0 ;
110
+ }
111
+ }
112
+
113
+ #endif
114
+
52
115
#ifdef __cplusplus
53
116
extern "C" {
54
117
#endif
@@ -326,8 +389,9 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
326
389
char buf [512 ];
327
390
int len ;
328
391
wchar_t * str = NULL ;
329
- wchar_t wbuf [256 ];
330
392
393
+ #ifndef __ANDROID__ /* we don't use iconv on Android */
394
+ wchar_t wbuf [256 ];
331
395
/* iconv variables */
332
396
iconv_t ic ;
333
397
size_t inbytes ;
@@ -339,6 +403,7 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
339
403
char * inptr ;
340
404
#endif
341
405
char * outptr ;
406
+ #endif
342
407
343
408
/* Determine which language to use. */
344
409
uint16_t lang ;
@@ -355,6 +420,25 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
355
420
if (len < 0 )
356
421
return NULL ;
357
422
423
+ #ifdef __ANDROID__
424
+
425
+ /* Bionic does not have iconv support nor wcsdup() function, so it
426
+ has to be done manually. The following code will only work for
427
+ code points that can be represented as a single UTF-16 character,
428
+ and will incorrectly convert any code points which require more
429
+ than one UTF-16 character.
430
+
431
+ Skip over the first character (2-bytes). */
432
+ len -= 2 ;
433
+ str = malloc ((len / 2 + 1 ) * sizeof (wchar_t ));
434
+ int i ;
435
+ for (i = 0 ; i < len / 2 ; i ++ ) {
436
+ str [i ] = buf [i * 2 + 2 ] | (buf [i * 2 + 3 ] << 8 );
437
+ }
438
+ str [len / 2 ] = 0x00000000 ;
439
+
440
+ #else
441
+
358
442
/* buf does not need to be explicitly NULL-terminated because
359
443
it is only passed into iconv() which does not need it. */
360
444
@@ -388,6 +472,8 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
388
472
err :
389
473
iconv_close (ic );
390
474
475
+ #endif
476
+
391
477
return str ;
392
478
}
393
479
0 commit comments