| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/sgl/SkString.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkString.h" | |
| 19 #include "SkFixed.h" | |
| 20 #include "SkUtils.h" | |
| 21 #include <stdarg.h> | |
| 22 | |
| 23 bool SkStrStartsWith(const char string[], const char prefix[]) | |
| 24 { | |
| 25 SkASSERT(string); | |
| 26 SkASSERT(prefix); | |
| 27 return !strncmp(string, prefix, strlen(prefix)); | |
| 28 } | |
| 29 | |
| 30 bool SkStrEndsWith(const char string[], const char suffix[]) | |
| 31 { | |
| 32 SkASSERT(string); | |
| 33 SkASSERT(suffix); | |
| 34 size_t strLen = strlen(string); | |
| 35 size_t suffixLen = strlen(suffix); | |
| 36 return strLen >= suffixLen && | |
| 37 !strncmp(string + strLen - suffixLen, suffix, suffixLen); | |
| 38 } | |
| 39 | |
| 40 int SkStrStartsWithOneOf(const char string[], const char prefixes[]) | |
| 41 { | |
| 42 int index = 0; | |
| 43 do { | |
| 44 const char* limit = strchr(prefixes, '\0'); | |
| 45 if (!strncmp(string, prefixes, limit - prefixes)) | |
| 46 return index; | |
| 47 prefixes = limit + 1; | |
| 48 index++; | |
| 49 } while (prefixes[0]); | |
| 50 return -1; | |
| 51 } | |
| 52 | |
| 53 char* SkStrAppendS32(char string[], int32_t dec) | |
| 54 { | |
| 55 SkDEBUGCODE(char* start = string;) | |
| 56 | |
| 57 char buffer[SkStrAppendS32_MaxSize]; | |
| 58 char* p = buffer + sizeof(buffer); | |
| 59 bool neg = false; | |
| 60 | |
| 61 if (dec < 0) | |
| 62 { | |
| 63 neg = true; | |
| 64 dec = -dec; | |
| 65 } | |
| 66 do { | |
| 67 *--p = SkToU8('0' + dec % 10); | |
| 68 dec /= 10; | |
| 69 } while (dec != 0); | |
| 70 if (neg) | |
| 71 *--p = '-'; | |
| 72 | |
| 73 SkASSERT(p >= buffer); | |
| 74 char* stop = buffer + sizeof(buffer); | |
| 75 while (p < stop) | |
| 76 *string++ = *p++; | |
| 77 | |
| 78 SkASSERT(string - start <= SkStrAppendS32_MaxSize); | |
| 79 return string; | |
| 80 } | |
| 81 | |
| 82 char* SkStrAppendScalar(char string[], SkScalar value) | |
| 83 { | |
| 84 SkDEBUGCODE(char* start = string;) | |
| 85 | |
| 86 SkFixed x = SkScalarToFixed(value); | |
| 87 | |
| 88 if (x < 0) | |
| 89 { | |
| 90 *string++ = '-'; | |
| 91 x = -x; | |
| 92 } | |
| 93 | |
| 94 unsigned frac = x & 0xFFFF; | |
| 95 x >>= 16; | |
| 96 if (frac == 0xFFFF) // need to do this to "round up", since 65535/65536 is c
loser to 1 than to .9999 | |
| 97 { | |
| 98 x += 1; | |
| 99 frac = 0; | |
| 100 } | |
| 101 string = SkStrAppendS32(string, x); | |
| 102 | |
| 103 // now handle the fractional part (if any) | |
| 104 if (frac) | |
| 105 { | |
| 106 static const uint16_t gTens[] = { 1000, 100, 10, 1 }; | |
| 107 const uint16_t* tens = gTens; | |
| 108 | |
| 109 x = SkFixedRound(frac * 10000); | |
| 110 SkASSERT(x <= 10000); | |
| 111 if (x == 10000) { | |
| 112 x -= 1; | |
| 113 } | |
| 114 *string++ = '.'; | |
| 115 do { | |
| 116 unsigned powerOfTen = *tens++; | |
| 117 *string++ = SkToU8('0' + x / powerOfTen); | |
| 118 x %= powerOfTen; | |
| 119 } while (x != 0); | |
| 120 } | |
| 121 | |
| 122 SkASSERT(string - start <= SkStrAppendScalar_MaxSize); | |
| 123 return string; | |
| 124 } | |
| 125 | |
| 126 ////////////////////////////////////////////////////////////////////////////////
//// | |
| 127 | |
| 128 #define kMaxRefCnt_SkString SK_MaxU16 | |
| 129 | |
| 130 // the 3 values are [length] [refcnt] [terminating zero data] | |
| 131 const SkString::Rec SkString::gEmptyRec = { 0, 0, 0 }; | |
| 132 | |
| 133 #define SizeOfRec() (gEmptyRec.data() - (const char*)&gEmptyRec) | |
| 134 | |
| 135 SkString::Rec* SkString::AllocRec(const char text[], U16CPU len) | |
| 136 { | |
| 137 Rec* rec; | |
| 138 | |
| 139 if (len == 0) | |
| 140 rec = const_cast<Rec*>(&gEmptyRec); | |
| 141 else | |
| 142 { | |
| 143 // add 1 for terminating 0, then align4 so we can have some slop when gr
owing the string | |
| 144 rec = (Rec*)sk_malloc_throw(SizeOfRec() + SkAlign4(len + 1)); | |
| 145 rec->fLength = SkToU16(len); | |
| 146 rec->fRefCnt = 1; | |
| 147 if (text) | |
| 148 memcpy(rec->data(), text, len); | |
| 149 rec->data()[len] = 0; | |
| 150 } | |
| 151 return rec; | |
| 152 } | |
| 153 | |
| 154 SkString::Rec* SkString::RefRec(Rec* src) | |
| 155 { | |
| 156 if (src != &gEmptyRec) | |
| 157 { | |
| 158 if (src->fRefCnt == kMaxRefCnt_SkString) { | |
| 159 src = AllocRec(src->data(), src->fLength); | |
| 160 } else | |
| 161 src->fRefCnt += 1; | |
| 162 } | |
| 163 return src; | |
| 164 } | |
| 165 | |
| 166 #ifdef SK_DEBUG | |
| 167 void SkString::validate() const | |
| 168 { | |
| 169 // make sure know one has written over our global | |
| 170 SkASSERT(gEmptyRec.fLength == 0); | |
| 171 SkASSERT(gEmptyRec.fRefCnt == 0); | |
| 172 SkASSERT(gEmptyRec.data()[0] == 0); | |
| 173 | |
| 174 if (fRec != &gEmptyRec) | |
| 175 { | |
| 176 SkASSERT(fRec->fLength > 0); | |
| 177 SkASSERT(fRec->fRefCnt > 0); | |
| 178 SkASSERT(fRec->data()[fRec->fLength] == 0); | |
| 179 } | |
| 180 SkASSERT(fStr == c_str()); | |
| 181 } | |
| 182 #endif | |
| 183 | |
| 184 /////////////////////////////////////////////////////////////////////// | |
| 185 | |
| 186 SkString::SkString() : fRec(const_cast<Rec*>(&gEmptyRec)) { | |
| 187 #ifdef SK_DEBUG | |
| 188 fStr = fRec->data(); | |
| 189 #endif | |
| 190 } | |
| 191 | |
| 192 SkString::SkString(size_t len) | |
| 193 { | |
| 194 SkASSERT(SkToU16(len) == len); // can't handle larger than 64K | |
| 195 | |
| 196 fRec = AllocRec(NULL, (U16CPU)len); | |
| 197 #ifdef SK_DEBUG | |
| 198 fStr = fRec->data(); | |
| 199 #endif | |
| 200 } | |
| 201 | |
| 202 SkString::SkString(const char text[]) | |
| 203 { | |
| 204 size_t len = text ? strlen(text) : 0; | |
| 205 | |
| 206 fRec = AllocRec(text, (U16CPU)len); | |
| 207 #ifdef SK_DEBUG | |
| 208 fStr = fRec->data(); | |
| 209 #endif | |
| 210 } | |
| 211 | |
| 212 SkString::SkString(const char text[], size_t len) | |
| 213 { | |
| 214 fRec = AllocRec(text, (U16CPU)len); | |
| 215 #ifdef SK_DEBUG | |
| 216 fStr = fRec->data(); | |
| 217 #endif | |
| 218 } | |
| 219 | |
| 220 SkString::SkString(const SkString& src) | |
| 221 { | |
| 222 src.validate(); | |
| 223 | |
| 224 fRec = RefRec(src.fRec); | |
| 225 #ifdef SK_DEBUG | |
| 226 fStr = fRec->data(); | |
| 227 #endif | |
| 228 } | |
| 229 | |
| 230 SkString::~SkString() | |
| 231 { | |
| 232 this->validate(); | |
| 233 | |
| 234 if (fRec->fLength) | |
| 235 { | |
| 236 SkASSERT(fRec->fRefCnt > 0); | |
| 237 if (--fRec->fRefCnt == 0) | |
| 238 sk_free(fRec); | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 bool SkString::equals(const SkString& src) const | |
| 243 { | |
| 244 return fRec == src.fRec || this->equals(src.c_str(), src.size()); | |
| 245 } | |
| 246 | |
| 247 bool SkString::equals(const char text[]) const | |
| 248 { | |
| 249 return this->equals(text, text ? strlen(text) : 0); | |
| 250 } | |
| 251 | |
| 252 bool SkString::equals(const char text[], size_t len) const | |
| 253 { | |
| 254 SkASSERT(len == 0 || text != NULL); | |
| 255 | |
| 256 return fRec->fLength == len && !memcmp(fRec->data(), text, len); | |
| 257 } | |
| 258 | |
| 259 SkString& SkString::operator=(const SkString& src) | |
| 260 { | |
| 261 this->validate(); | |
| 262 | |
| 263 if (fRec != src.fRec) | |
| 264 { | |
| 265 SkString tmp(src); | |
| 266 this->swap(tmp); | |
| 267 } | |
| 268 return *this; | |
| 269 } | |
| 270 | |
| 271 void SkString::reset() | |
| 272 { | |
| 273 this->validate(); | |
| 274 | |
| 275 if (fRec->fLength) | |
| 276 { | |
| 277 SkASSERT(fRec->fRefCnt > 0); | |
| 278 if (--fRec->fRefCnt == 0) | |
| 279 sk_free(fRec); | |
| 280 } | |
| 281 | |
| 282 fRec = const_cast<Rec*>(&gEmptyRec); | |
| 283 #ifdef SK_DEBUG | |
| 284 fStr = fRec->data(); | |
| 285 #endif | |
| 286 } | |
| 287 | |
| 288 char* SkString::writable_str() | |
| 289 { | |
| 290 this->validate(); | |
| 291 | |
| 292 if (fRec->fLength) | |
| 293 { | |
| 294 if (fRec->fRefCnt > 1) | |
| 295 { | |
| 296 fRec->fRefCnt -= 1; | |
| 297 fRec = AllocRec(fRec->data(), fRec->fLength); | |
| 298 #ifdef SK_DEBUG | |
| 299 fStr = fRec->data(); | |
| 300 #endif | |
| 301 } | |
| 302 } | |
| 303 return fRec->data(); | |
| 304 } | |
| 305 | |
| 306 void SkString::set(const char text[]) | |
| 307 { | |
| 308 this->set(text, text ? strlen(text) : 0); | |
| 309 } | |
| 310 | |
| 311 void SkString::set(const char text[], size_t len) | |
| 312 { | |
| 313 if (len == 0) | |
| 314 this->reset(); | |
| 315 else if (fRec->fRefCnt == 1 && len <= fRec->fLength) // should we resize
if len <<<< fLength, to save RAM? (e.g. len < (fLength>>1)) | |
| 316 { | |
| 317 // just use less of the buffer without allocating a smaller one | |
| 318 char* p = this->writable_str(); | |
| 319 if (text) | |
| 320 memcpy(p, text, len); | |
| 321 p[len] = 0; | |
| 322 fRec->fLength = SkToU16(len); | |
| 323 } | |
| 324 else if (fRec->fRefCnt == 1 && ((unsigned)fRec->fLength >> 2) == (len >> 2)) | |
| 325 { | |
| 326 // we have spare room in the current allocation, so don't alloc a larger
one | |
| 327 char* p = this->writable_str(); | |
| 328 if (text) | |
| 329 memcpy(p, text, len); | |
| 330 p[len] = 0; | |
| 331 fRec->fLength = SkToU16(len); | |
| 332 } | |
| 333 else | |
| 334 { | |
| 335 SkString tmp(text, len); | |
| 336 this->swap(tmp); | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 void SkString::setUTF16(const uint16_t src[]) | |
| 341 { | |
| 342 int count = 0; | |
| 343 | |
| 344 while (src[count]) | |
| 345 count += 1; | |
| 346 setUTF16(src, count); | |
| 347 } | |
| 348 | |
| 349 void SkString::setUTF16(const uint16_t src[], size_t count) | |
| 350 { | |
| 351 if (count == 0) | |
| 352 this->reset(); | |
| 353 else if (count <= fRec->fLength) // should we resize if len <<<< fLength,
to save RAM? (e.g. len < (fLength>>1)) | |
| 354 { | |
| 355 if (count < fRec->fLength) | |
| 356 this->resize(count); | |
| 357 char* p = this->writable_str(); | |
| 358 for (size_t i = 0; i < count; i++) | |
| 359 p[i] = SkToU8(src[i]); | |
| 360 p[count] = 0; | |
| 361 } | |
| 362 else | |
| 363 { | |
| 364 SkString tmp(count); // puts a null terminator at the end of the stri
ng | |
| 365 char* p = tmp.writable_str(); | |
| 366 | |
| 367 for (size_t i = 0; i < count; i++) | |
| 368 p[i] = SkToU8(src[i]); | |
| 369 | |
| 370 this->swap(tmp); | |
| 371 } | |
| 372 } | |
| 373 | |
| 374 void SkString::insert(size_t offset, const char text[]) | |
| 375 { | |
| 376 this->insert(offset, text, text ? strlen(text) : 0); | |
| 377 } | |
| 378 | |
| 379 void SkString::insert(size_t offset, const char text[], size_t len) | |
| 380 { | |
| 381 if (len) | |
| 382 { | |
| 383 size_t length = fRec->fLength; | |
| 384 if (offset > length) | |
| 385 offset = length; | |
| 386 | |
| 387 /* If we're the only owner, and we have room in our allocation for the
insert, | |
| 388 do it in place, rather than allocating a new buffer. | |
| 389 | |
| 390 To know we have room, compare the allocated sizes | |
| 391 beforeAlloc = SkAlign4(length + 1) | |
| 392 afterAlloc = SkAligh4(length + 1 + len) | |
| 393 but SkAlign4(x) is (x + 3) >> 2 << 2 | |
| 394 which is equivalent for testing to (length + 1 + 3) >> 2 == (length
+ 1 + 3 + len) >> 2 | |
| 395 and we can then eliminate the +1+3 since that doesn't affec the answ
er | |
| 396 */ | |
| 397 if (fRec->fRefCnt == 1 && (length >> 2) == ((length + len) >> 2)) | |
| 398 { | |
| 399 char* dst = this->writable_str(); | |
| 400 | |
| 401 if (offset < length) | |
| 402 memmove(dst + offset + len, dst + offset, length - offset); | |
| 403 memcpy(dst + offset, text, len); | |
| 404 | |
| 405 dst[length + len] = 0; | |
| 406 fRec->fLength = SkToU16(length + len); | |
| 407 } | |
| 408 else | |
| 409 { | |
| 410 /* Seems we should use realloc here, since that is safe if it fails | |
| 411 (we have the original data), and might be faster than alloc/copy
/free. | |
| 412 */ | |
| 413 SkString tmp(fRec->fLength + len); | |
| 414 char* dst = tmp.writable_str(); | |
| 415 | |
| 416 if (offset > 0) | |
| 417 memcpy(dst, fRec->data(), offset); | |
| 418 memcpy(dst + offset, text, len); | |
| 419 if (offset < fRec->fLength) | |
| 420 memcpy(dst + offset + len, fRec->data() + offset, fRec->fLength
- offset); | |
| 421 | |
| 422 this->swap(tmp); | |
| 423 } | |
| 424 } | |
| 425 } | |
| 426 | |
| 427 void SkString::insertUnichar(size_t offset, SkUnichar uni) | |
| 428 { | |
| 429 char buffer[kMaxBytesInUTF8Sequence]; | |
| 430 size_t len = SkUTF8_FromUnichar(uni, buffer); | |
| 431 | |
| 432 if (len) | |
| 433 this->insert(offset, buffer, len); | |
| 434 } | |
| 435 | |
| 436 void SkString::insertS32(size_t offset, int32_t dec) | |
| 437 { | |
| 438 char buffer[SkStrAppendS32_MaxSize]; | |
| 439 char* stop = SkStrAppendS32(buffer, dec); | |
| 440 this->insert(offset, buffer, stop - buffer); | |
| 441 } | |
| 442 | |
| 443 void SkString::insertHex(size_t offset, uint32_t hex, int minDigits) | |
| 444 { | |
| 445 minDigits = SkPin32(minDigits, 0, 8); | |
| 446 | |
| 447 static const char gHex[] = "0123456789ABCDEF"; | |
| 448 | |
| 449 char buffer[8]; | |
| 450 char* p = buffer + sizeof(buffer); | |
| 451 | |
| 452 do { | |
| 453 *--p = gHex[hex & 0xF]; | |
| 454 hex >>= 4; | |
| 455 minDigits -= 1; | |
| 456 } while (hex != 0); | |
| 457 while (--minDigits >= 0) | |
| 458 *--p = '0'; | |
| 459 | |
| 460 SkASSERT(p >= buffer); | |
| 461 this->insert(offset, p, buffer + sizeof(buffer) - p); | |
| 462 } | |
| 463 | |
| 464 void SkString::insertScalar(size_t offset, SkScalar value) | |
| 465 { | |
| 466 char buffer[SkStrAppendScalar_MaxSize]; | |
| 467 char* stop = SkStrAppendScalar(buffer, value); | |
| 468 this->insert(offset, buffer, stop - buffer); | |
| 469 } | |
| 470 | |
| 471 /////////////////////////////////////////////////////////////////////////// | |
| 472 | |
| 473 //#include <stdarg.h> | |
| 474 #if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_F
OR_UNIX) | |
| 475 #include <stdio.h> | |
| 476 #endif | |
| 477 | |
| 478 void SkString::printf(const char format[], ...) | |
| 479 { | |
| 480 static const size_t kBufferSize = 100; | |
| 481 | |
| 482 char buffer[kBufferSize + 1]; | |
| 483 | |
| 484 #ifdef SK_BUILD_FOR_WIN | |
| 485 va_list args; | |
| 486 va_start(args, format); | |
| 487 _vsnprintf(buffer, kBufferSize, format, args); | |
| 488 va_end(args); | |
| 489 #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) | |
| 490 va_list args; | |
| 491 va_start(args, format); | |
| 492 vsnprintf(buffer, kBufferSize, format, args); | |
| 493 va_end(args); | |
| 494 #else | |
| 495 buffer[0] = 0; | |
| 496 #endif | |
| 497 | |
| 498 this->set(buffer, strlen(buffer)); | |
| 499 } | |
| 500 | |
| 501 /////////////////////////////////////////////////////////////////////////// | |
| 502 | |
| 503 void SkString::remove(size_t offset, size_t length) | |
| 504 { | |
| 505 size_t size = this->size(); | |
| 506 | |
| 507 if (offset < size) | |
| 508 { | |
| 509 if (offset + length > size) | |
| 510 length = size - offset; | |
| 511 if (length > 0) | |
| 512 { | |
| 513 SkASSERT(size > length); | |
| 514 SkString tmp(size - length); | |
| 515 char* dst = tmp.writable_str(); | |
| 516 const char* src = this->c_str(); | |
| 517 | |
| 518 if (offset) | |
| 519 { | |
| 520 SkASSERT(offset <= tmp.size()); | |
| 521 memcpy(dst, src, offset); | |
| 522 } | |
| 523 size_t tail = size - offset - length; | |
| 524 SkASSERT((int32_t)tail >= 0); | |
| 525 if (tail) | |
| 526 { | |
| 527 // SkASSERT(offset + length <= tmp.size()); | |
| 528 memcpy(dst + offset, src + offset + length, tail); | |
| 529 } | |
| 530 SkASSERT(dst[tmp.size()] == 0); | |
| 531 this->swap(tmp); | |
| 532 } | |
| 533 } | |
| 534 } | |
| 535 | |
| 536 void SkString::swap(SkString& other) | |
| 537 { | |
| 538 this->validate(); | |
| 539 other.validate(); | |
| 540 | |
| 541 SkTSwap<Rec*>(fRec, other.fRec); | |
| 542 #ifdef SK_DEBUG | |
| 543 SkTSwap<const char*>(fStr, other.fStr); | |
| 544 #endif | |
| 545 } | |
| 546 | |
| 547 ////////////////////////////////////////////////////////////////////////////////
/ | |
| 548 | |
| 549 SkAutoUCS2::SkAutoUCS2(const char utf8[]) | |
| 550 { | |
| 551 size_t len = strlen(utf8); | |
| 552 fUCS2 = (uint16_t*)sk_malloc_throw((len + 1) * sizeof(uint16_t)); | |
| 553 | |
| 554 uint16_t* dst = fUCS2; | |
| 555 for (;;) | |
| 556 { | |
| 557 SkUnichar uni = SkUTF8_NextUnichar(&utf8); | |
| 558 *dst++ = SkToU16(uni); | |
| 559 if (uni == 0) | |
| 560 break; | |
| 561 } | |
| 562 fCount = (int)(dst - fUCS2); | |
| 563 } | |
| 564 | |
| 565 SkAutoUCS2::~SkAutoUCS2() | |
| 566 { | |
| 567 delete[] fUCS2; | |
| 568 } | |
| 569 | |
| 570 ////////////////////////////////////////////////////////////////////////////////
/ | |
| 571 ////////////////////////////////////////////////////////////////////////////////
/ | |
| 572 | |
| 573 #ifdef SK_DEBUG | |
| 574 | |
| 575 void SkString::UnitTest() | |
| 576 { | |
| 577 #ifdef SK_SUPPORT_UNITTEST | |
| 578 SkString a; | |
| 579 SkString b((size_t)0); | |
| 580 SkString c(""); | |
| 581 SkString d(NULL, 0); | |
| 582 | |
| 583 SkASSERT(a.isEmpty()); | |
| 584 SkASSERT(a == b && a == c && a == d); | |
| 585 | |
| 586 a.set("hello"); | |
| 587 b.set("hellox", 5); | |
| 588 c.set(a); | |
| 589 d.resize(5); | |
| 590 memcpy(d.writable_str(), "helloz", 5); | |
| 591 | |
| 592 SkASSERT(!a.isEmpty()); | |
| 593 SkASSERT(a.size() == 5); | |
| 594 SkASSERT(a == b && a == c && a == d); | |
| 595 SkASSERT(a.equals("hello", 5)); | |
| 596 SkASSERT(a.equals("hello")); | |
| 597 SkASSERT(!a.equals("help")); | |
| 598 | |
| 599 SkString e(a); | |
| 600 SkString f("hello"); | |
| 601 SkString g("helloz", 5); | |
| 602 | |
| 603 SkASSERT(a == e && a == f && a == g); | |
| 604 | |
| 605 b.set("world"); | |
| 606 c = b; | |
| 607 SkASSERT(a != b && a != c && b == c); | |
| 608 | |
| 609 a.append(" world"); | |
| 610 e.append("worldz", 5); | |
| 611 e.insert(5, " "); | |
| 612 f.set("world"); | |
| 613 f.prepend("hello "); | |
| 614 SkASSERT(a.equals("hello world") && a == e && a == f); | |
| 615 | |
| 616 a.reset(); | |
| 617 b.resize(0); | |
| 618 SkASSERT(a.isEmpty() && b.isEmpty() && a == b); | |
| 619 | |
| 620 a.set("a"); | |
| 621 a.set("ab"); | |
| 622 a.set("abc"); | |
| 623 a.set("abcd"); | |
| 624 #endif | |
| 625 } | |
| 626 | |
| 627 #endif | |
| 628 | |
| OLD | NEW |