[BREAKGLASS] Append-only mirror of github.com/sparrowwallet/usb4java
unsigned integers, which is what libusb uses everywhere.
As it was before, there are parts of the library that return bytes & shorts, like the Descriptors (mostly to
be compatible with javax.usb), and others that take and return int, even where an 8 or 16-bit quantity would
be expected by libusb. I suspect this was done to avoid casting and try to side-step the sign-extension
problem with Java as much as possible, but in the end it leads to an API that's inconsistent, that doesn't
express the ranges it can use well (it's an int but in reality only 16 bits for libusb and so on). It also
fails at basic operations in ways you'd not expect because of the above inconsistencies:
if (deviceDescriptor.bDeviceClass() == LibUsb.CLASS_VENDOR_SPEC) { do something; }
will never work, since the constant is an int and the returned short from bDeviceClass() will be cast up to an
int too, but CLASS_VENDOR_SPEC is 0xFF (MSB=1), it will be sign-extended and the comparison will fail always.
There are two solutions I can see here:
A) consistently use int/long everywhere, both input and output. Everything becomes simpler to write, with less
casts, BUT javax.usb compatibility is gone for the Descriptors and it becomes even unclearer what those values
effectively mean and what range they support.
B) restrict the API to use the proper integer sizes as the C API, ie. 8-bit quantities (char, uint8_t, int8_t)
are represented by jbyte, 16-bit by jshort, and all the constants get properly sized too. With this approach
the sizes and ranges are much clearer, comparisons like the above work out-of-the-box, javax.usb compatibility
is maintained for the Descriptors. The downside is more casting and the occasional need to mask off returned
values to kill the sign-extension when you want to use those values as integers (like when printing stuff in
decimal notation).
I chose to try out the approach from B) for now, this commit implements it as explained above.
It requires minimal changes to the javax.usb implementation, just two casts to byte in AbstractDevice.java.
|
||
|---|---|---|
| src | ||
| .gitignore | ||
| LICENSE.md | ||
| pom.xml | ||
| README.md | ||
usb4java
USB library for Java based on libusb 1.0
Copyright (C) 2011 Klaus Reimer k@ailis.de
See LICENSE.md for licensing information.
This library can be used to access USB devices in Java. It is based on the native libusb 1.0 shared library and reflects this API as complete as possible. usb4java also implements the javax.usb (JSR80) API. So you can choose if you want to access the USB devices via the low-level libusb 1.0 API or via the high level javax.usb API.
The native libraries are included in pre-compiled form for Linux, Windows and Mac OS X in 32 and 64 bit versions. The libraries are automatically extracted and loaded so you don't need to care about them.
For more detailed information please visit the usb4java website.