2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 File: HIDCountDescriptorItems.c
25 Contains: xxx put contents here xxx
27 Version: xxx put version here xxx
29 Copyright: © 1999 by Apple Computer, Inc., all rights reserved.
33 DRI: xxx put dri here xxx
35 Other Contact: xxx put other contact here xxx
37 Technology: xxx put technology here xxx
43 Change History (most recent first):
45 <USB1> 3/5/99 BWS first checked in
53 *------------------------------------------------------------------------------
55 * HIDCountDescriptorItems
58 * ptDescriptor - Descriptor Pointer Structure
59 * ptPreparsedData - The PreParsedData Structure
61 * ptPreparsedData - The PreParsedData Structure
63 * kHIDSuccess - Success
64 * kHIDNullPointerErr - Argument, Pointer was Null
66 *------------------------------------------------------------------------------
68 OSStatus
HIDCountDescriptorItems(HIDReportDescriptor
*ptDescriptor
, HIDPreparsedDataPtr ptPreparsedData
)
71 ByteCount iSpaceRequired
;
77 int collectionCount
= 1;
78 int reportItemCount
= 0;
82 int iStringRanges
= 0;
86 int globalsNesting
= 0;
87 int iMaxGlobalsNesting
= 0;
88 int collectionNesting
= 0;
89 int iMaxCollectionNesting
= 0;
91 * Disallow NULL Pointers
93 if ((ptDescriptor
== NULL
) || (ptPreparsedData
== NULL
))
94 return kHIDNullPointerErr
;
96 * Initialize the memory allocation pointer
98 ptPreparsedData
->rawMemPtr
= NULL
;
100 * Initialize the Descriptor Pointer Structure
102 ptDescriptor
->index
= 0;
103 ptItem
= &ptDescriptor
->item
;
105 * Count various items in the descriptor
107 while ((iStatus
= HIDNextItem(ptDescriptor
)) == kHIDSuccess
)
109 switch (ptItem
->itemType
)
114 case kHIDTagCollection
:
117 if (collectionNesting
> iMaxCollectionNesting
)
118 iMaxCollectionNesting
= collectionNesting
;
120 case kHIDTagEndCollection
:
121 if (collectionNesting
-- == 0)
122 return kHIDInvalidPreparsedDataErr
;
134 case kHIDTagReportID
:
139 if (globalsNesting
> iMaxGlobalsNesting
)
140 iMaxGlobalsNesting
= globalsNesting
;
144 if (globalsNesting
< 0)
145 return kHIDInvalidPreparsedDataErr
;
155 case kHIDTagUsageMinimum
:
156 case kHIDTagUsageMaximum
:
159 case kHIDTagStringIndex
:
162 case kHIDTagStringMinimum
:
163 case kHIDTagStringMaximum
:
166 case kHIDTagDesignatorIndex
:
169 case kHIDTagDesignatorMinimum
:
170 case kHIDTagDesignatorMaximum
:
177 * Disallow malformed descriptors
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
;
187 * Summarize the Indices and Ranges
189 iUsages
+= (iUsageRanges
/2);
190 iStrings
+= (iStringRanges
/2);
191 iDesigs
+= (iDesigRanges
/2);
193 * Calculate the space needed for the structures
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
);
206 return kHIDNotEnoughMemoryErr
;
207 ptPreparsedData
->rawMemPtr
= pMem
;
208 ptPreparsedData
->numBytesAllocated
= iSpaceRequired
;
210 * Allocate space to the various structures
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
)