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

Side by Side Diff: base/string_util.h

Issue 8418034: Make string_util::WriteInto() DCHECK() that the supplied |length_with_null| > 1, meaning that the... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // This file defines utility functions for working with strings. 5 // This file defines utility functions for working with strings.
6 6
7 #ifndef BASE_STRING_UTIL_H_ 7 #ifndef BASE_STRING_UTIL_H_
8 #define BASE_STRING_UTIL_H_ 8 #define BASE_STRING_UTIL_H_
9 #pragma once 9 #pragma once
10 10
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 string16* str, 436 string16* str,
437 string16::size_type start_offset, 437 string16::size_type start_offset,
438 const string16& find_this, 438 const string16& find_this,
439 const string16& replace_with); 439 const string16& replace_with);
440 BASE_EXPORT void ReplaceSubstringsAfterOffset( 440 BASE_EXPORT void ReplaceSubstringsAfterOffset(
441 std::string* str, 441 std::string* str,
442 std::string::size_type start_offset, 442 std::string::size_type start_offset,
443 const std::string& find_this, 443 const std::string& find_this,
444 const std::string& replace_with); 444 const std::string& replace_with);
445 445
446 // Reserves enough memory in |str| to accommodate |length_with_null| 446 // Reserves enough memory in |str| to accommodate |length_with_null| characters,
447 // characters, sets the size of |str| to |length_with_null - 1| characters, 447 // sets the size of |str| to |length_with_null - 1| characters, and returns a
448 // and returns a pointer to the underlying contiguous array of characters. 448 // pointer to the underlying contiguous array of characters. This is typically
449 // used when calling a function that writes results into a character array, but
450 // the caller wants the data to be managed by a string-like object. It is
451 // convenient in that is can be used inline in the call, and fast in that it
cbentzel 2011/11/01 12:15:07 I'm not sure about the fast comment. With WriteIn
Peter Kasting 2011/11/01 19:43:28 Mostly I was trying to restore some of the detail
452 // avoids copying the results of the call from a char* into a string.
449 // 453 //
450 // This is typically used when calling a function that writes results into a 454 // |length_with_null| must be at least 2, since otherwise the underlying string
451 // character array, but the caller wants the data to be managed by a 455 // would have size 0, and trying to access &((*str)[0]) in that case can result
452 // string-like object. 456 // in a number of problems.
453 // 457 //
454 // |length_with_null| must be >= 1. In the |length_with_null| == 1 case, 458 // Internally, this takes linear time because the resize() call 0-fills the
455 // NULL is returned rather than a pointer to the array, since there is no way 459 // underlying array for potentially all
456 // to provide access to the underlying character array of a 0-length 460 // (|length_with_null - 1| * sizeof(string_type::value_type)) bytes. Ideally we
457 // string-like object without breaking guarantees provided by the C++ 461 // could avoid this aspect of the resize() call, as we expect the caller to
458 // standards. 462 // immediately write over this memory, but there is no other way to set the size
459 // 463 // of the string, and not doing that will mean people who access |str| rather
460 // Internally, this takes linear time because the underlying array needs to 464 // than str.c_str() will get back a string of whatever size |str| had on entry
461 // be 0-filled for all |length_with_null - 1| * sizeof(character) bytes. 465 // to this function (probably 0).
462 template <class string_type> 466 template <class string_type>
463 inline typename string_type::value_type* WriteInto(string_type* str, 467 inline typename string_type::value_type* WriteInto(string_type* str,
464 size_t length_with_null) { 468 size_t length_with_null) {
joth 2011/11/01 11:25:32 completely orthogonal issue to the one you're tack
Peter Kasting 2011/11/01 19:43:28 But the size of the string after the call and the
465 DCHECK_NE(0u, length_with_null); 469 DCHECK_GT(length_with_null, 1u);
466 str->reserve(length_with_null); 470 str->reserve(length_with_null);
467 str->resize(length_with_null - 1); 471 str->resize(length_with_null - 1);
468
469 // If |length_with_null| is 1, calling (*str)[0] is invalid since the
470 // size() is 0. In some implementations this triggers an assertion.
471 //
472 // Trying to access the underlying byte array by casting away const
473 // when calling str->data() or str->c_str() is also incorrect.
474 // Some implementations of basic_string use a copy-on-write approach and
475 // this could end up mutating the data that is shared across multiple string
476 // objects.
477 if (length_with_null <= 1)
478 return NULL;
joth 2011/11/01 11:25:32 Worth noting there are a couple drawbacks in remov
Peter Kasting 2011/11/01 19:43:28 And that would violate our "do not handle assertio
479
480 return &((*str)[0]); 472 return &((*str)[0]);
joth 2011/11/01 11:25:32 Maybe while you're here, the standards-approved wa
Peter Kasting 2011/11/01 19:43:28 I see the standard using this as an example of an
481 } 473 }
482 474
483 //----------------------------------------------------------------------------- 475 //-----------------------------------------------------------------------------
484 476
485 // Splits a string into its fields delimited by any of the characters in 477 // Splits a string into its fields delimited by any of the characters in
486 // |delimiters|. Each field is added to the |tokens| vector. Returns the 478 // |delimiters|. Each field is added to the |tokens| vector. Returns the
487 // number of tokens found. 479 // number of tokens found.
488 BASE_EXPORT size_t Tokenize(const std::wstring& str, 480 BASE_EXPORT size_t Tokenize(const std::wstring& str,
489 const std::wstring& delimiters, 481 const std::wstring& delimiters,
490 std::vector<std::wstring>* tokens); 482 std::vector<std::wstring>* tokens);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 #elif defined(WCHAR_T_IS_UTF32) 546 #elif defined(WCHAR_T_IS_UTF32)
555 typedef uint32 Unsigned; 547 typedef uint32 Unsigned;
556 #endif 548 #endif
557 }; 549 };
558 template<> 550 template<>
559 struct ToUnsigned<short> { 551 struct ToUnsigned<short> {
560 typedef unsigned short Unsigned; 552 typedef unsigned short Unsigned;
561 }; 553 };
562 554
563 #endif // BASE_STRING_UTIL_H_ 555 #endif // BASE_STRING_UTIL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698