Spinning Topp Logo BlackTopp Studios
inc
ftpresponse.cpp
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 
41 #ifndef _networkftpresponse_cpp
42 #define _networkftpresponse_cpp
43 
44 #include "Network/ftpresponse.h"
45 
46 #include "stringtool.h"
47 
48 namespace Mezzanine
49 {
50  namespace Network
51  {
53  ResponseCode(FRC_Invalid)
54  { }
55 
56  FTPResponse::FTPResponse(const Network::FTPResponseCode Code, const String& Description) :
57  ResponseCode(Code)
58  {
59  String ConvertedCode = StringTools::ConvertToString(Code);
60  this->AddLine(ConvertedCode + " " + Description);
61  }
62 
64  { this->Decompose(Response); }
65 
67  { }
68 
70  {
71  String NumStr;
72  StringIterator ActualEnd = ( EndIt - CurrIt > 3 ? CurrIt + 3 : EndIt );
73  while( CurrIt != ActualEnd )
74  {
75  if( StringTools::IsDigit( *CurrIt ) ) {
76  NumStr.push_back( *CurrIt );
77  ++CurrIt;
78  }else{
79  break;
80  }
81  }
82  if( NumStr.size() == 3 ) {
83  Whole ParsedCode = StringTools::ConvertToWhole(NumStr);
84  this->ResponseCode = ( FTPResponse::CodeIsValid(ParsedCode) ? static_cast<FTPResponseCode>(ParsedCode) : FRC_Invalid );
85  return true;
86  }
87  return false;
88  }
89 
91  {
92  while( CurrIt != EndIt )
93  {
94  if( this->IsEndOfLine(CurrIt) ) {
95  CurrIt += 2;
96  return true;
97  }
98  Line.push_back( *CurrIt );
99  ++CurrIt;
100  }
101  return true;
102  }
103 
104  ///////////////////////////////////////////////////////////////////////////////
105  // Core Operations
106 
108  {
109  StringStream ResponseStream;
110  for( ConstLineIterator LineIt = this->ResponseLines.begin() ; LineIt != this->ResponseLines.end() ; ++LineIt )
111  { ResponseStream << (*LineIt) << "\r\n"; }
112  return ResponseStream.str();
113  }
114 
116  {
117  StringIterator CurrIt = Message.begin();
118  return this->Decompose(CurrIt,Message.end());
119  }
120 
122  {
123  this->ResponseLines.clear();
124  this->ResponseCode = FRC_Invalid;
125 
126  String NewLine;
127  // Do a size check here, size the first line must contain at least 4 characters in all situations.
128  if( !this->GetResponseLine(CurrIt,EndIt,NewLine) && NewLine.size() > 3 )
129  return false;
130 
131  // Extract the response code.
132  if( !this->ParseResponseCode(NewLine.begin(),NewLine.end()) )
133  return false;
134 
135  // Determine if this is a multi-line response or not. If not, we're done parsing.
136  if( NewLine[3] == '-' ) {
137  this->ResponseLines.push_back(NewLine);
138  while( CurrIt != EndIt )
139  {
140  // Clear our line and fetch a new one.
141  NewLine.clear();
142  if( !this->GetResponseLine(CurrIt,EndIt,NewLine) )
143  return false;
144 
145  this->ResponseLines.push_back(NewLine);
146  // Check if it's the last line.
147  if( NewLine.size() >= 4 &&
148  NewLine[0] == this->ResponseLines[0][0] &&
149  NewLine[1] == this->ResponseLines[0][1] &&
150  NewLine[2] == this->ResponseLines[0][2] &&
151  NewLine[3] == ' ' )
152  {
153  return true;
154  }
155  }
156  return false;
157  }else if( NewLine[3] == ' ' ) {
158  this->ResponseLines.push_back(NewLine);
159  return true;
160  }
161  return false;
162  }
163 
164  ///////////////////////////////////////////////////////////////////////////////
165  // Utility
166 
168  {
169  switch( Code )
170  {
171  // 100 Series
172  case 110: case 120: case 125: case 150:
173  // 200 Series
174  case 200: case 202: case 211: case 212:
175  case 213: case 214: case 215: case 220:
176  case 221: case 225: case 226: case 227:
177  case 228: case 229: case 230: case 231:
178  case 232: case 234: case 250: case 257:
179  // 300 Series
180  case 331: case 332: case 350:
181  // 400 Series
182  case 421: case 425: case 426: case 430:
183  case 434: case 450: case 451: case 452:
184  // 500 Series
185  case 501: case 502: case 503: case 504:
186  case 530: case 532: case 550: case 551:
187  case 552: case 553:
188  // 600 Series
189  case 631: case 632: case 633:
190  {
191  return true;
192  }
193  default:
194  {
195  return false;
196  }
197  }
198  return false;
199  }
200 
202  { this->ResponseCode = Code; }
203 
205  { return this->ResponseCode; }
206 
207  void FTPResponse::AddLine(const String& NewLine)
208  { this->ResponseLines.push_back(NewLine); }
209 
210  const String& FTPResponse::GetLine(const Whole Index) const
211  { return this->ResponseLines.at(Index); }
212 
214  { return this->ResponseLines.size(); }
215 
217  { this->ResponseLines.clear(); }
218 
220  { return this->ResponseLines.size() > 1; }
221  }//Network
222 }//Mezzanine
223 
224 #endif
Boole GetResponseLine(StringIterator &CurrIt, const StringIterator EndIt, String &Line)
Parses/verifies a single line of a FTP response.
Definition: ftpresponse.cpp:90
FTPResponseCode ResponseCode
The 3 digit response code that identifies the nature of the response from the server.
Definition: ftpresponse.h:73
Network::FTPResponseCode GetCode() const
Gets the code describing this response.
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
LineContainer ResponseLines
Container storing each line in this response.
Definition: ftpresponse.h:70
~FTPResponse()
Class destructor.
Definition: ftpresponse.cpp:66
Boole Decompose(const String &Message)
Populates the members of this class with data from a text FTP message.
String ConvertToString(const Vector2 &ToConvert)
Converts a Vector2 into a string.
Definition: stringtool.cpp:291
Not an actual return code, used in error conditions.
Whole GetNumLines() const
Gets the number of lines in this response.
std::stringstream StringStream
A Datatype used for streaming operations with strings.
Definition: datatypes.h:176
Boole IsMultiline() const
Checks to see if this is a multi-line response.
const String & GetLine(const Whole Index) const
Gets a line in this response.
Boole ParseResponseCode(StringIterator CurrIt, const StringIterator EndIt)
Converts the first three characters in the range into a 3 digit response code.
Definition: ftpresponse.cpp:69
LineContainer::const_iterator ConstLineIterator
Const Iterator type for each line in a response.
Definition: ftpresponse.h:66
FTPResponseCode
This enum is a listing of the response codes that can be used in response to FTP commands.
FTPResponse()
Invalid constructor.
Definition: ftpresponse.cpp:52
String Compose() const
Creates a completed message that can be sent across an FTP connection.
void SetCode(const Network::FTPResponseCode Code)
Sets the code describing this response.
String::const_iterator StringIterator
Convenience typedef for String iterators.
Definition: ftpmessage.h:58
Whole ConvertToWhole(const String &ToConvert)
Converts a string into an Whole.
Definition: stringtool.cpp:408
void ClearLines()
Clears all lines from this response.
Boole IsDigit(const Mezzanine::Char8 ToCheck)
Checks if a character is a decimal digit.
Definition: stringtool.cpp:98
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
Boole IsEndOfLine(const StringIterator CurrIt) const
Checks to see if a parsing iterator is at a Telnet End-Of-Line.
Definition: ftpmessage.cpp:53
static Boole CodeIsValid(const Whole Code)
Checks if a number is a valid response code.
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
void AddLine(const String &NewLine)
Adds a new line to this response.