Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
doxverilog
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
doxverilog
Commits
a9dcbfe2
Commit
a9dcbfe2
authored
Oct 21, 2014
by
Dimitri van Heesch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed refcounting bug in new string implementation
parent
9323ae47
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
15 additions
and
803 deletions
+15
-803
qcstring.h
qtools/qcstring.h
+15
-12
rcstring.h
qtools/rcstring.h
+0
-791
No files found.
qtools/qcstring.h
View file @
a9dcbfe2
...
...
@@ -498,19 +498,22 @@ public:
}
StringRep
&
operator
=
(
const
StringRep
&
s
)
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
if
(
s
.
u
.
s
.
isShort
)
// copy by value
{
u
.
s
=
s
.
u
.
s
;
}
else
// copy by reference
if
(
&
s
!=
this
)
{
u
.
l
.
isShort
=
FALSE
;
u
.
l
.
d
=
s
.
u
.
l
.
d
;
u
.
l
.
d
->
refCount
++
;
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
if
(
s
.
u
.
s
.
isShort
)
// copy by value
{
u
.
s
=
s
.
u
.
s
;
}
else
// copy by reference
{
u
.
l
.
isShort
=
FALSE
;
u
.
l
.
d
=
s
.
u
.
l
.
d
;
u
.
l
.
d
->
refCount
++
;
}
}
return
*
this
;
}
...
...
qtools/rcstring.h
deleted
100644 → 0
View file @
9323ae47
/******************************************************************************
*
* Copyright (C) 1997-2004 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
* granted. No representations are made about the suitability of this software
* for any purpose. It is provided "as is" without express or implied warranty.
* See the GNU General Public License for more details.
*
* Documents produced by Doxygen are derivative works derived from the
* input used in their production; they are not affected by this license.
*
*/
#ifndef RCSTRING_H
#define RCSTRING_H
#define RCString QCString
#ifndef QT_H
#include "qarray.h"
#endif // QT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined(_OS_WIN32_) || defined(__MINGW32__)
#include <stdint.h>
#endif
#if defined(_OS_SUN_) && defined(_CC_GNU_)
#include <strings.h>
#endif
#include <assert.h>
class
QGString
;
/*****************************************************************************
Fixes and workarounds for some platforms
*****************************************************************************/
#if defined(_OS_HPUX_)
// HP-UX has badly defined strstr() etc.
// ### fix in 3.0: change hack_* to qt_hack_*
// by the way HP-UX is probably right, the standard has evolved and
// we'll have to adapt to it
inline
char
*
hack_strstr
(
const
char
*
s1
,
const
char
*
s2
)
{
return
(
char
*
)
strstr
(
s1
,
s2
);
}
inline
char
*
hack_strchr
(
const
char
*
s
,
int
c
)
{
return
(
char
*
)
strchr
(
s
,
c
);
}
inline
char
*
hack_strrchr
(
const
char
*
s
,
int
c
)
{
return
(
char
*
)
strrchr
(
s
,
c
);
}
#define strstr(s1,s2) hack_strstr((s1),(s2))
#define strchr(s,c) hack_strchr((s),(c))
#define strrchr(s,c) hack_strrchr((s),(c))
#endif
/*****************************************************************************
Safe and portable C string functions; extensions to standard string.h
*****************************************************************************/
Q_EXPORT
void
*
qmemmove
(
void
*
dst
,
const
void
*
src
,
uint
len
);
#if defined(_OS_SUN_) || defined(_CC_OC_)
#define memmove(s1,s2,n) qmemmove((s1),(s2),(n))
#endif
#if defined(_OS_WIN32_)
#define qsnprintf _snprintf
#else
#define qsnprintf snprintf
#endif
Q_EXPORT
char
*
qstrdup
(
const
char
*
);
Q_EXPORT
inline
uint
cstrlen
(
const
char
*
str
)
{
return
(
uint
)
strlen
(
str
);
}
Q_EXPORT
inline
uint
qstrlen
(
const
char
*
str
)
{
return
str
?
(
uint
)
strlen
(
str
)
:
0
;
}
Q_EXPORT
inline
char
*
cstrcpy
(
char
*
dst
,
const
char
*
src
)
{
return
strcpy
(
dst
,
src
);
}
Q_EXPORT
inline
char
*
qstrcpy
(
char
*
dst
,
const
char
*
src
)
{
return
src
?
strcpy
(
dst
,
src
)
:
0
;
}
Q_EXPORT
char
*
qstrncpy
(
char
*
src
,
const
char
*
dst
,
uint
len
);
Q_EXPORT
inline
int
cstrcmp
(
const
char
*
str1
,
const
char
*
str2
)
{
return
strcmp
(
str1
,
str2
);
}
Q_EXPORT
inline
int
qstrcmp
(
const
char
*
str1
,
const
char
*
str2
)
{
return
(
str1
&&
str2
)
?
strcmp
(
str1
,
str2
)
:
(
int
)((
intptr_t
)
str2
-
(
intptr_t
)
str1
);
}
Q_EXPORT
inline
int
cstrncmp
(
const
char
*
str1
,
const
char
*
str2
,
uint
len
)
{
return
strncmp
(
str1
,
str2
,
len
);
}
Q_EXPORT
inline
int
qstrncmp
(
const
char
*
str1
,
const
char
*
str2
,
uint
len
)
{
return
(
str1
&&
str2
)
?
strncmp
(
str1
,
str2
,
len
)
:
(
int
)((
intptr_t
)
str2
-
(
intptr_t
)
str1
);
}
Q_EXPORT
int
qstricmp
(
const
char
*
str1
,
const
char
*
str2
);
Q_EXPORT
int
qstrnicmp
(
const
char
*
str1
,
const
char
*
str2
,
uint
len
);
/*****************************************************************************
QByteArray class
*****************************************************************************/
#if defined(Q_TEMPLATEDLL)
template
class
Q_EXPORT
QArray
<
char
>
;
#endif
typedef
QArray
<
char
>
QByteArray
;
/*****************************************************************************
QByteArray stream functions
*****************************************************************************/
#ifndef QT_NO_DATASTREAM
Q_EXPORT
QDataStream
&
operator
<<
(
QDataStream
&
,
const
QByteArray
&
);
Q_EXPORT
QDataStream
&
operator
>>
(
QDataStream
&
,
QByteArray
&
);
#endif
class
QRegExp
;
/** This is an alternative implementation of QCString. It provides basically
* the same functions but uses reference counting and copy on write.
*/
class
RCString
{
public
:
/** creates an empty string */
RCString
()
{
}
/** destroys the string */
~
RCString
()
{
}
/** makes a copy of a string. */
RCString
(
const
RCString
&
s
)
:
m_rep
(
s
.
m_rep
)
{
}
/** creates a string with room for size characters
* @param[in] size the number of character to allocate (including the 0-terminator)
*/
RCString
(
int
size
)
:
m_rep
(
size
)
{
}
/** creates a string from a plain C string.
* @param[in] str A zero terminated C string. When 0 an empty string is created.
*/
RCString
(
const
char
*
str
)
:
m_rep
(
str
)
{
}
/** creates a string from \a str and copies over the first \a maxlen characters. */
RCString
(
const
char
*
str
,
uint
maxlen
)
:
m_rep
(
str
,
maxlen
)
{
}
/** replaces the contents by that of string \a s. */
RCString
&
operator
=
(
const
RCString
&
s
)
{
m_rep
=
s
.
m_rep
;
return
*
this
;
}
/** replaces the contents by that of C string \a str. */
RCString
&
operator
=
(
const
char
*
str
)
{
m_rep
=
str
;
return
*
this
;
}
/** Returns TRUE iff the string is empty. Equivalent to isEmpty(). */
bool
isNull
()
const
{
return
m_rep
.
isEmpty
();
}
/** Returns TRUE iff the string is empty */
bool
isEmpty
()
const
{
return
m_rep
.
isEmpty
();
}
/** Returns the length of the string, excluding the 0-terminator. Equivalent to size(). */
uint
length
()
const
{
return
m_rep
.
length
();
}
/** Returns the length of the string, excluding the 0-terminator. */
uint
size
()
const
{
return
m_rep
.
length
();
}
/** Returns a pointer to the contents of the string in the form of a 0-terminated C string */
char
*
data
()
const
{
return
m_rep
.
data
();
}
/** Resizes the string to hold \a newlen characters
* (this value should include the 0-terminator). If the string is enlarged the contents will
* be left unmodified.
*/
bool
resize
(
uint
newlen
)
{
m_rep
.
resize
(
newlen
);
return
TRUE
;
}
/** Truncates the string at position \a pos. */
bool
truncate
(
uint
pos
)
{
return
resize
(
pos
+
1
);
}
/** Fills a string with a predefined character
* @param[in] c the character used to fill the string with.
* @param[in] len the number of character to fill. Use -1 to fill the whole string.
* @note the string will be resized to contain \a len characters. The contents of the
* string will be lost.
*/
bool
fill
(
char
c
,
int
len
=
-
1
)
{
m_rep
.
fill
(
c
,
len
);
return
TRUE
;
}
/** Returns a deep copy of the string. */
RCString
copy
()
const
{
if
(
length
()
==
0
)
return
RCString
();
RCString
cs
(
length
()
+
1
);
memcpy
(
cs
.
data
(),
data
(),
length
());
return
cs
;
}
RCString
&
sprintf
(
const
char
*
format
,
...
);
int
find
(
char
c
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
char
*
str
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
RCString
&
str
,
int
index
=
0
,
bool
cs
=
TRUE
)
const
;
int
find
(
const
QRegExp
&
rx
,
int
index
=
0
)
const
;
int
findRev
(
char
c
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
char
*
str
,
int
index
=-
1
,
bool
cs
=
TRUE
)
const
;
int
findRev
(
const
QRegExp
&
rx
,
int
index
=-
1
)
const
;
int
contains
(
char
c
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
char
*
str
,
bool
cs
=
TRUE
)
const
;
int
contains
(
const
QRegExp
&
rx
)
const
;
bool
stripPrefix
(
const
char
*
prefix
);
RCString
left
(
uint
len
)
const
;
RCString
right
(
uint
len
)
const
;
RCString
mid
(
uint
index
,
uint
len
=
0xffffffff
)
const
;
RCString
lower
()
const
;
RCString
upper
()
const
;
RCString
stripWhiteSpace
()
const
;
RCString
simplifyWhiteSpace
()
const
;
RCString
&
assign
(
const
char
*
str
);
RCString
&
insert
(
uint
index
,
const
char
*
s
);
RCString
&
insert
(
uint
index
,
char
c
);
RCString
&
append
(
const
char
*
s
);
RCString
&
prepend
(
const
char
*
s
);
RCString
&
remove
(
uint
index
,
uint
len
);
RCString
&
replace
(
uint
index
,
uint
len
,
const
char
*
s
);
RCString
&
replace
(
const
QRegExp
&
rx
,
const
char
*
str
);
short
toShort
(
bool
*
ok
=
0
)
const
;
ushort
toUShort
(
bool
*
ok
=
0
)
const
;
int
toInt
(
bool
*
ok
=
0
)
const
;
uint
toUInt
(
bool
*
ok
=
0
)
const
;
long
toLong
(
bool
*
ok
=
0
)
const
;
ulong
toULong
(
bool
*
ok
=
0
)
const
;
RCString
&
setNum
(
short
n
);
RCString
&
setNum
(
ushort
n
);
RCString
&
setNum
(
int
n
);
RCString
&
setNum
(
uint
n
);
RCString
&
setNum
(
long
n
);
RCString
&
setNum
(
ulong
n
);
/** Converts the string to a plain C string */
operator
const
char
*
()
const
{
return
(
const
char
*
)
data
();
}
/** Appends string \a str to this string and returns a reference to the result. */
RCString
&
operator
+=
(
const
char
*
str
)
{
if
(
!
str
)
return
*
this
;
int
len1
=
length
();
int
len2
=
strlen
(
str
);
resize
(
len1
+
len2
+
1
);
memcpy
(
data
()
+
len1
,
str
,
len2
);
return
*
this
;
}
/** Appends character \a c to this string and returns a reference to the result. */
RCString
&
operator
+=
(
char
c
)
{
int
len
=
length
();
resize
(
len
+
2
);
data
()[
len
]
=
c
;
return
*
this
;
}
/** Returns a reference to the character at index \a i. */
char
&
at
(
uint
i
)
const
{
return
m_rep
.
at
(
i
);
}
/** Indexing operator. Equavalent to at(). */
char
&
operator
[](
int
i
)
const
{
return
m_rep
.
at
((
uint
)
i
);
}
private
:
struct
LSData
;
// long string representation
struct
LongStringRep
{
uchar
isShort
:
1
;
// should be shared with ShortStringRep
uchar
:
7
;
LSData
*
d
;
};
#define SHORT_STR_CAPACITY ((int)sizeof(LongStringRep)-1)
#define SHORT_STR_MAX_LEN (SHORT_STR_CAPACITY-1)
// short string representation
struct
ShortStringRep
{
uchar
isShort
:
1
;
// should be shared with LongStringRep
uchar
len
:
7
;
char
str
[
SHORT_STR_CAPACITY
];
// size including 0-terminator
};
// ref counting string header
struct
LSHeader
{
int
len
;
// length of string without 0 terminator
int
refCount
;
// -1=leaked, 0=one ref & non-cost, n>0, n+1 refs, const
};
// ref counting string data and methods
struct
LSData
:
public
LSHeader
{
char
*
toStr
()
{
return
(
char
*
)(
this
+
1
);
// string data starts after the header
}
// creates a LSData item with room for size bytes (which includes the 0 terminator!)
// if size is zero, an empty string will be created.
static
LSData
*
create
(
int
size
)
{
LSData
*
data
;
data
=
(
LSData
*
)
malloc
(
sizeof
(
LSHeader
)
+
size
);
data
->
len
=
size
-
1
;
data
->
refCount
=
0
;
data
->
toStr
()[
size
-
1
]
=
0
;
return
data
;
}
// remove out reference to the data. Frees memory if no more users
void
dispose
()
{
if
(
--
refCount
<
0
)
free
(
this
);
}
// resizes LSData so it can hold size bytes (which includes the 0 terminator!)
// if size is zero, the string will become empty
static
LSData
*
resize
(
LSData
*
d
,
int
size
)
{
if
(
d
->
len
>
0
&&
d
->
refCount
==
0
)
// non-const, non-empty
{
d
=
(
LSData
*
)
realloc
(
d
,
sizeof
(
LSHeader
)
+
size
);
d
->
len
=
size
-
1
;
d
->
toStr
()[
size
-
1
]
=
0
;
return
d
;
}
else
// need to make a copy
{
LSData
*
newData
=
LSData
::
create
(
size
);
int
len
=
d
->
len
;
if
(
len
>=
size
)
len
=
size
-
1
;
memcpy
(
newData
->
toStr
(),
d
->
toStr
(),
len
);
newData
->
toStr
()[
len
]
=
0
;
d
->
dispose
();
return
newData
;
}
}
};
class
StringRep
{
public
:
StringRep
()
{
//printf("%p:StringRep:empty construct\n",this);
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
~
StringRep
()
{
//printf("%p:StringRep:destruct(short=%d) str='%s'\n",this,u.s.isShort,data());
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
}
StringRep
(
const
StringRep
&
s
)
{
if
(
&
s
!=
this
)
{
//printf("%p:StringRep:copy construct(short=%d)\n",this,s.u.s.isShort);
u
=
s
.
u
;
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
refCount
++
;
}
}
}
StringRep
(
int
size
)
{
u
.
s
.
isShort
=
size
<=
SHORT_STR_CAPACITY
;
//printf("%p:StringRep:size construct(size=%d,isShort=%d)\n",this,size,u.s.isShort);
if
(
u
.
s
.
isShort
)
// init short string
{
if
(
size
>
0
)
{
u
.
s
.
len
=
size
-
1
;
u
.
s
.
str
[
size
-
1
]
=
'\0'
;
}
else
{
u
.
s
.
len
=
0
;
}
}
else
// int long string
{
u
.
l
.
d
=
LSData
::
create
(
size
);
}
}
StringRep
(
const
char
*
str
)
{
if
(
str
)
{
int
len
=
strlen
(
str
);
u
.
s
.
isShort
=
len
<=
SHORT_STR_MAX_LEN
;
//printf("%p:StringRep:c_str construct(isShort=%d,str='%s')\n",this,u.s.isShort,str);
if
(
u
.
s
.
isShort
)
{
u
.
s
.
len
=
len
;
memcpy
(
u
.
s
.
str
,
str
,
len
+
1
);
}
else
{
u
.
l
.
d
=
LSData
::
create
(
len
+
1
);
memcpy
(
u
.
l
.
d
->
toStr
(),
str
,
u
.
l
.
d
->
len
);
}
}
else
// create empty string
{
//printf("%p:StringRep:empty c_str construct\n",this);
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
StringRep
(
const
char
*
str
,
uint
maxlen
)
{
if
(
str
&&
maxlen
>
0
)
{
uint
len
=
strlen
(
str
);
if
(
len
>
maxlen
)
len
=
maxlen
;
u
.
s
.
isShort
=
len
<=
SHORT_STR_MAX_LEN
;
//printf("%p:StringRep:c_str maxlen construct(isShort=%d)\n",this,u.s.isShort);
if
(
u
.
s
.
isShort
)
{
u
.
s
.
len
=
len
;
memcpy
(
u
.
s
.
str
,
str
,
len
);
u
.
s
.
str
[
len
]
=
'\0'
;
}
else
{
u
.
l
.
d
=
LSData
::
create
(
len
+
1
);
memcpy
(
u
.
l
.
d
->
toStr
(),
str
,
len
);
}
}
else
// create empty string
{
//printf("%p:StringRep:empty c_str construct\n",this);
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
StringRep
&
operator
=
(
const
StringRep
&
s
)
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
if
(
s
.
u
.
s
.
isShort
)
// copy by value
{
//printf("%p:StringRep:operator=(short) s='%s'\n",this,s.data());
u
.
s
=
s
.
u
.
s
;
}
else
// copy by reference
{
//printf("%p:StringRep:operator=(long) s='%s'\n",this,s.data());
u
.
l
.
isShort
=
FALSE
;
u
.
l
.
d
=
s
.
u
.
l
.
d
;
u
.
l
.
d
->
refCount
++
;
}
return
*
this
;
}
StringRep
&
operator
=
(
const
char
*
str
)
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
if
(
str
)
{
int
len
=
strlen
(
str
);
u
.
s
.
isShort
=
len
<=
SHORT_STR_MAX_LEN
;
//printf("%p:StringRep:operator=(c_str) isShort=%d\n",this,u.s.isShort);
if
(
u
.
s
.
isShort
)
{
u
.
s
.
len
=
len
;
memcpy
(
u
.
s
.
str
,
str
,
len
+
1
);
}
else
{
u
.
l
.
d
=
LSData
::
create
(
len
+
1
);
memcpy
(
u
.
l
.
d
->
toStr
(),
str
,
u
.
l
.
d
->
len
);
}
}
else
{
//printf("%p:StringRep:operator=(empty c_str)\n",this);
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
return
*
this
;
}
bool
isEmpty
()
const
{
return
u
.
s
.
isShort
&&
u
.
s
.
len
==
0
;
}
uint
length
()
const
{
return
u
.
s
.
isShort
?
u
.
s
.
len
:
u
.
l
.
d
->
len
;
}
char
*
data
()
const
{
if
(
u
.
s
.
isShort
)
{
return
u
.
s
.
len
==
0
?
0
:
(
char
*
)
u
.
s
.
str
;
}
else
{
return
u
.
l
.
d
->
len
==
0
?
0
:
u
.
l
.
d
->
toStr
();
}
}
char
&
at
(
int
i
)
const
{
if
(
u
.
s
.
isShort
)
{
return
(
char
&
)
u
.
s
.
str
[
i
];
}
else
{
return
u
.
l
.
d
->
toStr
()[
i
];
}
}
bool
resize
(
uint
newlen
)
{
if
(
u
.
s
.
isShort
&&
newlen
<=
SHORT_STR_CAPACITY
)
// resize short string
{
if
(
newlen
>
0
)
{
//printf("%p:StringRep:resize short2short\n",this);
u
.
s
.
len
=
newlen
-
1
;
u
.
s
.
str
[
newlen
-
1
]
=
'\0'
;
}
else
{
//printf("%p:StringRep:resize short2empty\n",this);
u
.
s
.
len
=
0
;
}
}
else
if
(
u
.
s
.
isShort
)
// turn short string into long string
{
//printf("%p:StringRep:resize short2long\n",this);
StringRep
tmp
=
*
this
;
u
.
s
.
isShort
=
FALSE
;
u
.
l
.
d
=
LSData
::
create
(
newlen
);
if
(
tmp
.
u
.
s
.
len
>
0
)
{
memcpy
(
u
.
l
.
d
->
toStr
(),
tmp
.
u
.
s
.
str
,
tmp
.
u
.
s
.
len
+
1
);
}
else
{
u
.
l
.
d
->
toStr
()[
0
]
=
'\0'
;
}
}
else
if
(
!
u
.
s
.
isShort
&&
newlen
<=
SHORT_STR_CAPACITY
)
// turn long string into short string
{
if
(
newlen
>
0
)
{
//printf("%p:StringRep:resize long2short\n",this);
StringRep
tmp
(
newlen
);
// copy short part into tmp buffer
memcpy
(
tmp
.
u
.
s
.
str
,
u
.
l
.
d
->
toStr
(),
newlen
-
1
);
tmp
.
u
.
s
.
str
[
newlen
-
1
]
=
'\0'
;
u
.
l
.
d
->
dispose
();
u
.
s
=
tmp
.
u
.
s
;
}
else
{
//printf("%p:StringRep:resize long2empty\n",this);
u
.
l
.
d
->
dispose
();
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
else
// resize long string
{
//printf("%p:StringRep:resize long2long\n",this);
u
.
l
.
d
=
u
.
l
.
d
->
resize
(
u
.
l
.
d
,
newlen
);
}
return
TRUE
;
}
bool
fill
(
char
c
,
int
len
)
{
if
(
len
<
0
)
len
=
length
();
if
(
len
!=
(
int
)
length
())
{
if
(
len
>
0
)
{
resize
(
len
+
1
);
}
else
{
if
(
!
u
.
s
.
isShort
)
{
u
.
l
.
d
->
dispose
();
}
u
.
s
.
isShort
=
TRUE
;
u
.
s
.
len
=
0
;
}
}
if
(
len
>
0
)
{
memset
(
data
(),
c
,
len
);
}
return
TRUE
;
}
private
:
union
{
ShortStringRep
s
;
LongStringRep
l
;
}
u
;
};
StringRep
m_rep
;
};
/*****************************************************************************
QCString stream functions
*****************************************************************************/
#ifndef QT_NO_DATASTREAM
Q_EXPORT
QDataStream
&
operator
<<
(
QDataStream
&
,
const
QCString
&
);
Q_EXPORT
QDataStream
&
operator
>>
(
QDataStream
&
,
QCString
&
);
#endif
/*****************************************************************************
RCString non-member operators
*****************************************************************************/
Q_EXPORT
inline
bool
operator
==
(
const
RCString
&
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
.
data
())
==
0
;
}
Q_EXPORT
inline
bool
operator
==
(
const
RCString
&
s1
,
const
char
*
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
)
==
0
;
}
Q_EXPORT
inline
bool
operator
==
(
const
char
*
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
,
s2
.
data
())
==
0
;
}
Q_EXPORT
inline
bool
operator
!=
(
const
RCString
&
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
.
data
())
!=
0
;
}
Q_EXPORT
inline
bool
operator
!=
(
const
RCString
&
s1
,
const
char
*
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
)
!=
0
;
}
Q_EXPORT
inline
bool
operator
!=
(
const
char
*
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
,
s2
.
data
())
!=
0
;
}
Q_EXPORT
inline
bool
operator
<
(
const
RCString
&
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
.
data
())
<
0
;
}
Q_EXPORT
inline
bool
operator
<
(
const
RCString
&
s1
,
const
char
*
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
)
<
0
;
}
Q_EXPORT
inline
bool
operator
<
(
const
char
*
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
,
s2
.
data
())
<
0
;
}
Q_EXPORT
inline
bool
operator
<=
(
const
RCString
&
s1
,
const
char
*
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
)
<=
0
;
}
Q_EXPORT
inline
bool
operator
<=
(
const
char
*
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
,
s2
.
data
())
<=
0
;
}
Q_EXPORT
inline
bool
operator
>
(
const
RCString
&
s1
,
const
char
*
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
)
>
0
;
}
Q_EXPORT
inline
bool
operator
>
(
const
char
*
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
,
s2
.
data
())
>
0
;
}
Q_EXPORT
inline
bool
operator
>=
(
const
RCString
&
s1
,
const
char
*
s2
)
{
return
qstrcmp
(
s1
.
data
(),
s2
)
>=
0
;
}
Q_EXPORT
inline
bool
operator
>=
(
const
char
*
s1
,
const
RCString
&
s2
)
{
return
qstrcmp
(
s1
,
s2
.
data
())
>=
0
;
}
Q_EXPORT
inline
RCString
operator
+
(
const
RCString
&
s1
,
const
RCString
&
s2
)
{
RCString
tmp
(
s1
);
tmp
+=
s2
;
return
tmp
;
}
inline
RCString
operator
+
(
const
RCString
&
s1
,
const
QGString
&
s2
);
inline
RCString
operator
+
(
const
QGString
&
s1
,
const
RCString
&
s2
);
Q_EXPORT
inline
RCString
operator
+
(
const
RCString
&
s1
,
const
char
*
s2
)
{
RCString
tmp
(
s1
);
tmp
+=
s2
;
return
tmp
;
}
Q_EXPORT
inline
RCString
operator
+
(
const
char
*
s1
,
const
RCString
&
s2
)
{
RCString
tmp
(
s1
);
tmp
+=
s2
;
return
tmp
;
}
Q_EXPORT
inline
RCString
operator
+
(
const
RCString
&
s1
,
char
c2
)
{
RCString
tmp
(
s1
.
data
()
);
tmp
+=
c2
;
return
tmp
;
}
Q_EXPORT
inline
RCString
operator
+
(
char
c1
,
const
RCString
&
s2
)
{
RCString
tmp
;
tmp
+=
c1
;
tmp
+=
s2
;
return
tmp
;
}
inline
const
char
*
qPrint
(
const
char
*
s
)
{
if
(
s
)
return
s
;
else
return
""
;
}
inline
const
char
*
qPrint
(
const
RCString
&
s
)
{
if
(
!
s
.
isEmpty
())
return
s
.
data
();
else
return
""
;
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment