finalcut/include/final/fstring.h

501 lines
19 KiB
C
Raw Normal View History

2017-11-04 07:03:53 +01:00
/***********************************************************************
* fstring.h - Unicode string class with UTF-8 support *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2012-2018 Markus Gans *
2017-11-04 07:03:53 +01:00
* *
* The Final Cut is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License *
* as published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* The Final Cut is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
/* Standalone class
*
*
*
* FString
*
*/
2015-05-23 13:35:12 +02:00
#ifndef FSTRING_H
#define FSTRING_H
2015-05-23 13:35:12 +02:00
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
#error "Only <final/final.h> can be included directly."
#endif
#include <langinfo.h>
2015-05-23 13:35:12 +02:00
#include <stdint.h>
#include <cassert>
#include <cerrno> // for read errno
#include <cfloat>
2015-05-23 13:35:12 +02:00
#include <climits>
#include <cmath>
#include <cstdarg> // need for va_list, va_start and va_end
#include <cstdio> // need for vsprintf
2015-05-23 13:35:12 +02:00
#include <cstring>
#include <cwchar>
#include <cwctype>
#include <iostream>
#include <new>
#include <stdexcept>
#include <string>
#include <vector>
#include "final/ftypes.h"
2017-09-20 16:56:20 +02:00
// class forward declaration
class FString;
// Global typedef
typedef std::vector<FString> FStringList;
2015-05-23 13:35:12 +02:00
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
// class FString
//----------------------------------------------------------------------
class FString
{
2017-09-11 03:06:02 +02:00
public:
// Typedef
typedef const wchar_t* iterator;
// Constructors
FString ();
explicit FString (int);
explicit FString (uInt);
FString (int, wchar_t);
FString (uInt, wchar_t);
FString (int, char);
FString (uInt, char);
FString (const FString&); // implicit conversion copy constructor
FString (const std::wstring&); // implicit conversion constructor
FString (const wchar_t[]); // implicit conversion constructor
2017-09-11 03:06:02 +02:00
FString (const std::string&); // implicit conversion constructor
FString (const char[]); // implicit conversion constructor
2017-09-11 03:06:02 +02:00
FString (const wchar_t); // implicit conversion constructor
FString (const char); // implicit conversion constructor
// Destructor
virtual ~FString ();
// Overloaded operators
FString& operator = (const FString&);
FString& operator = (const std::wstring&);
const FString& operator = (const wchar_t[]);
2017-09-11 03:06:02 +02:00
FString& operator = (const std::string&);
const FString& operator = (const char[]);
2017-09-11 03:06:02 +02:00
const FString& operator = (const wchar_t);
const FString& operator = (const char);
const FString& operator += (const FString&);
const FString& operator += (const std::wstring&);
const FString& operator += (const wchar_t[]);
2017-09-11 03:06:02 +02:00
const FString& operator += (const std::string&);
const FString& operator += (const char[]);
2017-09-11 03:06:02 +02:00
const FString& operator += (const wchar_t);
const FString& operator += (const char);
const FString operator + (const FString&);
const FString operator + (const std::wstring&);
const FString operator + (const wchar_t[]);
2017-09-11 03:06:02 +02:00
const FString operator + (const std::string&);
const FString operator + (const char[]);
2017-09-11 03:06:02 +02:00
const FString operator + (const wchar_t);
const FString operator + (const char);
2017-09-20 02:51:17 +02:00
FString& operator << (const FString&);
FString& operator << (const wchar_t);
FString& operator << (const char);
FString& operator << (const sInt16);
FString& operator << (const uInt16);
FString& operator << (const int);
FString& operator << (const uInt);
FString& operator << (const long);
FString& operator << (const uLong);
FString& operator << (const float);
FString& operator << (const double);
FString& operator << (const lDouble);
const FString& operator >> (FString&);
const FString& operator >> (std::wstring&);
2018-03-03 22:24:57 +01:00
const FString& operator >> (std::string&);
2017-09-20 02:51:17 +02:00
const FString& operator >> (wchar_t&);
const FString& operator >> (char&);
const FString& operator >> (sInt16&);
const FString& operator >> (uInt16&);
const FString& operator >> (int&);
const FString& operator >> (uInt&);
const FString& operator >> (long&);
const FString& operator >> (uLong&);
const FString& operator >> (double&);
const FString& operator >> (float&);
2017-09-11 03:06:02 +02:00
wchar_t& operator [] (int);
wchar_t& operator [] (uInt);
const FString& operator () ();
bool operator < (const FString&) const;
bool operator < (const std::wstring&) const;
bool operator < (const wchar_t[]) const;
2017-09-11 03:06:02 +02:00
bool operator < (const std::string&) const;
bool operator < (const char[]) const;
2017-09-11 03:06:02 +02:00
bool operator < (const wchar_t) const;
bool operator < (const char) const;
bool operator <= (const FString&) const;
bool operator <= (const std::wstring&) const;
bool operator <= (const wchar_t[]) const;
2017-09-11 03:06:02 +02:00
bool operator <= (const std::string&) const;
bool operator <= (const char[]) const;
2017-09-11 03:06:02 +02:00
bool operator <= (const wchar_t) const;
bool operator <= (const char) const;
bool operator == (const FString&) const;
bool operator == (const std::wstring&) const;
bool operator == (const wchar_t[]) const;
2017-09-11 03:06:02 +02:00
bool operator == (const std::string&) const;
bool operator == (const char[]) const;
2017-09-11 03:06:02 +02:00
bool operator == (const wchar_t) const;
bool operator == (const char) const;
bool operator != (const FString&) const;
bool operator != (const std::wstring&) const;
bool operator != (const wchar_t[]) const;
2017-09-11 03:06:02 +02:00
bool operator != (const std::string&) const;
bool operator != (const char[]) const;
2017-09-11 03:06:02 +02:00
bool operator != (const wchar_t) const;
bool operator != (const char) const;
bool operator >= (const FString&) const;
bool operator >= (const std::wstring&) const;
bool operator >= (const wchar_t[]) const;
2017-09-11 03:06:02 +02:00
bool operator >= (const std::string&) const;
bool operator >= (const char[]) const;
2017-09-11 03:06:02 +02:00
bool operator >= (const wchar_t) const;
bool operator >= (const char) const;
bool operator > (const FString&) const;
bool operator > (const std::wstring&) const;
bool operator > (const wchar_t[]) const;
2017-09-11 03:06:02 +02:00
bool operator > (const std::string&) const;
bool operator > (const char[]) const;
2017-09-11 03:06:02 +02:00
bool operator > (const wchar_t) const;
bool operator > (const char) const;
operator const char* () const { return c_str(); }
// Non-member operators
friend const FString operator + (const FString&, const FString&);
friend const FString operator + (const FString&, const wchar_t);
friend const FString operator + (const std::wstring&, const FString&);
friend const FString operator + (const wchar_t[], const FString&);
2017-09-11 03:06:02 +02:00
friend const FString operator + (const std::string&, const FString&);
friend const FString operator + (const char[], const FString&);
2017-09-11 03:06:02 +02:00
friend const FString operator + (const wchar_t, const FString&);
friend const FString operator + (const char, const FString&);
friend const FString operator + (const FString&, const char);
2017-09-11 03:06:02 +02:00
2017-09-20 02:51:17 +02:00
friend std::ostream& operator << (std::ostream& outstr, const FString& s);
friend std::istream& operator >> (std::istream& instr, FString& s);
friend std::wostream& operator << (std::wostream& outstr, const FString& s);
friend std::wistream& operator >> (std::wistream& instr, FString& s);
2018-03-13 01:04:46 +01:00
// Accessor
virtual const char* getClassName();
2017-09-11 03:06:02 +02:00
// inquiries
bool isNull() const;
bool isEmpty() const;
// Methods
uInt getLength() const;
uInt getUTF8length() const;
iterator begin() const;
iterator end() const;
wchar_t front() const;
wchar_t back() const;
2018-03-21 00:02:43 +01:00
FString& sprintf (const FString&, ...);
FString& sprintf (const wchar_t[], ...);
FString& sprintf (const char[], ...)
2017-09-11 03:06:02 +02:00
#if defined(__clang__)
__attribute__((__format__ (__printf__, 2, 3)))
#elif defined(__GNUC__)
__attribute__ ((format (printf, 2, 3)))
#endif
;
FString clear();
const wchar_t* wc_str() const;
wchar_t* wc_str();
2017-09-11 03:06:02 +02:00
const char* c_str() const;
char* c_str();
2017-09-11 03:06:02 +02:00
const std::string toString() const;
FString toLower() const;
FString toUpper() const;
sInt16 toShort() const;
uInt16 toUShort() const;
int toInt() const;
uInt toUInt() const;
long toLong() const;
uLong toULong() const;
float toFloat() const;
double toDouble() const;
FString ltrim() const;
FString rtrim() const;
FString trim() const;
FString left (int) const;
FString left (uInt) const;
FString right (int) const;
FString right (uInt) const;
FString mid (int, int) const;
FString mid (uInt, uInt) const;
2017-09-20 16:56:20 +02:00
FStringList split (const FString&);
FStringList split (const std::wstring&);
FStringList split (const wchar_t[]);
2017-09-20 16:56:20 +02:00
FStringList split (const std::string&);
FStringList split (const char[]);
2017-09-20 16:56:20 +02:00
FStringList split (const wchar_t);
FStringList split (const char);
2017-09-11 03:06:02 +02:00
FString& setString (const wchar_t[]);
FString& setString (const char[]);
2017-09-11 03:06:02 +02:00
FString& setNumber (sInt16);
FString& setNumber (uInt16);
FString& setNumber (int);
FString& setNumber (uInt);
FString& setNumber (long);
FString& setNumber (uLong);
2017-09-20 02:51:17 +02:00
FString& setNumber (float, int = FLT_DIG);
FString& setNumber (double, int = DBL_DIG);
FString& setNumber (lDouble, int = LDBL_DIG);
2017-09-11 03:06:02 +02:00
FString& setFormatedNumber (sInt16, char = nl_langinfo(THOUSEP)[0]);
FString& setFormatedNumber (uInt16, char = nl_langinfo(THOUSEP)[0]);
FString& setFormatedNumber (int, char = nl_langinfo(THOUSEP)[0]);
FString& setFormatedNumber (uInt, char = nl_langinfo(THOUSEP)[0]);
FString& setFormatedNumber (long, char = nl_langinfo(THOUSEP)[0]);
FString& setFormatedNumber (uLong, char = nl_langinfo(THOUSEP)[0]);
const FString& insert (const FString&, uInt);
const FString& insert (const wchar_t[], uInt);
const FString& insert (const char[], uInt);
2017-09-11 03:06:02 +02:00
const FString& insert (const wchar_t, uInt);
const FString& insert (const char, uInt);
FString replace (const FString&, const FString&);
FString replace (const FString&, const std::wstring&);
FString replace (const FString&, const wchar_t[]);
2017-09-11 03:06:02 +02:00
FString replace (const FString&, const std::string&);
FString replace (const FString&, const char[]);
2017-09-11 03:06:02 +02:00
FString replace (const FString&, const wchar_t);
FString replace (const FString&, const char);
FString replace (const std::wstring&, const FString&);
FString replace (const std::wstring&, const std::wstring&);
FString replace (const std::wstring&, const wchar_t[]);
2017-09-11 03:06:02 +02:00
FString replace (const std::wstring&, const std::string&);
FString replace (const std::wstring&, const char[]);
2017-09-11 03:06:02 +02:00
FString replace (const std::wstring&, const wchar_t);
FString replace (const std::wstring&, const char);
FString replace (const std::string&, const FString&);
FString replace (const std::string&, const std::wstring&);
FString replace (const std::string&, const wchar_t[]);
2017-09-11 03:06:02 +02:00
FString replace (const std::string&, const std::string&);
FString replace (const std::string&, const char[]);
2017-09-11 03:06:02 +02:00
FString replace (const std::string&, const wchar_t);
FString replace (const std::string&, const char);
FString replace (const wchar_t[], const FString&);
FString replace (const wchar_t[], const std::wstring&);
FString replace (const wchar_t[], const wchar_t[]);
FString replace (const wchar_t[], const std::string&);
FString replace (const wchar_t[], const char[]);
FString replace (const wchar_t[], const wchar_t);
FString replace (const wchar_t[], const char);
FString replace (const char[], const FString&);
FString replace (const char[], const std::wstring&);
FString replace (const char[], const wchar_t[]);
FString replace (const char[], const std::string&);
FString replace (const char[], const char[]);
FString replace (const char[], const wchar_t);
FString replace (const char[], const char);
2017-09-11 03:06:02 +02:00
FString replace (const wchar_t, const FString&);
FString replace (const wchar_t, const std::wstring&);
FString replace (const wchar_t, const wchar_t[]);
2017-09-11 03:06:02 +02:00
FString replace (const wchar_t, const std::string&);
FString replace (const wchar_t, const char[]);
2017-09-11 03:06:02 +02:00
FString replace (const wchar_t, const wchar_t);
FString replace (const wchar_t, const char);
FString replace (const char, const FString&);
FString replace (const char, const std::wstring&);
FString replace (const char, const wchar_t[]);
2017-09-11 03:06:02 +02:00
FString replace (const char, const std::string&);
FString replace (const char, const char[]);
2017-09-11 03:06:02 +02:00
FString replace (const char, const wchar_t);
FString replace (const char, const char);
FString replaceControlCodes() const;
FString expandTabs (int = 8) const;
FString removeDel() const;
FString removeBackspaces() const;
2018-03-10 05:27:55 +01:00
const FString& overwrite (const FString&, int);
const FString& overwrite (const FString&, uInt = 0);
const FString& overwrite (const wchar_t[], int);
const FString& overwrite (const wchar_t[], uInt = 0);
const FString& overwrite (const wchar_t, int);
const FString& overwrite (const wchar_t, uInt = 0);
2017-09-11 03:06:02 +02:00
const FString& remove (uInt, uInt);
2018-03-10 05:27:55 +01:00
bool includes (const FString&) const;
bool includes (const wchar_t[]) const;
bool includes (const char[]) const;
bool includes (const wchar_t) const;
bool includes (const char) const;
2017-09-11 03:06:02 +02:00
private:
// Constants
static const uInt FWDBUFFER = 15;
static const uInt INPBUFFER = 200;
static const uInt CHAR_SIZE = sizeof(wchar_t); // bytes per character
static const char* const bad_alloc_str;
// Methods
void initLength (uInt);
void _assign (const wchar_t[]);
void _insert (uInt, uInt, const wchar_t[]);
2017-09-11 03:06:02 +02:00
void _remove (uInt, uInt);
char* wc_to_c_str (const wchar_t[]) const;
wchar_t* c_to_wc_str (const char[]) const;
wchar_t* extractToken (wchar_t*[], const wchar_t[], const wchar_t[]);
2017-09-11 03:06:02 +02:00
// Data Members
wchar_t* string;
uInt length;
uInt bufsize;
mutable char* c_string;
2015-05-23 13:35:12 +02:00
};
// FString inline functions
2018-03-13 01:04:46 +01:00
//----------------------------------------------------------------------
inline const char* FString::getClassName()
{ return "FString"; }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
inline bool FString::isNull() const
{ return ! string; }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
inline bool FString::isEmpty() const
{ return ( ! string ) || ( ! *string ); }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
inline uInt FString::getLength() const
{ return length; }
//----------------------------------------------------------------------
inline FString::iterator FString::begin() const
{ return string; }
//----------------------------------------------------------------------
inline FString::iterator FString::end() const
{ return string + length; }
//----------------------------------------------------------------------
inline wchar_t FString::front() const
{
assert( ! isEmpty() );
return string[0];
}
//----------------------------------------------------------------------
inline wchar_t FString::back() const
{
assert( ! isEmpty() );
2017-09-15 01:31:02 +02:00
return string[length - 1];
2015-05-23 13:35:12 +02:00
}
2015-05-28 22:48:15 +02:00
//----------------------------------------------------------------------
2017-09-20 16:56:20 +02:00
inline FStringList FString::split (const std::wstring& s)
2015-05-28 22:48:15 +02:00
{ return split(FString(s)); }
//----------------------------------------------------------------------
inline FStringList FString::split (const wchar_t s[])
2015-05-28 22:48:15 +02:00
{ return split(FString(s)); }
//----------------------------------------------------------------------
2017-09-20 16:56:20 +02:00
inline FStringList FString::split (const std::string& s)
2015-05-28 22:48:15 +02:00
{ return split(FString(s)); }
//----------------------------------------------------------------------
inline FStringList FString::split (const char s[])
2015-05-28 22:48:15 +02:00
{ return split(FString(s)); }
//----------------------------------------------------------------------
2017-09-20 16:56:20 +02:00
inline FStringList FString::split (const wchar_t c)
2015-05-28 22:48:15 +02:00
{ return split(FString(c)); }
//----------------------------------------------------------------------
2017-09-20 16:56:20 +02:00
inline FStringList FString::split (const char c)
2015-05-28 22:48:15 +02:00
{ return split(FString(c)); }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
inline FString& FString::setNumber (sInt16 num)
{ return setNumber (long(num)); }
//----------------------------------------------------------------------
inline FString& FString::setNumber (uInt16 num)
{ return setNumber (uLong(num)); }
//----------------------------------------------------------------------
inline FString& FString::setNumber (int num)
{ return setNumber (long(num)); }
//----------------------------------------------------------------------
inline FString& FString::setNumber (uInt num)
{ return setNumber (uLong(num)); }
//----------------------------------------------------------------------
inline FString& FString::setNumber (float num, int precision)
{ return setNumber (lDouble(num), precision); }
//----------------------------------------------------------------------
inline FString& FString::setNumber (double num, int precision)
{ return setNumber (lDouble(num), precision); }
2015-05-23 13:35:12 +02:00
//----------------------------------------------------------------------
inline FString& FString::setFormatedNumber (sInt16 num, char separator)
{ return setFormatedNumber (long(num), separator); }
//----------------------------------------------------------------------
inline FString& FString::setFormatedNumber (uInt16 num, char separator)
{ return setFormatedNumber (uLong(num), separator); }
//----------------------------------------------------------------------
inline FString& FString::setFormatedNumber (int num, char separator)
{ return setFormatedNumber (long(num), separator); }
//----------------------------------------------------------------------
inline FString& FString::setFormatedNumber (uInt num, char separator)
{ return setFormatedNumber (uLong(num), separator); }
#endif // FSTRING_H