1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/string/public/nsTPromiseFlatString.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,106 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 + 1.11 + /** 1.12 + * NOTE: 1.13 + * 1.14 + * Try to avoid flat strings. |PromiseFlat[C]String| will help you as a last 1.15 + * resort, and this may be necessary when dealing with legacy or OS calls, 1.16 + * but in general, requiring a null-terminated array of characters kills many 1.17 + * of the performance wins the string classes offer. Write your own code to 1.18 + * use |nsA[C]String&|s for parameters. Write your string proccessing 1.19 + * algorithms to exploit iterators. If you do this, you will benefit from 1.20 + * being able to chain operations without copying or allocating and your code 1.21 + * will be significantly more efficient. Remember, a function that takes an 1.22 + * |const nsA[C]String&| can always be passed a raw character pointer by 1.23 + * wrapping it (for free) in a |nsDependent[C]String|. But a function that 1.24 + * takes a character pointer always has the potential to force allocation and 1.25 + * copying. 1.26 + * 1.27 + * 1.28 + * How to use it: 1.29 + * 1.30 + * A |nsPromiseFlat[C]String| doesn't necessarily own the characters it 1.31 + * promises. You must never use it to promise characters out of a string 1.32 + * with a shorter lifespan. The typical use will be something like this: 1.33 + * 1.34 + * SomeOSFunction( PromiseFlatCString(aCSubstring).get() ); // GOOD 1.35 + * 1.36 + * Here's a BAD use: 1.37 + * 1.38 + * const char* buffer = PromiseFlatCString(aCSubstring).get(); 1.39 + * SomeOSFunction(buffer); // BAD!! |buffer| is a dangling pointer 1.40 + * 1.41 + * The only way to make one is with the function |PromiseFlat[C]String|, 1.42 + * which produce a |const| instance. ``What if I need to keep a promise 1.43 + * around for a little while?'' you might ask. In that case, you can keep a 1.44 + * reference, like so 1.45 + * 1.46 + * const nsCString& flat = PromiseFlatString(aCSubstring); 1.47 + * // this reference holds the anonymous temporary alive, but remember, 1.48 + * // it must _still_ have a lifetime shorter than that of |aCSubstring| 1.49 + * 1.50 + * SomeOSFunction(flat.get()); 1.51 + * SomeOtherOSFunction(flat.get()); 1.52 + * 1.53 + * 1.54 + * How does it work? 1.55 + * 1.56 + * A |nsPromiseFlat[C]String| is just a wrapper for another string. If you 1.57 + * apply it to a string that happens to be flat, your promise is just a 1.58 + * dependent reference to the string's data. If you apply it to a non-flat 1.59 + * string, then a temporary flat string is created for you, by allocating and 1.60 + * copying. In the event that you end up assigning the result into a sharing 1.61 + * string (e.g., |nsTString|), the right thing happens. 1.62 + */ 1.63 + 1.64 +class nsTPromiseFlatString_CharT : public nsTString_CharT 1.65 + { 1.66 + public: 1.67 + 1.68 + typedef nsTPromiseFlatString_CharT self_type; 1.69 + 1.70 + private: 1.71 + 1.72 + void Init( const substring_type& ); 1.73 + 1.74 + // NOT TO BE IMPLEMENTED 1.75 + void operator=( const self_type& ) MOZ_DELETE; 1.76 + 1.77 + // NOT TO BE IMPLEMENTED 1.78 + nsTPromiseFlatString_CharT() MOZ_DELETE; 1.79 + 1.80 + // NOT TO BE IMPLEMENTED 1.81 + nsTPromiseFlatString_CharT( const string_type& str ) MOZ_DELETE; 1.82 + 1.83 + public: 1.84 + 1.85 + explicit 1.86 + nsTPromiseFlatString_CharT( const substring_type& str ) 1.87 + : string_type() 1.88 + { 1.89 + Init(str); 1.90 + } 1.91 + 1.92 + explicit 1.93 + nsTPromiseFlatString_CharT( const substring_tuple_type& tuple ) 1.94 + : string_type() 1.95 + { 1.96 + // nothing else to do here except assign the value of the tuple 1.97 + // into ourselves. 1.98 + Assign(tuple); 1.99 + } 1.100 + }; 1.101 + 1.102 +// We template this so that the constructor is chosen based on the type of the 1.103 +// parameter. This allows us to reject attempts to promise a flat flat string. 1.104 +template<class T> 1.105 +const nsTPromiseFlatString_CharT 1.106 +TPromiseFlatString_CharT( const T& string ) 1.107 + { 1.108 + return nsTPromiseFlatString_CharT(string); 1.109 + }