1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file.
4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifndef CORE_INCLUDE_FXCRT_FX_STRING_H_
8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define CORE_INCLUDE_FXCRT_FX_STRING_H_
9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <stdint.h>  // For intptr_t.
11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <algorithm>
12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "fx_memory.h"
14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "fx_system.h"
15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CFX_BinaryBuf;
17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CFX_ByteString;
18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CFX_WideString;
19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovstruct CFX_CharMap;
20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// An immutable string with caller-provided storage which must outlive the
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// string itself.
23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CFX_ByteStringC
24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic:
26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    typedef FX_CHAR value_type;
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC()
29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = NULL;
31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = 0;
32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC(FX_LPCBYTE ptr, FX_STRSIZE size)
35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = ptr;
37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = size;
38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC(FX_LPCSTR ptr)
41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = (FX_LPCBYTE)ptr;
43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = ptr ? FXSYS_strlen(ptr) : 0;
44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // |ch| must be an lvalue that outlives the the CFX_ByteStringC. However,
47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // the use of char rvalues are not caught at compile time.  They are
48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // implicitly promoted to CFX_ByteString (see below) and then the
49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // CFX_ByteStringC is constructed from the CFX_ByteString via the alternate
50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // constructor below. The CFX_ByteString then typically goes out of scope
51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // and |m_Ptr| may be left pointing to invalid memory. Beware.
52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // TODO(tsepez): Mark single-argument string constructors as explicit.
53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC(FX_CHAR& ch)
54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = (FX_LPCBYTE)&ch;
56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = 1;
57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC(FX_LPCSTR ptr, FX_STRSIZE len)
60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = (FX_LPCBYTE)ptr;
62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = (len == -1) ? FXSYS_strlen(ptr) : len;
63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC(const CFX_ByteStringC& src)
66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = src.m_Ptr;
68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = src.m_Length;
69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC(const CFX_ByteString& src);
72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC& operator = (FX_LPCSTR src)
74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = (FX_LPCBYTE)src;
76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = m_Ptr ? FXSYS_strlen(src) : 0;
77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return *this;
78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC& operator = (const CFX_ByteStringC& src)
81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = src.m_Ptr;
83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = src.m_Length;
84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return *this;
85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC& operator = (const CFX_ByteString& src);
88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const char* ptr) const {
90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FXSYS_strlen(ptr) == m_Length &&
91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FXSYS_memcmp32(ptr, m_Ptr, m_Length) == 0;
92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const CFX_ByteStringC& other) const {
94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return other.m_Length == m_Length &&
95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                FXSYS_memcmp32(other.m_Ptr, m_Ptr, m_Length) == 0;
96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const char* ptr) const { return !(*this == ptr); }
98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const CFX_ByteStringC& other) const {
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !(*this == other);
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_DWORD		GetID(FX_STRSIZE start_pos = 0) const;
103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPCBYTE		GetPtr() const
105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Ptr;
107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPCSTR		GetCStr() const
110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return (FX_LPCSTR)m_Ptr;
112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE		GetLength() const
115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Length;
117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool			IsEmpty() const
120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Length == 0;
122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_BYTE			GetAt(FX_STRSIZE index) const
125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Ptr[index];
127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteStringC	Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const
130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (index < 0) {
132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            index = 0;
133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (index > m_Length) {
135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return CFX_ByteStringC();
136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (count < 0 || count > m_Length - index) {
138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            count = m_Length - index;
139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CFX_ByteStringC(m_Ptr + index, count);
141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const FX_BYTE& operator[] (size_t index) const
144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Ptr[index];
146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator< (const CFX_ByteStringC& that) const
149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        int result = memcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length));
151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return result < 0 || (result == 0 && m_Length < that.m_Length);
152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprotected:
155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPCBYTE		m_Ptr;
156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE		m_Length;
157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprivate:
159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void*			operator new (size_t) throw()
160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return NULL;
162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov};
164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator== (const char* lhs, const CFX_ByteStringC& rhs) {
165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs == lhs;
166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator!= (const char* lhs, const CFX_ByteStringC& rhs) {
168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs != lhs;
169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtypedef const CFX_ByteStringC& FX_BSTR;
171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FX_BSTRC(str) CFX_ByteStringC(str, sizeof str-1)
172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FXBSTR_ID(c1, c2, c3, c4) ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4))
173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// A mutable string with shared buffers using copy-on-write semantics that
175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// avoids the cost of std::string's iterator stability guarantees.
176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CFX_ByteString
177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic:
179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    typedef FX_CHAR value_type;
180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString()
182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_pData = NULL;
184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString(const CFX_ByteString& str);
187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString(char ch);
189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString(FX_LPCSTR ptr)
191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            : CFX_ByteString(ptr, ptr ? FXSYS_strlen(ptr) : 0) { }
192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString(FX_LPCSTR ptr, FX_STRSIZE len);
194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString(FX_LPCBYTE ptr, FX_STRSIZE len);
196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString(FX_BSTR bstrc);
198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString(FX_BSTR bstrc1, FX_BSTR bstrc2);
199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    ~CFX_ByteString();
201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static CFX_ByteString	FromUnicode(FX_LPCWSTR ptr, FX_STRSIZE len = -1);
203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static CFX_ByteString	FromUnicode(const CFX_WideString& str);
205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // Explicit conversion to raw string
207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPCSTR c_str() const
208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String : "";
210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // Implicit conversion to C-style string -- deprecated
213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    operator				FX_LPCSTR() const
214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String : "";
216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    operator				FX_LPCBYTE() const
219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? (FX_LPCBYTE)m_pData->m_String : NULL;
221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				GetLength() const
224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_nDataLength : 0;
226e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
227e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
228e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool					IsEmpty() const
229e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
230e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !GetLength();
231e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
232e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
233e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    int						Compare(FX_BSTR str) const;
234e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
235e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
236e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool Equal(const char* ptr) const;
237e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool Equal(const CFX_ByteStringC& str) const;
238e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool Equal(const CFX_ByteString& other) const;
239e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
240e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool EqualNoCase(FX_BSTR str) const;
241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const char* ptr) const { return Equal(ptr); }
243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const CFX_ByteStringC& str) const { return Equal(str); }
244e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const CFX_ByteString& other) const { return Equal(other); }
245e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
246e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const char* ptr) const { return !(*this == ptr); }
247e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const CFX_ByteStringC& str) const {
248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !(*this == str);
249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const CFX_ByteString& other) const {
251e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !(*this == other);
252e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
253e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator< (const CFX_ByteString& str) const
255e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
256e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        int result = FXSYS_memcmp32(c_str(), str.c_str(), std::min(GetLength(), str.GetLength()));
257e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return result < 0 || (result == 0 && GetLength() < str.GetLength());
258e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
259e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					Empty();
261e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator = (FX_LPCSTR str);
263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator = (FX_BSTR bstrc);
265e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
266e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator = (const CFX_ByteString& stringSrc);
267e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
268e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator = (const CFX_BinaryBuf& buf);
269e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					Load(FX_LPCBYTE str, FX_STRSIZE len);
271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator += (FX_CHAR ch);
273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator += (FX_LPCSTR str);
275e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator += (const CFX_ByteString& str);
277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
278e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_ByteString&	operator += (FX_BSTR bstrc);
279e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
280e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_BYTE					GetAt(FX_STRSIZE nIndex) const
281e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
282e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String[nIndex] : 0;
283e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
284e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
285e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_BYTE					operator[](FX_STRSIZE nIndex) const
286e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
287e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String[nIndex] : 0;
288e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
289e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
290e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					SetAt(FX_STRSIZE nIndex, FX_CHAR ch);
291e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
292e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Insert(FX_STRSIZE index, FX_CHAR ch);
293e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
294e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
295e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					Format(FX_LPCSTR lpszFormat, ... );
298e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					FormatV(FX_LPCSTR lpszFormat, va_list argList);
300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
301e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					Reserve(FX_STRSIZE len);
303e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
304e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPSTR				GetBuffer(FX_STRSIZE len);
305e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
306e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					ReleaseBuffer(FX_STRSIZE len = -1);
307e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
308e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString			Mid(FX_STRSIZE first) const;
309e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
310e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString			Mid(FX_STRSIZE first, FX_STRSIZE count) const;
311e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
312e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString			Left(FX_STRSIZE count) const;
313e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
314e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString			Right(FX_STRSIZE count) const;
315e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
316e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Find(FX_BSTR lpszSub, FX_STRSIZE start = 0) const;
317e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
318e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Find(FX_CHAR ch, FX_STRSIZE start = 0) const;
319e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
320e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				ReverseFind(FX_CHAR ch) const;
321e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
322e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					MakeLower();
323e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
324e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					MakeUpper();
325e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
326e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimRight();
327e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
328e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimRight(FX_CHAR chTarget);
329e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
330e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimRight(FX_BSTR lpszTargets);
331e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
332e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimLeft();
333e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
334e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimLeft(FX_CHAR chTarget);
335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimLeft(FX_BSTR lpszTargets);
337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Replace(FX_BSTR lpszOld, FX_BSTR lpszNew);
339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
340e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Remove(FX_CHAR ch);
341e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
342e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString			UTF8Decode() const;
343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					ConvertFrom(const CFX_WideString& str, CFX_CharMap* pCharMap = NULL);
345e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_DWORD				GetID(FX_STRSIZE start_pos = 0) const;
347e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
348e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FXFORMAT_SIGNED			1
349e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FXFORMAT_HEX			2
350e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FXFORMAT_CAPITAL		4
351e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static CFX_ByteString	FormatInteger(int i, FX_DWORD flags = 0);
353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static CFX_ByteString	FormatFloat(FX_FLOAT f, int precision = 0);
354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
355e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprotected:
356e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // To ensure ref counts do not overflow, consider the worst possible case:
357e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // the entire address space contains nothing but pointers to this object.
358e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // Since the count increments with each new pointer, the largest value is
359e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // the number of pointers that can fit into the address space. The size of
360e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // the address space itself is a good upper bound on it; we need not go
361e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // larger.
362e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    class StringData {
363e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      public:
364e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        static StringData* Create(int nLen);
365e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        void Retain() { ++m_nRefs; }
366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        void Release() { if (--m_nRefs <= 0) FX_Free(this); }
367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        intptr_t    m_nRefs;  // Would prefer ssize_t, but no windows support.
369e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_STRSIZE  m_nDataLength;
370e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_STRSIZE  m_nAllocLength;
371e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_CHAR     m_String[1];
372e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
373e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      private:
374e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen)
375e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) {
376e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            FXSYS_assert(dataLen >= 0);
377e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            FXSYS_assert(allocLen >= 0);
378e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            FXSYS_assert(dataLen <= allocLen);
379e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            m_String[dataLen] = 0;
380e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
381e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        ~StringData() = delete;
382e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    };
383e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
384e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					AllocCopy(CFX_ByteString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const;
385e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					AssignCopy(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData);
386e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCSTR lpszSrc2Data);
387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData);
388e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					CopyBeforeWrite();
389e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					AllocBeforeWrite(FX_STRSIZE nLen);
390e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
391e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    StringData* m_pData;
392e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    friend class fxcrt_ByteStringConcatInPlace_Test;
393e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov};
394e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteStringC::CFX_ByteStringC(const CFX_ByteString& src)
395e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
396e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Ptr = (FX_LPCBYTE)src;
397e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Length = src.GetLength();
398e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
399e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteStringC& CFX_ByteStringC::operator = (const CFX_ByteString& src)
400e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
401e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Ptr = (FX_LPCBYTE)src;
402e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Length = src.GetLength();
403e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return *this;
404e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
405e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
406e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator== (const char* lhs, const CFX_ByteString& rhs) {
407e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs == lhs;
408e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
409e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator== (const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) {
410e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs == lhs;
411e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
412e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator!= (const char* lhs, const CFX_ByteString& rhs) {
413e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs != lhs;
414e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
415e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator!= (const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) {
416e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs != lhs;
417e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
418e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
419e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_BSTR str1, FX_BSTR str2)
420e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
421e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
422e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
423e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_BSTR str1, FX_LPCSTR str2)
424e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
425e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
426e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
427e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_LPCSTR str1, FX_BSTR str2)
428e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
429e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
430e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
431e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_BSTR str1, FX_CHAR ch)
432e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
433e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, CFX_ByteStringC(ch));
434e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
435e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_CHAR ch, FX_BSTR str2)
436e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
437e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(ch, str2);
438e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
439e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (const CFX_ByteString& str1, const CFX_ByteString& str2)
440e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
441e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
442e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
443e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (const CFX_ByteString& str1, FX_CHAR ch)
444e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
445e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, CFX_ByteStringC(ch));
446e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
447e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_CHAR ch, const CFX_ByteString& str2)
448e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
449e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(ch, str2);
450e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
451e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (const CFX_ByteString& str1, FX_LPCSTR str2)
452e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
453e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
454e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
455e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_LPCSTR str1, const CFX_ByteString& str2)
456e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
457e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
458e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
459e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (const CFX_ByteString& str1, FX_BSTR str2)
460e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
461e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
462e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
463e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString operator + (FX_BSTR str1, const CFX_ByteString& str2)
464e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
465e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_ByteString(str1, str2);
466e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
467e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CFX_WideStringC
468e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
469e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic:
470e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    typedef FX_WCHAR value_type;
471e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
472e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC()
473e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
474e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = NULL;
475e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = 0;
476e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
477e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
478e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC(FX_LPCWSTR ptr)
479e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
480e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = ptr;
481e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = ptr ? FXSYS_wcslen(ptr) : 0;
482e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
483e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
484e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC(FX_WCHAR& ch)
485e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
486e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = &ch;
487e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = 1;
488e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
489e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
490e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC(FX_LPCWSTR ptr, FX_STRSIZE len)
491e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
492e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = ptr;
493e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = (len == -1) ? FXSYS_wcslen(ptr) : len;
494e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
495e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
496e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC(const CFX_WideStringC& src)
497e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
498e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = src.m_Ptr;
499e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = src.m_Length;
500e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
501e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
502e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC(const CFX_WideString& src);
503e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
504e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC& operator = (FX_LPCWSTR src)
505e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
506e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = src;
507e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = FXSYS_wcslen(src);
508e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return *this;
509e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
510e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
511e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC& operator = (const CFX_WideStringC& src)
512e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
513e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Ptr = src.m_Ptr;
514e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_Length = src.m_Length;
515e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return *this;
516e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
517e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
518e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC& operator = (const CFX_WideString& src);
519e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
520e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const wchar_t* ptr) const  {
521e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return FXSYS_wcslen(ptr) == m_Length &&
522e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            wmemcmp(ptr, m_Ptr, m_Length) == 0;
523e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
524e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const CFX_WideStringC& str) const  {
525e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return str.m_Length == m_Length &&
526e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            wmemcmp(str.m_Ptr, m_Ptr, m_Length) == 0;
527e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
528e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const wchar_t* ptr) const { return !(*this == ptr); }
529e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const CFX_WideStringC& str) const {
530e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !(*this == str);
531e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
532e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
533e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPCWSTR		GetPtr() const
534e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
535e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Ptr;
536e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
537e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
538e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE		GetLength() const
539e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
540e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Length;
541e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
542e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
543e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool			IsEmpty() const
544e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
545e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Length == 0;
546e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
547e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
548e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_WCHAR		GetAt(FX_STRSIZE index) const
549e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
550e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Ptr[index];
551e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
552e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
553e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC	Left(FX_STRSIZE count) const
554e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
555e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (count < 1) {
556e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return CFX_WideStringC();
557e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
558e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (count > m_Length) {
559e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            count = m_Length;
560e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
561e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CFX_WideStringC(m_Ptr, count);
562e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
563e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
564e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC	Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const
565e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
566e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (index < 0) {
567e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            index = 0;
568e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
569e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (index > m_Length) {
570e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return CFX_WideStringC();
571e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
572e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (count < 0 || count > m_Length - index) {
573e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            count = m_Length - index;
574e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
575e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CFX_WideStringC(m_Ptr + index, count);
576e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
577e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
578e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideStringC	Right(FX_STRSIZE count) const
579e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
580e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (count < 1) {
581e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            return CFX_WideStringC();
582e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
583e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if (count > m_Length) {
584e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            count = m_Length;
585e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
586e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return CFX_WideStringC(m_Ptr + m_Length - count, count);
587e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
588e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
589e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const FX_WCHAR& operator[] (size_t index) const
590e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
591e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_Ptr[index];
592e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
593e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
594e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator< (const CFX_WideStringC& that) const
595e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
596e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        int result = wmemcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length));
597e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return result < 0 || (result == 0 && m_Length < that.m_Length);
598e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov     }
599e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
600e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprotected:
601e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPCWSTR		m_Ptr;
602e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE		m_Length;
603e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
604e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprivate:
605e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void*			operator new (size_t) throw()
606e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
607e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return NULL;
608e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
609e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov};
610e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator== (const wchar_t* lhs, const CFX_WideStringC& rhs) {
611e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs == lhs;
612e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
613e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator!= (const wchar_t* lhs, const CFX_WideStringC& rhs) {
614e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs != lhs;
615e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
616e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtypedef const CFX_WideStringC&	FX_WSTR;
617e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1)
618e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
619e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// A mutable string with shared buffers using copy-on-write semantics that
620e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// avoids the cost of std::string's iterator stability guarantees.
621e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovclass CFX_WideString
622e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
623e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovpublic:
624e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    typedef FX_WCHAR value_type;
625e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
626e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString()
627e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
628e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        m_pData = NULL;
629e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
630e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
631e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString(const CFX_WideString& str);
632e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
633e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString(FX_LPCWSTR ptr)
634e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            : CFX_WideString(ptr, ptr ? FXSYS_wcslen(ptr) : 0) { }
635e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
636e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString(FX_LPCWSTR ptr, FX_STRSIZE len);
637e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
638e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString(FX_WCHAR ch);
639e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
640e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString(const CFX_WideStringC& str);
641e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
642e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString(const CFX_WideStringC& str1, const CFX_WideStringC& str2);
643e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
644e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    ~CFX_WideString();
645e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
646e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static CFX_WideString	FromLocal(const char* str, FX_STRSIZE len = -1);
647e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
648e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static CFX_WideString	FromUTF8(const char* str, FX_STRSIZE len);
649e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
650e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static CFX_WideString	FromUTF16LE(const unsigned short* str, FX_STRSIZE len);
651e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
652e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    static FX_STRSIZE       WStringLength(const unsigned short* str);
653e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
654e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // Explicit conversion to raw string
655e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPCWSTR c_str() const
656e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
657e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String : L"";
658e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
659e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
660e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    // Implicit conversion to C-style wide string -- deprecated
661e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    operator FX_LPCWSTR() const
662e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
663e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String : L"";
664e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
665e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
666e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					Empty();
667e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
668e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
669e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_BOOL					IsEmpty() const
670e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
671e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !GetLength();
672e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
673e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
674e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				GetLength() const
675e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
676e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_nDataLength : 0;
677e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
678e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
679e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_WideString&	operator = (FX_LPCWSTR str);
680e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
681e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_WideString&	operator =(const CFX_WideString& stringSrc);
682e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
683e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_WideString&	operator =(const CFX_WideStringC& stringSrc);
684e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
685e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_WideString&	operator += (FX_LPCWSTR str);
686e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
687e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_WideString&	operator += (FX_WCHAR ch);
688e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
689e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_WideString&	operator += (const CFX_WideString& str);
690e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
691e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    const CFX_WideString&	operator += (const CFX_WideStringC& str);
692e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
693e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const wchar_t* ptr) const { return Equal(ptr); }
694e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const CFX_WideStringC& str) const { return Equal(str); }
695e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator== (const CFX_WideString& other) const { return Equal(other); }
696e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
697e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const wchar_t* ptr) const { return !(*this == ptr); }
698e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const CFX_WideStringC& str) const {
699e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !(*this == str);
700e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
701e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator!= (const CFX_WideString& other) const {
702e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return !(*this == other);
703e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
704e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
705e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool operator< (const CFX_WideString& str) const {
706e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        int result = wmemcmp(c_str(), str.c_str(), std::min(GetLength(), str.GetLength()));
707e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return result < 0 || (result == 0 && GetLength() < str.GetLength());
708e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
709e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
710e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_WCHAR				GetAt(FX_STRSIZE nIndex) const
711e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
712e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String[nIndex] : 0;
713e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
714e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
715e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_WCHAR				operator[](FX_STRSIZE nIndex) const
716e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    {
717e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        return m_pData ? m_pData->m_String[nIndex] : 0;
718e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    }
719e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
720e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					SetAt(FX_STRSIZE nIndex, FX_WCHAR ch);
721e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
722e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    int						Compare(FX_LPCWSTR str) const;
723e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
724e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    int						Compare(const CFX_WideString& str) const;
725e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
726e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    int						CompareNoCase(FX_LPCWSTR str) const;
727e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
728e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool Equal(const wchar_t* ptr) const;
729e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool Equal(const CFX_WideStringC& str) const;
730e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    bool Equal(const CFX_WideString& other) const;
731e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
732e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString			Mid(FX_STRSIZE first) const;
733e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
734e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString			Mid(FX_STRSIZE first, FX_STRSIZE count) const;
735e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
736e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString			Left(FX_STRSIZE count) const;
737e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
738e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_WideString			Right(FX_STRSIZE count) const;
739e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
740e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Insert(FX_STRSIZE index, FX_WCHAR ch);
741e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
742e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
743e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
744e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					Format(FX_LPCWSTR lpszFormat, ... );
745e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
746e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					FormatV(FX_LPCWSTR lpszFormat, va_list argList);
747e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
748e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					MakeLower();
749e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
750e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					MakeUpper();
751e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
752e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimRight();
753e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
754e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimRight(FX_WCHAR chTarget);
755e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
756e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimRight(FX_LPCWSTR lpszTargets);
757e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
758e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimLeft();
759e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
760e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimLeft(FX_WCHAR chTarget);
761e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
762e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					TrimLeft(FX_LPCWSTR lpszTargets);
763e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
764e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					Reserve(FX_STRSIZE len);
765e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
766e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_LPWSTR				GetBuffer(FX_STRSIZE len);
767e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
768e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					ReleaseBuffer(FX_STRSIZE len = -1);
769e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
770e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    int						GetInteger() const;
771e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
772e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_FLOAT				GetFloat() const;
773e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
774e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Find(FX_LPCWSTR lpszSub, FX_STRSIZE start = 0) const;
775e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
776e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Find(FX_WCHAR ch, FX_STRSIZE start = 0) const;
777e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
778e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Replace(FX_LPCWSTR lpszOld, FX_LPCWSTR lpszNew);
779e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
780e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    FX_STRSIZE				Remove(FX_WCHAR ch);
781e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
782e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString			UTF8Encode() const;
783e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
784e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    CFX_ByteString			UTF16LE_Encode() const;
785e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
786e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void					ConvertFrom(const CFX_ByteString& str, CFX_CharMap* pCharMap = NULL);
787e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
788e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovprotected:
789e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    class StringData {
790e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      public:
791e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        static StringData* Create(int nLen);
792e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        void Retain() { ++m_nRefs; }
793e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        void Release() { if (--m_nRefs <= 0) FX_Free(this); }
794e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
795e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        intptr_t    m_nRefs;  // Would prefer ssize_t, but no windows support.
796e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_STRSIZE  m_nDataLength;
797e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_STRSIZE  m_nAllocLength;
798e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        FX_WCHAR    m_String[1];
799e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
800e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      private:
801e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen)
802e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) {
803e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            FXSYS_assert(dataLen >= 0);
804e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            FXSYS_assert(allocLen >= 0);
805e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            FXSYS_assert(dataLen <= allocLen);
806e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            m_String[dataLen] = 0;
807e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        }
808e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        ~StringData() = delete;
809e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    };
810e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
811e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void                    CopyBeforeWrite();
812e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void                    AllocBeforeWrite(FX_STRSIZE nLen);
813e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void                    ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData);
814e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void                    ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCWSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCWSTR lpszSrc2Data);
815e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void                    AssignCopy(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData);
816e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    void                    AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const;
817e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
818e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    StringData* m_pData;
819e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    friend class fxcrt_WideStringConcatInPlace_Test;
820e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov};
821e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideStringC::CFX_WideStringC(const CFX_WideString& src)
822e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
823e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Ptr = src.c_str();
824e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Length = src.GetLength();
825e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
826e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideStringC& CFX_WideStringC::operator = (const CFX_WideString& src)
827e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
828e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Ptr = src.c_str();
829e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    m_Length = src.GetLength();
830e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return *this;
831e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
832e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
833e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideStringC& str2)
834e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
835e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
836e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
837e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideStringC& str1, FX_LPCWSTR str2)
838e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
839e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
840e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
841e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideStringC& str2)
842e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
843e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
844e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
845e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideStringC& str1, FX_WCHAR ch)
846e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
847e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, CFX_WideStringC(ch));
848e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
849e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideStringC& str2)
850e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
851e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(ch, str2);
852e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
853e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideString& str2)
854e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
855e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
856e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
857e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideString& str1, FX_WCHAR ch)
858e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
859e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, CFX_WideStringC(ch));
860e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
861e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideString& str2)
862e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
863e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(ch, str2);
864e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
865e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideString& str1, FX_LPCWSTR str2)
866e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
867e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
868e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
869e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideString& str2)
870e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
871e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
872e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
873e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideStringC& str2)
874e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
875e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
876e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
877e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideString& str2)
878e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
879e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return CFX_WideString(str1, str2);
880e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
881e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator== (const wchar_t* lhs, const CFX_WideString& rhs) {
882e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs == lhs;
883e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
884e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator== (const CFX_WideStringC& lhs, const CFX_WideString& rhs) {
885e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs == lhs;
886e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
887e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator!= (const wchar_t* lhs, const CFX_WideString& rhs) {
888e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs != lhs;
889e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
890e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline bool operator!= (const CFX_WideStringC& lhs, const CFX_WideString& rhs) {
891e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return rhs != lhs;
892e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
893e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_FLOAT FX_atof(FX_BSTR str);
894e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid FX_atonum(FX_BSTR str, FX_BOOL& bInteger, void* pData);
895e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovFX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
896e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovCFX_ByteString	FX_UTF8Encode(FX_LPCWSTR pwsStr, FX_STRSIZE len);
897e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString	FX_UTF8Encode(FX_WSTR wsStr)
898e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
899e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return FX_UTF8Encode(wsStr.GetPtr(), wsStr.GetLength());
900e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
901e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline CFX_ByteString	FX_UTF8Encode(const CFX_WideString &wsStr)
902e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov{
903e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength());
904e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
905e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
906e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif  // CORE_INCLUDE_FXCRT_FX_STRING_H_
907