Updated HID code with Vector class instead of hand made growing arrays

Change-Id: Iec8cd3922d9c21a046d225181d326253ae88d395
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4324
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: John Scipione <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Lt-Henry
2021-08-23 18:31:50 +00:00
committed by Adrien Destugues
parent 4b12b16e8d
commit 8df8655366
6 changed files with 70 additions and 130 deletions
@@ -23,12 +23,7 @@ HIDCollection::HIDCollection(HIDCollection *parent, uint8 type,
: fParent(parent),
fType(type),
fStringID(localState.string_index),
fPhysicalID(localState.designator_index),
fChildCount(0),
fChildren(NULL),
fItemCount(0),
fItemsAllocated(0),
fItems(NULL)
fPhysicalID(localState.designator_index)
{
usage_value usageValue;
if (localState.usage_stack != NULL && localState.usage_stack_used > 0)
@@ -51,10 +46,8 @@ HIDCollection::HIDCollection(HIDCollection *parent, uint8 type,
HIDCollection::~HIDCollection()
{
for (uint32 i = 0; i < fChildCount; i++)
for (int32 i = 0; i < fChildren.Count(); i++)
delete fChildren[i];
free(fChildren);
free(fItems);
}
@@ -79,15 +72,10 @@ HIDCollection::UsageID()
status_t
HIDCollection::AddChild(HIDCollection *child)
{
HIDCollection **newChildren = (HIDCollection **)realloc(fChildren,
(fChildCount + 1) * sizeof(HIDCollection *));
if (newChildren == NULL) {
if (fChildren.PushBack(child) == B_NO_MEMORY) {
TRACE_ALWAYS("no memory when trying to resize collection child list\n");
return B_NO_MEMORY;
}
fChildren = newChildren;
fChildren[fChildCount++] = child;
return B_OK;
}
@@ -95,7 +83,7 @@ HIDCollection::AddChild(HIDCollection *child)
HIDCollection *
HIDCollection::ChildAt(uint32 index)
{
if (index >= fChildCount)
if (index >= fChildren.Count())
return NULL;
return fChildren[index];
@@ -109,7 +97,7 @@ HIDCollection::CountChildrenFlat(uint8 type)
if (type == COLLECTION_ALL || fType == type)
count++;
for (uint32 i = 0; i < fChildCount; i++) {
for (int32 i = 0; i < fChildren.Count(); i++) {
HIDCollection *child = fChildren[i];
if (child == NULL)
continue;
@@ -131,27 +119,17 @@ HIDCollection::ChildAtFlat(uint8 type, uint32 index)
void
HIDCollection::AddItem(HIDReportItem *item)
{
if (fItemCount >= fItemsAllocated) {
fItemsAllocated += 10;
HIDReportItem **newItems = (HIDReportItem **)realloc(fItems,
fItemsAllocated * sizeof(HIDReportItem *));
if (newItems == NULL) {
TRACE_ALWAYS("no memory when trying to resize collection items\n");
fItemsAllocated -= 10;
return;
}
fItems = newItems;
if (fItems.PushBack(item) == B_NO_MEMORY) {
TRACE_ALWAYS("no memory when trying to resize collection items\n");
}
fItems[fItemCount++] = item;
}
HIDReportItem *
HIDCollection::ItemAt(uint32 index)
{
if (index >= fItemCount)
if (index >= fItems.Count())
return NULL;
return fItems[index];
@@ -161,9 +139,9 @@ HIDCollection::ItemAt(uint32 index)
uint32
HIDCollection::CountItemsFlat()
{
uint32 count = fItemCount;
uint32 count = fItems.Count();
for (uint32 i = 0; i < fChildCount; i++) {
for (int32 i = 0; i < fChildren.Count(); i++) {
HIDCollection *child = fChildren[i];
if (child != NULL)
count += child->CountItemsFlat();
@@ -218,15 +196,15 @@ HIDCollection::PrintToStream(uint32 indentLevel)
TRACE_ALWAYS("%s\tstring id: %u\n", indent, fStringID);
TRACE_ALWAYS("%s\tphysical id: %u\n", indent, fPhysicalID);
TRACE_ALWAYS("%s\titem count: %" B_PRIu32 "\n", indent, fItemCount);
for (uint32 i = 0; i < fItemCount; i++) {
TRACE_ALWAYS("%s\titem count: %" B_PRIu32 "\n", indent, fItems.Count());
for (int32 i = 0; i < fItems.Count(); i++) {
HIDReportItem *item = fItems[i];
if (item != NULL)
item->PrintToStream(indentLevel + 1);
}
TRACE_ALWAYS("%s\tchild count: %" B_PRIu32 "\n", indent, fChildCount);
for (uint32 i = 0; i < fChildCount; i++) {
TRACE_ALWAYS("%s\tchild count: %" B_PRIu32 "\n", indent, fChildren.Count());
for (int32 i = 0; i < fChildren.Count(); i++) {
HIDCollection *child = fChildren[i];
if (child != NULL)
child->PrintToStream(indentLevel + 1);
@@ -244,7 +222,7 @@ HIDCollection::_ChildAtFlat(uint8 type, uint32 &index)
index--;
}
for (uint32 i = 0; i < fChildCount; i++) {
for (int32 i = 0; i < fChildren.Count(); i++) {
HIDCollection *child = fChildren[i];
if (child == NULL)
continue;
@@ -261,12 +239,12 @@ HIDCollection::_ChildAtFlat(uint8 type, uint32 &index)
HIDReportItem *
HIDCollection::_ItemAtFlat(uint32 &index)
{
if (index < fItemCount)
if (index < fItems.Count())
return fItems[index];
index -= fItemCount;
index -= fItems.Count();
for (uint32 i = 0; i < fChildCount; i++) {
for (int32 i = 0; i < fChildren.Count(); i++) {
HIDCollection *child = fChildren[i];
if (child == NULL)
continue;
@@ -285,7 +263,7 @@ HIDCollection::BuildReportList(uint8 reportType,
HIDReport **reportList, uint32 &reportCount)
{
for (uint32 i = 0; i < fItemCount; i++) {
for (int32 i = 0; i < fItems.Count(); i++) {
HIDReportItem *item = fItems[i];
if (item == NULL)
continue;
@@ -308,7 +286,7 @@ HIDCollection::BuildReportList(uint8 reportType,
reportList[reportCount++] = report;
}
for (uint32 i = 0; i < fChildCount; i++) {
for (int32 i = 0; i < fChildren.Count(); i++) {
HIDCollection *child = fChildren[i];
if (child == NULL)
continue;
@@ -6,6 +6,8 @@
#define HID_COLLECTION_H
#include "HIDParser.h"
#include "util/Vector.h"
class HIDReport;
class HIDReportItem;
@@ -24,14 +26,14 @@ public:
HIDCollection * Parent() { return fParent; };
status_t AddChild(HIDCollection *child);
uint32 CountChildren() { return fChildCount; };
uint32 CountChildren() { return fChildren.Count(); };
HIDCollection * ChildAt(uint32 index);
uint32 CountChildrenFlat(uint8 type);
HIDCollection * ChildAtFlat(uint8 type, uint32 index);
void AddItem(HIDReportItem *item);
uint32 CountItems() { return fItemCount; };
uint32 CountItems() { return fItems.Count(); };
HIDReportItem * ItemAt(uint32 index);
uint32 CountItemsFlat();
@@ -53,13 +55,9 @@ private:
uint32 fUsage;
uint8 fStringID;
uint8 fPhysicalID;
Vector<HIDCollection *> fChildren;
Vector<HIDReportItem *> fItems;
uint32 fChildCount;
HIDCollection ** fChildren;
uint32 fItemCount;
uint32 fItemsAllocated;
HIDReportItem ** fItems;
};
#endif // HID_COLLECTION_H
@@ -28,8 +28,6 @@ static int8 sUnitExponent[16] = {
HIDParser::HIDParser(HIDDevice *device)
: fDevice(device),
fUsesReportIDs(false),
fReportCount(0),
fReports(NULL),
fRootCollection(NULL)
{
}
@@ -53,20 +51,12 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
local_item_state localState;
memset(&localState, 0, sizeof(local_item_state));
uint32 usageStackUsed = 0;
uint32 usageStackSize = 10;
usage_value *usageStack = (usage_value *)malloc(usageStackSize
* sizeof(usage_value));
if (usageStack == NULL) {
TRACE_ALWAYS("no memory to allocate usage stack\n");
return B_NO_MEMORY;
}
Vector<usage_value> usageStack;
fRootCollection = new(std::nothrow) HIDCollection(NULL, COLLECTION_LOGICAL,
localState);
if (fRootCollection == NULL) {
TRACE_ALWAYS("no memory to allocate root collection\n");
free(usageStack);
return B_NO_MEMORY;
}
@@ -115,7 +105,7 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
// collections and report items)
if (item->tag != ITEM_TAG_MAIN_END_COLLECTION) {
// make all usages extended for easier later processing
for (uint32 i = 0; i < usageStackUsed; i++) {
for (int32 i = 0; i < usageStack.Count(); i++) {
if (usageStack[i].is_extended)
continue;
usageStack[i].u.s.usage_page = globalState.usage_page;
@@ -133,8 +123,8 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
= localState.usage_maximum.is_extended = true;
}
localState.usage_stack = usageStack;
localState.usage_stack_used = usageStackUsed;
localState.usage_stack = &usageStack[0];
localState.usage_stack_used = usageStack.Count();
}
if (item->tag == ITEM_TAG_MAIN_COLLECTION) {
@@ -200,7 +190,7 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
// reset the local item state
memset(&localState, 0, sizeof(local_item_state));
usageStackUsed = 0;
usageStack.MakeEmpty();
break;
}
@@ -289,24 +279,15 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
switch (item->tag) {
case ITEM_TAG_LOCAL_USAGE:
{
if (usageStackUsed >= usageStackSize) {
usageStackSize += 10;
usage_value *newUsageStack
= (usage_value *)realloc(usageStack,
usageStackSize * sizeof(usage_value));
if (newUsageStack == NULL) {
TRACE_ALWAYS("no memory when growing usages\n");
usageStackSize -= 10;
break;
}
usageStack = newUsageStack;
usage_value value;
value.is_extended = itemSize == sizeof(uint32);
value.u.extended = data;
if (usageStack.PushBack(value)==B_NO_MEMORY) {
TRACE_ALWAYS("no memory when growing usages\n");
break;
}
usage_value *value = &usageStack[usageStackUsed];
value->is_extended = itemSize == sizeof(uint32);
value->u.extended = data;
usageStackUsed++;
break;
}
@@ -385,7 +366,6 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
state = next;
}
free(usageStack);
return B_OK;
}
@@ -393,7 +373,7 @@ HIDParser::ParseReportDescriptor(const uint8 *reportDescriptor,
HIDReport *
HIDParser::FindReport(uint8 type, uint8 id)
{
for (uint8 i = 0; i < fReportCount; i++) {
for (int32 i = 0; i < fReports.Count(); i++) {
HIDReport *report = fReports[i];
if (report == NULL)
continue;
@@ -410,7 +390,7 @@ uint8
HIDParser::CountReports(uint8 type)
{
uint8 count = 0;
for (uint8 i = 0; i < fReportCount; i++) {
for (int32 i = 0; i < fReports.Count(); i++) {
HIDReport *report = fReports[i];
if (report == NULL)
continue;
@@ -426,7 +406,7 @@ HIDParser::CountReports(uint8 type)
HIDReport *
HIDParser::ReportAt(uint8 type, uint8 index)
{
for (uint8 i = 0; i < fReportCount; i++) {
for (int32 i = 0; i < fReports.Count(); i++) {
HIDReport *report = fReports[i];
if (report == NULL || (report->Type() & type) == 0)
continue;
@@ -443,7 +423,7 @@ size_t
HIDParser::MaxReportSize()
{
size_t maxSize = 0;
for (uint32 i = 0; i < fReportCount; i++) {
for (int32 i = 0; i < fReports.Count(); i++) {
HIDReport *report = fReports[i];
if (report == NULL)
continue;
@@ -480,7 +460,7 @@ HIDParser::SetReport(status_t status, uint8 *report, size_t length)
// We need to notify all input reports, as we don't know who has waiting
// listeners. Anyone other than the target report also waiting for a
// transfer to happen needs to reschedule one now.
for (uint32 i = 0; i < fReportCount; i++) {
for (int32 i = 0; i < fReports.Count(); i++) {
if (fReports[i] == NULL
|| fReports[i]->Type() != HID_REPORT_TYPE_INPUT)
continue;
@@ -496,7 +476,7 @@ HIDParser::SetReport(status_t status, uint8 *report, size_t length)
void
HIDParser::PrintToStream()
{
for (uint8 i = 0; i < fReportCount; i++) {
for (int32 i = 0; i < fReports.Count(); i++) {
HIDReport *report = fReports[i];
if (report == NULL)
continue;
@@ -521,16 +501,12 @@ HIDParser::_FindOrCreateReport(uint8 type, uint8 id)
return NULL;
}
HIDReport **newReports = (HIDReport **)realloc(fReports,
(fReportCount + 1) * sizeof(HIDReport *));
if (newReports == NULL) {
if (fReports.PushBack(report) == B_NO_MEMORY) {
TRACE_ALWAYS("no memory when growing report list\n");
delete report;
return NULL;
}
fReports = newReports;
fReports[fReportCount++] = report;
return report;
}
@@ -567,14 +543,14 @@ HIDParser::_CalculateResolution(global_item_state *state)
void
HIDParser::_Reset()
{
for (uint8 i = 0; i < fReportCount; i++)
for (int32 i = 0; i < fReports.Count(); i++)
delete fReports[i];
fReports.MakeEmpty();
delete fRootCollection;
free(fReports);
fUsesReportIDs = false;
fReportCount = 0;
fReports = NULL;
fRootCollection = NULL;
}
@@ -6,6 +6,8 @@
#define HID_PARSER_H
#include "HIDDataTypes.h"
#include "util/Vector.h"
class HIDCollection;
class HIDDevice;
@@ -43,8 +45,7 @@ private:
HIDDevice * fDevice;
bool fUsesReportIDs;
uint8 fReportCount;
HIDReport ** fReports;
Vector<HIDReport *> fReports;
HIDCollection * fRootCollection;
};
@@ -24,9 +24,6 @@ HIDReport::HIDReport(HIDParser *parser, uint8 type, uint8 id)
fType(type),
fReportID(id),
fReportSize(0),
fItemsUsed(0),
fItemsAllocated(0),
fItems(NULL),
fReportStatus(B_NO_INIT),
fCurrentReport(NULL),
fBusyCount(0)
@@ -39,7 +36,7 @@ HIDReport::HIDReport(HIDParser *parser, uint8 type, uint8 id)
HIDReport::~HIDReport()
{
free(fItems);
}
@@ -112,19 +109,6 @@ HIDReport::AddMainItem(global_item_state &globalState,
uint32 usageRangeIndex = 0;
for (uint32 i = 0; i < globalState.report_count; i++) {
if (fItemsUsed >= fItemsAllocated) {
fItemsAllocated += 10;
HIDReportItem **newItems = (HIDReportItem **)realloc(fItems,
sizeof(HIDReportItem *) * fItemsAllocated);
if (newItems == NULL) {
TRACE_ALWAYS("no memory when growing report item list\n");
fItemsAllocated -= 10;
return;
}
fItems = newItems;
}
if (mainData.array_variable == 1) {
usage_value usage;
if (i < localState.usage_stack_used)
@@ -139,20 +123,23 @@ HIDReport::AddMainItem(global_item_state &globalState,
usageMinimum = usageMaximum = usage.u.extended;
}
fItems[fItemsUsed] = new(std::nothrow) HIDReportItem(this,
HIDReportItem *item = new(std::nothrow) HIDReportItem(this,
fReportSize, globalState.report_size, mainData.data_constant == 0,
mainData.array_variable == 0, mainData.relative != 0,
logicalMinimum, logicalMaximum, usageMinimum, usageMaximum);
if (fItems[fItemsUsed] == NULL)
if (item == NULL)
TRACE_ALWAYS("no memory when creating report item\n");
if (collection != NULL)
collection->AddItem(fItems[fItemsUsed]);
collection->AddItem(item);
else
TRACE_ALWAYS("main item not part of a collection\n");
if (fItems.PushBack(item) == B_NO_MEMORY) {
TRACE_ALWAYS("no memory when growing report item list\n");
}
fReportSize += globalState.report_size;
fItemsUsed++;
}
}
@@ -186,7 +173,7 @@ HIDReport::SendReport()
fCurrentReport = report;
memset(fCurrentReport, 0, reportSize);
for (uint32 i = 0; i < fItemsUsed; i++) {
for (int32 i = 0; i < fItems.Count(); i++) {
HIDReportItem *item = fItems[i];
if (item == NULL)
continue;
@@ -206,7 +193,7 @@ HIDReport::SendReport()
HIDReportItem *
HIDReport::ItemAt(uint32 index)
{
if (index >= fItemsUsed)
if (index >= fItems.Count())
return NULL;
return fItems[index];
}
@@ -215,7 +202,7 @@ HIDReport::ItemAt(uint32 index)
HIDReportItem *
HIDReport::FindItem(uint16 usagePage, uint16 usageID)
{
for (uint32 i = 0; i < fItemsUsed; i++) {
for (int32 i = 0; i < fItems.Count(); i++) {
if (fItems[i]->UsagePage() == usagePage
&& fItems[i]->UsageID() == usageID)
return fItems[i];
@@ -285,8 +272,8 @@ HIDReport::PrintToStream()
TRACE_ALWAYS("\treport size: %" B_PRIu32 " bits = %" B_PRIu32 " bytes\n",
fReportSize, (fReportSize + 7) / 8);
TRACE_ALWAYS("\titem count: %" B_PRIu32 "\n", fItemsUsed);
for (uint32 i = 0; i < fItemsUsed; i++) {
TRACE_ALWAYS("\titem count: %" B_PRIu32 "\n", fItems.Count());
for (int32 i = 0; i < fItems.Count(); i++) {
HIDReportItem *item = fItems[i];
if (item != NULL)
item->PrintToStream(1);
@@ -6,6 +6,8 @@
#define HID_REPORT_H
#include "HIDParser.h"
#include "util/Vector.h"
#ifndef USERLAND_HID
#include <condition_variable.h>
@@ -45,7 +47,7 @@ public:
status_t SendReport();
#endif
uint32 CountItems() { return fItemsUsed; };
uint32 CountItems() { return fItems.Count(); };
HIDReportItem * ItemAt(uint32 index);
HIDReportItem * FindItem(uint16 usagePage, uint16 usageID);
@@ -65,9 +67,7 @@ private:
uint8 fReportID;
uint32 fReportSize;
uint32 fItemsUsed;
uint32 fItemsAllocated;
HIDReportItem ** fItems;
Vector<HIDReportItem *> fItems;
status_t fReportStatus;
uint8 * fCurrentReport;