37 reply.m_done_code = 250 ;
46 G_ASSERT(
static_cast<int>(v) >= 1 &&
static_cast<int>(v) < 100 ) ;
48 reply.m_value =
static_cast<int>( v ) ;
49 reply.m_done_code = done_code ;
55 return internal( Value::Internal_secure , 0 ) ;
60 return internal( Value::Internal_start , 0 ) ;
65 return internal( Value::Internal_filter_ok , 0 ) ;
70 return internal( Value::Internal_filter_abandon , -1 ) ;
74 const std::string & filter_reason )
77 reply.m_value =
static_cast<int>( Value::Internal_filter_error ) ;
78 reply.m_done_code = -2 ;
79 reply.m_text = response ;
80 reply.m_filter_reason = filter_reason ;
86 G_ASSERT( complete(lines) ) ;
87 if( !complete(lines) )
90 m_value =
G::Str::toInt( lines.at(lines.size()-1U).substr(0U,3U) ) ;
91 m_done_code = m_value ;
92 G_ASSERT( m_value >= 100 && m_value < 600 ) ;
94 for(
const auto & line : lines )
96 if( line.length() > 4U )
98 std::string s = line.substr( 4U ) ;
103 if( !m_text.empty() && !s.empty() ) m_text.append(1U,sep) ;
115 for( std::size_t i = 0U ; i < lines.size() ; i++ )
117 if( !validLine(lines[i],digits,i,lines.size()) )
125 if( lines.empty() )
return false ;
126 const std::string & last = lines[lines.size()-1U] ;
127 return valid(lines) && ( last.size() == 3U || last.at(3U) ==
' ' ) ;
130bool GSmtp::ClientReply::validLine(
const std::string & line , std::string & digits ,
131 std::size_t index , std::size_t )
133 if( index == 0U && line.length() >= 3U )
134 digits = line.substr( 0U , 3U ) ;
135 else if( index == 0U )
139 line.length() >= 3U &&
140 isDigit(line.at(0U)) &&
141 line.at(0U) >=
'1' && line.at(0U) <=
'5' &&
142 isDigit(line.at(1U)) &&
143 isDigit(line.at(2U)) &&
144 digits == line.substr(0U,3U) &&
145 ( line.length() == 3U || ( line.at(3U) ==
' ' || line.at(3U) ==
'-' ) ) ;
148bool GSmtp::ClientReply::isDigit(
char c )
150 return c >=
'0' && c <=
'9' ;
155 return m_value >= 100 && m_value < 400 ;
160 return m_value >= 200 && m_value < 300 ;
170 return m_value ==
static_cast<int>(v) ;
180 return positiveCompletion() ? std::string() : ( m_text.empty() ? std::string(
"error") : m_text ) ;
185 return m_filter_reason ;
Encapsulates SMTP replies from a remote client, or replies from a client filter, or the result of a T...
std::string errorText() const
Returns the empty string if positiveCompletion() or non-empty text() or "error".
bool positiveCompletion() const
Returns true if value() is between 200 and 299.
static ClientReply secure()
Factory function for Internal_secure.
static ClientReply filterAbandon()
Factory function for Internal_filter_abandon.
int value() const
Returns the numeric value of the reply.
std::string text() const
Returns the text of the reply, with some whitespace normalisation and no tabs.
static ClientReply start()
Factory function for Internal_start.
bool positive() const
Returns true if value() is between 100 and 399.
std::string reason() const
Returns the filter-reason text from a filterError() reply or the empty string.
static ClientReply filterOk()
Factory function for Internal_filter_ok.
static ClientReply ok()
Factory function returning a generic 'Ok' reply object with a value() of 250.
ClientReply(const G::StringArray &text, char sep='\n')
Constructor taking lines of text from the remote SMTP client.
static bool complete(const G::StringArray &)
Returns true if the reply text is valid() and complete.
bool is(Value v) const
Returns true if the value() is as given.
static ClientReply filterError(const std::string &response, const std::string &filter_reason)
Factory function for Internal_filter_error.
int doneCode() const
Returns -1 for filterAbandon() or -2 for filterError() or zero if less than 100 or value().
static bool valid(const G::StringArray &)
Returns true if the reply text is syntactivally valid but possibly incomplete.
A general-purpose exception class derived from std::exception and containing an error message.
static int toInt(std::string_view s)
Converts string 's' to an int.
static void removeAll(std::string &, char)
Removes all occurrences of the character from the string. See also only().
static std::string & trimLeft(std::string &s, std::string_view ws, std::size_t limit=0U)
Trims the lhs of s, taking off up to 'limit' of the 'ws' characters.
static bool replace(std::string &s, std::string_view from, std::string_view to, std::size_t *pos_p=nullptr)
A std::string_view overload.
std::vector< std::string > StringArray
A std::vector of std::strings.