|
|
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: /* OSSerialize.cpp created by rsulack on Wen 25-Nov-1998 */
23:
24: #include <libkern/c++/OSContainers.h>
25: #include <libkern/c++/OSLib.h>
26: #include <libkern/c++/OSDictionary.h>
27:
28: #define super OSObject
29:
30: OSDefineMetaClassAndStructors(OSSerialize, OSObject)
31:
32: #ifdef DEBUG
33: extern "C" {
34: extern int debug_container_malloc_size;
35: };
36: #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
37: #else
38: #define ACCUMSIZE(s)
39: #endif
40:
41: char * OSSerialize::text() const
42: {
43: return data;
44: }
45:
46: void OSSerialize::clearText()
47: {
48: bzero((void *)data, capacity);
49: length = 1;
50: tag = 0;
51: tags->flushCollection();
52: }
53:
54: bool OSSerialize::previouslySerialized(const OSObject* o)
55: {
56: char temp[16];
57: OSString *tagString;
58:
59: // look it up
60: tagString = (OSString *)tags->getObject((const OSSymbol *) o);
61:
62: // does it exist?
63: if (tagString) {
64: addString("<reference IDREF=\"");
65: addString(tagString->getCStringNoCopy());
66: addString("\"/>");
67: return true;
68: }
69:
70: // build a tag
71: sprintf(temp, "%u", tag++);
72: tagString = OSString::withCString(temp);
73:
74: // add to tag dictionary
75: tags->setObject((const OSSymbol *) o, tagString);// XXX check return
76: tagString->release();
77:
78: return false;
79: }
80:
81: bool OSSerialize::addXMLStartTag(const OSObject *o, const char *tagString)
82: {
83:
84: if (!addChar('<')) return false;
85: if (!addString(tagString)) return false;
86: if (!addString(" ID=\"")) return false;
87: if (!addString(((OSString *)tags->getObject((const OSSymbol *)o))->getCStringNoCopy()))
88: return false;
89: if (!addChar('\"')) return false;
90: if (!addChar('>')) return false;
91: return true;
92: }
93:
94: bool OSSerialize::addXMLEndTag(const char *tagString)
95: {
96:
97: if (!addChar('<')) return false;
98: if (!addChar('/')) return false;
99: if (!addString(tagString)) return false;
100: if (!addChar('>')) return false;
101: return true;
102: }
103:
104: bool OSSerialize::addChar(const char c)
105: {
106: // add char, possibly extending our capacity
107: if (length >= capacity && length >=ensureCapacity(capacity+capacityIncrement))
108: return false;
109:
110: data[length - 1] = c;
111: length++;
112:
113: return true;
114: }
115:
116: bool OSSerialize::addString(const char *s)
117: {
118: bool rc = false;
119:
120: while (*s && (rc = addChar(*s++))) ;
121:
122: return rc;
123: }
124:
125: bool OSSerialize::initWithCapacity(unsigned int inCapacity)
126: {
127: if (!super::init())
128: return false;
129:
130: tags = OSDictionary::withCapacity(32);
131: if (!tags) {
132: return false;
133: }
134:
135: data = (char *) kalloc(inCapacity);
136: if (!data) {
137: tags->release();
138: return false;
139: }
140: bzero((void *)data, inCapacity);
141:
142: tag = 0;
143: length = 1;
144: capacity = inCapacity;
145: capacityIncrement = inCapacity;
146:
147:
148: ACCUMSIZE(capacity);
149:
150: return true;
151: }
152:
153: OSSerialize *OSSerialize::withCapacity(unsigned int inCapacity)
154: {
155: OSSerialize *me = new OSSerialize;
156:
157: if (me && !me->initWithCapacity(inCapacity)) {
158: me->free();
159: return 0;
160: }
161:
162: return me;
163: }
164:
165: unsigned int OSSerialize::getLength() const { return length; }
166: unsigned int OSSerialize::getCapacity() const { return capacity; }
167: unsigned int OSSerialize::getCapacityIncrement() const { return capacityIncrement; }
168: unsigned int OSSerialize::setCapacityIncrement(unsigned int increment)
169: {
170: return capacityIncrement = increment;
171: }
172:
173: unsigned int OSSerialize::ensureCapacity(unsigned int newCapacity)
174: {
175: char *newData;
176: unsigned int oldCapacity;
177:
178: if (!capacityIncrement || newCapacity <= capacity)
179: return capacity;
180:
181: // round up
182: newCapacity = (((newCapacity - 1) / capacityIncrement) + 1)
183: * capacityIncrement;
184:
185: newData = (char *) kalloc(newCapacity);
186: if (newData) {
187: oldCapacity = capacity;
188:
189: ACCUMSIZE(newCapacity - oldCapacity);
190:
191: bcopy(data, newData, oldCapacity);
192: bzero(&newData[capacity], newCapacity - oldCapacity);
193: kfree((vm_offset_t)data, oldCapacity);
194: data = newData;
195: capacity = newCapacity;
196: }
197:
198: return capacity;
199: }
200:
201: void OSSerialize::free()
202: {
203: if (tags)
204: tags->release();
205:
206: if (data) {
207: kfree((vm_offset_t)data, capacity);
208: ACCUMSIZE( -capacity );
209: }
210: super::free();
211: }
212:
213:
214: OSDefineMetaClassAndStructors(OSSerializer, OSObject)
215:
216: OSSerializer * OSSerializer::forTarget( void * target,
217: OSSerializerCallback callback, void * ref = 0 )
218: {
219: OSSerializer * thing;
220:
221: thing = new OSSerializer;
222: if( thing && !thing->init()) {
223: thing->release();
224: thing = 0;
225: }
226:
227: if( thing) {
228: thing->target = target;
229: thing->ref = ref;
230: thing->callback = callback;
231: }
232: return( thing );
233: }
234:
235: bool OSSerializer::serialize( OSSerialize * s ) const
236: {
237: return( (*callback)(target, ref, s) );
238: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.