]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IOHIDSystem/IOHIDDescriptorParser/HIDCountDescriptorItems.c
xnu-123.5.tar.gz
[apple/xnu.git] / iokit / Families / IOHIDSystem / IOHIDDescriptorParser / HIDCountDescriptorItems.c
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 File: HIDCountDescriptorItems.c
24
25 Contains: xxx put contents here xxx
26
27 Version: xxx put version here xxx
28
29 Copyright: © 1999 by Apple Computer, Inc., all rights reserved.
30
31 File Ownership:
32
33 DRI: xxx put dri here xxx
34
35 Other Contact: xxx put other contact here xxx
36
37 Technology: xxx put technology here xxx
38
39 Writers:
40
41 (BWS) Brent Schorsch
42
43 Change History (most recent first):
44
45 <USB1> 3/5/99 BWS first checked in
46 */
47
48 #include "HIDLib.h"
49
50 //#include <stdlib.h>
51
52 /*
53 *------------------------------------------------------------------------------
54 *
55 * HIDCountDescriptorItems
56 *
57 * Input:
58 * ptDescriptor - Descriptor Pointer Structure
59 * ptPreparsedData - The PreParsedData Structure
60 * Output:
61 * ptPreparsedData - The PreParsedData Structure
62 * Returns:
63 * kHIDSuccess - Success
64 * kHIDNullPointerErr - Argument, Pointer was Null
65 *
66 *------------------------------------------------------------------------------
67 */
68 OSStatus HIDCountDescriptorItems(HIDReportDescriptor *ptDescriptor, HIDPreparsedDataPtr ptPreparsedData)
69 {
70 OSStatus iStatus;
71 ByteCount iSpaceRequired;
72 HIDItem *ptItem;
73 Byte *pMem;
74 /*
75 * Initialize Counters
76 */
77 int collectionCount = 1;
78 int reportItemCount = 0;
79 int iUsages = 0;
80 int iUsageRanges = 0;
81 int iStrings = 0;
82 int iStringRanges = 0;
83 int iDesigs = 0;
84 int iDesigRanges = 0;
85 int reportCount = 1;
86 int globalsNesting = 0;
87 int iMaxGlobalsNesting = 0;
88 int collectionNesting = 0;
89 int iMaxCollectionNesting = 0;
90 /*
91 * Disallow NULL Pointers
92 */
93 if ((ptDescriptor == NULL) || (ptPreparsedData == NULL))
94 return kHIDNullPointerErr;
95 /*
96 * Initialize the memory allocation pointer
97 */
98 ptPreparsedData->rawMemPtr = NULL;
99 /*
100 * Initialize the Descriptor Pointer Structure
101 */
102 ptDescriptor->index = 0;
103 ptItem = &ptDescriptor->item;
104 /*
105 * Count various items in the descriptor
106 */
107 while ((iStatus = HIDNextItem(ptDescriptor)) == kHIDSuccess)
108 {
109 switch (ptItem->itemType)
110 {
111 case kHIDTypeMain:
112 switch (ptItem->tag)
113 {
114 case kHIDTagCollection:
115 collectionCount++;
116 collectionNesting++;
117 if (collectionNesting > iMaxCollectionNesting)
118 iMaxCollectionNesting = collectionNesting;
119 break;
120 case kHIDTagEndCollection:
121 if (collectionNesting-- == 0)
122 return kHIDInvalidPreparsedDataErr;
123 break;
124 case kHIDTagInput:
125 case kHIDTagOutput:
126 case kHIDTagFeature:
127 reportItemCount++;
128 break;
129 }
130 break;
131 case kHIDTypeGlobal:
132 switch (ptItem->tag)
133 {
134 case kHIDTagReportID:
135 reportCount++;
136 break;
137 case kHIDTagPush:
138 globalsNesting++;
139 if (globalsNesting > iMaxGlobalsNesting)
140 iMaxGlobalsNesting = globalsNesting;
141 break;
142 case kHIDTagPop:
143 globalsNesting--;
144 if (globalsNesting < 0)
145 return kHIDInvalidPreparsedDataErr;
146 break;
147 }
148 break;
149 case kHIDTypeLocal:
150 switch (ptItem->tag)
151 {
152 case kHIDTagUsage:
153 iUsages++;
154 break;
155 case kHIDTagUsageMinimum:
156 case kHIDTagUsageMaximum:
157 iUsageRanges++;
158 break;
159 case kHIDTagStringIndex:
160 iStrings++;
161 break;
162 case kHIDTagStringMinimum:
163 case kHIDTagStringMaximum:
164 iStringRanges++;
165 break;
166 case kHIDTagDesignatorIndex:
167 iDesigs++;
168 break;
169 case kHIDTagDesignatorMinimum:
170 case kHIDTagDesignatorMaximum:
171 iDesigRanges++;
172 break;
173 }
174 }
175 }
176 /*
177 * Disallow malformed descriptors
178 */
179 if ((collectionNesting != 0)
180 || (collectionCount == 1)
181 || (reportItemCount == 0)
182 || ((iUsageRanges & 1) == 1)
183 || ((iStringRanges & 1) == 1)
184 || ((iDesigRanges & 1) == 1))
185 return kHIDInvalidPreparsedDataErr;
186 /*
187 * Summarize the Indices and Ranges
188 */
189 iUsages += (iUsageRanges/2);
190 iStrings += (iStringRanges/2);
191 iDesigs += (iDesigRanges/2);
192 /*
193 * Calculate the space needed for the structures
194 */
195 iSpaceRequired = (sizeof(HIDCollection) * collectionCount)
196 + (sizeof(HIDReportItem) * reportItemCount)
197 + (sizeof(HIDReportSizes) * reportCount)
198 + (sizeof(HIDP_UsageItem) * iUsages)
199 + (sizeof(HIDStringItem) * iStrings)
200 + (sizeof(HIDDesignatorItem) * iDesigs)
201 + (sizeof(int) * iMaxCollectionNesting)
202 + (sizeof(HIDGlobalItems) * iMaxGlobalsNesting);
203 pMem = PoolAllocateResident(iSpaceRequired, kShouldClearMem);
204
205 if (pMem == NULL)
206 return kHIDNotEnoughMemoryErr;
207 ptPreparsedData->rawMemPtr = pMem;
208 ptPreparsedData->numBytesAllocated = iSpaceRequired;
209 /*
210 * Allocate space to the various structures
211 */
212 ptPreparsedData->collections = (HIDCollection *) pMem;
213 ptPreparsedData->collectionCount = 0;
214 pMem += (sizeof(HIDCollection) * collectionCount);
215 ptPreparsedData->reportItems = (HIDReportItem *) pMem;
216 ptPreparsedData->reportItemCount = 0;
217 pMem += (sizeof(HIDReportItem) * reportItemCount);
218 ptPreparsedData->reports = (HIDReportSizes *) pMem;
219 ptPreparsedData->reportCount = 0;
220 pMem += (sizeof(HIDReportSizes) * reportCount);
221 ptPreparsedData->usageItems = (HIDP_UsageItem *) pMem;
222 ptPreparsedData->usageItemCount = 0;
223 pMem += (sizeof(HIDP_UsageItem) * iUsages);
224 ptPreparsedData->stringItems = (HIDStringItem *) pMem;
225 ptPreparsedData->stringItemCount = 0;
226 pMem += (sizeof(HIDStringItem) * iStrings);
227 ptPreparsedData->desigItems = (HIDDesignatorItem *) pMem;
228 ptPreparsedData->desigItemCount = 0;
229 pMem += (sizeof(HIDDesignatorItem) * iDesigs);
230 ptDescriptor->collectionStack = (SInt32 *) pMem;
231 ptDescriptor->collectionNesting = 0;
232 pMem += (sizeof(SInt32) * iMaxCollectionNesting);
233 ptDescriptor->globalsStack = (HIDGlobalItems *) pMem;
234 ptDescriptor->globalsNesting = 0;
235 if (iStatus == kHIDEndOfDescriptorErr)
236 return kHIDSuccess;
237 return iStatus;
238 }