From b208774174e102da9f218d89bf8a3af7a0e37f09 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Wed, 22 Apr 2015 12:29:21 -0700 Subject: Merge to XFA: Add missing operators for CFX_xxxString combo patch. This pulls in: Review URL: https://codereview.chromium.org/1099193002 Review URL: https://codereview.chromium.org/1090303003 Review URL: https://codereview.chromium.org/1084293003 Review URL: https://codereview.chromium.org/1099213002 Plus one fix to an XFA file to fix compilation. TBR=thestig@chromium.org Review URL: https://codereview.chromium.org/1095893005 --- core/include/fxcrt/fx_string.h | 56 ++++++--- .../fpdfapi/fpdf_page/fpdf_page_graph_state.cpp | 2 +- .../src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp | 4 +- .../fpdfapi/fpdf_parser/fpdf_parser_utility.cpp | 4 +- core/src/fxcrt/fx_basic_bstring.cpp | 2 +- core/src/fxcrt/fx_basic_bstring_unittest.cpp | 78 ++++++++++++ core/src/fxcrt/fx_basic_buffer.cpp | 10 +- core/src/fxcrt/fx_basic_maps.cpp | 12 +- core/src/fxcrt/fx_basic_wstring_unittest.cpp | 137 ++++++++++++++++----- 9 files changed, 245 insertions(+), 60 deletions(-) (limited to 'core') diff --git a/core/include/fxcrt/fx_string.h b/core/include/fxcrt/fx_string.h index 70f64932c8..1efb814b08 100644 --- a/core/include/fxcrt/fx_string.h +++ b/core/include/fxcrt/fx_string.h @@ -7,6 +7,8 @@ #ifndef _FX_STRING_H_ #define _FX_STRING_H_ +#include + #include "fx_memory.h" class CFX_ByteStringC; @@ -21,7 +23,7 @@ class CFX_WideStringL; // An immutable string with caller-provided storage which must outlive the // string itself. -class CFX_ByteStringC +class CFX_ByteStringC { public: typedef FX_CHAR value_type; @@ -100,7 +102,6 @@ public: { return str.m_Length != m_Length || FXSYS_memcmp32(str.m_Ptr, m_Ptr, m_Length) != 0; } -#define FXBSTR_ID(c1, c2, c3, c4) ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4)) FX_DWORD GetID(FX_STRSIZE start_pos = 0) const; @@ -124,11 +125,6 @@ public: return m_Length == 0; } - operator FX_LPCBYTE() const - { - return m_Ptr; - } - FX_BYTE GetAt(FX_STRSIZE index) const { return m_Ptr[index]; @@ -147,13 +143,23 @@ public: } return CFX_ByteStringC(m_Ptr + index, count); } -protected: - FX_LPCBYTE m_Ptr; + const FX_BYTE& 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: + FX_LPCBYTE m_Ptr; FX_STRSIZE m_Length; -private: +private: void* operator new (size_t) throw() { return NULL; @@ -161,6 +167,7 @@ private: }; typedef const CFX_ByteStringC& FX_BSTR; #define FX_BSTRC(str) CFX_ByteStringC(str, sizeof str-1) +#define FXBSTR_ID(c1, c2, c3, c4) ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4)) struct CFX_StringData { long m_nRefs; @@ -261,6 +268,12 @@ public: return !operator==(str); } + bool operator< (const CFX_ByteString& str) const + { + int result = FXSYS_memcmp32(c_str(), str.c_str(), std::min(GetLength(), str.GetLength())); + return result < 0 || (result == 0 && GetLength() < str.GetLength()); + } + void Empty(); const CFX_ByteString& operator = (FX_LPCSTR str); @@ -428,7 +441,7 @@ inline CFX_ByteString operator + (FX_BSTR str1, const CFX_ByteString& str2) { return CFX_ByteString(str1, str2); } -class CFX_WideStringC +class CFX_WideStringC { public: typedef FX_WCHAR value_type; @@ -550,13 +563,23 @@ public: } return CFX_WideStringC(m_Ptr + m_Length - count, count); } -protected: - FX_LPCWSTR m_Ptr; + 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: + FX_LPCWSTR m_Ptr; FX_STRSIZE m_Length; -private: +private: void* operator new (size_t) throw() { return NULL; @@ -646,6 +669,11 @@ public: const CFX_WideString& operator += (const CFX_WideStringC& str); + bool operator< (const CFX_WideString& str) const { + int result = wmemcmp(c_str(), str.c_str(), std::min(GetLength(), str.GetLength())); + return result < 0 || (result == 0 && GetLength() < str.GetLength()); + } + FX_WCHAR GetAt(FX_STRSIZE nIndex) const { return m_pData ? m_pData->m_String[nIndex] : 0; diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp index 612b0e3716..4ba65f2ccb 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_graph_state.cpp @@ -427,7 +427,7 @@ void CPDF_GeneralStateData::SetBlendMode(FX_BSTR blend_mode) if (blend_mode.GetLength() > 15) { return; } - FXSYS_memcpy32(m_BlendMode, (FX_LPCBYTE)blend_mode, blend_mode.GetLength()); + FXSYS_memcpy32(m_BlendMode, blend_mode.GetPtr(), blend_mode.GetLength()); m_BlendMode[blend_mode.GetLength()] = 0; m_BlendType = ::GetBlendType(blend_mode); } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp index b45e23467f..cc517dd4c2 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp @@ -2562,7 +2562,7 @@ FX_BOOL CPDF_SyntaxParser::SearchWord(FX_BSTR tag, FX_BOOL bWholeWord, FX_BOOL b if (!bForward) { offset = taglen - 1; } - FX_LPCBYTE tag_data = tag; + FX_LPCBYTE tag_data = tag.GetPtr(); FX_BYTE byte; while (1) { if (bForward) { @@ -2599,7 +2599,7 @@ FX_BOOL CPDF_SyntaxParser::SearchWord(FX_BSTR tag, FX_BOOL bWholeWord, FX_BOOL b } } FX_FILESIZE startpos = bForward ? pos - taglen + 1 : pos; - if (!bWholeWord || IsWholeWord(startpos, limit, tag, taglen)) { + if (!bWholeWord || IsWholeWord(startpos, limit, tag.GetPtr(), taglen)) { m_Pos = startpos; return TRUE; } diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp index bbfd4cc680..df154eae90 100644 --- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp +++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_utility.cpp @@ -51,7 +51,7 @@ CPDF_SimpleParser::CPDF_SimpleParser(FX_LPCBYTE pData, FX_DWORD dwSize) } CPDF_SimpleParser::CPDF_SimpleParser(FX_BSTR str) { - m_pData = str; + m_pData = str.GetPtr(); m_dwSize = str.GetLength(); m_dwCurPos = 0; } @@ -198,7 +198,7 @@ FX_BOOL CPDF_SimpleParser::SearchToken(FX_BSTR token) { int token_len = token.GetLength(); while (m_dwCurPos < m_dwSize - token_len) { - if (FXSYS_memcmp32(m_pData + m_dwCurPos, token, token_len) == 0) { + if (FXSYS_memcmp32(m_pData + m_dwCurPos, token.GetPtr(), token_len) == 0) { break; } m_dwCurPos ++; diff --git a/core/src/fxcrt/fx_basic_bstring.cpp b/core/src/fxcrt/fx_basic_bstring.cpp index ea9ca85021..cda7d1fdd7 100644 --- a/core/src/fxcrt/fx_basic_bstring.cpp +++ b/core/src/fxcrt/fx_basic_bstring.cpp @@ -276,7 +276,7 @@ bool CFX_ByteString::EqualNoCase(FX_BSTR str) const return false; } FX_LPCBYTE pThis = (FX_LPCBYTE)m_pData->m_String; - FX_LPCBYTE pThat = (FX_LPCBYTE)str; + FX_LPCBYTE pThat = str.GetPtr(); for (FX_STRSIZE i = 0; i < len; i ++) { if ((*pThis) != (*pThat)) { FX_BYTE bThis = *pThis; diff --git a/core/src/fxcrt/fx_basic_bstring_unittest.cpp b/core/src/fxcrt/fx_basic_bstring_unittest.cpp index 53427e3650..57cfc8047e 100644 --- a/core/src/fxcrt/fx_basic_bstring_unittest.cpp +++ b/core/src/fxcrt/fx_basic_bstring_unittest.cpp @@ -6,6 +6,45 @@ #include "../../../testing/fx_string_testhelpers.h" #include "../../include/fxcrt/fx_basic.h" +TEST(fxcrt, ByteStringOperatorSubscript) { + // CFX_ByteString includes the NUL terminator for non-empty strings. + CFX_ByteString abc("abc"); + EXPECT_EQ('a', abc[0]); + EXPECT_EQ('b', abc[1]); + EXPECT_EQ('c', abc[2]); + EXPECT_EQ(0, abc[3]); +} + +TEST(fxcrt, ByteStringOperatorLT) { + CFX_ByteString empty; + CFX_ByteString a("a"); + CFX_ByteString abc("abc"); + CFX_ByteString def("def"); + + EXPECT_FALSE(empty < empty); + EXPECT_FALSE(a < a); + EXPECT_FALSE(abc < abc); + EXPECT_FALSE(def < def); + + EXPECT_TRUE(empty < a); + EXPECT_FALSE(a < empty); + + EXPECT_TRUE(empty < abc); + EXPECT_FALSE(abc < empty); + + EXPECT_TRUE(empty < def); + EXPECT_FALSE(def < empty); + + EXPECT_TRUE(a < abc); + EXPECT_FALSE(abc < a); + + EXPECT_TRUE(a < def); + EXPECT_FALSE(def < a); + + EXPECT_TRUE(abc < def); + EXPECT_FALSE(def < abc); +} + TEST(fxcrt, ByteStringCNull) { CFX_ByteStringC null_string; EXPECT_EQ(null_string.GetPtr(), nullptr); @@ -190,3 +229,42 @@ TEST(fxcrt, ByteStringCGetAt) { EXPECT_EQ('\0', embedded_nul_string.GetAt(2)); EXPECT_EQ('c', embedded_nul_string.GetAt(3)); } + +TEST(fxcrt, ByteStringCOperatorSubscript) { + // CFX_ByteStringC includes the NUL terminator for non-empty strings. + CFX_ByteStringC abc("abc"); + EXPECT_EQ('a', abc[0]); + EXPECT_EQ('b', abc[1]); + EXPECT_EQ('c', abc[2]); + EXPECT_EQ(0, abc[3]); +} + +TEST(fxcrt, ByteStringCOperatorLT) { + CFX_ByteStringC empty; + CFX_ByteStringC a("a"); + CFX_ByteStringC abc("abc"); + CFX_ByteStringC def("def"); + + EXPECT_FALSE(empty < empty); + EXPECT_FALSE(a < a); + EXPECT_FALSE(abc < abc); + EXPECT_FALSE(def < def); + + EXPECT_TRUE(empty < a); + EXPECT_FALSE(a < empty); + + EXPECT_TRUE(empty < abc); + EXPECT_FALSE(abc < empty); + + EXPECT_TRUE(empty < def); + EXPECT_FALSE(def < empty); + + EXPECT_TRUE(a < abc); + EXPECT_FALSE(abc < a); + + EXPECT_TRUE(a < def); + EXPECT_FALSE(def < a); + + EXPECT_TRUE(abc < def); + EXPECT_FALSE(def < abc); +} diff --git a/core/src/fxcrt/fx_basic_buffer.cpp b/core/src/fxcrt/fx_basic_buffer.cpp index bb8466debe..eb5246acec 100644 --- a/core/src/fxcrt/fx_basic_buffer.cpp +++ b/core/src/fxcrt/fx_basic_buffer.cpp @@ -143,7 +143,7 @@ CFX_ByteStringC CFX_BinaryBuf::GetByteString() const } CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (FX_BSTR lpsz) { - AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength()); + AppendBlock(lpsz.GetPtr(), lpsz.GetLength()); return *this; } CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (int i) @@ -174,7 +174,7 @@ CFX_ByteTextBuf& CFX_ByteTextBuf::operator << (const CFX_ByteTextBuf& buf) } void CFX_ByteTextBuf::operator =(const CFX_ByteStringC& str) { - CopyData((FX_LPCBYTE)str, str.GetLength()); + CopyData(str.GetPtr(), str.GetLength()); } void CFX_WideTextBuf::AppendChar(FX_WCHAR ch) { @@ -285,10 +285,10 @@ CFX_ArchiveSaver& CFX_ArchiveSaver::operator << (FX_BSTR bstr) int len = bstr.GetLength(); if (m_pStream) { m_pStream->WriteBlock(&len, sizeof(int)); - m_pStream->WriteBlock(bstr, len); + m_pStream->WriteBlock(bstr.GetPtr(), len); } else { m_SavingBuf.AppendBlock(&len, sizeof(int)); - m_SavingBuf.AppendBlock(bstr, len); + m_SavingBuf.AppendBlock(bstr.GetPtr(), len); } return *this; } @@ -488,7 +488,7 @@ FX_INT32 IFX_BufferArchive::AppendDWord(FX_DWORD i) } FX_INT32 IFX_BufferArchive::AppendString(FX_BSTR lpsz) { - return AppendBlock((FX_LPCBYTE)lpsz, lpsz.GetLength()); + return AppendBlock(lpsz.GetPtr(), lpsz.GetLength()); } CFX_FileBufferArchive::CFX_FileBufferArchive(FX_STRSIZE size) : IFX_BufferArchive(size) diff --git a/core/src/fxcrt/fx_basic_maps.cpp b/core/src/fxcrt/fx_basic_maps.cpp index e85d35e4ac..8ae44ce6a0 100644 --- a/core/src/fxcrt/fx_basic_maps.cpp +++ b/core/src/fxcrt/fx_basic_maps.cpp @@ -352,7 +352,7 @@ inline FX_DWORD CFX_MapByteStringToPtr::HashKey(FX_BSTR key) const { FX_DWORD nHash = 0; int len = key.GetLength(); - FX_LPCBYTE buf = key; + FX_LPCBYTE buf = key.GetPtr(); for (int i = 0; i < len; i ++) { nHash = (nHash << 5) + nHash + buf[i]; } @@ -518,7 +518,7 @@ void CFX_CMapByteStringToPtr::SetAt(FX_BSTR key, void* value) int size = m_Buffer.GetSize(); for (index = 0; index < size; index ++) { _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); - if (!_CompactStringSame(pKey, (FX_LPCBYTE)key, key_len)) { + if (!_CompactStringSame(pKey, key.GetPtr(), key_len)) { continue; } *(void**)(pKey + 1) = value; @@ -529,19 +529,19 @@ void CFX_CMapByteStringToPtr::SetAt(FX_BSTR key, void* value) if (pKey->m_CompactLen) { continue; } - _CompactStringStore(pKey, (FX_LPCBYTE)key, key_len); + _CompactStringStore(pKey, key.GetPtr(), key_len); *(void**)(pKey + 1) = value; return; } _CompactString* pKey = (_CompactString*)m_Buffer.Add(); - _CompactStringStore(pKey, (FX_LPCBYTE)key, key_len); + _CompactStringStore(pKey, key.GetPtr(), key_len); *(void**)(pKey + 1) = value; } void CFX_CMapByteStringToPtr::AddValue(FX_BSTR key, void* value) { ASSERT(value != NULL); _CompactString* pKey = (_CompactString*)m_Buffer.Add(); - _CompactStringStore(pKey, (FX_LPCBYTE)key, key.GetLength()); + _CompactStringStore(pKey, key.GetPtr(), key.GetLength()); *(void**)(pKey + 1) = value; } void CFX_CMapByteStringToPtr::RemoveKey(FX_BSTR key) @@ -550,7 +550,7 @@ void CFX_CMapByteStringToPtr::RemoveKey(FX_BSTR key) int size = m_Buffer.GetSize(); for (int index = 0; index < size; index++) { _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index); - if (!_CompactStringSame(pKey, (FX_LPCBYTE)key, key_len)) { + if (!_CompactStringSame(pKey, key.GetPtr(), key_len)) { continue; } _CompactStringRelease(pKey); diff --git a/core/src/fxcrt/fx_basic_wstring_unittest.cpp b/core/src/fxcrt/fx_basic_wstring_unittest.cpp index c6e5c2f3d0..084410ad19 100644 --- a/core/src/fxcrt/fx_basic_wstring_unittest.cpp +++ b/core/src/fxcrt/fx_basic_wstring_unittest.cpp @@ -1,29 +1,108 @@ -// Copyright 2014 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. - -#include "testing/gtest/include/gtest/gtest.h" -#include "../../../testing/fx_string_testhelpers.h" -#include "../../include/fxcrt/fx_basic.h" - -#define ByteStringLiteral(str) CFX_ByteString(FX_BSTRC(str)) - -TEST(fxcrt, WideStringUTF16LE_Encode) { - struct UTF16LEEncodeCase { - CFX_WideString ws; - CFX_ByteString bs; - } utf16le_encode_cases[] = { - { L"", ByteStringLiteral("\0\0") }, - { L"abc", ByteStringLiteral("a\0b\0c\0\0\0") }, - { L"abcdef", ByteStringLiteral("a\0b\0c\0d\0e\0f\0\0\0") }, - { L"abc\0def", ByteStringLiteral("a\0b\0c\0\0\0") }, - { L"\xaabb\xccdd", ByteStringLiteral("\xbb\xaa\xdd\xcc\0\0") }, - { L"\x3132\x6162", ByteStringLiteral("\x32\x31\x62\x61\0\0") }, - }; - - for (size_t i = 0; i < FX_ArraySize(utf16le_encode_cases); ++i) { - EXPECT_EQ(utf16le_encode_cases[i].bs, - utf16le_encode_cases[i].ws.UTF16LE_Encode()) - << " for case number " << i; - } -} +// Copyright 2014 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. + +#include "testing/gtest/include/gtest/gtest.h" +#include "../../../testing/fx_string_testhelpers.h" +#include "../../include/fxcrt/fx_basic.h" + +TEST(fxcrt, WideStringOperatorSubscript) { + // CFX_WideString includes the NUL terminator for non-empty strings. + CFX_WideString abc(L"abc"); + EXPECT_EQ(L'a', abc[0]); + EXPECT_EQ(L'b', abc[1]); + EXPECT_EQ(L'c', abc[2]); + EXPECT_EQ(L'\0', abc[3]); +} + +TEST(fxcrt, WideStringOperatorLT) { + CFX_WideString empty; + CFX_WideString a(L"a"); + CFX_WideString abc(L"\x0110qq"); // Comes before despite endianness. + CFX_WideString def(L"\x1001qq"); // Comes after despite endianness. + + EXPECT_FALSE(empty < empty); + EXPECT_FALSE(a < a); + EXPECT_FALSE(abc < abc); + EXPECT_FALSE(def < def); + + EXPECT_TRUE(empty < a); + EXPECT_FALSE(a < empty); + + EXPECT_TRUE(empty < abc); + EXPECT_FALSE(abc < empty); + + EXPECT_TRUE(empty < def); + EXPECT_FALSE(def < empty); + + EXPECT_TRUE(a < abc); + EXPECT_FALSE(abc < a); + + EXPECT_TRUE(a < def); + EXPECT_FALSE(def < a); + + EXPECT_TRUE(abc < def); + EXPECT_FALSE(def < abc); +} + +#define ByteStringLiteral(str) CFX_ByteString(FX_BSTRC(str)) + +TEST(fxcrt, WideStringUTF16LE_Encode) { + struct UTF16LEEncodeCase { + CFX_WideString ws; + CFX_ByteString bs; + } utf16le_encode_cases[] = { + { L"", ByteStringLiteral("\0\0") }, + { L"abc", ByteStringLiteral("a\0b\0c\0\0\0") }, + { L"abcdef", ByteStringLiteral("a\0b\0c\0d\0e\0f\0\0\0") }, + { L"abc\0def", ByteStringLiteral("a\0b\0c\0\0\0") }, + { L"\xaabb\xccdd", ByteStringLiteral("\xbb\xaa\xdd\xcc\0\0") }, + { L"\x3132\x6162", ByteStringLiteral("\x32\x31\x62\x61\0\0") }, + }; + + for (size_t i = 0; i < FX_ArraySize(utf16le_encode_cases); ++i) { + EXPECT_EQ(utf16le_encode_cases[i].bs, + utf16le_encode_cases[i].ws.UTF16LE_Encode()) + << " for case number " << i; + } +} + +TEST(fxcrt, WideStringCOperatorSubscript) { + // CFX_WideStringC includes the NUL terminator for non-empty strings. + CFX_WideStringC abc(L"abc"); + EXPECT_EQ(L'a', abc[0]); + EXPECT_EQ(L'b', abc[1]); + EXPECT_EQ(L'c', abc[2]); + EXPECT_EQ(L'\0', abc[3]); +} + +TEST(fxcrt, WideStringCOperatorLT) { + CFX_WideStringC empty; + CFX_WideStringC a(L"a"); + CFX_WideStringC abc(L"\x0110qq"); // Comes before despite endianness. + CFX_WideStringC def(L"\x1001qq"); // Comes after despite endianness. + + EXPECT_FALSE(empty < empty); + EXPECT_FALSE(a < a); + EXPECT_FALSE(abc < abc); + EXPECT_FALSE(def < def); + + EXPECT_TRUE(empty < a); + EXPECT_FALSE(a < empty); + + EXPECT_TRUE(empty < abc); + EXPECT_FALSE(abc < empty); + + EXPECT_TRUE(empty < def); + EXPECT_FALSE(def < empty); + + EXPECT_TRUE(a < abc); + EXPECT_FALSE(abc < a); + + EXPECT_TRUE(a < def); + EXPECT_FALSE(def < a); + + EXPECT_TRUE(abc < def); + EXPECT_FALSE(def < abc); +} + -- cgit v1.2.3