ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
recordparser.cpp
2
3//##################################################################################################
4// EnumRecordParser
5//##################################################################################################
6#if !DOXYGEN
7
8namespace {
9void assembleMsgAndThrow [[noreturn]] ( const NString& error ) {
11 - EnumRecordParser::Input .Length();
12
13 NAString msg;
14 msg << "ERROR WHILE PARSING ENUMERATION RECORD STRING" << NEW_LINE
15 << " Detail: " << error << NEW_LINE
16 << " Resrc : "; if(EnumRecordParser::ResourceCategory.IsNotEmpty() )
18 << "\" / \"" << EnumRecordParser::ResourceName << '"';
19 else
20 msg << "(Not resourced)";
21 msg << NEW_LINE
22 << " Column: " << column + 1 << NEW_LINE
23 << " Input : \"" << EnumRecordParser::OriginalInput << '"' << NEW_LINE
24 << " ";
25 for( integer i= column ; i >= 0 ; --i )
26 msg << (i != 0 ? '-' : '>');
27 msg << "^<--";
28
29 throw std::runtime_error( msg.Terminate() );
30}
31} // anonymous namespace
32
39
40void EnumRecordParser::error [[noreturn]] (const NCString& what)
41{ assembleMsgAndThrow( NString256() << what << '.' ); }
42
44 if( Input.IsNotEmpty()
46 assembleMsgAndThrow( NString256() << "Found whitespaces "
47 << where );
48}
49
51 if( token.LastIndexOfAny<lang::Inclusion::Exclude>( DEFAULT_WHITESPACES ) != token.Length() -1 )
52 assembleMsgAndThrow( NString256() << "Found trailing whitespaces in string value \""
53 << token << '"' );
54}
55
56void EnumRecordParser::assertNoUnnecessary(character specificChar, const NCString& where) {
57 if( Input.CharAtStart() == specificChar )
58 assembleMsgAndThrow( NString256() << "Unnecessary character \""
59 << specificChar
60 << "\" found " << where );
61}
62
63void EnumRecordParser::assertChar(character specificChar, const NCString& where)
64{
65 if( !Input.ConsumeChar(specificChar) )
66 assembleMsgAndThrow( NString256() << where << '\"' << specificChar << '\"');
67}
68
70 if ( Input.IsEmpty() )
71 return;
72 assertNoWhitespaces( "after record" );
73 if( Input.CharAtStart() != OuterDelimChar )
74 assembleMsgAndThrow( NString256() << "Expected outer delimiter or end of input" );
75}
76
78{
79 if ( !Input.IsEmpty() )
80 assembleMsgAndThrow( NString256() << "Expected end of parsable input string" );
81}
82
83integer EnumRecordParser::getInteger( bool isLastField ) {
84 integer bigInt;
85 assertNoWhitespaces( "before integral value" );
86 assertNoUnnecessary( A_CHAR('+'), "before integral value" );
87
88 if( Input.ConsumeString<lang::Case::Ignore>( A_CHAR("max") ) )
89 bigInt= (std::numeric_limits<integer>::max)();
90 else if( Input.ConsumeString<lang::Case::Ignore>( A_CHAR("min") ) ) bigInt= (std::numeric_limits<integer>::min)();
91 else if( Input.ConsumeChar( A_CHAR('^') ) ) {
92 int exp;
93 if( !Input.ConsumeDec( exp ) )
94 error("Power of 2 symbol '^' is not followed by a number" );
95 bigInt= integer(1LL << exp);
96 } else {
97 if( (!isLastField && ( Input.CharAtStart() == InnerDelimChar ) )
98 || ( isLastField && ( Input.CharAtStart() == OuterDelimChar || Input.IsEmpty()) ) )
99 bigInt= 0;
100 else
101 if( ! Input.ConsumeInt( bigInt ) )
102 error( "Not an integral value" );
103 }
104
105 if( !isLastField )
106 Delim();
107 else
109 return bigInt;
110}
111
112
113void EnumRecordParser::Get( String& result, bool isLastField ) {
114 assertNoWhitespaces( "before string" );
115 if( !isLastField )
116 result= Input.ConsumeToken(InnerDelimChar);
117 else
118 Input.ConsumeChars<NC>( Input.IndexOfOrLength( OuterDelimChar ), result );
120 if( isLastField )
122}
123
124void EnumRecordParser::Get( character& result, bool isLastField ) {
125 assertNoWhitespaces( "before a character value" );
126 result= Input.ConsumeChar<CHK, lang::Whitespaces::Keep>();
127 if( (!isLastField && ( result == InnerDelimChar ) )
128 || ( isLastField && ( result == OuterDelimChar || result == '\0' ) ) )
129 result= '\0';
130 else {
131 if( result == '\0' )
132 error("End of input when parsing a character." );
133 assertNoWhitespaces( "after a character value" );
134 if( !isLastField )
135 Delim();
136 else
138} }
139
140void EnumRecordParser::Get( double& result, bool isLastField ) {
141 assertNoWhitespaces( "before a floating point value" );
142 assertNoUnnecessary( A_CHAR('+'), "before floating point value" );
143 if( (!isLastField && ( Input.CharAtStart() == InnerDelimChar ) )
144 || ( isLastField && ( Input.CharAtStart() == OuterDelimChar || Input.IsEmpty()) ) )
145 result= 0.0;
146 else
147 if( !Input.ConsumeFloat( result ) )
148 error("Not a floating point value" );
149
150 if( !isLastField )
151 Delim();
152 else
154}
155
157 assertNoWhitespaces( "before a delimiter");
158 assertChar(InnerDelimChar,"expected inner delimiter" );
159 assertNoWhitespaces( "after an inner delimiter");
160}
161
163 assertNoWhitespaces( "before an outer delimiter");
164 assertChar(OuterDelimChar,"expected outer delimiter" );
165 assertNoWhitespaces( "after an outer delimiter");
166}
167
168#endif // #if !DOXYGEN
169
170
171//##################################################################################################
172// enumrecords::detail::bootstrap()
173//##################################################################################################
174} namespace alib::enumrecords::detail {
175
176# include "ALib.Lang.CIFunctions.H"
177void shutdown() {
178 #if ALIB_MONOMEM && ALIB_CONTAINERS
179 getInternalRecordMap().Reset();
180 #endif
181}
182
183} // namespace [alib::enumrecords::detail]
184# include "ALib.Lang.CIMethods.H"
#define A_CHAR(STR)
HashMap< MonoAllocator, EnumRecordKey, const void *, EnumRecordKey::Hash, EnumRecordKey::EqualTo > & getInternalRecordMap()
Definition records.cpp:50
@ Keep
Keep whitespaces in string.
@ Exclude
Chooses exclusion.
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
strings::TCString< nchar > NCString
Type alias in namespace #"%alib".
Definition cstring.hpp:408
constexpr CString NEW_LINE
A zero-terminated string containing the new-line character sequence.
Definition cstring.hpp:536
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace #"%alib".
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
strings::TSubstring< character > Substring
Type alias in namespace #"%alib".
constexpr CString DEFAULT_WHITESPACES
A zero-terminated string of default whitespace characters.
Definition cstring.hpp:556
NLocalString< 256 > NString256
Type alias name for #"TLocalString;TLocalString<nchar,256>".
characters::character character
Type alias in namespace #"%alib".
static NString ResourceCategory
The resource category (if a resourced string was parsed).
static void assertChar(character specificChar, const NCString &where)
static void error(const NCString &what)
static void Get(String &result, bool isLastField=false)
static character OuterDelimChar
The delimiter of records.
static Substring Input
The remaining input string.
static character InnerDelimChar
The delimiter of fields of a record.
static NString ResourceName
The resource name (if a resourced string was parsed).
static void assertNoTrailingWhitespaces(String &token)
static void assertNoUnnecessary(character specificChar, const NCString &where)
static String OriginalInput
A backup of the originally given string to parse.
static void assertNoWhitespaces(const NCString &where)
static integer getInteger(bool isLastField)