Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6270ae6
part one of optimizations, created testbench app
buggins Jul 22, 2026
799724f
trying to get working with memory pool turned on
buggins Jul 22, 2026
4258b74
extended lStringXX test coverage
buggins Jul 23, 2026
a24e227
fix memory corruption - replace memcpy with memmove
buggins Jul 23, 2026
cfb9f17
separate string library tests to stringtest.* files
buggins Jul 23, 2026
14739e5
extended test suite for strings, improved diagnostics; tests still fa…
buggins Jul 23, 2026
01c3ebb
strings library fixes
buggins Jul 23, 2026
001ec9a
initial version of new string library - in test
buggins Jul 24, 2026
a676dfd
extending new strings library
buggins Jul 24, 2026
f8e2822
new strings, add comparision
buggins Jul 24, 2026
d01d20f
extend test coverage
buggins Jul 24, 2026
36bd654
lstring2 library tests moved to separate files; added string [] and at()
buggins Jul 25, 2026
885e6da
fix self-assignments
buggins Jul 25, 2026
bb27f75
lvstring2 -- implemented reserve
buggins Jul 25, 2026
cf0c24b
extend lvstring2 impl with c_str() data() lock() modify()
buggins Jul 25, 2026
80834bf
add getFirstChar() / getLastChar()
buggins Jul 25, 2026
3838090
fragment assignments, typedefs
buggins Jul 25, 2026
1ddc318
reserved size constructor
buggins Jul 25, 2026
c9e358e
implement erase
buggins Jul 25, 2026
c3f19b1
implement more append() methods
buggins Jul 25, 2026
5c3239d
implement inserts
buggins Jul 25, 2026
c414332
insert(), pack()
buggins Jul 25, 2026
6c1f54c
replace()
buggins Jul 25, 2026
ee9b375
additional compare()
buggins Jul 25, 2026
f00aeab
increase coverage of new strings implementation
buggins Jul 27, 2026
32ca4cf
more methods implemented in new string; covered with tests
buggins Jul 27, 2026
8ef5e01
refactor: add base read-only string class and place readonly methods …
buggins Jul 27, 2026
a200bea
add missing modify methods to wr_string, cover with tests
buggins Jul 27, 2026
db04da4
implement itoa() and atoi() in new strings implementation
buggins Jul 27, 2026
392d13d
fix itoa/atoi
buggins Jul 27, 2026
5a01307
implement getHash() and trim()
buggins Jul 28, 2026
a01ffa7
utf decode support
buggins Jul 28, 2026
5d75e1b
string ops optimizations
buggins Jul 28, 2026
c32b522
utf conversions
buggins Jul 28, 2026
39503d1
utf encoding/decoding
buggins Jul 29, 2026
74c17a8
compareUtf()
buggins Jul 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ endif()

PROJECT(cr3)

set(CMAKE_CXX_STANDARD 17`)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/")
Expand Down Expand Up @@ -83,6 +83,16 @@ ADD_DEFINITIONS( -DUSE_EXTERNAL_EDICT_DICTIONARY=${USE_EXTERNAL_EDICT_DICTIONARY

# Document buffer cache / compression settings

#own memory manager
if (NOT DEFINED LDOM_USE_OWN_MEM_MAN)
SET(LDOM_USE_OWN_MEM_MAN 0)
else()
SET(LDOM_USE_OWN_MEM_MAN ${LDOM_USE_OWN_MEM_MAN})
endif(NOT DEFINED LDOM_USE_OWN_MEM_MAN)
message("using LDOM_USE_OWN_MEM_MAN=${LDOM_USE_OWN_MEM_MAN}")
ADD_DEFINITIONS( -DLDOM_USE_OWN_MEM_MAN=${LDOM_USE_OWN_MEM_MAN} )


#whether to compress data
if (NOT DEFINED DOC_DATA_COMPRESSION_LEVEL)
message("-D DOC_DATA_COMPRESSION_LEVEL=0|1|2|3|4|5 parameter is not defined: will use default value")
Expand Down Expand Up @@ -147,7 +157,7 @@ endif (NOT DEFINED ENABLE_DBUS_VIEWER_EVENTS)

SET (CRGUI_DEFS -DCOLOR_BACKBUFFER=0 -DLDOM_USE_OWN_MEM_MAN=0 -DGRAY_BACKBUFFER_BITS=${GRAY_BACKBUFFER_BITS}
-DENABLE_DBUS_VIEWER_EVENTS=${ENABLE_DBUS_VIEWER_EVENTS})
SET (DESKTOP_DEFS -DCOLOR_BACKBUFFER=1 -DLDOM_USE_OWN_MEM_MAN=1 -DUSE_FREETYPE=1 )
SET (DESKTOP_DEFS -DCOLOR_BACKBUFFER=1 -DLDOM_USE_OWN_MEM_MAN=0 -DUSE_FREETYPE=1 )
# Uncomment to test e-ink style color palette on Desktop
#SET (DESKTOP_DEFS -DCOLOR_BACKBUFFER=0 -DGRAY_BACKBUFFER_BITS=4 -DLDOM_USE_OWN_MEM_MAN=1 -DUSE_FREETYPE=1 )

Expand All @@ -167,6 +177,7 @@ if( ${GUI} STREQUAL QT5 )
add_definitions(${Qt5Core_DEFINITIONS})
endif( ${GUI} STREQUAL QT5 )


# thirdparty sources definitions
include("${CMAKE_SOURCE_DIR}/thirdparty_repo/repo_srcdirs.cmake")

Expand Down Expand Up @@ -480,6 +491,11 @@ elseif ( ${GUI} STREQUAL QT6 )
ADD_DEFINITIONS( ${DESKTOP_DEFS} )
ADD_SUBDIRECTORY(crengine)
ADD_SUBDIRECTORY(cr3qt)
elseif ( ${GUI} STREQUAL CR3TEST )
message("Will make CR3TEST benchmarks")
#ADD_DEFINITIONS( ${DESKTOP_DEFS} )
ADD_SUBDIRECTORY(crengine)
ADD_SUBDIRECTORY(tests)
elseif ( ${GUI} STREQUAL WX )
message("Will make CR3/WX")
ADD_DEFINITIONS( ${DESKTOP_DEFS} -DCR_WX_SUPPORT=1 )
Expand Down
122 changes: 109 additions & 13 deletions crengine/include/lvstring.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include <limits.h>
#include "lvtypes.h"
#include "lvmemman.h"
#include "utility"

// (Note: some of these 0x have lowercase hex digit, to avoid
// 'redefined' warnings as they are already defined in lowercase
Expand Down Expand Up @@ -297,6 +298,10 @@ namespace fmt {
};
}

#if LDOM_USE_OWN_MEM_MAN==1
/// returns true if string chunk storage has been destroyed
bool ls_storage_is_destroyed();
#endif

/**
\brief lChar8 string
Expand All @@ -312,8 +317,8 @@ class lString8
public:
// typedefs for STL compatibility
typedef lChar8 value_type; ///< character type
typedef int size_type; ///< size type
typedef int difference_type; ///< difference type
typedef lUInt32 size_type; ///< size type
typedef lInt32 difference_type; ///< difference type
typedef value_type * pointer; ///< pointer to char type
typedef value_type & reference; ///< reference to char type
typedef const value_type * const_pointer; ///< pointer to const char type
Expand Down Expand Up @@ -341,21 +346,29 @@ class lString8
void alloc(size_type sz);
void free();
inline void addref() const {
#if LDOM_USE_OWN_MEM_MAN==1
if (ls_storage_is_destroyed()) return;
#endif
#ifdef USE_ATOMIC_REFCOUNT
pchunk->refCount.fetch_add(1);
#else
++pchunk->refCount;
#endif
}
inline void release() {
inline void release() {
if (!pchunk) return;
#ifdef USE_ATOMIC_REFCOUNT
if (pchunk->refCount.fetch_sub(1) <= 1)
free();
#else
if (--pchunk->refCount==0) free();
#endif
pchunk = nullptr;
}
inline int refCount() {
#if LDOM_USE_OWN_MEM_MAN==1
if (ls_storage_is_destroyed()) return 0;
#endif
return pchunk->refCount;
}
explicit lString8(lstring_chunk_t * chunk) : pchunk(chunk) { addref(); }
Expand All @@ -366,6 +379,11 @@ class lString8
explicit lString8( int size ) : pchunk(EMPTY_STR_8) { addref(); reserve(size); }
/// copy constructor
lString8(const lString8 & str) : pchunk(str.pchunk) { addref(); }
/// move constructor
lString8(lString8&& str) : pchunk(nullptr) {
pchunk = str.pchunk;
str.pchunk = nullptr;
}
/// constructor from C string
explicit lString8(const value_type * str);
/// constructor from 16-bit C string
Expand All @@ -388,6 +406,18 @@ class lString8
}
return *this;
}
/// move assignment
lString8 & assign(lString8 && str)
{
if (pchunk!=str.pchunk)
{
release();
pchunk = str.pchunk;
str.pchunk = nullptr;
//addref();
}
return *this;
}
/// C-string assignment
lString8 & assign(const value_type * str);
/// C-string fragment assignment
Expand All @@ -398,6 +428,8 @@ class lString8
lString8 & operator = (const value_type * str) { return assign(str); }
/// string copy assignment
lString8 & operator = (const lString8 & str) { return assign(str); }
/// string copy assignment
lString8 & operator = (lString8 && str) { return assign(std::move(str)); }
/// erase part of string
lString8 & erase(size_type offset, size_type count);
/// append C-string
Expand Down Expand Up @@ -522,7 +554,7 @@ class lString8
/// changes buffer size
void resize(size_type count = 0, value_type e = 0);
/// returns maximum number of chars that can fit into buffer
size_type capacity() const { return pchunk->size-1; }
size_type capacity() const { return pchunk->size; }
/// reserve space for specified amount of chars
void reserve(size_type count = 0);
/// returns true if string is empty
Expand Down Expand Up @@ -586,8 +618,8 @@ class lString16
public:
// typedefs for STL compatibility
typedef lChar16 value_type;
typedef int size_type;
typedef int difference_type;
typedef lUInt32 size_type;
typedef lInt32 difference_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef const value_type * const_pointer;
Expand All @@ -601,21 +633,29 @@ class lString16
void alloc(size_type sz);
void free();
inline void addref() const {
#if LDOM_USE_OWN_MEM_MAN==1
if (ls_storage_is_destroyed()) return;
#endif
#ifdef USE_ATOMIC_REFCOUNT
pchunk->refCount.fetch_add(1);
#else
++pchunk->refCount;
#endif
}
inline void release() {
inline void release() {
if (!pchunk) return;
#ifdef USE_ATOMIC_REFCOUNT
if (pchunk->refCount.fetch_sub(1) <= 1)
free();
#else
if (--pchunk->refCount==0) free();
#endif
pchunk = nullptr;
}
inline int refCount() {
#if LDOM_USE_OWN_MEM_MAN==1
if (ls_storage_is_destroyed()) return 0;
#endif
return pchunk->refCount;
}
public:
Expand All @@ -624,6 +664,11 @@ class lString16
explicit lString16() : pchunk(EMPTY_STR_16) { addref(); }
/// copy constructor
lString16(const lString16 & str) : pchunk(str.pchunk) { addref(); }
/// move constructor
lString16(lString16 && str) : pchunk(nullptr) {
pchunk = str.pchunk;
str.pchunk = nullptr;
}
/// constructor from wide c-string
lString16(const value_type * str);
/// constructor from 8bit c-string (ASCII only)
Expand All @@ -648,6 +693,17 @@ class lString16
}
return *this;
}
/// move assignment from string
lString16 & assign(lString16 && str)
{
if (pchunk!=str.pchunk)
{
release();
pchunk = str.pchunk;
str.pchunk = nullptr;
}
return *this;
}
/// assignment from c-string
lString16 & assign(const value_type * str);
/// assignment from 8bit c-string (ASCII only)
Expand All @@ -664,8 +720,12 @@ class lString16
lString16 & operator = (const lChar8 * str) { return assign(str); }
/// assignment from string
lString16 & operator = (const lString16 & str) { return assign(str); }
/// move assignment from string
lString16 & operator = (lString16 && str) { return assign(std::move(str)); }
lString16 & erase(size_type offset, size_type count);

lString16 & append(const lChar32 * str);
lString16 & append(const lChar32 * str, size_type count);
lString16 & append(const value_type * str);
lString16 & append(const value_type * str, size_type count);
lString16 & append(const lChar8 * str);
Expand Down Expand Up @@ -753,7 +813,7 @@ class lString16
/// resizes string buffer, appends with specified character if buffer is being extended
void resize(size_type count = 0, value_type e = 0);
/// returns string buffer size
size_type capacity() const { return pchunk->size-1; }
size_type capacity() const { return pchunk->size; }
/// ensures string buffer can hold at least count characters
void reserve(size_type count = 0);
/// erase all extra characters from end of string after size
Expand Down Expand Up @@ -821,8 +881,8 @@ class lString32
public:
// typedefs for STL compatibility
typedef lChar32 value_type;
typedef int size_type;
typedef int difference_type;
typedef lUInt32 size_type;
typedef lInt32 difference_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef const value_type * const_pointer;
Expand All @@ -836,21 +896,29 @@ class lString32
void alloc(size_type sz);
void free();
inline void addref() const {
#if LDOM_USE_OWN_MEM_MAN==1
if (ls_storage_is_destroyed()) return;
#endif
#ifdef USE_ATOMIC_REFCOUNT
pchunk->refCount.fetch_add(1);
#else
++pchunk->refCount;
#endif
}
inline void release() {
inline void release() {
if (!pchunk) return;
#ifdef USE_ATOMIC_REFCOUNT
if (pchunk->refCount.fetch_sub(1) <= 1)
free();
#else
if (--pchunk->refCount==0) free();
#endif
pchunk = nullptr;
}
inline int refCount() {
#if LDOM_USE_OWN_MEM_MAN==1
if (ls_storage_is_destroyed()) return 0;
#endif
return pchunk->refCount;
}
public:
Expand All @@ -859,6 +927,8 @@ class lString32
explicit lString32() : pchunk(EMPTY_STR_32) { addref(); }
/// copy constructor
lString32(const lString32 & str) : pchunk(str.pchunk) { addref(); }
/// move constructor
lString32(lString32 && str) : pchunk(str.pchunk) { str.pchunk = nullptr; }
/// constructor from wide c-string
lString32(const value_type * str);
/// constructor from 8bit c-string (ASCII only)
Expand All @@ -870,7 +940,9 @@ class lString32
/// constructor from another string substring
explicit lString32(const lString32 & str, size_type offset, size_type count);
/// desctructor
~lString32() { release(); }
~lString32() {
release();
}

/// assignment from string
lString32 & assign(const lString32 & str)
Expand All @@ -883,6 +955,17 @@ class lString32
}
return *this;
}
/// assignment from string
lString32 & assign(lString32 && str)
{
if (pchunk!=str.pchunk)
{
release();
pchunk = str.pchunk;
str.pchunk = nullptr;
}
return *this;
}
/// assignment from c-string
lString32 & assign(const value_type * str);
/// assignment from 8bit c-string (ASCII only)
Expand All @@ -899,12 +982,16 @@ class lString32
lString32 & operator = (const lChar8 * str) { return assign(str); }
/// assignment from string
lString32 & operator = (const lString32 & str) { return assign(str); }
/// moving assignment from string
lString32 & operator = (lString32 && str) { return assign(std::move(str)); }
lString32 & erase(size_type offset, size_type count);

lString32 & append(const value_type * str);
lString32 & append(const value_type * str, size_type count);
lString32 & append(const lChar8 * str);
lString32 & append(const lChar8 * str, size_type count);
lString32 & append(const lChar16 * str);
lString32 & append(const lChar16 * str, size_type count);
lString32 & append(const lString32 & str);
lString32 & append(const lString32 & str, size_type offset, size_type count);
lString32 & append(size_type count, value_type ch);
Expand Down Expand Up @@ -1036,7 +1123,7 @@ class lString32
/// resizes string buffer, appends with specified character if buffer is being extended
void resize(size_type count = 0, value_type e = 0);
/// returns string buffer size
size_type capacity() const { return pchunk->size-1; }
size_type capacity() const { return pchunk->size; }
/// ensures string buffer can hold at least count characters
void reserve(size_type count = 0);
/// erase all extra characters from end of string after size
Expand Down Expand Up @@ -1186,6 +1273,7 @@ inline bool operator != (const lChar8 * s1, const lString16& s2 )
{ return s2.compare(s1)!=0; }
inline bool operator != (const lChar8 * s1, const lString32& s2 )
{ return s2.compare(s1)!=0; }
inline lString32 operator + (const lString32 &s1, const lChar16 * s2) { lString32 s(s1); s.append(s2); return s; }
inline lString32 operator + (const lString32 &s1, const lString32 &s2) { lString32 s(s1); s.append(s2); return s; }
inline lString32 operator + (const lString32 &s1, const lChar32 * s2) { lString32 s(s1); s.append(s2); return s; }
inline lString32 operator + (const lString32 &s1, const lChar8 * s2) { lString32 s(s1); s.append(s2); return s; }
Expand Down Expand Up @@ -1215,6 +1303,11 @@ inline lString8 operator + (const lString8 &s1, fmt::decimal v)
inline lString8 operator + (const lString8 &s1, fmt::hex v)
{ lString8 s(s1); s.appendHex(v.get()); return s; }

inline lString16 operator + (const lString16 &s1, const lChar32 * s2) { lString16 s(s1); s.append(s2); return s; }
inline lString16 operator + (const lString16 &s1, const lString16 &s2) { lString16 s(s1); s.append(s2); return s; }
inline lString16 operator + (const lString16 &s1, const lChar16 * s2) { lString16 s(s1); s.append(s2); return s; }
inline lString16 operator + (const lString16 &s1, fmt::decimal v) { lString16 s(s1); s.appendDecimal(v.get()); return s; }
inline lString16 operator + (const lString16 &s1, fmt::hex v) { lString16 s(s1); s.appendHex(v.get()); return s; }

lString8 UnicodeToTranslit( const lString32 & str );
/// converts wide unicode string to local 8-bit encoding
Expand Down Expand Up @@ -1275,6 +1368,9 @@ bool splitIntegerList( lString32 s, lString32 delim, int & value1, int & value2

#if LDOM_USE_OWN_MEM_MAN==1
void free_ls_storage();
bool ls_storage_is_destroyed();
/// checks free list in string chunk storage for consistency
void check_ls_storage(const char * msg);
#endif

#endif // __LV_STRING_H_INCLUDED__
Loading
Loading