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