summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2020-04-17 13:22:34 -0700
committerChris Dickens <christopher.a.dickens@gmail.com>2020-04-17 13:22:34 -0700
commite873677b9196b191d6cdbdf9783c6d6a18379249 (patch)
treef083f210da89a4647b76d881fc9ef6796c847ff7
parent9ececdb0ecbbb77edd5a40cb8914ddc54b77dea2 (diff)
downloadlibusb-e873677b9196b191d6cdbdf9783c6d6a18379249.tar.gz
descriptor: Minor improvements to the parse_descriptor() function
Change the type of the source pointer to 'void' so that callers need not cast to 'unsigned char'. Also change working types to 'uint8_t' to make it explicit that we are dealing with 8-bit types. Refactor the parsing loop to avoid unnecessary stack variables. The generated assembly with this change is more efficient. Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--libusb/descriptor.c78
-rw-r--r--libusb/version_nano.h2
2 files changed, 43 insertions, 37 deletions
diff --git a/libusb/descriptor.c b/libusb/descriptor.c
index e4f376f..b65557f 100644
--- a/libusb/descriptor.c
+++ b/libusb/descriptor.c
@@ -30,41 +30,47 @@
* for detected devices
*/
-static void parse_descriptor(const unsigned char *source, const char *descriptor, void *dest)
+#define READ_LE16(p) ((uint16_t) \
+ (((uint16_t)((p)[1]) << 8) | \
+ ((uint16_t)((p)[0]))))
+
+#define READ_LE32(p) ((uint32_t) \
+ (((uint32_t)((p)[3]) << 24) | \
+ ((uint32_t)((p)[2]) << 16) | \
+ ((uint32_t)((p)[1]) << 8) | \
+ ((uint32_t)((p)[0]))))
+
+static void parse_descriptor(const void *source, const char *descriptor, void *dest)
{
- const unsigned char *sp = source;
- unsigned char *dp = dest;
- uint16_t w;
- const char *cp;
- uint32_t d;
-
- for (cp = descriptor; *cp; cp++) {
- switch (*cp) {
- case 'b': /* 8-bit byte */
- *dp++ = *sp++;
- break;
- case 'w': /* 16-bit word, convert from little endian to CPU */
- dp += ((uintptr_t)dp & 1); /* Align to word boundary */
+ const uint8_t *sp = source;
+ uint8_t *dp = dest;
+ char field_type;
+
+ while (*descriptor) {
+ field_type = *descriptor++;
+ switch (field_type) {
+ case 'b': /* 8-bit byte */
+ *dp++ = *sp++;
+ break;
+ case 'w': /* 16-bit word, convert from little endian to CPU */
+ dp += ((uintptr_t)dp & 1); /* Align to word boundary */
- w = (uint16_t)((sp[1] << 8) | sp[0]);
- *((uint16_t *)dp) = w;
- sp += 2;
- dp += 2;
- break;
- case 'd': /* 32-bit word, convert from little endian to CPU */
- dp += ((uintptr_t)dp & 1); /* Align to word boundary */
-
- d = (uint32_t)((sp[3] << 24) | (sp[2] << 16) |
- (sp[1] << 8) | sp[0]);
- *((uint32_t *)dp) = d;
- sp += 4;
- dp += 4;
- break;
- case 'u': /* 16 byte UUID */
- memcpy(dp, sp, 16);
- sp += 16;
- dp += 16;
- break;
+ *((uint16_t *)dp) = READ_LE16(sp);
+ sp += 2;
+ dp += 2;
+ break;
+ case 'd': /* 32-bit word, convert from little endian to CPU */
+ dp += ((uintptr_t)dp & 1); /* Align to word boundary */
+
+ *((uint32_t *)dp) = READ_LE32(sp);
+ sp += 4;
+ dp += 4;
+ break;
+ case 'u': /* 16 byte UUID */
+ memcpy(dp, sp, 16);
+ sp += 16;
+ dp += 16;
+ break;
}
}
}
@@ -950,7 +956,7 @@ int API_EXPORTED libusb_get_usb_2_0_extension_descriptor(
if (!_usb_2_0_extension)
return LIBUSB_ERROR_NO_MEM;
- parse_descriptor((unsigned char *)dev_cap, "bbbd", _usb_2_0_extension);
+ parse_descriptor(dev_cap, "bbbd", _usb_2_0_extension);
*usb_2_0_extension = _usb_2_0_extension;
return LIBUSB_SUCCESS;
@@ -1006,7 +1012,7 @@ int API_EXPORTED libusb_get_ss_usb_device_capability_descriptor(
if (!_ss_usb_device_cap)
return LIBUSB_ERROR_NO_MEM;
- parse_descriptor((unsigned char *)dev_cap, "bbbbwbbw", _ss_usb_device_cap);
+ parse_descriptor(dev_cap, "bbbbwbbw", _ss_usb_device_cap);
*ss_usb_device_cap = _ss_usb_device_cap;
return LIBUSB_SUCCESS;
@@ -1062,7 +1068,7 @@ int API_EXPORTED libusb_get_container_id_descriptor(struct libusb_context *ctx,
if (!_container_id)
return LIBUSB_ERROR_NO_MEM;
- parse_descriptor((unsigned char *)dev_cap, "bbbbu", _container_id);
+ parse_descriptor(dev_cap, "bbbbu", _container_id);
*container_id = _container_id;
return LIBUSB_SUCCESS;
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index f2e5eaa..49b7a05 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11506
+#define LIBUSB_NANO 11507