1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla.
17 : *
18 : * The Initial Developer of the Original Code is IBM Corporation.
19 : * Portions created by IBM Corporation are Copyright (C) 2003
20 : * IBM Corporation. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Scott Collins <scc@mozilla.org> (original author)
24 : * Darin Fisher <darin@meer.net>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 :
41 : /**
42 : * NOTE:
43 : *
44 : * Try to avoid flat strings. |PromiseFlat[C]String| will help you as a last
45 : * resort, and this may be necessary when dealing with legacy or OS calls,
46 : * but in general, requiring a null-terminated array of characters kills many
47 : * of the performance wins the string classes offer. Write your own code to
48 : * use |nsA[C]String&|s for parameters. Write your string proccessing
49 : * algorithms to exploit iterators. If you do this, you will benefit from
50 : * being able to chain operations without copying or allocating and your code
51 : * will be significantly more efficient. Remember, a function that takes an
52 : * |const nsA[C]String&| can always be passed a raw character pointer by
53 : * wrapping it (for free) in a |nsDependent[C]String|. But a function that
54 : * takes a character pointer always has the potential to force allocation and
55 : * copying.
56 : *
57 : *
58 : * How to use it:
59 : *
60 : * A |nsPromiseFlat[C]String| doesn't necessarily own the characters it
61 : * promises. You must never use it to promise characters out of a string
62 : * with a shorter lifespan. The typical use will be something like this:
63 : *
64 : * SomeOSFunction( PromiseFlatCString(aCString).get() ); // GOOD
65 : *
66 : * Here's a BAD use:
67 : *
68 : * const char* buffer = PromiseFlatCString(aCString).get();
69 : * SomeOSFunction(buffer); // BAD!! |buffer| is a dangling pointer
70 : *
71 : * The only way to make one is with the function |PromiseFlat[C]String|,
72 : * which produce a |const| instance. ``What if I need to keep a promise
73 : * around for a little while?'' you might ask. In that case, you can keep a
74 : * reference, like so
75 : *
76 : * const nsPromiseFlatString& flat = PromiseFlatString(aString);
77 : * // this reference holds the anonymous temporary alive, but remember,
78 : * // it must _still_ have a lifetime shorter than that of |aString|
79 : *
80 : * SomeOSFunction(flat.get());
81 : * SomeOtherOSFunction(flat.get());
82 : *
83 : *
84 : * How does it work?
85 : *
86 : * A |nsPromiseFlat[C]String| is just a wrapper for another string. If you
87 : * apply it to a string that happens to be flat, your promise is just a
88 : * dependent reference to the string's data. If you apply it to a non-flat
89 : * string, then a temporary flat string is created for you, by allocating and
90 : * copying. In the event that you end up assigning the result into a sharing
91 : * string (e.g., |nsTString|), the right thing happens.
92 : */
93 :
94 : class nsTPromiseFlatString_CharT : public nsTString_CharT
95 2039739 : {
96 : public:
97 :
98 : typedef nsTPromiseFlatString_CharT self_type;
99 :
100 : private:
101 :
102 : void Init( const substring_type& );
103 :
104 : // NOT TO BE IMPLEMENTED
105 : void operator=( const self_type& );
106 :
107 : // NOT TO BE IMPLEMENTED
108 : nsTPromiseFlatString_CharT();
109 :
110 : public:
111 :
112 : explicit
113 2024189 : nsTPromiseFlatString_CharT( const substring_type& str )
114 2024189 : : string_type()
115 : {
116 2024189 : Init(str);
117 2024189 : }
118 :
119 : explicit
120 15550 : nsTPromiseFlatString_CharT( const substring_tuple_type& tuple )
121 15550 : : string_type()
122 : {
123 : // nothing else to do here except assign the value of the tuple
124 : // into ourselves.
125 15550 : Assign(tuple);
126 15550 : }
127 : };
128 :
129 : // e.g., PromiseFlatCString(Substring(s))
130 : inline
131 : const nsTPromiseFlatString_CharT
132 2021579 : TPromiseFlatString_CharT( const nsTSubstring_CharT& frag )
133 : {
134 2021579 : return nsTPromiseFlatString_CharT(frag);
135 : }
136 :
137 : // e.g., PromiseFlatCString(a + b)
138 : inline
139 : const nsTPromiseFlatString_CharT
140 15550 : TPromiseFlatString_CharT( const nsTSubstringTuple_CharT& tuple )
141 : {
142 15550 : return nsTPromiseFlatString_CharT(tuple);
143 : }
|