summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-05-13 15:02:43 -0700
committerCommit bot <commit-bot@chromium.org>2016-05-13 15:02:44 -0700
commitf7036ba5884b9829fcb17aea4f3a16831abb7516 (patch)
treee142bb59eea5d48d354a6f4841d1ef57306e985f
parent19ea309f3d46bbd76d4201b4e791b11d736f7834 (diff)
downloadpdfium-f7036ba5884b9829fcb17aea4f3a16831abb7516.tar.xz
Templatize CFX_{Byte,Wide}StringC
Review-Url: https://codereview.chromium.org/1874773002
-rw-r--r--BUILD.gn1
-rw-r--r--core/fxcrt/cfx_string_c_template.h168
-rw-r--r--core/fxcrt/fx_basic_bstring.cpp21
-rw-r--r--core/fxcrt/fx_basic_wstring.cpp1
-rw-r--r--core/fxcrt/include/fx_string.h249
-rw-r--r--core/fxcrt/include/fx_system.h25
-rw-r--r--pdfium.gyp1
-rw-r--r--testing/fx_string_testhelpers.cpp2
8 files changed, 205 insertions, 263 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 1d87424f97..30fd1e04f3 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -593,6 +593,7 @@ config("fxge_warnings") {
static_library("fxcrt") {
sources = [
+ "core/fxcrt/cfx_string_c_template.h",
"core/fxcrt/cfx_string_data_template.h",
"core/fxcrt/extension.h",
"core/fxcrt/fx_basic_array.cpp",
diff --git a/core/fxcrt/cfx_string_c_template.h b/core/fxcrt/cfx_string_c_template.h
new file mode 100644
index 0000000000..70b9fcd609
--- /dev/null
+++ b/core/fxcrt/cfx_string_c_template.h
@@ -0,0 +1,168 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_
+#define CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_
+
+#include <algorithm>
+#include <type_traits>
+
+#include "core/fxcrt/include/fx_system.h"
+
+// An immutable string with caller-provided storage which must outlive the
+// string itself. These are not necessarily nul-terminated, so that substring
+// extraction (via the Mid(), Left(), and Right() methods) is copy-free.
+template <typename T>
+class CFX_StringCTemplate {
+ public:
+ using CharType = T;
+ using UnsignedType = typename std::make_unsigned<CharType>::type;
+
+ CFX_StringCTemplate() : m_Ptr(nullptr), m_Length(0) {}
+
+ // Deliberately implicit to avoid calling on every string literal.
+ CFX_StringCTemplate(const CharType* ptr)
+ : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)),
+ m_Length(ptr ? FXSYS_len(ptr) : 0) {}
+
+ CFX_StringCTemplate(const CharType* ptr, FX_STRSIZE len)
+ : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)),
+ m_Length(len == -1 ? FXSYS_len(ptr) : len) {}
+
+ template <typename U = UnsignedType>
+ CFX_StringCTemplate(
+ const UnsignedType* ptr,
+ FX_STRSIZE size,
+ typename std::enable_if<!std::is_same<U, CharType>::value>::type* = 0)
+ : m_Ptr(ptr), m_Length(size) {}
+
+ // Deliberately implicit to avoid calling on every string literal.
+ // |ch| must be an lvalue that outlives the the CFX_StringCTemplate.
+ CFX_StringCTemplate(CharType& ch) {
+ m_Ptr = reinterpret_cast<const UnsignedType*>(&ch);
+ m_Length = 1;
+ }
+
+ CFX_StringCTemplate(const CFX_StringCTemplate& src) {
+ m_Ptr = src.m_Ptr;
+ m_Length = src.m_Length;
+ }
+
+ CFX_StringCTemplate& operator=(const CharType* src) {
+ m_Ptr = reinterpret_cast<const UnsignedType*>(src);
+ m_Length = src ? FXSYS_len(src) : 0;
+ return *this;
+ }
+
+ CFX_StringCTemplate& operator=(const CFX_StringCTemplate& src) {
+ m_Ptr = src.m_Ptr;
+ m_Length = src.m_Length;
+ return *this;
+ }
+
+ bool operator==(const CharType* ptr) const {
+ return FXSYS_len(ptr) == m_Length &&
+ FXSYS_cmp(ptr, reinterpret_cast<const CharType*>(m_Ptr), m_Length) ==
+ 0;
+ }
+ bool operator==(const CFX_StringCTemplate& other) const {
+ return other.m_Length == m_Length &&
+ FXSYS_cmp(reinterpret_cast<const CharType*>(other.m_Ptr),
+ reinterpret_cast<const CharType*>(m_Ptr), m_Length) == 0;
+ }
+ bool operator!=(const CharType* ptr) const { return !(*this == ptr); }
+ bool operator!=(const CFX_StringCTemplate& other) const {
+ return !(*this == other);
+ }
+
+ uint32_t GetID(FX_STRSIZE start_pos = 0) const {
+ if (m_Length == 0 || start_pos < 0 || start_pos >= m_Length)
+ return 0;
+
+ uint32_t strid = 0;
+ FX_STRSIZE size = std::min(4, m_Length - start_pos);
+ for (FX_STRSIZE i = 0; i < size; i++)
+ strid = strid * 256 + m_Ptr[start_pos + i];
+
+ return strid << ((4 - size) * 8);
+ }
+
+ const UnsignedType* raw_str() const { return m_Ptr; }
+ const CharType* c_str() const {
+ return reinterpret_cast<const CharType*>(m_Ptr);
+ }
+
+ FX_STRSIZE GetLength() const { return m_Length; }
+ bool IsEmpty() const { return m_Length == 0; }
+
+ UnsignedType GetAt(FX_STRSIZE index) const { return m_Ptr[index]; }
+ CharType CharAt(FX_STRSIZE index) const {
+ return static_cast<CharType>(m_Ptr[index]);
+ }
+
+ FX_STRSIZE Find(CharType ch) const {
+ const UnsignedType* found = reinterpret_cast<const UnsignedType*>(
+ FXSYS_chr(reinterpret_cast<const CharType*>(m_Ptr), ch, m_Length));
+ return found ? found - m_Ptr : -1;
+ }
+
+ CFX_StringCTemplate Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const {
+ index = std::max(0, index);
+ if (index > m_Length)
+ return CFX_StringCTemplate();
+
+ if (count < 0 || count > m_Length - index)
+ count = m_Length - index;
+
+ return CFX_StringCTemplate(m_Ptr + index, count);
+ }
+
+ CFX_StringCTemplate Left(FX_STRSIZE count) const {
+ if (count <= 0)
+ return CFX_StringCTemplate();
+
+ return CFX_StringCTemplate(m_Ptr, std::min(count, m_Length));
+ }
+
+ CFX_StringCTemplate Right(FX_STRSIZE count) const {
+ if (count <= 0)
+ return CFX_StringCTemplate();
+
+ count = std::min(count, m_Length);
+ return CFX_StringCTemplate(m_Ptr + m_Length - count, count);
+ }
+
+ const UnsignedType& operator[](size_t index) const { return m_Ptr[index]; }
+
+ bool operator<(const CFX_StringCTemplate& that) const {
+ int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr),
+ reinterpret_cast<const CharType*>(that.m_Ptr),
+ std::min(m_Length, that.m_Length));
+ return result < 0 || (result == 0 && m_Length < that.m_Length);
+ }
+
+ protected:
+ const UnsignedType* m_Ptr;
+ FX_STRSIZE m_Length;
+
+ private:
+ void* operator new(size_t) throw() { return nullptr; }
+};
+
+template <typename T>
+inline bool operator==(const T* lhs, const CFX_StringCTemplate<T>& rhs) {
+ return rhs == lhs;
+}
+
+template <typename T>
+inline bool operator!=(const T* lhs, const CFX_StringCTemplate<T>& rhs) {
+ return rhs != lhs;
+}
+
+extern template class CFX_StringCTemplate<FX_CHAR>;
+extern template class CFX_StringCTemplate<FX_WCHAR>;
+
+#endif // CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_
diff --git a/core/fxcrt/fx_basic_bstring.cpp b/core/fxcrt/fx_basic_bstring.cpp
index e035dd53d1..3a81e41920 100644
--- a/core/fxcrt/fx_basic_bstring.cpp
+++ b/core/fxcrt/fx_basic_bstring.cpp
@@ -13,6 +13,7 @@
#include "third_party/base/numerics/safe_math.h"
template class CFX_StringDataTemplate<FX_CHAR>;
+template class CFX_StringCTemplate<FX_CHAR>;
namespace {
@@ -931,26 +932,6 @@ void CFX_ByteString::TrimLeft() {
uint32_t CFX_ByteString::GetID(FX_STRSIZE start_pos) const {
return AsStringC().GetID(start_pos);
}
-uint32_t CFX_ByteStringC::GetID(FX_STRSIZE start_pos) const {
- if (m_Length == 0) {
- return 0;
- }
- if (start_pos < 0 || start_pos >= m_Length) {
- return 0;
- }
- uint32_t strid = 0;
- if (start_pos + 4 > m_Length) {
- for (FX_STRSIZE i = 0; i < m_Length - start_pos; i++) {
- strid = strid * 256 + m_Ptr[start_pos + i];
- }
- strid = strid << ((4 - m_Length + start_pos) * 8);
- } else {
- for (int i = 0; i < 4; i++) {
- strid = strid * 256 + m_Ptr[start_pos + i];
- }
- }
- return strid;
-}
FX_STRSIZE FX_ftoa(FX_FLOAT d, FX_CHAR* buf) {
buf[0] = '0';
buf[1] = '\0';
diff --git a/core/fxcrt/fx_basic_wstring.cpp b/core/fxcrt/fx_basic_wstring.cpp
index 03cb0599d5..8c1d494e7a 100644
--- a/core/fxcrt/fx_basic_wstring.cpp
+++ b/core/fxcrt/fx_basic_wstring.cpp
@@ -14,6 +14,7 @@
#include "third_party/base/numerics/safe_math.h"
template class CFX_StringDataTemplate<FX_WCHAR>;
+template class CFX_StringCTemplate<FX_WCHAR>;
namespace {
diff --git a/core/fxcrt/include/fx_string.h b/core/fxcrt/include/fx_string.h
index 617e02ee5a..9019522eca 100644
--- a/core/fxcrt/include/fx_string.h
+++ b/core/fxcrt/include/fx_string.h
@@ -10,6 +10,7 @@
#include <stdint.h> // For intptr_t.
#include <algorithm>
+#include "core/fxcrt/cfx_string_c_template.h"
#include "core/fxcrt/cfx_string_data_template.h"
#include "core/fxcrt/include/cfx_retain_ptr.h"
#include "core/fxcrt/include/fx_memory.h"
@@ -18,134 +19,20 @@
class CFX_ByteString;
class CFX_WideString;
-// An immutable string with caller-provided storage which must outlive the
-// string itself. These are not necessarily nul-terminated, so that substring
-// extraction (via the Mid() method) is copy-free.
-class CFX_ByteStringC {
- public:
- typedef FX_CHAR value_type;
-
- CFX_ByteStringC() {
- m_Ptr = NULL;
- m_Length = 0;
- }
-
- CFX_ByteStringC(const uint8_t* ptr, FX_STRSIZE size) {
- m_Ptr = ptr;
- m_Length = size;
- }
-
- // Deliberately implicit to avoid calling on every string literal.
- CFX_ByteStringC(const FX_CHAR* ptr) {
- m_Ptr = (const uint8_t*)ptr;
- m_Length = ptr ? FXSYS_strlen(ptr) : 0;
- }
-
- // Deliberately implicit to avoid calling on every string literal.
- // |ch| must be an lvalue that outlives the the CFX_ByteStringC.
- CFX_ByteStringC(FX_CHAR& ch) {
- m_Ptr = (const uint8_t*)&ch;
- m_Length = 1;
- }
-
- CFX_ByteStringC(const FX_CHAR* ptr, FX_STRSIZE len) {
- m_Ptr = (const uint8_t*)ptr;
- m_Length = (len == -1) ? FXSYS_strlen(ptr) : len;
- }
-
- CFX_ByteStringC(const CFX_ByteStringC& src) {
- m_Ptr = src.m_Ptr;
- m_Length = src.m_Length;
- }
-
- CFX_ByteStringC& operator=(const FX_CHAR* src) {
- m_Ptr = (const uint8_t*)src;
- m_Length = m_Ptr ? FXSYS_strlen(src) : 0;
- return *this;
- }
-
- CFX_ByteStringC& operator=(const CFX_ByteStringC& src) {
- m_Ptr = src.m_Ptr;
- m_Length = src.m_Length;
- return *this;
- }
-
- bool operator==(const char* ptr) const {
- return FXSYS_strlen(ptr) == m_Length &&
- FXSYS_memcmp(ptr, m_Ptr, m_Length) == 0;
- }
- bool operator==(const CFX_ByteStringC& other) const {
- return other.m_Length == m_Length &&
- FXSYS_memcmp(other.m_Ptr, m_Ptr, m_Length) == 0;
- }
- bool operator!=(const char* ptr) const { return !(*this == ptr); }
- bool operator!=(const CFX_ByteStringC& other) const {
- return !(*this == other);
- }
-
- uint32_t GetID(FX_STRSIZE start_pos = 0) const;
-
- const uint8_t* raw_str() const { return m_Ptr; }
- const FX_CHAR* c_str() const {
- return reinterpret_cast<const FX_CHAR*>(m_Ptr);
- }
-
- FX_STRSIZE GetLength() const { return m_Length; }
- bool IsEmpty() const { return m_Length == 0; }
-
- uint8_t GetAt(FX_STRSIZE index) const { return m_Ptr[index]; }
- FX_CHAR CharAt(FX_STRSIZE index) const {
- return static_cast<FX_CHAR>(m_Ptr[index]);
- }
-
- FX_STRSIZE Find(FX_CHAR ch) const {
- const uint8_t* found =
- static_cast<const uint8_t*>(memchr(m_Ptr, ch, m_Length));
- return found ? found - m_Ptr : -1;
- }
-
- CFX_ByteStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const {
- if (index < 0) {
- index = 0;
- }
- if (index > m_Length) {
- return CFX_ByteStringC();
- }
- if (count < 0 || count > m_Length - index) {
- count = m_Length - index;
- }
- return CFX_ByteStringC(m_Ptr + index, count);
- }
+using CFX_ByteStringC = CFX_StringCTemplate<FX_CHAR>;
+using CFX_WideStringC = CFX_StringCTemplate<FX_WCHAR>;
- const uint8_t& operator[](size_t index) const { return m_Ptr[index]; }
-
- bool operator<(const CFX_ByteStringC& that) const {
- int result = memcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length));
- return result < 0 || (result == 0 && m_Length < that.m_Length);
- }
-
- protected:
- const uint8_t* m_Ptr;
- FX_STRSIZE m_Length;
-
- private:
- void* operator new(size_t) throw() { return NULL; }
-};
-inline bool operator==(const char* lhs, const CFX_ByteStringC& rhs) {
- return rhs == lhs;
-}
-inline bool operator!=(const char* lhs, const CFX_ByteStringC& rhs) {
- return rhs != lhs;
-}
#define FXBSTR_ID(c1, c2, c3, c4) \
(((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | ((uint32_t)c3 << 8) | \
((uint32_t)c4))
+#define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1)
+
// A mutable string with shared buffers using copy-on-write semantics that
// avoids the cost of std::string's iterator stability guarantees.
class CFX_ByteString {
public:
- typedef FX_CHAR value_type;
+ using CharType = FX_CHAR;
CFX_ByteString() {}
CFX_ByteString(const CFX_ByteString& other) : m_pData(other.m_pData) {}
@@ -346,133 +233,11 @@ inline CFX_ByteString operator+(const CFX_ByteStringC& str1,
return CFX_ByteString(str1, str2.AsStringC());
}
-class CFX_WideStringC {
- public:
- typedef FX_WCHAR value_type;
-
- CFX_WideStringC() {
- m_Ptr = NULL;
- m_Length = 0;
- }
-
- // Deliberately implicit to avoid calling on every string literal.
- CFX_WideStringC(const FX_WCHAR* ptr) {
- m_Ptr = ptr;
- m_Length = ptr ? FXSYS_wcslen(ptr) : 0;
- }
-
- // Deliberately implicit to avoid calling on every string literal.
- // |ch| must be an lvalue that outlives the the CFX_WideStringC.
- CFX_WideStringC(FX_WCHAR& ch) {
- m_Ptr = &ch;
- m_Length = 1;
- }
-
- CFX_WideStringC(const FX_WCHAR* ptr, FX_STRSIZE len) {
- m_Ptr = ptr;
- m_Length = (len == -1) ? FXSYS_wcslen(ptr) : len;
- }
-
- CFX_WideStringC(const CFX_WideStringC& src) {
- m_Ptr = src.m_Ptr;
- m_Length = src.m_Length;
- }
-
- CFX_WideStringC& operator=(const FX_WCHAR* src) {
- m_Ptr = src;
- m_Length = FXSYS_wcslen(src);
- return *this;
- }
-
- CFX_WideStringC& operator=(const CFX_WideStringC& src) {
- m_Ptr = src.m_Ptr;
- m_Length = src.m_Length;
- return *this;
- }
-
- bool operator==(const wchar_t* ptr) const {
- return FXSYS_wcslen(ptr) == m_Length && wmemcmp(ptr, m_Ptr, m_Length) == 0;
- }
- bool operator==(const CFX_WideStringC& str) const {
- return str.m_Length == m_Length && wmemcmp(str.m_Ptr, m_Ptr, m_Length) == 0;
- }
- bool operator!=(const wchar_t* ptr) const { return !(*this == ptr); }
- bool operator!=(const CFX_WideStringC& str) const { return !(*this == str); }
-
- const FX_WCHAR* c_str() const { return m_Ptr; }
-
- FX_STRSIZE GetLength() const { return m_Length; }
- bool IsEmpty() const { return m_Length == 0; }
-
- FX_WCHAR GetAt(FX_STRSIZE index) const { return m_Ptr[index]; }
-
- CFX_WideStringC Left(FX_STRSIZE count) const {
- if (count < 1) {
- return CFX_WideStringC();
- }
- if (count > m_Length) {
- count = m_Length;
- }
- return CFX_WideStringC(m_Ptr, count);
- }
-
- FX_STRSIZE Find(FX_WCHAR ch) const {
- const FX_WCHAR* found =
- static_cast<const FX_WCHAR*>(wmemchr(m_Ptr, ch, m_Length));
- return found ? found - m_Ptr : -1;
- }
-
- CFX_WideStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const {
- if (index < 0) {
- index = 0;
- }
- if (index > m_Length) {
- return CFX_WideStringC();
- }
- if (count < 0 || count > m_Length - index) {
- count = m_Length - index;
- }
- return CFX_WideStringC(m_Ptr + index, count);
- }
-
- CFX_WideStringC Right(FX_STRSIZE count) const {
- if (count < 1) {
- return CFX_WideStringC();
- }
- if (count > m_Length) {
- count = m_Length;
- }
- return CFX_WideStringC(m_Ptr + m_Length - count, count);
- }
-
- const FX_WCHAR& operator[](size_t index) const { return m_Ptr[index]; }
-
- bool operator<(const CFX_WideStringC& that) const {
- int result = wmemcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length));
- return result < 0 || (result == 0 && m_Length < that.m_Length);
- }
-
- protected:
- const FX_WCHAR* m_Ptr;
- FX_STRSIZE m_Length;
-
- private:
- void* operator new(size_t) throw() { return NULL; }
-};
-
-inline bool operator==(const wchar_t* lhs, const CFX_WideStringC& rhs) {
- return rhs == lhs;
-}
-inline bool operator!=(const wchar_t* lhs, const CFX_WideStringC& rhs) {
- return rhs != lhs;
-}
-#define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1)
-
// A mutable string with shared buffers using copy-on-write semantics that
// avoids the cost of std::string's iterator stability guarantees.
class CFX_WideString {
public:
- typedef FX_WCHAR value_type;
+ using CharType = FX_WCHAR;
CFX_WideString() {}
CFX_WideString(const CFX_WideString& other) : m_pData(other.m_pData) {}
diff --git a/core/fxcrt/include/fx_system.h b/core/fxcrt/include/fx_system.h
index b4659d14e4..205976fb15 100644
--- a/core/fxcrt/include/fx_system.h
+++ b/core/fxcrt/include/fx_system.h
@@ -158,6 +158,31 @@ FXSYS_FILE* FXSYS_wfopen(const FX_WCHAR* filename, const FX_WCHAR* mode);
#define FXSYS_strlen(ptr) pdfium::base::checked_cast<FX_STRSIZE>(strlen(ptr))
#define FXSYS_wcslen(ptr) pdfium::base::checked_cast<FX_STRSIZE>(wcslen(ptr))
+// Overloaded functions for C++ templates
+inline FX_STRSIZE FXSYS_len(const FX_CHAR* ptr) {
+ return FXSYS_strlen(ptr);
+}
+
+inline FX_STRSIZE FXSYS_len(const FX_WCHAR* ptr) {
+ return FXSYS_wcslen(ptr);
+}
+
+inline int FXSYS_cmp(const FX_CHAR* ptr1, const FX_CHAR* ptr2, size_t len) {
+ return memcmp(ptr1, ptr2, len);
+}
+
+inline int FXSYS_cmp(const FX_WCHAR* ptr1, const FX_WCHAR* ptr2, size_t len) {
+ return wmemcmp(ptr1, ptr2, len);
+}
+
+inline const FX_CHAR* FXSYS_chr(const FX_CHAR* ptr, FX_CHAR ch, size_t len) {
+ return reinterpret_cast<const FX_CHAR*>(memchr(ptr, ch, len));
+}
+
+inline const FX_WCHAR* FXSYS_chr(const FX_WCHAR* ptr, FX_WCHAR ch, size_t len) {
+ return wmemchr(ptr, ch, len);
+}
+
extern "C" {
#else
#define FXSYS_strlen(ptr) ((FX_STRSIZE)strlen(ptr))
diff --git a/pdfium.gyp b/pdfium.gyp
index 63b4011e3f..5532bc8360 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -615,6 +615,7 @@
'target_name': 'fxcrt',
'type': 'static_library',
'sources': [
+ 'core/fxcrt/cfx_string_c_template.h',
'core/fxcrt/cfx_string_data_template.h',
'core/fxcrt/extension.h',
'core/fxcrt/fx_basic_array.cpp',
diff --git a/testing/fx_string_testhelpers.cpp b/testing/fx_string_testhelpers.cpp
index b2d30f3a06..934dd680e4 100644
--- a/testing/fx_string_testhelpers.cpp
+++ b/testing/fx_string_testhelpers.cpp
@@ -17,7 +17,7 @@ std::ostream& output_string(std::ostream& out, const T& str) {
unsigned int c = str.GetAt(i);
if (c >= 0x20 && c < 0x7F) {
out << static_cast<char>(c);
- } else if (sizeof(typename T::value_type) == 1) {
+ } else if (sizeof(typename T::CharType) == 1) {
out << "\\x" << std::setw(2) << c << std::setw(0);
} else if (c < 0x10000) {
out << "\\u" << std::setw(4) << c << std::setw(0);