]> git.saurik.com Git - apple/xnu.git/blame - libkern/c++/OSString.cpp
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / libkern / c++ / OSString.cpp
CommitLineData
1c79356b 1/*
0a7de745 2 * Copyright (c) 2019 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
0a7de745 5 *
2d21ac55
A
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.
0a7de745 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
0a7de745 17 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
0a7de745 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/* IOString.m created by rsulack on Wed 17-Sep-1997 */
29/* IOString.cpp converted to C++ on Tue 1998-9-22 */
30
f427ee49
A
31#define IOKIT_ENABLE_SHARED_PTR
32
9bccf70c 33#include <string.h>
1c79356b
A
34
35#include <libkern/c++/OSString.h>
36#include <libkern/c++/OSSerialize.h>
f427ee49 37#include <libkern/c++/OSSharedPtr.h>
1c79356b
A
38#include <libkern/c++/OSLib.h>
39#include <libkern/c++/OSData.h>
9bccf70c 40#include <string.h>
1c79356b
A
41
42#define super OSObject
43
f427ee49
A
44OSDefineMetaClassAndStructorsWithZone(OSString, OSObject,
45 (zone_create_flags_t) (ZC_CACHING | ZC_ZFREE_CLEARMEM))
0a7de745
A
46OSMetaClassDefineReservedUnused(OSString, 0);
47OSMetaClassDefineReservedUnused(OSString, 1);
48OSMetaClassDefineReservedUnused(OSString, 2);
49OSMetaClassDefineReservedUnused(OSString, 3);
50OSMetaClassDefineReservedUnused(OSString, 4);
51OSMetaClassDefineReservedUnused(OSString, 5);
52OSMetaClassDefineReservedUnused(OSString, 6);
53OSMetaClassDefineReservedUnused(OSString, 7);
54OSMetaClassDefineReservedUnused(OSString, 8);
55OSMetaClassDefineReservedUnused(OSString, 9);
1c79356b
A
56OSMetaClassDefineReservedUnused(OSString, 10);
57OSMetaClassDefineReservedUnused(OSString, 11);
58OSMetaClassDefineReservedUnused(OSString, 12);
59OSMetaClassDefineReservedUnused(OSString, 13);
60OSMetaClassDefineReservedUnused(OSString, 14);
61OSMetaClassDefineReservedUnused(OSString, 15);
62
0a7de745
A
63bool
64OSString::initWithString(const OSString *aString)
1c79356b 65{
0a7de745 66 return initWithCString(aString->string);
1c79356b
A
67}
68
0a7de745
A
69bool
70OSString::initWithCString(const char *cString)
1c79356b 71{
0a7de745
A
72 unsigned int newLength;
73 char * newString;
1c79356b 74
0a7de745
A
75 if (!cString || !super::init()) {
76 return false;
77 }
3e170ce0 78
f427ee49 79 newLength = (unsigned int) strnlen(cString, kMaxStringLength);
0a7de745
A
80 if (newLength >= kMaxStringLength) {
81 return false;
82 }
39037602 83
0a7de745 84 newLength++;
f427ee49 85 newString = (char *)kalloc_data_container(newLength, Z_WAITOK);
0a7de745
A
86 if (!newString) {
87 return false;
88 }
1c79356b 89
0a7de745 90 bcopy(cString, newString, newLength);
1c79356b 91
0a7de745 92 if (!(flags & kOSStringNoCopy) && string) {
f427ee49 93 kfree_data_container(string, length);
0a7de745
A
94 OSCONTAINER_ACCUMSIZE(-((size_t)length));
95 }
96 string = newString;
97 length = newLength;
98 flags &= ~kOSStringNoCopy;
3e170ce0 99
0a7de745 100 OSCONTAINER_ACCUMSIZE(length);
1c79356b 101
0a7de745 102 return true;
1c79356b
A
103}
104
0a7de745
A
105bool
106OSString::initWithStringOfLength(const char *cString, size_t inlength)
fe8ab488 107{
0a7de745
A
108 unsigned int newLength;
109 char * newString;
fe8ab488 110
0a7de745
A
111 if (!cString || !super::init()) {
112 return false;
113 }
3e170ce0 114
0a7de745
A
115 if (inlength >= kMaxStringLength) {
116 return false;
117 }
39037602 118
0a7de745
A
119 if (strnlen(cString, inlength) < inlength) {
120 return false;
121 }
3e170ce0 122
f427ee49
A
123 newLength = (unsigned int) (inlength + 1);
124 newString = (char *)kalloc_data_container(newLength, Z_WAITOK);
0a7de745
A
125 if (!newString) {
126 return false;
127 }
3e170ce0 128
0a7de745
A
129 bcopy(cString, newString, inlength);
130 newString[inlength] = 0;
fe8ab488 131
0a7de745 132 if (!(flags & kOSStringNoCopy) && string) {
f427ee49 133 kfree_data_container(string, length);
0a7de745
A
134 OSCONTAINER_ACCUMSIZE(-((size_t)length));
135 }
fe8ab488 136
0a7de745
A
137 string = newString;
138 length = newLength;
139 flags &= ~kOSStringNoCopy;
fe8ab488 140
0a7de745
A
141 OSCONTAINER_ACCUMSIZE(length);
142
143 return true;
fe8ab488
A
144}
145
0a7de745
A
146bool
147OSString::initWithCStringNoCopy(const char *cString)
1c79356b 148{
0a7de745
A
149 if (!cString || !super::init()) {
150 return false;
151 }
1c79356b 152
f427ee49 153 length = (unsigned int) strnlen(cString, kMaxStringLength);
0a7de745
A
154 if (length >= kMaxStringLength) {
155 return false;
156 }
39037602 157
0a7de745
A
158 length++;
159 flags |= kOSStringNoCopy;
160 string = const_cast<char *>(cString);
1c79356b 161
0a7de745 162 return true;
1c79356b
A
163}
164
f427ee49 165OSSharedPtr<OSString>
0a7de745 166OSString::withString(const OSString *aString)
1c79356b 167{
f427ee49 168 OSSharedPtr<OSString> me = OSMakeShared<OSString>();
1c79356b 169
0a7de745 170 if (me && !me->initWithString(aString)) {
f427ee49 171 return nullptr;
0a7de745 172 }
1c79356b 173
0a7de745 174 return me;
1c79356b
A
175}
176
f427ee49 177OSSharedPtr<OSString>
0a7de745 178OSString::withCString(const char *cString)
1c79356b 179{
f427ee49 180 OSSharedPtr<OSString> me = OSMakeShared<OSString>();
1c79356b 181
0a7de745 182 if (me && !me->initWithCString(cString)) {
f427ee49 183 return nullptr;
0a7de745 184 }
1c79356b 185
0a7de745 186 return me;
1c79356b
A
187}
188
f427ee49 189OSSharedPtr<OSString>
0a7de745 190OSString::withCStringNoCopy(const char *cString)
1c79356b 191{
f427ee49 192 OSSharedPtr<OSString> me = OSMakeShared<OSString>();
1c79356b 193
0a7de745 194 if (me && !me->initWithCStringNoCopy(cString)) {
f427ee49 195 return nullptr;
0a7de745 196 }
1c79356b 197
0a7de745 198 return me;
1c79356b
A
199}
200
f427ee49 201OSSharedPtr<OSString>
0a7de745 202OSString::withStringOfLength(const char *cString, size_t length)
fe8ab488 203{
f427ee49 204 OSSharedPtr<OSString> me = OSMakeShared<OSString>();
fe8ab488 205
0a7de745 206 if (me && !me->initWithStringOfLength(cString, length)) {
f427ee49 207 return nullptr;
0a7de745 208 }
fe8ab488 209
0a7de745 210 return me;
fe8ab488
A
211}
212
213
214
1c79356b
A
215/* @@@ gvdl */
216#if 0
0a7de745
A
217OSString *
218OSString::stringWithFormat(const char *format, ...)
1c79356b 219{
0a7de745
A
220#ifndef KERNEL // mach3xxx
221 OSString *me;
222 va_list argList;
223
224 if (!format) {
225 return 0;
226 }
227
228 va_start(argList, format);
229 me = stringWithCapacity(256);
230 me->length = vsnprintf(me->string, 256, format, argList);
231 me->length++; // we include the null in the length
232 if (me->Length > 256) {
233 me->Length = 256;
234 }
235 va_end(argList);
236
237 return me;
1c79356b 238#else
0a7de745 239 return 0;
1c79356b
A
240#endif
241}
242#endif /* 0 */
243
0a7de745
A
244void
245OSString::free()
1c79356b 246{
0a7de745 247 if (!(flags & kOSStringNoCopy) && string) {
f427ee49 248 kfree_data_container(string, length);
0a7de745
A
249 OSCONTAINER_ACCUMSIZE(-((size_t)length));
250 }
1c79356b 251
0a7de745 252 super::free();
1c79356b
A
253}
254
0a7de745
A
255unsigned int
256OSString::getLength() const
257{
258 return length - 1;
259}
1c79356b 260
0a7de745
A
261const char *
262OSString::getCStringNoCopy() const
1c79356b 263{
0a7de745 264 return string;
1c79356b
A
265}
266
0a7de745
A
267bool
268OSString::setChar(char aChar, unsigned int index)
1c79356b 269{
0a7de745
A
270 if (!(flags & kOSStringNoCopy) && index < length - 1) {
271 string[index] = aChar;
1c79356b 272
0a7de745
A
273 return true;
274 } else {
275 return false;
276 }
1c79356b
A
277}
278
0a7de745
A
279char
280OSString::getChar(unsigned int index) const
1c79356b 281{
0a7de745
A
282 if (index < length) {
283 return string[index];
284 } else {
285 return '\0';
286 }
1c79356b
A
287}
288
289
0a7de745
A
290bool
291OSString::isEqualTo(const OSString *aString) const
1c79356b 292{
0a7de745
A
293 if (length != aString->length) {
294 return false;
295 } else {
296 return isEqualTo((const char *) aString->string);
297 }
1c79356b
A
298}
299
0a7de745
A
300bool
301OSString::isEqualTo(const char *aCString) const
1c79356b 302{
0a7de745 303 return strncmp(string, aCString, length) == 0;
1c79356b
A
304}
305
0a7de745
A
306bool
307OSString::isEqualTo(const OSMetaClassBase *obj) const
1c79356b 308{
0a7de745
A
309 OSString * str;
310 OSData * data;
311
312 if ((str = OSDynamicCast(OSString, obj))) {
313 return isEqualTo(str);
314 } else if ((data = OSDynamicCast(OSData, obj))) {
315 return isEqualTo(data);
316 } else {
317 return false;
318 }
1c79356b
A
319}
320
0a7de745
A
321bool
322OSString::isEqualTo(const OSData *obj) const
1c79356b 323{
0a7de745
A
324 if (NULL == obj) {
325 return false;
326 }
327
328 unsigned int dataLen = obj->getLength();;
329 const char * dataPtr = (const char *) obj->getBytesNoCopy();
330
331 if (dataLen != length) {
332 // check for the fact that OSData may be a buffer that
333 // that includes a termination byte and will thus have
334 // a length of the actual string length PLUS 1. In this
335 // case we verify that the additional byte is a terminator
336 // and if so count the two lengths as being the same.
337
338 if ((dataLen - length) == 1) {
339 if (dataPtr[dataLen - 1] != 0) {
340 return false;
341 }
342 dataLen--;
343 } else {
344 return false;
345 }
346 }
347
348 for (unsigned int i = 0; i < dataLen; i++) {
349 if (*dataPtr++ != string[i]) {
350 return false;
351 }
352 }
353
354 return true;
1c79356b
A
355}
356
0a7de745
A
357bool
358OSString::serialize(OSSerialize *s) const
1c79356b 359{
0a7de745
A
360 char *c = string;
361
362 if (s->previouslySerialized(this)) {
363 return true;
364 }
365
366 if (!s->addXMLStartTag(this, "string")) {
367 return false;
368 }
369 while (*c) {
370 if (*c == '<') {
371 if (!s->addString("&lt;")) {
372 return false;
373 }
374 } else if (*c == '>') {
375 if (!s->addString("&gt;")) {
376 return false;
377 }
378 } else if (*c == '&') {
379 if (!s->addString("&amp;")) {
380 return false;
381 }
382 } else {
383 if (!s->addChar(*c)) {
384 return false;
385 }
386 }
387 c++;
388 }
389
390 return s->addXMLEndTag("string");
1c79356b 391}