Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(721)

Side by Side Diff: src/core/SkString.cpp

Issue 16356006: change impl to explicitly store length as u32, rather than size_t, so we keep a packed struct on 64… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/core/SkString.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkString.h" 10 #include "SkString.h"
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 return string; 182 return string;
183 } 183 }
184 184
185 /////////////////////////////////////////////////////////////////////////////// 185 ///////////////////////////////////////////////////////////////////////////////
186 186
187 // the 3 values are [length] [refcnt] [terminating zero data] 187 // the 3 values are [length] [refcnt] [terminating zero data]
188 const SkString::Rec SkString::gEmptyRec = { 0, 0, 0 }; 188 const SkString::Rec SkString::gEmptyRec = { 0, 0, 0 };
189 189
190 #define SizeOfRec() (gEmptyRec.data() - (const char*)&gEmptyRec) 190 #define SizeOfRec() (gEmptyRec.data() - (const char*)&gEmptyRec)
191 191
192 static uint32_t trim_size_t_to_u32(size_t value) {
193 if (sizeof(size_t) > sizeof(uint32_t)) {
bungeman-skia 2013/06/04 15:30:45 I just added SkTFitsIn<T> for exactly this kind of
194 if (value > SK_MaxU32) {
195 value = SK_MaxU32;
196 }
197 }
198 return (uint32_t)value;
199 }
200
201 static size_t check_add32(size_t base, size_t extra) {
202 SkASSERT(base <= SK_MaxU32);
203 if (sizeof(size_t) > sizeof(uint32_t)) {
204 if (base + extra > SK_MaxU32) {
205 extra = SK_MaxU32 - base;
206 }
207 }
208 return extra;
209 }
210
192 SkString::Rec* SkString::AllocRec(const char text[], size_t len) { 211 SkString::Rec* SkString::AllocRec(const char text[], size_t len) {
193 Rec* rec; 212 Rec* rec;
194 213
195 if (0 == len) { 214 if (0 == len) {
196 rec = const_cast<Rec*>(&gEmptyRec); 215 rec = const_cast<Rec*>(&gEmptyRec);
197 } else { 216 } else {
217 len = trim_size_t_to_u32(len);
218
198 // add 1 for terminating 0, then align4 so we can have some slop when gr owing the string 219 // add 1 for terminating 0, then align4 so we can have some slop when gr owing the string
199 rec = (Rec*)sk_malloc_throw(SizeOfRec() + SkAlign4(len + 1)); 220 rec = (Rec*)sk_malloc_throw(SizeOfRec() + SkAlign4(len + 1));
200 rec->fLength = len; 221 rec->fLength = SkToU32(len);
201 rec->fRefCnt = 1; 222 rec->fRefCnt = 1;
202 if (text) { 223 if (text) {
203 memcpy(rec->data(), text, len); 224 memcpy(rec->data(), text, len);
204 } 225 }
205 rec->data()[len] = 0; 226 rec->data()[len] = 0;
206 } 227 }
207 return rec; 228 return rec;
208 } 229 }
209 230
210 SkString::Rec* SkString::RefRec(Rec* src) { 231 SkString::Rec* SkString::RefRec(Rec* src) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 } 370 }
350 } 371 }
351 return fRec->data(); 372 return fRec->data();
352 } 373 }
353 374
354 void SkString::set(const char text[]) { 375 void SkString::set(const char text[]) {
355 this->set(text, text ? strlen(text) : 0); 376 this->set(text, text ? strlen(text) : 0);
356 } 377 }
357 378
358 void SkString::set(const char text[], size_t len) { 379 void SkString::set(const char text[], size_t len) {
380 len = trim_size_t_to_u32(len);
381
359 if (0 == len) { 382 if (0 == len) {
360 this->reset(); 383 this->reset();
361 } else if (1 == fRec->fRefCnt && len <= fRec->fLength) { 384 } else if (1 == fRec->fRefCnt && len <= fRec->fLength) {
362 // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLeng th>>1))? 385 // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLeng th>>1))?
363 // just use less of the buffer without allocating a smaller one 386 // just use less of the buffer without allocating a smaller one
364 char* p = this->writable_str(); 387 char* p = this->writable_str();
365 if (text) { 388 if (text) {
366 memcpy(p, text, len); 389 memcpy(p, text, len);
367 } 390 }
368 p[len] = 0; 391 p[len] = 0;
369 fRec->fLength = len; 392 fRec->fLength = SkToU32(len);
370 } else if (1 == fRec->fRefCnt && (fRec->fLength >> 2) == (len >> 2)) { 393 } else if (1 == fRec->fRefCnt && (fRec->fLength >> 2) == (len >> 2)) {
371 // we have spare room in the current allocation, so don't alloc a larger one 394 // we have spare room in the current allocation, so don't alloc a larger one
372 char* p = this->writable_str(); 395 char* p = this->writable_str();
373 if (text) { 396 if (text) {
374 memcpy(p, text, len); 397 memcpy(p, text, len);
375 } 398 }
376 p[len] = 0; 399 p[len] = 0;
377 fRec->fLength = len; 400 fRec->fLength = SkToU32(len);
378 } else { 401 } else {
379 SkString tmp(text, len); 402 SkString tmp(text, len);
380 this->swap(tmp); 403 this->swap(tmp);
381 } 404 }
382 } 405 }
383 406
384 void SkString::setUTF16(const uint16_t src[]) { 407 void SkString::setUTF16(const uint16_t src[]) {
385 int count = 0; 408 int count = 0;
386 409
387 while (src[count]) { 410 while (src[count]) {
388 count += 1; 411 count += 1;
389 } 412 }
390 setUTF16(src, count); 413 this->setUTF16(src, count);
391 } 414 }
392 415
393 void SkString::setUTF16(const uint16_t src[], size_t count) { 416 void SkString::setUTF16(const uint16_t src[], size_t count) {
417 count = trim_size_t_to_u32(count);
418
394 if (0 == count) { 419 if (0 == count) {
395 this->reset(); 420 this->reset();
396 } else if (count <= fRec->fLength) { 421 } else if (count <= fRec->fLength) {
397 // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLeng th>>1)) 422 // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLeng th>>1))
398 if (count < fRec->fLength) { 423 if (count < fRec->fLength) {
399 this->resize(count); 424 this->resize(count);
400 } 425 }
401 char* p = this->writable_str(); 426 char* p = this->writable_str();
402 for (size_t i = 0; i < count; i++) { 427 for (size_t i = 0; i < count; i++) {
403 p[i] = SkToU8(src[i]); 428 p[i] = SkToU8(src[i]);
(...skipping 13 matching lines...) Expand all
417 void SkString::insert(size_t offset, const char text[]) { 442 void SkString::insert(size_t offset, const char text[]) {
418 this->insert(offset, text, text ? strlen(text) : 0); 443 this->insert(offset, text, text ? strlen(text) : 0);
419 } 444 }
420 445
421 void SkString::insert(size_t offset, const char text[], size_t len) { 446 void SkString::insert(size_t offset, const char text[], size_t len) {
422 if (len) { 447 if (len) {
423 size_t length = fRec->fLength; 448 size_t length = fRec->fLength;
424 if (offset > length) { 449 if (offset > length) {
425 offset = length; 450 offset = length;
426 } 451 }
452
453 // Check if length + len exceeds 32bits, we trim len
454 len = check_add32(length, len);
455 if (0 == len) {
456 return;
457 }
427 458
428 /* If we're the only owner, and we have room in our allocation for the insert, 459 /* If we're the only owner, and we have room in our allocation for the insert,
429 do it in place, rather than allocating a new buffer. 460 do it in place, rather than allocating a new buffer.
430 461
431 To know we have room, compare the allocated sizes 462 To know we have room, compare the allocated sizes
432 beforeAlloc = SkAlign4(length + 1) 463 beforeAlloc = SkAlign4(length + 1)
433 afterAlloc = SkAligh4(length + 1 + len) 464 afterAlloc = SkAligh4(length + 1 + len)
434 but SkAlign4(x) is (x + 3) >> 2 << 2 465 but SkAlign4(x) is (x + 3) >> 2 << 2
435 which is equivalent for testing to (length + 1 + 3) >> 2 == (length + 1 + 3 + len) >> 2 466 which is equivalent for testing to (length + 1 + 3) >> 2 == (length + 1 + 3 + len) >> 2
436 and we can then eliminate the +1+3 since that doesn't affec the answ er 467 and we can then eliminate the +1+3 since that doesn't affec the answ er
437 */ 468 */
438 if (1 == fRec->fRefCnt && (length >> 2) == ((length + len) >> 2)) { 469 if (1 == fRec->fRefCnt && (length >> 2) == ((length + len) >> 2)) {
439 char* dst = this->writable_str(); 470 char* dst = this->writable_str();
440 471
441 if (offset < length) { 472 if (offset < length) {
442 memmove(dst + offset + len, dst + offset, length - offset); 473 memmove(dst + offset + len, dst + offset, length - offset);
443 } 474 }
444 memcpy(dst + offset, text, len); 475 memcpy(dst + offset, text, len);
445 476
446 dst[length + len] = 0; 477 dst[length + len] = 0;
447 fRec->fLength = length + len; 478 fRec->fLength = SkToU32(length + len);
448 } else { 479 } else {
449 /* Seems we should use realloc here, since that is safe if it fails 480 /* Seems we should use realloc here, since that is safe if it fails
450 (we have the original data), and might be faster than alloc/copy /free. 481 (we have the original data), and might be faster than alloc/copy /free.
451 */ 482 */
452 SkString tmp(fRec->fLength + len); 483 SkString tmp(fRec->fLength + len);
453 char* dst = tmp.writable_str(); 484 char* dst = tmp.writable_str();
454 485
455 if (offset > 0) { 486 if (offset > 0) {
456 memcpy(dst, fRec->data(), offset); 487 memcpy(dst, fRec->data(), offset);
457 } 488 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 SkString SkStringPrintf(const char* format, ...) { 641 SkString SkStringPrintf(const char* format, ...) {
611 SkString formattedOutput; 642 SkString formattedOutput;
612 char buffer[kBufferSize]; 643 char buffer[kBufferSize];
613 ARGS_TO_BUFFER(format, buffer, kBufferSize); 644 ARGS_TO_BUFFER(format, buffer, kBufferSize);
614 formattedOutput.set(buffer); 645 formattedOutput.set(buffer);
615 return formattedOutput; 646 return formattedOutput;
616 } 647 }
617 648
618 #undef VSNPRINTF 649 #undef VSNPRINTF
619 #undef SNPRINTF 650 #undef SNPRINTF
OLDNEW
« no previous file with comments | « include/core/SkString.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698