ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
autosizes.cpp
1//##################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6//##################################################################################################
7#include "alib_precompile.hpp"
8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14//========================================= Global Fragment ========================================
16//============================================== Module ============================================
17#if ALIB_C20_MODULES
18 module ALib.Strings.AutoSizes;
19 import ALib.Strings.Tokenizer;
20#else
23#endif
24//========================================== Implementation ========================================
25namespace alib { namespace strings { namespace util {
26
27integer AutoSizes::Actual( Types type, integer requestedSize, integer growthPadding ) {
28 // grow arrays as needed
29 while ( data.size() <= ActualIndex ) {
30 data.emplace_back( type, -1, -1 );
31 dirty= true;
32 }
33
34 if ( data[ActualIndex].type != type ) {
35 data[ActualIndex].type = type;
36 data[ActualIndex].actual= 0;
37 data[ActualIndex].session= -1;
38 dirty= true;
39 }
40
41 if( WriteProtected )
42 return (std::max)( data[ ActualIndex ].actual, requestedSize );
43
44 // set measured size as it would be for the next session
45 integer& session= data[ ActualIndex ].session;
46 if ( session < requestedSize ) {
47 session= requestedSize;
48 dirty= true;
49 }
50
51 // get size as it is for actual values (max of imported and session)
52 integer& actual= data[ ActualIndex ].actual;
53 if ( actual < requestedSize ) {
54 actual= (requestedSize + ( actual < 0 ? 0 : growthPadding ));
55 dirty= true;
56 }
57
58 return actual;
59}
60
61void AutoSizes::Export( AString& target ) {
62 if( WriteProtected )
63 target._( "! ");
64
65 auto it= data.begin();
66 while( it!=data.end() ) {
67 target << ((*it).type == Types::Tabstop ? 'T' : 'F' )
68 << (*it).actual;
69 if( !WriteProtected && (*it).session != (*it).actual)
70 target << ',' << (*it).session;
71
72 ++it;
73 if( it!=data.end())
74 target << '/';
75 else
76 break;
77 }
78
79 // remove unused entries at the end
80 while( target.EndsWith(A_CHAR("/T0" ))
81 || target.EndsWith(A_CHAR("/F0" ))
82 || target.EndsWith(A_CHAR("/T-1" ))
83 || target.EndsWith(A_CHAR("/F-1" )) )
84 target.DeleteEnd<NC>(target.Length() - target.LastIndexOf('/'));
85
86 dirty= false;
87}
88
89void AutoSizes::Import( const String& src, lang::CurrentData session ) {
90 Reset();
91 dirty= false;
92
93 #if ALIB_DEBUG
94 # define PARSERROR ALIB_WARNING( "STRINGS", \
95 "Error reading tab stops string \"{}\":\n at position ", \
96 src, src.Length() - parser.Length() )
97 #else
98 # define PARSERROR
99 #endif
100 Substring parser(src);
102 if(parser.Trim().IsEmpty())
103 return;
104
105 Tokenizer tknzr( parser, '/' );
106 while(tknzr.HasNext()) {
107 parser= tknzr.Next();
108 Types type;
111 else { PARSERROR break; }
112
113 integer actual;
114 parser.ConsumeInt( actual );
115
116 integer sessionValue;
118 sessionValue= actual;
119 else
120 parser.ConsumeInt( sessionValue );
121
122 data.emplace_back( type, actual, sessionValue );
123 }
124
125 if( session == lang::CurrentData::Clear )
126 Consolidate();
127}
128
130 integer tabDiff = 0;
131 integer lastTabStop = 0;
132 for( auto& entry : data ) {
133 integer actDiff= entry.session - entry.actual;
134 if( actDiff > 0 ) // should never happen. Maybe improper data import?
135 actDiff= 0;
136 if( entry.type == Types::Tabstop ) {
137 // reset tab difference if (for some strange application-specific reason) this
138 // tab stop is smaller than the previous one. Obviously some multi-line tab stop
139 // is used (does not happen with ALox)
140 if( entry.actual > lastTabStop ) {
141 lastTabStop= entry.actual;
142 entry.actual= entry.session + tabDiff;
143 } else {
144 lastTabStop= entry.actual;
145 tabDiff= 0;
146 entry.actual= entry.session + tabDiff;
147 }
148 } else {
149 entry.actual = entry.session;
150 }
151 tabDiff+= actDiff;
152 entry.session = -1;
153} }
154
155
156}}} // namespace [alib::strings::util]
TAString & DeleteEnd(integer regionLength)
TAString & _(const TAppendable &src)
constexpr integer Length() const
Definition string.inl:316
constexpr bool IsEmpty() const
Definition string.inl:365
bool EndsWith(const TString &needle) const
Definition string.inl:780
integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
Definition string.inl:925
bool ConsumeInt(std::integral auto &result, TNumberFormat< TChar > *numberFormat=nullptr)
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
ALIB_DLL integer Actual(Types type, integer requestedSize, integer growthPadding)
Definition autosizes.cpp:27
ALIB_DLL void Export(AString &target)
Definition autosizes.cpp:61
bool dirty
Determines whether any value was changed sincel last Reset.
Definition autosizes.inl:89
ALIB_DLL void Import(const String &source, lang::CurrentData session=lang::CurrentData::Clear)
Definition autosizes.cpp:89
std::vector< Entry > data
The current and measured sizes.
Definition autosizes.inl:86
Types
The entry type, tab stop or field width.
Definition autosizes.inl:56
@ Field
denotes a field width entry.
Definition autosizes.inl:58
@ Tabstop
denotes a tab stop entry.
Definition autosizes.inl:57
ALIB_DLL TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:26
#define A_CHAR(STR)
@ Clear
Chooses to clear existing data.
@ Trim
Trim whitespaces away.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
strings::TSubstring< character > Substring
Type alias in namespace alib.