|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: * Copyright (c) 1997 Apple Computer, Inc.
26: *
27: *
28: * HISTORY
29: *
30: * Simon Douglas 22 Oct 97
31: * - first checked in.
32: */
33:
34:
35:
36: #include <stdlib.h>
37: #include <string.h>
38:
39: #include <driverkit/ppc/IOPropertyTable.h>
40:
41:
42: typedef struct PTEntry PTEntry;
43: struct PTEntry
44: {
45: PTEntry * next;
46: void * data;
47: ByteCount dataLength;
48: OptionBits flags;
49: char name[ 1 ];
50: };
51:
52:
53: struct PTable
54: {
55: PTEntry dummy;
56: };
57: typedef struct PTable PTable;
58:
59: @implementation IOPropertyTable
60:
61: void * PTAlloc( UInt32 size, Boolean clear )
62: {
63: void * mem;
64:
65: mem = (void *) IOMalloc( size);
66: if( mem && clear)
67: bzero( mem, size);
68: return( mem);
69: }
70:
71: void PTFree( void * data, UInt32 size )
72: {
73: IOFree( data, size);
74: }
75:
76:
77: - init
78: {
79: _ptprivate = PTAlloc( sizeof( PTable), true);
80:
81: return( self);
82: }
83:
84: -(IOReturn) deleteEntry:(PTEntry *)entry prev:(PTEntry *)prev
85: {
86: prev->next = entry->next;
87:
88: if( 0 == (entry->flags & kReferenceProperty))
89: PTFree( entry->data, entry->dataLength);
90:
91: PTFree( entry, strlen( entry->name) + sizeof( PTEntry));
92:
93: return( noErr);
94: }
95:
96: - free
97: {
98: PTable * table = _ptprivate;
99: PTEntry * previous = &table->dummy;
100: PTEntry * entry;
101:
102: while( (entry = previous->next))
103: [self deleteEntry:entry prev:previous];
104:
105: PTFree( table, sizeof( PTable));
106: return( [super free]);
107: }
108:
109:
110: - (PTEntry *) findProperty:(const char *)name prev:(PTEntry **)prev
111: {
112: PTable * table = _ptprivate;
113: PTEntry * previous = &table->dummy;
114: PTEntry * entry;
115:
116: while( (entry = previous->next)) {
117: if( 0 == strcmp( name, entry->name)) {
118: if( prev)
119: *prev = previous;
120: return( entry);
121: }
122: previous = entry;
123: }
124:
125: return( NULL);
126: }
127:
128:
129: -(IOReturn) getPropertyWithIndex:(UInt32)index name:(char *)name
130: {
131:
132: PTable * table = _ptprivate;
133: PTEntry * previous = &table->dummy;
134: PTEntry * entry;
135:
136: while( (entry = previous->next)) {
137: if( (index--) == 0) {
138: strcpy( name, entry->name );
139: return( noErr);
140: }
141: previous = entry;
142: }
143:
144: return( nrNotFoundErr);
145: }
146:
147:
148: -(IOReturn) setEntryProperty:(PTEntry *)entry
149: flags:(OptionBits)flags value:(void *)value length:(ByteCount)length
150: {
151: void * copy;
152:
153: if( flags & kReferenceProperty) {
154: copy = value;
155: } else {
156: copy = PTAlloc( length, false);
157: if( nil == copy)
158: return( nrNotEnoughMemoryErr);
159: bcopy( value, copy, length );
160: }
161:
162: if( (0 == (entry->flags & kReferenceProperty))
163: && entry->data )
164: PTFree( entry->data, entry->dataLength);
165:
166: entry->flags = flags;
167: entry->data = copy;
168: entry->dataLength = length;
169:
170: return( noErr);
171: }
172:
173:
174: -(IOReturn) createProperty:(const char *)name flags:(OptionBits)flags
175: value:(void *)value length:(ByteCount)length
176: {
177: IOReturn err;
178: PTable * table = _ptprivate;
179: PTEntry * entry;
180:
181: if( [self findProperty:name prev:NULL] )
182: return( nrPropertyAlreadyExists);
183:
184: entry = PTAlloc( strlen(name) + sizeof( PTEntry), true);
185: if( NULL == entry)
186: return( nrNotEnoughMemoryErr);
187:
188: err = [self setEntryProperty:entry flags:flags value:value length:length];
189: if( err) {
190: PTFree( entry, strlen(name) + sizeof( PTEntry));
191: return( err);
192: }
193:
194: entry->next = table->dummy.next;
195: table->dummy.next = entry;
196: strcpy( entry->name, name );
197:
198: return( noErr);
199:
200: }
201:
202: -(IOReturn) setProperty:(const char *)name flags:(OptionBits)flags
203: value:(void *)value length:(ByteCount)length
204: {
205: PTEntry * entry;
206:
207: entry = [self findProperty:name prev:NULL];
208: if( entry == NULL)
209: return( nrNotFoundErr);
210:
211: return( [self setEntryProperty:entry flags:flags value:value length:length] );
212: }
213:
214: -(IOReturn) deleteProperty:(const char *)name
215: {
216: PTEntry * entry;
217: PTEntry * prev;
218:
219: entry = [self findProperty:name prev:&prev];
220: if( entry == NULL)
221: return( nrNotFoundErr);
222:
223: return( [self deleteEntry:entry prev:prev] );
224: }
225:
226: -(IOReturn) getProperty:(const char *)name flags:(OptionBits)flags
227: value:(void **)value length:(ByteCount *)length
228: {
229: PTEntry * entry;
230:
231: entry = [self findProperty:name prev:NULL];
232: if( entry == NULL)
233: return( nrNotFoundErr);
234:
235: if( flags & kReferenceProperty) {
236: if( value) // can be NULL to just get the size
237: *value = entry->data;
238: } else {
239: bcopy( entry->data, *value, ((*length) < entry->dataLength)
240: ? (*length) : entry->dataLength );
241: }
242:
243: *length = entry->dataLength;
244:
245: return( noErr);
246: }
247:
248: //////// IOConfigTable methods ////////
249:
250: - (const char *)valueForStringKey:(const char *)key
251: {
252: IOReturn err;
253: ByteCount length;
254: char * data;
255: char * result;
256: char nameBuf[ 88 ] = "AAPL,dk_";
257:
258: length = strlen( key);
259: if( length > 80)
260: length = 80;
261: strncpy( nameBuf + 8, key, length);
262: nameBuf[ 8 + length ] = 0;
263:
264: err = [self getProperty:nameBuf flags:kReferenceProperty
265: value:(void **)&data length:&length];
266: if( err)
267: return( NULL);
268:
269: result = (char *) IOMalloc( length + 1);
270: if( result) {
271: strncpy( result, data, length);
272: result[ length ] = 0;
273: }
274:
275: return( result);
276: }
277:
278: static const char * getNextStr( const char *where, UInt32 * len )
279: {
280: const char * start;
281: const char * end;
282:
283: start = strchr( where, '\"');
284: if( start != NULL) {
285: start++;
286: end = strchr( start, '\"');
287: if( end)
288: *len = end - start;
289: else
290: start = NULL;
291: }
292: return( start);
293: }
294:
295:
296: - addConfigData:(const char *)configData
297: {
298:
299: char nameBuf[ 88 ] = "AAPL,dk_";
300: const char * str;
301: const char * eol;
302: const char * value;
303: UInt32 len;
304:
305: str = configData;
306: while( (str = getNextStr( str, &len))) {
307:
308: if( len > 80)
309: len = 80;
310: strncpy( nameBuf + 8, str, len);
311: nameBuf[ 8 + len ] = 0;
312:
313: str += len + 1;
314: eol = strchr( str, ';');
315: value = getNextStr( str, &len);
316: if( value == NULL)
317: break;
318: [self deleteProperty:(const char *)nameBuf];
319: if( eol > value) {
320: [self createProperty:(const char *)nameBuf flags:0 value:value length:len];
321: str = value + len + 1;
322: } else // key with no value
323: [self createProperty:(const char *)nameBuf flags:0 value:value length:0];
324: }
325:
326: return( self);
327: }
328:
329: + (void)freeString : (const char *)string
330: {
331: IOFree((char *)string, strlen(string) + 1);
332: }
333:
334: - (void)freeString : (const char *)string
335: {
336: [IOPropertyTable freeString:string];
337: }
338:
339: @end
340:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.