1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
10 #include "fx_memory.h"
12 class CFX_ByteStringC;
14 class CFX_WideStringC;
18 typedef int FX_STRSIZE;
19 class CFX_ByteStringL;
20 class CFX_WideStringL;
22 // An immutable string with caller-provided storage which must outlive the
24 class CFX_ByteStringC : public CFX_Object
27 typedef FX_CHAR value_type;
35 CFX_ByteStringC(FX_LPCBYTE ptr, FX_STRSIZE size)
41 CFX_ByteStringC(FX_LPCSTR ptr)
43 m_Ptr = (FX_LPCBYTE)ptr;
44 m_Length = ptr ? (FX_STRSIZE)FXSYS_strlen(ptr) : 0;
47 // |ch| must be an lvalue that outlives the the CFX_ByteStringC. However,
48 // the use of char rvalues are not caught at compile time. They are
49 // implicitly promoted to CFX_ByteString (see below) and then the
50 // CFX_ByteStringC is constructed from the CFX_ByteString via the alternate
51 // constructor below. The CFX_ByteString then typically goes out of scope
52 // and |m_Ptr| may be left pointing to invalid memory. Beware.
53 // TODO(tsepez): Mark single-argument string constructors as explicit.
54 CFX_ByteStringC(FX_CHAR& ch)
56 m_Ptr = (FX_LPCBYTE)&ch;
60 CFX_ByteStringC(FX_LPCSTR ptr, FX_STRSIZE len)
62 m_Ptr = (FX_LPCBYTE)ptr;
64 m_Length = (FX_STRSIZE)FXSYS_strlen(ptr);
70 CFX_ByteStringC(const CFX_ByteStringC& src)
73 m_Length = src.m_Length;
76 CFX_ByteStringC(const CFX_ByteString& src);
78 CFX_ByteStringC& operator = (FX_LPCSTR src)
80 m_Ptr = (FX_LPCBYTE)src;
81 m_Length = m_Ptr ? (FX_STRSIZE)FXSYS_strlen(src) : 0;
85 CFX_ByteStringC& operator = (const CFX_ByteStringC& src)
88 m_Length = src.m_Length;
92 CFX_ByteStringC& operator = (const CFX_ByteString& src);
94 bool operator == (const CFX_ByteStringC& str) const
96 return str.m_Length == m_Length && FXSYS_memcmp32(str.m_Ptr, m_Ptr, m_Length) == 0;
99 bool operator != (const CFX_ByteStringC& str) const
101 return str.m_Length != m_Length || FXSYS_memcmp32(str.m_Ptr, m_Ptr, m_Length) != 0;
103 #define FXBSTR_ID(c1, c2, c3, c4) ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4))
105 FX_DWORD GetID(FX_STRSIZE start_pos = 0) const;
107 FX_LPCBYTE GetPtr() const
112 FX_LPCSTR GetCStr() const
114 return (FX_LPCSTR)m_Ptr;
117 FX_STRSIZE GetLength() const
124 return m_Length == 0;
127 operator FX_LPCBYTE() const
132 FX_BYTE GetAt(FX_STRSIZE index) const
137 CFX_ByteStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const
142 if (index > m_Length) {
143 return CFX_ByteStringC();
145 if (count < 0 || count > m_Length - index) {
146 count = m_Length - index;
148 return CFX_ByteStringC(m_Ptr + index, count);
157 void* operator new (size_t) throw()
162 typedef const CFX_ByteStringC& FX_BSTR;
163 #define FX_BSTRC(str) CFX_ByteStringC(str, sizeof str-1)
164 struct CFX_StringData {
168 FX_STRSIZE m_nDataLength;
170 FX_STRSIZE m_nAllocLength;
174 class CFX_ByteString : public CFX_Object
177 typedef FX_CHAR value_type;
184 CFX_ByteString(const CFX_ByteString& str);
186 CFX_ByteString(char ch);
188 CFX_ByteString(FX_LPCSTR ptr, FX_STRSIZE len = -1);
190 CFX_ByteString(FX_LPCBYTE ptr, FX_STRSIZE len);
192 CFX_ByteString(FX_BSTR bstrc);
194 CFX_ByteString(FX_BSTR bstrc1, FX_BSTR bstrc2);
198 static CFX_ByteString FromUnicode(FX_LPCWSTR ptr, FX_STRSIZE len = -1);
200 static CFX_ByteString FromUnicode(const CFX_WideString& str);
202 // Explicit conversion to raw string
203 FX_LPCSTR c_str() const
205 return m_pData ? m_pData->m_String : "";
208 // Implicit conversion to C-style string -- deprecated
209 operator FX_LPCSTR() const
211 return m_pData ? m_pData->m_String : "";
214 operator FX_LPCBYTE() const
216 return m_pData ? (FX_LPCBYTE)m_pData->m_String : NULL;
219 FX_STRSIZE GetLength() const
221 return m_pData ? m_pData->m_nDataLength : 0;
229 int Compare(FX_BSTR str) const;
232 bool Equal(FX_BSTR str) const;
235 bool EqualNoCase(FX_BSTR str) const;
237 bool operator == (FX_LPCSTR str) const
242 bool operator == (FX_BSTR str) const
247 bool operator == (const CFX_ByteString& str) const;
249 bool operator != (FX_LPCSTR str) const
254 bool operator != (FX_BSTR str) const
259 bool operator != (const CFX_ByteString& str) const
261 return !operator==(str);
266 const CFX_ByteString& operator = (FX_LPCSTR str);
268 const CFX_ByteString& operator = (FX_BSTR bstrc);
270 const CFX_ByteString& operator = (const CFX_ByteString& stringSrc);
272 const CFX_ByteString& operator = (const CFX_BinaryBuf& buf);
274 void Load(FX_LPCBYTE str, FX_STRSIZE len);
276 const CFX_ByteString& operator += (FX_CHAR ch);
278 const CFX_ByteString& operator += (FX_LPCSTR str);
280 const CFX_ByteString& operator += (const CFX_ByteString& str);
282 const CFX_ByteString& operator += (FX_BSTR bstrc);
284 FX_BYTE GetAt(FX_STRSIZE nIndex) const
286 return m_pData ? m_pData->m_String[nIndex] : 0;
289 FX_BYTE operator[](FX_STRSIZE nIndex) const
291 return m_pData ? m_pData->m_String[nIndex] : 0;
294 void SetAt(FX_STRSIZE nIndex, FX_CHAR ch);
296 FX_STRSIZE Insert(FX_STRSIZE index, FX_CHAR ch);
298 FX_STRSIZE Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
301 void Format(FX_LPCSTR lpszFormat, ... );
303 void FormatV(FX_LPCSTR lpszFormat, va_list argList);
306 void Reserve(FX_STRSIZE len);
308 FX_LPSTR GetBuffer(FX_STRSIZE len);
310 FX_LPSTR LockBuffer();
312 void ReleaseBuffer(FX_STRSIZE len = -1);
314 CFX_ByteString Mid(FX_STRSIZE first) const;
316 CFX_ByteString Mid(FX_STRSIZE first, FX_STRSIZE count) const;
318 CFX_ByteString Left(FX_STRSIZE count) const;
320 CFX_ByteString Right(FX_STRSIZE count) const;
322 FX_STRSIZE Find(FX_BSTR lpszSub, FX_STRSIZE start = 0) const;
324 FX_STRSIZE Find(FX_CHAR ch, FX_STRSIZE start = 0) const;
326 FX_STRSIZE ReverseFind(FX_CHAR ch) const;
334 void TrimRight(FX_CHAR chTarget);
336 void TrimRight(FX_BSTR lpszTargets);
340 void TrimLeft(FX_CHAR chTarget);
342 void TrimLeft(FX_BSTR lpszTargets);
344 FX_STRSIZE Replace(FX_BSTR lpszOld, FX_BSTR lpszNew);
346 FX_STRSIZE Remove(FX_CHAR ch);
348 CFX_WideString UTF8Decode() const;
350 void ConvertFrom(const CFX_WideString& str, CFX_CharMap* pCharMap = NULL);
352 FX_DWORD GetID(FX_STRSIZE start_pos = 0) const;
354 #define FXFORMAT_SIGNED 1
355 #define FXFORMAT_HEX 2
356 #define FXFORMAT_CAPITAL 4
358 static CFX_ByteString FormatInteger(int i, FX_DWORD flags = 0);
360 static CFX_ByteString FormatFloat(FX_FLOAT f, int precision = 0);
363 struct CFX_StringData* m_pData;
364 void AllocCopy(CFX_ByteString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const;
365 void AssignCopy(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData);
366 void ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCSTR lpszSrc2Data);
367 void ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData);
368 void CopyBeforeWrite();
369 void AllocBeforeWrite(FX_STRSIZE nLen);
371 inline CFX_ByteStringC::CFX_ByteStringC(const CFX_ByteString& src)
373 m_Ptr = (FX_LPCBYTE)src;
374 m_Length = src.GetLength();
376 inline CFX_ByteStringC& CFX_ByteStringC::operator = (const CFX_ByteString& src)
378 m_Ptr = (FX_LPCBYTE)src;
379 m_Length = src.GetLength();
383 inline CFX_ByteString operator + (FX_BSTR str1, FX_BSTR str2)
385 return CFX_ByteString(str1, str2);
387 inline CFX_ByteString operator + (FX_BSTR str1, FX_LPCSTR str2)
389 return CFX_ByteString(str1, str2);
391 inline CFX_ByteString operator + (FX_LPCSTR str1, FX_BSTR str2)
393 return CFX_ByteString(str1, str2);
395 inline CFX_ByteString operator + (FX_BSTR str1, FX_CHAR ch)
397 return CFX_ByteString(str1, CFX_ByteStringC(ch));
399 inline CFX_ByteString operator + (FX_CHAR ch, FX_BSTR str2)
401 return CFX_ByteString(ch, str2);
403 inline CFX_ByteString operator + (const CFX_ByteString& str1, const CFX_ByteString& str2)
405 return CFX_ByteString(str1, str2);
407 inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_CHAR ch)
409 return CFX_ByteString(str1, CFX_ByteStringC(ch));
411 inline CFX_ByteString operator + (FX_CHAR ch, const CFX_ByteString& str2)
413 return CFX_ByteString(ch, str2);
415 inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_LPCSTR str2)
417 return CFX_ByteString(str1, str2);
419 inline CFX_ByteString operator + (FX_LPCSTR str1, const CFX_ByteString& str2)
421 return CFX_ByteString(str1, str2);
423 inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_BSTR str2)
425 return CFX_ByteString(str1, str2);
427 inline CFX_ByteString operator + (FX_BSTR str1, const CFX_ByteString& str2)
429 return CFX_ByteString(str1, str2);
431 class CFX_StringBufBase : public CFX_Object
435 CFX_StringBufBase(FX_STRSIZE limit)
441 FX_CHAR* GetPtr() const
443 return (FX_CHAR*)(this + 1);
446 FX_STRSIZE GetSize() const
456 void Copy(FX_BSTR str);
458 void Append(FX_BSTR str);
460 void Append(int i, FX_DWORD flags = 0);
462 CFX_ByteStringC GetStringC() const
464 return CFX_ByteStringC((FX_CHAR*)(this + 1), m_Size);
467 CFX_ByteString GetString() const
469 return CFX_ByteString((FX_CHAR*)(this + 1), m_Size);
477 template<FX_STRSIZE limit>
478 class CFX_StringBufTemplate : public CFX_StringBufBase
482 CFX_StringBufTemplate() : CFX_StringBufBase(limit) {}
484 FX_CHAR m_Buffer[limit];
486 typedef CFX_StringBufTemplate<256> CFX_StringBuf256;
487 class CFX_WideStringC : public CFX_Object
490 typedef FX_WCHAR value_type;
498 CFX_WideStringC(FX_LPCWSTR ptr)
501 m_Length = ptr ? (FX_STRSIZE)FXSYS_wcslen(ptr) : 0;
504 CFX_WideStringC(FX_WCHAR& ch)
510 CFX_WideStringC(FX_LPCWSTR ptr, FX_STRSIZE len)
514 m_Length = (FX_STRSIZE)FXSYS_wcslen(ptr);
520 CFX_WideStringC(const CFX_WideStringC& src)
523 m_Length = src.m_Length;
526 CFX_WideStringC(const CFX_WideString& src);
528 CFX_WideStringC& operator = (FX_LPCWSTR src)
531 m_Length = (FX_STRSIZE)FXSYS_wcslen(src);
535 CFX_WideStringC& operator = (const CFX_WideStringC& src)
538 m_Length = src.m_Length;
542 CFX_WideStringC& operator = (const CFX_WideString& src);
544 bool operator == (const CFX_WideStringC& str) const
546 return str.m_Length == m_Length && FXSYS_memcmp32(str.m_Ptr, m_Ptr, m_Length * sizeof(FX_WCHAR)) == 0;
549 bool operator != (const CFX_WideStringC& str) const
551 return str.m_Length != m_Length || FXSYS_memcmp32(str.m_Ptr, m_Ptr, m_Length * sizeof(FX_WCHAR)) != 0;
554 FX_LPCWSTR GetPtr() const
559 FX_STRSIZE GetLength() const
566 return m_Length == 0;
569 FX_WCHAR GetAt(FX_STRSIZE index) const
574 CFX_WideStringC Left(FX_STRSIZE count) const
577 return CFX_WideStringC();
579 if (count > m_Length) {
582 return CFX_WideStringC(m_Ptr, count);
585 CFX_WideStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const
590 if (index > m_Length) {
591 return CFX_WideStringC();
593 if (count < 0 || count > m_Length - index) {
594 count = m_Length - index;
596 return CFX_WideStringC(m_Ptr + index, count);
599 CFX_WideStringC Right(FX_STRSIZE count) const
602 return CFX_WideStringC();
604 if (count > m_Length) {
607 return CFX_WideStringC(m_Ptr + m_Length - count, count);
616 void* operator new (size_t) throw()
621 typedef const CFX_WideStringC& FX_WSTR;
622 #define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1)
623 struct CFX_StringDataW {
627 FX_STRSIZE m_nDataLength;
629 FX_STRSIZE m_nAllocLength;
631 FX_WCHAR m_String[1];
633 class CFX_WideString : public CFX_Object
636 typedef FX_WCHAR value_type;
643 CFX_WideString(const CFX_WideString& str);
645 CFX_WideString(FX_LPCWSTR ptr, FX_STRSIZE len = -1)
650 CFX_WideString(FX_WCHAR ch);
652 CFX_WideString(const CFX_WideStringC& str);
654 CFX_WideString(const CFX_WideStringC& str1, const CFX_WideStringC& str2);
658 static CFX_WideString FromLocal(const char* str, FX_STRSIZE len = -1);
660 static CFX_WideString FromUTF8(const char* str, FX_STRSIZE len);
662 static CFX_WideString FromUTF16LE(const unsigned short* str, FX_STRSIZE len);
664 static FX_STRSIZE WStringLength(const unsigned short* str);
666 // Explicit conversion to raw string
667 FX_LPCWSTR c_str() const
669 return m_pData ? m_pData->m_String : L"";
672 // Implicit conversion to C-style wide string -- deprecated
673 operator FX_LPCWSTR() const
675 return m_pData ? m_pData->m_String : L"";
681 FX_BOOL IsEmpty() const
686 FX_STRSIZE GetLength() const
688 return m_pData ? m_pData->m_nDataLength : 0;
691 const CFX_WideString& operator = (FX_LPCWSTR str);
693 const CFX_WideString& operator =(const CFX_WideString& stringSrc);
695 const CFX_WideString& operator =(const CFX_WideStringC& stringSrc);
697 const CFX_WideString& operator += (FX_LPCWSTR str);
699 const CFX_WideString& operator += (FX_WCHAR ch);
701 const CFX_WideString& operator += (const CFX_WideString& str);
703 const CFX_WideString& operator += (const CFX_WideStringC& str);
705 FX_WCHAR GetAt(FX_STRSIZE nIndex) const
707 return m_pData ? m_pData->m_String[nIndex] : 0;
710 FX_WCHAR operator[](FX_STRSIZE nIndex) const
712 return m_pData ? m_pData->m_String[nIndex] : 0;
715 void SetAt(FX_STRSIZE nIndex, FX_WCHAR ch);
717 int Compare(FX_LPCWSTR str) const;
719 int Compare(const CFX_WideString& str) const;
721 int CompareNoCase(FX_LPCWSTR str) const;
723 bool Equal(const CFX_WideStringC& str) const;
725 CFX_WideString Mid(FX_STRSIZE first) const;
727 CFX_WideString Mid(FX_STRSIZE first, FX_STRSIZE count) const;
729 CFX_WideString Left(FX_STRSIZE count) const;
731 CFX_WideString Right(FX_STRSIZE count) const;
733 FX_STRSIZE Insert(FX_STRSIZE index, FX_WCHAR ch);
735 FX_STRSIZE Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
737 void Format(FX_LPCWSTR lpszFormat, ... );
739 void FormatV(FX_LPCWSTR lpszFormat, va_list argList);
747 void TrimRight(FX_WCHAR chTarget);
749 void TrimRight(FX_LPCWSTR lpszTargets);
753 void TrimLeft(FX_WCHAR chTarget);
755 void TrimLeft(FX_LPCWSTR lpszTargets);
757 void Reserve(FX_STRSIZE len);
759 FX_LPWSTR GetBuffer(FX_STRSIZE len);
761 FX_LPWSTR LockBuffer();
763 void ReleaseBuffer(FX_STRSIZE len = -1);
765 int GetInteger() const;
767 FX_FLOAT GetFloat() const;
769 FX_STRSIZE Find(FX_LPCWSTR lpszSub, FX_STRSIZE start = 0) const;
771 FX_STRSIZE Find(FX_WCHAR ch, FX_STRSIZE start = 0) const;
773 FX_STRSIZE Replace(FX_LPCWSTR lpszOld, FX_LPCWSTR lpszNew);
775 FX_STRSIZE Remove(FX_WCHAR ch);
777 CFX_ByteString UTF8Encode() const;
779 CFX_ByteString UTF16LE_Encode() const;
781 void ConvertFrom(const CFX_ByteString& str, CFX_CharMap* pCharMap = NULL);
783 void InitStr(FX_LPCWSTR ptr, int len);
785 CFX_StringDataW* m_pData;
786 void CopyBeforeWrite();
787 void AllocBeforeWrite(FX_STRSIZE nLen);
788 void ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData);
789 void ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCWSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCWSTR lpszSrc2Data);
790 void AssignCopy(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData);
791 void AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const;
793 inline CFX_WideStringC::CFX_WideStringC(const CFX_WideString& src)
796 m_Length = src.GetLength();
798 inline CFX_WideStringC& CFX_WideStringC::operator = (const CFX_WideString& src)
801 m_Length = src.GetLength();
805 inline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideStringC& str2)
807 return CFX_WideString(str1, str2);
809 inline CFX_WideString operator + (const CFX_WideStringC& str1, FX_LPCWSTR str2)
811 return CFX_WideString(str1, str2);
813 inline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideStringC& str2)
815 return CFX_WideString(str1, str2);
817 inline CFX_WideString operator + (const CFX_WideStringC& str1, FX_WCHAR ch)
819 return CFX_WideString(str1, CFX_WideStringC(ch));
821 inline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideStringC& str2)
823 return CFX_WideString(ch, str2);
825 inline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideString& str2)
827 return CFX_WideString(str1, str2);
829 inline CFX_WideString operator + (const CFX_WideString& str1, FX_WCHAR ch)
831 return CFX_WideString(str1, CFX_WideStringC(ch));
833 inline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideString& str2)
835 return CFX_WideString(ch, str2);
837 inline CFX_WideString operator + (const CFX_WideString& str1, FX_LPCWSTR str2)
839 return CFX_WideString(str1, str2);
841 inline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideString& str2)
843 return CFX_WideString(str1, str2);
845 inline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideStringC& str2)
847 return CFX_WideString(str1, str2);
849 inline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideString& str2)
851 return CFX_WideString(str1, str2);
854 bool operator==(const CFX_WideString& s1, const CFX_WideString& s2);
855 bool operator==(const CFX_WideString& s1, const CFX_WideStringC& s2);
856 bool operator==(const CFX_WideStringC& s1, const CFX_WideString& s2);
857 bool operator== (const CFX_WideString& s1, FX_LPCWSTR s2);
858 bool operator==(FX_LPCWSTR s1, const CFX_WideString& s2);
859 bool operator!=(const CFX_WideString& s1, const CFX_WideString& s2);
860 bool operator!=(const CFX_WideString& s1, const CFX_WideStringC& s2);
861 bool operator!=(const CFX_WideStringC& s1, const CFX_WideString& s2);
862 bool operator!= (const CFX_WideString& s1, FX_LPCWSTR s2);
863 bool operator!=(FX_LPCWSTR s1, const CFX_WideString& s2);
864 FX_FLOAT FX_atof(FX_BSTR str);
865 void FX_atonum(FX_BSTR str, FX_BOOL& bInteger, void* pData);
866 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
867 CFX_ByteString FX_UTF8Encode(FX_LPCWSTR pwsStr, FX_STRSIZE len);
868 inline CFX_ByteString FX_UTF8Encode(FX_WSTR wsStr)
870 return FX_UTF8Encode(wsStr.GetPtr(), wsStr.GetLength());
872 inline CFX_ByteString FX_UTF8Encode(const CFX_WideString &wsStr)
874 return FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength());