|
|
1.1 root 1: /*
2: * Copyright (c) 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: /* IOData.m created by rsulack on Thu 25-Sep-1997 */
23:
24:
25: #include <libkern/c++/OSData.h>
26: #include <libkern/c++/OSSerialize.h>
27: #include <libkern/c++/OSLib.h>
28:
29: #define super OSObject
30:
31: OSDefineMetaClassAndStructors(OSData, OSObject)
32:
33: #define EXTERNAL ((unsigned int) -1)
34:
35: #ifdef DEBUG
36: extern "C" {
37: extern int debug_container_malloc_size;
38: };
39: #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
40: #else
41: #define ACCUMSIZE(s)
42: #endif
43:
44: bool OSData::initWithCapacity(unsigned int inCapacity)
45: {
46: if (!super::init())
47: return false;
48:
49: if(inCapacity) {
50: data = (void *) kalloc(inCapacity);
51: if (!data)
52: return false;
53: }
54:
55: length = 0;
56: capacity = inCapacity;
57: capacityIncrement = capacity;
58:
59: ACCUMSIZE(capacity);
60:
61: return true;
62: }
63:
64: bool OSData::initWithBytes(const void *bytes, unsigned int inLength)
65: {
66: if (!bytes || !initWithCapacity(inLength))
67: return false;
68:
69: bcopy(bytes, data, inLength);
70: length = inLength;
71:
72: return true;
73: }
74:
75: bool OSData::initWithBytesNoCopy(void *bytes, unsigned int inLength)
76: {
77: if (!super::init())
78: return false;
79:
80: length = inLength;
81: capacity = EXTERNAL;
82: data = bytes;
83:
84: return true;
85: }
86:
87: bool OSData::initWithData(const OSData *inData)
88: {
89: return initWithBytes(inData->data, inData->length);
90: }
91:
92: bool OSData::initWithData(const OSData *inData,
93: unsigned int start, unsigned int inLength)
94: {
95: const void *localData = inData->getBytesNoCopy(start, inLength);
96:
97: if (localData)
98: return initWithBytes(localData, inLength);
99: else
100: return false;
101: }
102:
103: OSData *OSData::withCapacity(unsigned int inCapacity)
104: {
105: OSData *me = new OSData;
106:
107: if (me && !me->initWithCapacity(inCapacity)) {
108: me->free();
109: return 0;
110: }
111:
112: return me;
113: }
114:
115: OSData *OSData::withBytes(const void *bytes, unsigned int inLength)
116: {
117: OSData *me = new OSData;
118:
119: if (me && !me->initWithBytes(bytes, inLength)) {
120: me->free();
121: return 0;
122: }
123: return me;
124: }
125:
126: OSData *OSData::withBytesNoCopy(void *bytes, unsigned int inLength)
127: {
128: OSData *me = new OSData;
129:
130: if (me && !me->initWithBytesNoCopy(bytes, inLength)) {
131: me->free();
132: return 0;
133: }
134:
135: return me;
136: }
137:
138: OSData *OSData::withData(const OSData *inData)
139: {
140: OSData *me = new OSData;
141:
142: if (me && !me->initWithData(inData)) {
143: me->free();
144: return 0;
145: }
146:
147: return me;
148: }
149:
150: OSData *OSData::withData(const OSData *inData,
151: unsigned int start, unsigned int inLength)
152: {
153: OSData *me = new OSData;
154:
155: if (me && !me->initWithData(inData, start, inLength)) {
156: me->free();
157: return 0;
158: }
159:
160: return me;
161: }
162:
163: void OSData::free()
164: {
165: if (capacity != EXTERNAL && data && capacity) {
166: kfree((vm_offset_t)data, capacity);
167: ACCUMSIZE( -capacity );
168: }
169: super::free();
170: }
171:
172: unsigned int OSData::getLength() const { return length; }
173: unsigned int OSData::getCapacity() const { return capacity; }
174:
175: unsigned int OSData::getCapacityIncrement() const
176: {
177: return capacityIncrement;
178: }
179:
180: unsigned int OSData::setCapacityIncrement(unsigned increment)
181: {
182: return capacityIncrement = increment;
183: }
184:
185: unsigned int OSData::ensureCapacity(unsigned int newCapacity)
186: {
187: unsigned char * newData;
188:
189: if ( !capacityIncrement || (newCapacity <= capacity) )
190: return capacity;
191:
192: newCapacity = (((newCapacity - 1) / capacityIncrement) + 1)
193: * capacityIncrement;
194:
195: newData = (unsigned char *) kalloc(newCapacity);
196:
197: if ( newData ) {
198: bcopy(data, newData, capacity);
199: bzero(newData + capacity, newCapacity - capacity);
200: kfree((vm_offset_t)data, capacity);
201: ACCUMSIZE( newCapacity - capacity );
202: data = (void *) newData;
203: capacity = newCapacity;
204: }
205:
206: return capacity;
207: }
208:
209: bool OSData::appendBytes(const void *bytes, unsigned int inLength)
210: {
211: unsigned int newSize;
212:
213: if (inLength == 0)
214: return true;
215:
216: if (capacity == EXTERNAL)
217: return false;
218:
219: newSize = length + inLength;
220: if ( (newSize > capacity) && newSize > ensureCapacity(newSize) )
221: return false;
222:
223: bcopy(bytes, &((unsigned char *)data)[length], inLength);
224: length = newSize;
225:
226: return true;
227: }
228:
229: bool OSData::appendBytes(const OSData *other)
230: {
231: return appendBytes(other->data, other->length);
232: }
233:
234: const void *OSData::getBytesNoCopy() const
235: {
236: if (length == 0)
237: return 0;
238: else
239: return data;
240: }
241:
242: const void *OSData::getBytesNoCopy(unsigned int start,
243: unsigned int inLength) const
244: {
245: const void *outData = 0;
246:
247: if (length
248: && start < length
249: && (start + inLength) <= length)
250: outData = (const void *) ((char *) data + start);
251:
252: return outData;
253: }
254:
255: bool OSData::isEqualTo(const OSData *aData) const
256: {
257: unsigned int len;
258:
259: len = aData->length;
260: if ( length != len )
261: return false;
262:
263: return isEqualTo(aData->data, len);
264: }
265:
266: bool OSData::isEqualTo(const void *someData, unsigned int inLength) const
267: {
268: return (length >= inLength) && (bcmp(data, someData, inLength) == 0);
269: }
270:
271: bool OSData::isEqualTo(const OSObject *obj) const
272: {
273: OSData * data;
274: if ((data = OSDynamicCast(OSData, (OSObject *)obj )))
275: return isEqualTo(data);
276: else
277: return false;
278: }
279:
280: //this was taken from CFPropertyList.c
281: static const char __CFPLDataEncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
282:
283: bool OSData::serialize(OSSerialize *s) const
284: {
285: unsigned int i;
286: const unsigned char *p;
287: unsigned char c;
288:
289: if (s->previouslySerialized(this)) return true;
290:
291: if (!s->addXMLStartTag(this, "data")) return false;
292:
293: for (i = 0, p = (unsigned char *)data; i < length; i++, p++) {
294: /* 3 bytes are encoded as 4 */
295: switch (i % 3) {
296: case 0:
297: c = __CFPLDataEncodeTable [ ((p[0] >> 2) & 0x3f)];
298: if (!s->addChar(c)) return false;
299: break;
300: case 1:
301: c = __CFPLDataEncodeTable [ ((((p[-1] << 8) | p[0]) >> 4) & 0x3f)];
302: if (!s->addChar(c)) return false;
303: break;
304: case 2:
305: c = __CFPLDataEncodeTable [ ((((p[-1] << 8) | p[0]) >> 6) & 0x3f)];
306: if (!s->addChar(c)) return false;
307: c = __CFPLDataEncodeTable [ (p[0] & 0x3f)];
308: if (!s->addChar(c)) return false;
309: break;
310: }
311: }
312: switch (i % 3) {
313: case 0:
314: break;
315: case 1:
316: c = __CFPLDataEncodeTable [ ((p[-1] << 4) & 0x30)];
317: if (!s->addChar(c)) return false;
318: if (!s->addChar('=')) return false;
319: if (!s->addChar('=')) return false;
320: break;
321: case 2:
322: c = __CFPLDataEncodeTable [ ((p[-1] << 2) & 0x3c)];
323: if (!s->addChar(c)) return false;
324: if (!s->addChar('=')) return false;
325: break;
326: }
327:
328: return s->addXMLEndTag("data");
329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.