1d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved.
2d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
3d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// found in the LICENSE file.
4d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
5d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
7d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/bytestring.h"
8d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
9d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <stddef.h>
10d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <algorithm>
12d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <cctype>
13d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <string>
14d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
15d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/cfx_utf8decoder.h"
16d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/fx_codepage.h"
17d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/fx_extension.h"
18d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/fx_safe_types.h"
19d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/string_pool_template.h"
20d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/numerics/safe_math.h"
21d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/stl_util.h"
22d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
23d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanntemplate class fxcrt::StringDataTemplate<char>;
24d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanntemplate class fxcrt::StringViewTemplate<char>;
25d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanntemplate class fxcrt::StringPoolTemplate<ByteString>;
26d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanntemplate struct std::hash<ByteString>;
27d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
28d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannnamespace {
29d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
30d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconstexpr char kTrimChars[] = "\x09\x0a\x0b\x0c\x0d\x20";
31d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
32d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst char* FX_strstr(const char* haystack,
33d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                      int haystack_len,
34d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                      const char* needle,
35d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                      int needle_len) {
36d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (needle_len > haystack_len || needle_len == 0) {
37d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
38d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
39d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const char* end_ptr = haystack + haystack_len - needle_len;
40d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (haystack <= end_ptr) {
41d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int i = 0;
42d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    while (1) {
43d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (haystack[i] != needle[i]) {
44d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        break;
45d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
46d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      i++;
47d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (i == needle_len) {
48d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        return haystack;
49d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      }
50d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
51d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    haystack++;
52d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
53d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return nullptr;
54d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
55d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
56d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#ifndef NDEBUG
57d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool IsValidCodePage(uint16_t codepage) {
58d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  switch (codepage) {
59d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    case FX_CODEPAGE_DefANSI:
60d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    case FX_CODEPAGE_ShiftJIS:
61d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    case FX_CODEPAGE_ChineseSimplified:
62d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    case FX_CODEPAGE_Hangul:
63d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    case FX_CODEPAGE_ChineseTraditional:
64d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return true;
65d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    default:
66d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return false;
67d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
68d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
69d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#endif
70d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
71d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString GetByteString(uint16_t codepage, const WideStringView& wstr) {
72d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#ifndef NDEBUG
73d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(IsValidCodePage(codepage));
74d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#endif
75d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
76d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int src_len = wstr.GetLength();
77d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int dest_len =
78d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      FXSYS_WideCharToMultiByte(codepage, 0, wstr.unterminated_c_str(), src_len,
79d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                nullptr, 0, nullptr, nullptr);
80d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!dest_len)
81d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteString();
82d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
83d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString bstr;
84d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* dest_buf = bstr.GetBuffer(dest_len);
85d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FXSYS_WideCharToMultiByte(codepage, 0, wstr.unterminated_c_str(), src_len,
86d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                            dest_buf, dest_len, nullptr, nullptr);
87d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bstr.ReleaseBuffer(dest_len);
88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return bstr;
89d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
90d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
91d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}  // namespace
92d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
93d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannnamespace fxcrt {
94d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
95d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstatic_assert(sizeof(ByteString) <= sizeof(char*),
96d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              "Strings must not require more space than pointers");
97d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#define FORCE_ANSI 0x10000
99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#define FORCE_UNICODE 0x20000
100d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#define FORCE_INT64 0x40000
101d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
102d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// static
103d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::FormatInteger(int i) {
104d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char buf[32];
105d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FXSYS_snprintf(buf, sizeof(buf), "%d", i);
106d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(buf);
107d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
108d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
109d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// static
110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::FormatFloat(float d) {
111d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char buf[32];
112d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(buf, FX_ftoa(d, buf));
113d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
114d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// static
116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::FormatV(const char* pFormat, va_list argList) {
117d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  va_list argListCopy;
118d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  va_copy(argListCopy, argList);
119d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int nMaxLen = vsnprintf(nullptr, 0, pFormat, argListCopy);
120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  va_end(argListCopy);
121d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
122d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nMaxLen <= 0)
123d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return "";
124d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
125d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString ret;
126d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* buf = ret.GetBuffer(nMaxLen);
127d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (buf) {
128d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    // In the following two calls, there's always space in the buffer for
129d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    // a terminating NUL that's not included in nMaxLen.
130d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    memset(buf, 0, nMaxLen + 1);
131d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    va_copy(argListCopy, argList);
132d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    vsnprintf(buf, nMaxLen + 1, pFormat, argListCopy);
133d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    va_end(argListCopy);
134d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    ret.ReleaseBuffer(ret.GetStringLength());
135d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
136d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ret;
137d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
138d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
139d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// static
140d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::Format(const char* pFormat, ...) {
141d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  va_list argList;
142d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  va_start(argList, pFormat);
143d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString ret = FormatV(pFormat, argList);
144d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  va_end(argList);
145d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
146d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ret;
147d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
149d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const char* pStr, size_t nLen) {
150d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nLen)
151d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData.Reset(StringData::Create(pStr, nLen));
152d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
153d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
154d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const uint8_t* pStr, size_t nLen) {
155d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nLen)
156d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData.Reset(
157d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        StringData::Create(reinterpret_cast<const char*>(pStr), nLen));
158d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
159d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
160d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString() {}
161d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
162d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const ByteString& other) : m_pData(other.m_pData) {}
163d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
164d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(ByteString&& other) noexcept {
165d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Swap(other.m_pData);
166d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
167d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
168d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(char ch) {
169d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Reset(StringData::Create(1));
170d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_String[0] = ch;
171d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
172d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
173d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const char* ptr)
174d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    : ByteString(ptr, ptr ? strlen(ptr) : 0) {}
175d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
176d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const ByteStringView& stringSrc) {
177d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!stringSrc.IsEmpty())
178d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData.Reset(StringData::Create(stringSrc.unterminated_c_str(),
179d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                     stringSrc.GetLength()));
180d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
181d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
182d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const ByteStringView& str1, const ByteStringView& str2) {
183d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_SAFE_SIZE_T nSafeLen = str1.GetLength();
184d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  nSafeLen += str2.GetLength();
185d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
186d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nNewLen = nSafeLen.ValueOrDie();
187d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nNewLen == 0)
188d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
189d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
190d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Reset(StringData::Create(nNewLen));
191d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->CopyContents(str1.unterminated_c_str(), str1.GetLength());
192d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->CopyContentsAt(str1.GetLength(), str2.unterminated_c_str(),
193d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                          str2.GetLength());
194d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
195d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
196d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const std::initializer_list<ByteStringView>& list) {
197d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FX_SAFE_SIZE_T nSafeLen = 0;
198d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (const auto& item : list)
199d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    nSafeLen += item.GetLength();
200d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
201d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nNewLen = nSafeLen.ValueOrDie();
202d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nNewLen == 0)
203d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
204d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
205d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Reset(StringData::Create(nNewLen));
206d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
207d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nOffset = 0;
208d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (const auto& item : list) {
209d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->CopyContentsAt(nOffset, item.unterminated_c_str(),
210d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                            item.GetLength());
211d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    nOffset += item.GetLength();
212d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
213d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
214d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
215d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::ByteString(const std::ostringstream& outStream) {
216d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::string str = outStream.str();
217d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (str.length() > 0)
218d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData.Reset(StringData::Create(str.c_str(), str.length()));
219d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
220d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
221d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString::~ByteString() {}
222d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
223d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst ByteString& ByteString::operator=(const char* pStr) {
224d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!pStr || !pStr[0])
225d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    clear();
226d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  else
227d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    AssignCopy(pStr, strlen(pStr));
228d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
229d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return *this;
230d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
231d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
232d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst ByteString& ByteString::operator=(const ByteStringView& stringSrc) {
233d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (stringSrc.IsEmpty())
234d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    clear();
235d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  else
236d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    AssignCopy(stringSrc.unterminated_c_str(), stringSrc.GetLength());
237d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
238d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return *this;
239d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
240d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
241d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst ByteString& ByteString::operator=(const ByteString& stringSrc) {
242d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData != stringSrc.m_pData)
243d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData = stringSrc.m_pData;
244d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
245d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return *this;
246d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
247d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
248d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst ByteString& ByteString::operator+=(const char* pStr) {
249d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (pStr)
250d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    Concat(pStr, strlen(pStr));
251d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
252d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return *this;
253d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
254d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
255d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst ByteString& ByteString::operator+=(char ch) {
256d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  Concat(&ch, 1);
257d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return *this;
258d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
259d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
260d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst ByteString& ByteString::operator+=(const ByteString& str) {
261d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (str.m_pData)
262d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    Concat(str.m_pData->m_String, str.m_pData->m_nDataLength);
263d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
264d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return *this;
265d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
266d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
267d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst ByteString& ByteString::operator+=(const ByteStringView& str) {
268d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!str.IsEmpty())
269d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    Concat(str.unterminated_c_str(), str.GetLength());
270d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
271d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return *this;
272d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
273d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
274d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool ByteString::operator==(const char* ptr) const {
275d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
276d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return !ptr || !ptr[0];
277d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
278d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!ptr)
279d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pData->m_nDataLength == 0;
280d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
281d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return strlen(ptr) == m_pData->m_nDataLength &&
282d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann         memcmp(ptr, m_pData->m_String, m_pData->m_nDataLength) == 0;
283d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
284d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
285d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool ByteString::operator==(const ByteStringView& str) const {
286d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
287d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return str.IsEmpty();
288d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
289d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return m_pData->m_nDataLength == str.GetLength() &&
290d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann         memcmp(m_pData->m_String, str.unterminated_c_str(), str.GetLength()) ==
291d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann             0;
292d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
293d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
294d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool ByteString::operator==(const ByteString& other) const {
295d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData == other.m_pData)
296d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return true;
297d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
298d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (IsEmpty())
299d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return other.IsEmpty();
300d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
301d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (other.IsEmpty())
302d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
303d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
304d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
305d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann         memcmp(other.m_pData->m_String, m_pData->m_String,
306d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                m_pData->m_nDataLength) == 0;
307d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
308d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
309d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool ByteString::operator<(const char* ptr) const {
310d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData && !ptr)
311d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
312d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (c_str() == ptr)
313d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
314d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
315d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t len = GetLength();
316d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t other_len = ptr ? strlen(ptr) : 0;
317d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int result = memcmp(c_str(), ptr, std::min(len, other_len));
318d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return result < 0 || (result == 0 && len < other_len);
319d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
320d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
321d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool ByteString::operator<(const ByteStringView& str) const {
322d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return Compare(str) < 0;
323d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
324d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
325d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool ByteString::operator<(const ByteString& other) const {
326d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData == other.m_pData)
327d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
328d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
329d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t len = GetLength();
330d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t other_len = other.GetLength();
331d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int result = memcmp(c_str(), other.c_str(), std::min(len, other_len));
332d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return result < 0 || (result == 0 && len < other_len);
333d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
334d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
335d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool ByteString::EqualNoCase(const ByteStringView& str) const {
336d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
337d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return str.IsEmpty();
338d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
339d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t len = str.GetLength();
340d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData->m_nDataLength != len)
341d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
342d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
343d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const uint8_t* pThis = (const uint8_t*)m_pData->m_String;
344d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const uint8_t* pThat = str.raw_str();
345d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < len; i++) {
346d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if ((*pThis) != (*pThat)) {
347d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      uint8_t bThis = FXSYS_tolower(*pThis);
348d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      uint8_t bThat = FXSYS_tolower(*pThat);
349d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      if (bThis != bThat)
350d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        return false;
351d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
352d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pThis++;
353d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pThat++;
354d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
355d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return true;
356d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
357d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
358d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::AssignCopy(const char* pSrcData, size_t nSrcLen) {
359d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  AllocBeforeWrite(nSrcLen);
360d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->CopyContents(pSrcData, nSrcLen);
361d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_nDataLength = nSrcLen;
362d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
363d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
364d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::ReallocBeforeWrite(size_t nNewLength) {
365d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData && m_pData->CanOperateInPlace(nNewLength))
366d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
367d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
368d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nNewLength == 0) {
369d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    clear();
370d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
371d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
372d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
373d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
374d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData) {
375d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    size_t nCopyLength = std::min(m_pData->m_nDataLength, nNewLength);
376d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pNewData->CopyContents(m_pData->m_String, nCopyLength);
377d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pNewData->m_nDataLength = nCopyLength;
378d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else {
379d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pNewData->m_nDataLength = 0;
380d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
381d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pNewData->m_String[pNewData->m_nDataLength] = 0;
382d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Swap(pNewData);
383d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
384d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
385d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::AllocBeforeWrite(size_t nNewLength) {
386d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData && m_pData->CanOperateInPlace(nNewLength))
387d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
388d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
389d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nNewLength == 0) {
390d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    clear();
391d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
392d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
393d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
394d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Reset(StringData::Create(nNewLength));
395d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
396d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
397d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::ReleaseBuffer(size_t nNewLength) {
398d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
399d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
400d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
401d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  nNewLength = std::min(nNewLength, m_pData->m_nAllocLength);
402d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nNewLength == 0) {
403d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    clear();
404d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
405d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
406d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
407d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(m_pData->m_nRefs == 1);
408d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_nDataLength = nNewLength;
409d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_String[nNewLength] = 0;
410d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData->m_nAllocLength - nNewLength >= 32) {
411d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    // Over arbitrary threshold, so pay the price to relocate.  Force copy to
412d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    // always occur by holding a second reference to the string.
413d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    ByteString preserve(*this);
414d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    ReallocBeforeWrite(nNewLength);
415d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
416d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
417d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
418d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::Reserve(size_t len) {
419d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  GetBuffer(len);
420d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
421d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
422d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannchar* ByteString::GetBuffer(size_t nMinBufLength) {
423d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData) {
424d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (nMinBufLength == 0)
425d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return nullptr;
426d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
427d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData.Reset(StringData::Create(nMinBufLength));
428d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->m_nDataLength = 0;
429d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->m_String[0] = 0;
430d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pData->m_String;
431d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
432d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
433d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData->CanOperateInPlace(nMinBufLength))
434d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pData->m_String;
435d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
436d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  nMinBufLength = std::max(nMinBufLength, m_pData->m_nDataLength);
437d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nMinBufLength == 0)
438d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
439d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
440d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<StringData> pNewData(StringData::Create(nMinBufLength));
441d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pNewData->CopyContents(*m_pData);
442d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pNewData->m_nDataLength = m_pData->m_nDataLength;
443d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Swap(pNewData);
444d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return m_pData->m_String;
445d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
446d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
447d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannsize_t ByteString::Delete(size_t index, size_t count) {
448d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
449d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
450d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
451d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t old_length = m_pData->m_nDataLength;
452d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (count == 0 ||
453d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      index != pdfium::clamp(index, static_cast<size_t>(0), old_length))
454d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return old_length;
455d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
456d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t removal_length = index + count;
457d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (removal_length > old_length)
458d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return old_length;
459d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
460d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ReallocBeforeWrite(old_length);
461d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t chars_to_copy = old_length - removal_length + 1;
462d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  memmove(m_pData->m_String + index, m_pData->m_String + removal_length,
463d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          chars_to_copy);
464d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_nDataLength = old_length - count;
465d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return m_pData->m_nDataLength;
466d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
467d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
468d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::Concat(const char* pSrcData, size_t nSrcLen) {
469d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!pSrcData || nSrcLen == 0)
470d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
471d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
472d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData) {
473d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData.Reset(StringData::Create(pSrcData, nSrcLen));
474d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
475d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
476d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
477d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (m_pData->CanOperateInPlace(m_pData->m_nDataLength + nSrcLen)) {
478d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
479d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->m_nDataLength += nSrcLen;
480d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
481d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
482d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
483d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<StringData> pNewData(
484d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      StringData::Create(m_pData->m_nDataLength + nSrcLen));
485d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pNewData->CopyContents(*m_pData);
486d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pNewData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
487d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Swap(pNewData);
488d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
489d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
490d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::Mid(size_t first, size_t count) const {
491d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
492d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteString();
493d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
494d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!IsValidIndex(first))
495d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteString();
496d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
497d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (count == 0 || !IsValidLength(count))
498d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteString();
499d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
500d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!IsValidIndex(first + count - 1))
501d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteString();
502d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
503d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (first == 0 && count == m_pData->m_nDataLength)
504d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return *this;
505d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
506d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString dest;
507d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  AllocCopy(dest, count, first);
508d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return dest;
509d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
510d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
511d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::Left(size_t count) const {
512d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (count == 0 || !IsValidLength(count))
513d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteString();
514d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return Mid(0, count);
515d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
516d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
517d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::Right(size_t count) const {
518d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (count == 0 || !IsValidLength(count))
519d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteString();
520d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return Mid(GetLength() - count, count);
521d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
522d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
523d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::AllocCopy(ByteString& dest,
524d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                           size_t nCopyLen,
525d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                           size_t nCopyIndex) const {
526d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nCopyLen == 0)
527d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
528d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
529d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<StringData> pNewData(
530d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      StringData::Create(m_pData->m_String + nCopyIndex, nCopyLen));
531d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  dest.m_pData.Swap(pNewData);
532d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
533d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
534d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::SetAt(size_t index, char c) {
535d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ASSERT(IsValidIndex(index));
536d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ReallocBeforeWrite(m_pData->m_nDataLength);
537d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_String[index] = c;
538d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
539d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
540d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannsize_t ByteString::Insert(size_t location, char ch) {
541d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const size_t cur_length = m_pData ? m_pData->m_nDataLength : 0;
542d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!IsValidLength(location))
543d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return cur_length;
544d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
545d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const size_t new_length = cur_length + 1;
546d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ReallocBeforeWrite(new_length);
547d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  memmove(m_pData->m_String + location + 1, m_pData->m_String + location,
548d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          new_length - location);
549d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_String[location] = ch;
550d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_nDataLength = new_length;
551d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return new_length;
552d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
553d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
554d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannOptional<size_t> ByteString::Find(char ch, size_t start) const {
555d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
556d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Optional<size_t>();
557d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
558d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!IsValidIndex(start))
559d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Optional<size_t>();
560d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
561d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const char* pStr = static_cast<const char*>(
562d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      memchr(m_pData->m_String + start, ch, m_pData->m_nDataLength - start));
563d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return pStr ? Optional<size_t>(static_cast<size_t>(pStr - m_pData->m_String))
564d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              : Optional<size_t>();
565d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
566d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
567d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannOptional<size_t> ByteString::Find(const ByteStringView& subStr,
568d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                  size_t start) const {
569d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
570d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Optional<size_t>();
571d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
572d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!IsValidIndex(start))
573d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Optional<size_t>();
574d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
575d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const char* pStr =
576d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      FX_strstr(m_pData->m_String + start, m_pData->m_nDataLength - start,
577d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                subStr.unterminated_c_str(), subStr.GetLength());
578d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return pStr ? Optional<size_t>(static_cast<size_t>(pStr - m_pData->m_String))
579d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann              : Optional<size_t>();
580d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
581d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
582d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannOptional<size_t> ByteString::ReverseFind(char ch) const {
583d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
584d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Optional<size_t>();
585d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
586d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nLength = m_pData->m_nDataLength;
587d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (nLength--) {
588d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (m_pData->m_String[nLength] == ch)
589d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return Optional<size_t>(nLength);
590d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
591d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return Optional<size_t>();
592d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
593d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
594d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::MakeLower() {
595d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
596d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
597d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
598d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ReallocBeforeWrite(m_pData->m_nDataLength);
599d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FXSYS_strlwr(m_pData->m_String);
600d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
601d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
602d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::MakeUpper() {
603d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
604d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
605d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
606d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ReallocBeforeWrite(m_pData->m_nDataLength);
607d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  FXSYS_strupr(m_pData->m_String);
608d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
609d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
610d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannsize_t ByteString::Remove(char chRemove) {
611d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData || m_pData->m_nDataLength < 1)
612d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
613d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
614d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* pstrSource = m_pData->m_String;
615d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
616d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (pstrSource < pstrEnd) {
617d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (*pstrSource == chRemove)
618d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      break;
619d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pstrSource++;
620d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
621d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (pstrSource == pstrEnd)
622d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
623d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
624d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ptrdiff_t copied = pstrSource - m_pData->m_String;
625d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ReallocBeforeWrite(m_pData->m_nDataLength);
626d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pstrSource = m_pData->m_String + copied;
627d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
628d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
629d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* pstrDest = pstrSource;
630d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (pstrSource < pstrEnd) {
631d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (*pstrSource != chRemove) {
632d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      *pstrDest = *pstrSource;
633d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      pstrDest++;
634d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
635d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pstrSource++;
636d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
637d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
638d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  *pstrDest = 0;
639d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nCount = static_cast<size_t>(pstrSource - pstrDest);
640d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData->m_nDataLength -= nCount;
641d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return nCount;
642d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
643d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
644d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannsize_t ByteString::Replace(const ByteStringView& pOld,
645d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                           const ByteStringView& pNew) {
646d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData || pOld.IsEmpty())
647d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
648d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
649d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nSourceLen = pOld.GetLength();
650d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nReplacementLen = pNew.GetLength();
651d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nCount = 0;
652d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const char* pStart = m_pData->m_String;
653d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* pEnd = m_pData->m_String + m_pData->m_nDataLength;
654d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (1) {
655d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const char* pTarget = FX_strstr(pStart, static_cast<int>(pEnd - pStart),
656d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                    pOld.unterminated_c_str(), nSourceLen);
657d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!pTarget)
658d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      break;
659d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
660d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    nCount++;
661d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pStart = pTarget + nSourceLen;
662d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
663d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nCount == 0)
664d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
665d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
666d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t nNewLength =
667d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_pData->m_nDataLength + (nReplacementLen - nSourceLen) * nCount;
668d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
669d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (nNewLength == 0) {
670d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    clear();
671d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nCount;
672d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
673d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
674d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
675d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  pStart = m_pData->m_String;
676d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* pDest = pNewData->m_String;
677d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < nCount; i++) {
678d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const char* pTarget = FX_strstr(pStart, static_cast<int>(pEnd - pStart),
679d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                    pOld.unterminated_c_str(), nSourceLen);
680d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    memcpy(pDest, pStart, pTarget - pStart);
681d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pDest += pTarget - pStart;
682d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    memcpy(pDest, pNew.unterminated_c_str(), pNew.GetLength());
683d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pDest += pNew.GetLength();
684d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pStart = pTarget + nSourceLen;
685d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
686d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  memcpy(pDest, pStart, pEnd - pStart);
687d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_pData.Swap(pNewData);
688d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return nCount;
689d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
690d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
691d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannWideString ByteString::UTF8Decode() const {
692d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CFX_UTF8Decoder decoder;
693d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < GetLength(); i++) {
694d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    decoder.Input(static_cast<uint8_t>(m_pData->m_String[i]));
695d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
696d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return WideString(decoder.GetResult());
697d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
698d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
699d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// static
700d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannByteString ByteString::FromUnicode(const WideString& str) {
701d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return GetByteString(0, str.AsStringView());
702d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
703d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
704d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannint ByteString::Compare(const ByteStringView& str) const {
705d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData)
706d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return str.IsEmpty() ? 0 : -1;
707d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
708d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t this_len = m_pData->m_nDataLength;
709d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t that_len = str.GetLength();
710d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t min_len = std::min(this_len, that_len);
711d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int result = memcmp(m_pData->m_String, str.unterminated_c_str(), min_len);
712d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (result != 0)
713d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return result;
714d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (this_len == that_len)
715d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return 0;
716d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return this_len < that_len ? -1 : 1;
717d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
718d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
719d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::Trim() {
720d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimRight(kTrimChars);
721d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimLeft(kTrimChars);
722d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
723d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
724d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::Trim(char target) {
725d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteStringView targets(target);
726d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimRight(targets);
727d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimLeft(targets);
728d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
729d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
730d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::Trim(const ByteStringView& targets) {
731d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimRight(targets);
732d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimLeft(targets);
733d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
734d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
735d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::TrimLeft() {
736d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimLeft(kTrimChars);
737d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
738d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
739d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::TrimLeft(char target) {
740d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimLeft(ByteStringView(target));
741d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
742d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
743d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::TrimLeft(const ByteStringView& targets) {
744d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData || targets.IsEmpty())
745d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
746d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
747d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t len = GetLength();
748d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (len == 0)
749d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
750d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
751d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t pos = 0;
752d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (pos < len) {
753d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    size_t i = 0;
754d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    while (i < targets.GetLength() && targets[i] != m_pData->m_String[pos])
755d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      i++;
756d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (i == targets.GetLength())
757d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      break;
758d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pos++;
759d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
760d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (pos) {
761d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    ReallocBeforeWrite(len);
762d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    size_t nDataLength = len - pos;
763d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    memmove(m_pData->m_String, m_pData->m_String + pos,
764d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann            (nDataLength + 1) * sizeof(char));
765d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->m_nDataLength = nDataLength;
766d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
767d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
768d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
769d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::TrimRight() {
770d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimRight(kTrimChars);
771d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
772d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
773d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::TrimRight(char target) {
774d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  TrimRight(ByteStringView(target));
775d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
776d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
777d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannvoid ByteString::TrimRight(const ByteStringView& targets) {
778d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!m_pData || targets.IsEmpty())
779d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
780d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
781d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t pos = GetLength();
782d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (pos == 0)
783d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
784d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
785d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (pos) {
786d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    size_t i = 0;
787d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    while (i < targets.GetLength() && targets[i] != m_pData->m_String[pos - 1])
788d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      i++;
789d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (i == targets.GetLength())
790d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      break;
791d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    pos--;
792d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
793d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (pos < m_pData->m_nDataLength) {
794d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    ReallocBeforeWrite(m_pData->m_nDataLength);
795d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->m_String[pos] = 0;
796d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_pData->m_nDataLength = pos;
797d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
798d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
799d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
800d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::ostream& operator<<(std::ostream& os, const ByteString& str) {
801d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return os.write(str.c_str(), str.GetLength());
802d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
803d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
804d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::ostream& operator<<(std::ostream& os, const ByteStringView& str) {
805d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return os.write(str.unterminated_c_str(), str.GetLength());
806d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
807d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
808d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}  // namespace fxcrt
809