]>
Commit | Line | Data |
---|---|---|
3e170ce0 A |
1 | /* |
2 | * Copyright (c) 2015 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
24 | * limitations under the License. | |
25 | * | |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
27 | */ | |
28 | ||
29 | #import "KCDBasicTypeDescription.h" | |
30 | ||
39037602 A |
31 | const char * name_for_subtype(uint8_t elem_type); |
32 | ||
33 | const char * name_for_subtype(uint8_t elem_type) | |
34 | { | |
35 | char * retval = "unknown"; | |
36 | ||
37 | switch (elem_type) { | |
38 | case KC_ST_CHAR: retval = "char"; break; | |
39 | case KC_ST_INT8: retval = "int8_t"; break; | |
40 | case KC_ST_UINT8: retval = "uint8_t"; break; | |
41 | case KC_ST_INT16: retval = "int16_t"; break; | |
42 | case KC_ST_UINT16: retval = "uint16_t"; break; | |
43 | case KC_ST_INT32: retval = "int32_t"; break; | |
44 | case KC_ST_UINT32: retval = "uint32_t"; break; | |
45 | case KC_ST_INT64: retval = "int64_t"; break; | |
46 | case KC_ST_UINT64: retval = "uint64_t"; break; | |
47 | ||
48 | default: retval = "Unknown"; break; | |
49 | } | |
50 | ||
51 | return retval; | |
52 | } | |
53 | ||
54 | ||
3e170ce0 A |
55 | @interface |
56 | KCDBasicTypeDescription () { | |
39037602 | 57 | unsigned int _typeID; |
3e170ce0 A |
58 | uint32_t _size; |
59 | uint32_t _count; | |
60 | NSString * _name; | |
61 | struct kcdata_subtype_descriptor _subtype_desc; | |
62 | } | |
63 | ||
64 | @end | |
65 | ||
66 | @implementation KCDBasicTypeDescription | |
67 | ||
68 | - (id)initWithKCTypeDesc:(kcdata_subtype_descriptor_t)sub_type_desc | |
69 | { | |
70 | _typeID = sub_type_desc->kcs_elem_type; | |
71 | _count = kcs_get_elem_count(sub_type_desc); | |
72 | _size = kcs_get_elem_size(sub_type_desc); | |
73 | ||
74 | memcpy(&_subtype_desc, sub_type_desc, sizeof(_subtype_desc)); | |
75 | _name = [NSString stringWithFormat:@"%s", _subtype_desc.kcs_name]; | |
76 | ||
77 | return self; | |
78 | } | |
79 | ||
80 | - (id)createDefaultForType:(uint32_t)typeID | |
81 | { | |
82 | struct kcdata_subtype_descriptor subtype; | |
83 | subtype.kcs_flags = KCS_SUBTYPE_FLAGS_ARRAY; | |
84 | subtype.kcs_elem_type = KC_ST_UINT8; | |
85 | subtype.kcs_elem_offset = 0; | |
86 | subtype.kcs_elem_size = KCS_SUBTYPE_PACK_SIZE(UINT16_MAX, (uint16_t)sizeof(uint8_t)); | |
87 | subtype.kcs_name[0] = '\0'; | |
88 | (void)[self initWithKCTypeDesc:&subtype]; | |
89 | _name = [NSString stringWithFormat:@"Type_0x%x", typeID]; | |
90 | return self; | |
91 | } | |
92 | ||
93 | - (NSObject *)objectForType:(kctype_subtype_t)elem_type withData:(uint8_t *)data | |
94 | { | |
95 | NSObject * obj; | |
96 | ||
97 | switch (elem_type) { | |
98 | case KC_ST_CHAR: obj = [NSString stringWithFormat:@"%c", *(char *)data]; break; | |
99 | case KC_ST_INT8: obj = [NSNumber numberWithInt:*(int8_t *)data]; break; | |
100 | case KC_ST_UINT8: obj = [NSNumber numberWithInt:*(uint8_t *)data]; break; | |
101 | case KC_ST_INT16: obj = [NSNumber numberWithShort:*(int16_t *)data]; break; | |
102 | case KC_ST_UINT16: obj = [NSNumber numberWithUnsignedShort:*(uint16_t *)data]; break; | |
103 | case KC_ST_INT32: obj = [NSNumber numberWithInt:*(int32_t *)data]; break; | |
104 | case KC_ST_UINT32: obj = [NSNumber numberWithUnsignedInt:*(uint32_t *)data]; break; | |
105 | case KC_ST_INT64: obj = [NSNumber numberWithLongLong:*(int64_t *)data]; break; | |
106 | case KC_ST_UINT64: obj = [NSNumber numberWithUnsignedLongLong:*(uint64_t *)data]; break; | |
107 | ||
108 | default: obj = @"<Unknown error occurred>"; break; | |
109 | } | |
110 | ||
111 | return obj; | |
112 | } | |
113 | ||
39037602 | 114 | - (NSDictionary *)parseData:(void *)dataBuffer ofLength:(uint32_t)length |
3e170ce0 A |
115 | { |
116 | NSMutableDictionary * retval = [[NSMutableDictionary alloc] init]; | |
39037602 A |
117 | if (length <= _subtype_desc.kcs_elem_offset) |
118 | return retval; | |
3e170ce0 | 119 | uint8_t * data = (uint8_t *)dataBuffer; |
39037602 A |
120 | /* |
121 | * Calculate the maximum number of data elements we can parse, Taking into | |
122 | * account the maximum size specified by the type description, and also the | |
123 | * actual length of the data buffer and the offset into the buffer where we | |
124 | * begin parsing. | |
125 | */ | |
126 | uint32_t elem_count = MIN(_count, (length - _subtype_desc.kcs_elem_offset) / (_size / _count)); | |
3e170ce0 | 127 | uint32_t elem_size = _size / _count; |
39037602 A |
128 | if (elem_count == 0) { |
129 | return retval; | |
130 | } else if (elem_count == 1) { | |
3e170ce0 A |
131 | retval[_name] = [self objectForType:_subtype_desc.kcs_elem_type withData:&data[_subtype_desc.kcs_elem_offset]]; |
132 | } else if (_subtype_desc.kcs_elem_type == KC_ST_CHAR) { | |
39037602 A |
133 | char *s = (char *)&data[_subtype_desc.kcs_elem_offset]; |
134 | if (!(strnlen(s, length) < length)) { | |
135 | return nil; | |
136 | } | |
137 | retval[_name] = [NSString stringWithFormat:@"%s", s]; | |
3e170ce0 A |
138 | } else { |
139 | NSMutableArray * objArray = [NSMutableArray arrayWithCapacity:elem_count]; | |
140 | for (unsigned int i = 0; i < elem_count; i++) { | |
141 | [objArray addObject:[self objectForType:_subtype_desc.kcs_elem_type | |
142 | withData:&data[(_subtype_desc.kcs_elem_offset + (elem_size * i))]]]; | |
143 | } | |
144 | retval[_name] = objArray; | |
145 | } | |
146 | return retval; | |
147 | } | |
148 | ||
149 | - (NSString *)description | |
150 | { | |
39037602 A |
151 | if (_subtype_desc.kcs_flags & KCS_SUBTYPE_FLAGS_ARRAY) { |
152 | return [NSString stringWithFormat:@"[%d,%d] %s %s[%d];", _subtype_desc.kcs_elem_offset, kcs_get_elem_size(&_subtype_desc), name_for_subtype(_subtype_desc.kcs_elem_type), _subtype_desc.kcs_name, kcs_get_elem_count(&_subtype_desc) ]; | |
153 | }else { | |
154 | return [NSString stringWithFormat:@"[%d,%d] %s %s;", _subtype_desc.kcs_elem_offset, kcs_get_elem_size(&_subtype_desc), name_for_subtype(_subtype_desc.kcs_elem_type), _subtype_desc.kcs_name ]; | |
155 | } | |
156 | //return [NSString stringWithFormat:@"type: %d => \"%@\" ", [self typeID], [self name]]; | |
3e170ce0 A |
157 | } |
158 | ||
159 | - (NSString *)name | |
160 | { | |
161 | return _name; | |
162 | } | |
163 | ||
164 | - (uint32_t)count | |
165 | { | |
166 | return _count; | |
167 | } | |
168 | ||
39037602 | 169 | - (unsigned int)typeID |
3e170ce0 A |
170 | { |
171 | return _typeID; | |
172 | } | |
173 | ||
39037602 A |
174 | - (BOOL) shouldMergeData |
175 | { | |
176 | return TRUE; | |
177 | } | |
178 | ||
3e170ce0 | 179 | @end |