1d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Copyright 2017 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#ifndef CORE_FXCRT_BYTESTRING_H_
8d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#define CORE_FXCRT_BYTESTRING_H_
9d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
10d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <functional>
11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <iterator>
12d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <sstream>
13d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <utility>
14d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
15d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/fx_system.h"
16d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/retain_ptr.h"
17d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/string_data_template.h"
18d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "core/fxcrt/string_view_template.h"
19d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/optional.h"
20d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
21d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannnamespace fxcrt {
22d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
23d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannclass ByteString_Concat_Test;
24d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannclass StringPool_ByteString_Test;
25d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannclass WideString;
26d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
27d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// A mutable string with shared buffers using copy-on-write semantics that
28d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// avoids the cost of std::string's iterator stability guarantees.
29d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannclass ByteString {
30d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann public:
31d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  using CharType = char;
32d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  using const_iterator = const CharType*;
33d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
34d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
35d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  static ByteString FormatInteger(int i) WARN_UNUSED_RESULT;
36d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  static ByteString FormatFloat(float f) WARN_UNUSED_RESULT;
37d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  static ByteString Format(const char* lpszFormat, ...) WARN_UNUSED_RESULT;
38d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  static ByteString FormatV(const char* lpszFormat,
39d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                            va_list argList) WARN_UNUSED_RESULT;
40d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
41d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString();
42d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(const ByteString& other);
43d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(ByteString&& other) noexcept;
44d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
45d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Deliberately implicit to avoid calling on every string literal.
46d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // NOLINTNEXTLINE(runtime/explicit)
47d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(char ch);
48d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // NOLINTNEXTLINE(runtime/explicit)
49d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(const char* ptr);
50d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
51d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // No implicit conversions from wide strings.
52d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // NOLINTNEXTLINE(runtime/explicit)
53d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(wchar_t) = delete;
54d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
55d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(const char* ptr, size_t len);
56d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(const uint8_t* ptr, size_t len);
57d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
58d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  explicit ByteString(const ByteStringView& bstrc);
59d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(const ByteStringView& bstrc1, const ByteStringView& bstrc2);
60d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString(const std::initializer_list<ByteStringView>& list);
61d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  explicit ByteString(const std::ostringstream& outStream);
62d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
63d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ~ByteString();
64d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
65d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void clear() { m_pData.Reset(); }
66d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
67d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  static ByteString FromUnicode(const WideString& str) WARN_UNUSED_RESULT;
68d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
69d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Explicit conversion to C-style string.
70d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Note: Any subsequent modification of |this| will invalidate the result.
71d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const char* c_str() const { return m_pData ? m_pData->m_String : ""; }
72d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
73d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Explicit conversion to uint8_t*.
74d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Note: Any subsequent modification of |this| will invalidate the result.
75d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const uint8_t* raw_str() const {
76d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pData ? reinterpret_cast<const uint8_t*>(m_pData->m_String)
77d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                   : nullptr;
78d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
79d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
80d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Explicit conversion to ByteStringView.
81d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Note: Any subsequent modification of |this| will invalidate the result.
82d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteStringView AsStringView() const {
83d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return ByteStringView(raw_str(), GetLength());
84d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
85d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
86d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Note: Any subsequent modification of |this| will invalidate iterators.
87d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const_iterator begin() const { return m_pData ? m_pData->m_String : nullptr; }
88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const_iterator end() const {
89d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pData ? m_pData->m_String + m_pData->m_nDataLength : nullptr;
90d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
91d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
92d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  // Note: Any subsequent modification of |this| will invalidate iterators.
93d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const_reverse_iterator rbegin() const {
94d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return const_reverse_iterator(end());
95d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
96d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const_reverse_iterator rend() const {
97d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return const_reverse_iterator(begin());
98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
100d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
101d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t GetStringLength() const {
102d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pData ? strlen(m_pData->m_String) : 0;
103d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
104d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool IsEmpty() const { return !GetLength(); }
105d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool IsValidIndex(size_t index) const { return index < GetLength(); }
106d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool IsValidLength(size_t length) const { return length <= GetLength(); }
107d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
108d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int Compare(const ByteStringView& str) const;
109d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool EqualNoCase(const ByteStringView& str) const;
110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
111d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator==(const char* ptr) const;
112d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator==(const ByteStringView& str) const;
113d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator==(const ByteString& other) const;
114d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator!=(const char* ptr) const { return !(*this == ptr); }
116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator!=(const ByteStringView& str) const { return !(*this == str); }
117d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator!=(const ByteString& other) const { return !(*this == other); }
118d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
119d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator<(const char* ptr) const;
120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator<(const ByteStringView& str) const;
121d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool operator<(const ByteString& other) const;
122d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
123d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const ByteString& operator=(const char* str);
124d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const ByteString& operator=(const ByteStringView& bstrc);
125d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const ByteString& operator=(const ByteString& stringSrc);
126d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
127d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const ByteString& operator+=(char ch);
128d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const ByteString& operator+=(const char* str);
129d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const ByteString& operator+=(const ByteString& str);
130d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const ByteString& operator+=(const ByteStringView& bstrc);
131d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
132d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CharType operator[](const size_t index) const {
133d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    ASSERT(IsValidIndex(index));
134d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_pData ? m_pData->m_String[index] : 0;
135d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
136d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
137d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CharType First() const { return GetLength() ? (*this)[0] : 0; }
138d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  CharType Last() const { return GetLength() ? (*this)[GetLength() - 1] : 0; }
139d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
140d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void SetAt(size_t index, char c);
141d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
142d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t Insert(size_t index, char ch);
143d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t InsertAtFront(char ch) { return Insert(0, ch); }
144d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t InsertAtBack(char ch) { return Insert(GetLength(), ch); }
145d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t Delete(size_t index, size_t count = 1);
146d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
147d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void Reserve(size_t len);
148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  char* GetBuffer(size_t len);
149d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void ReleaseBuffer(size_t len);
150d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
151d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString Mid(size_t first, size_t count) const;
152d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString Left(size_t count) const;
153d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  ByteString Right(size_t count) const;
154d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
155d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  Optional<size_t> Find(const ByteStringView& lpszSub, size_t start = 0) const;
156d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  Optional<size_t> Find(char ch, size_t start = 0) const;
157d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  Optional<size_t> ReverseFind(char ch) const;
158d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
159d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool Contains(const ByteStringView& lpszSub, size_t start = 0) const {
160d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Find(lpszSub, start).has_value();
161d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
162d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
163d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  bool Contains(char ch, size_t start = 0) const {
164d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Find(ch, start).has_value();
165d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
166d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
167d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void MakeLower();
168d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void MakeUpper();
169d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
170d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void Trim();
171d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void Trim(char target);
172d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void Trim(const ByteStringView& targets);
173d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
174d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void TrimLeft();
175d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void TrimLeft(char target);
176d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void TrimLeft(const ByteStringView& targets);
177d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
178d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void TrimRight();
179d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void TrimRight(char target);
180d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void TrimRight(const ByteStringView& targets);
181d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
182d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t Replace(const ByteStringView& lpszOld, const ByteStringView& lpszNew);
183d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
184d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t Remove(char ch);
185d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
186d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  WideString UTF8Decode() const;
187d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
188d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  uint32_t GetID() const { return AsStringView().GetID(); }
189d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
190d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann protected:
191d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  using StringData = StringDataTemplate<char>;
192d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
193d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void ReallocBeforeWrite(size_t nNewLen);
194d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void AllocBeforeWrite(size_t nNewLen);
195d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void AllocCopy(ByteString& dest, size_t nCopyLen, size_t nCopyIndex) const;
196d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void AssignCopy(const char* pSrcData, size_t nSrcLen);
197d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  void Concat(const char* lpszSrcData, size_t nSrcLen);
198d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
199d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  RetainPtr<StringData> m_pData;
200d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
201d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  friend ByteString_Concat_Test;
202d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  friend class StringPool_ByteString_Test;
203d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann};
204d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
205d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline bool operator==(const char* lhs, const ByteString& rhs) {
206d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return rhs == lhs;
207d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
208d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline bool operator==(const ByteStringView& lhs, const ByteString& rhs) {
209d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return rhs == lhs;
210d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
211d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline bool operator!=(const char* lhs, const ByteString& rhs) {
212d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return rhs != lhs;
213d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
214d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline bool operator!=(const ByteStringView& lhs, const ByteString& rhs) {
215d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return rhs != lhs;
216d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
217d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline bool operator<(const char* lhs, const ByteString& rhs) {
218d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return rhs.Compare(lhs) > 0;
219d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
220d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
221d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteStringView& str1,
222d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                            const ByteStringView& str2) {
223d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1, str2);
224d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
225d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteStringView& str1, const char* str2) {
226d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1, str2);
227d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
228d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const char* str1, const ByteStringView& str2) {
229d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1, str2);
230d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
231d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteStringView& str1, char ch) {
232d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1, ByteStringView(ch));
233d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
234d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(char ch, const ByteStringView& str2) {
235d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(ch, str2);
236d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
237d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteString& str1, const ByteString& str2) {
238d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1.AsStringView(), str2.AsStringView());
239d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
240d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteString& str1, char ch) {
241d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1.AsStringView(), ByteStringView(ch));
242d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
243d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(char ch, const ByteString& str2) {
244d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(ch, str2.AsStringView());
245d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
246d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteString& str1, const char* str2) {
247d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1.AsStringView(), str2);
248d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
249d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const char* str1, const ByteString& str2) {
250d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1, str2.AsStringView());
251d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
252d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteString& str1,
253d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                            const ByteStringView& str2) {
254d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1.AsStringView(), str2);
255d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
256d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanninline ByteString operator+(const ByteStringView& str1,
257d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                            const ByteString& str2) {
258d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return ByteString(str1, str2.AsStringView());
259d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
260d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
261d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::ostream& operator<<(std::ostream& os, const ByteString& str);
262d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::ostream& operator<<(std::ostream& os, const ByteStringView& str);
263d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
264d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}  // namespace fxcrt
265d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
266d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannusing ByteString = fxcrt::ByteString;
267d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
268d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannuint32_t FX_HashCode_GetA(const ByteStringView& str, bool bIgnoreCase);
269d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
270d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannnamespace std {
271d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
272d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmanntemplate <>
273d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstruct hash<ByteString> {
274d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::size_t operator()(const ByteString& str) const {
275d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return FX_HashCode_GetA(str.AsStringView(), false);
276d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
277d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann};
278d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
279d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}  // namespace std
280d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
281d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannextern template struct std::hash<ByteString>;
282d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
283d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#endif  // CORE_FXCRT_BYTESTRING_H_
284