1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this 2 // source code is governed by a BSD-style license that can be found in the 3 // LICENSE file. 4 5 #ifndef NET_FTP_FTP_CTRL_RESPONSE_BUFFER_H_ 6 #define NET_FTP_FTP_CTRL_RESPONSE_BUFFER_H_ 7 8 #include <queue> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 14 namespace net { 15 16 struct FtpCtrlResponse { 17 static const int kInvalidStatusCode; 18 19 FtpCtrlResponse() : status_code(kInvalidStatusCode) {} 20 21 int status_code; // Three-digit status code. 22 std::vector<std::string> lines; // Response lines, without CRLFs. 23 }; 24 25 class FtpCtrlResponseBuffer { 26 public: 27 FtpCtrlResponseBuffer() : multiline_(false) { 28 } 29 30 // Called when data is received from the control socket. Returns error code. 31 int ConsumeData(const char* data, int data_length); 32 33 bool ResponseAvailable() const { 34 return !responses_.empty(); 35 } 36 37 // Returns the next response. It is an error to call this function 38 // unless ResponseAvailable returns true. 39 FtpCtrlResponse PopResponse() { 40 FtpCtrlResponse result = responses_.front(); 41 responses_.pop(); 42 return result; 43 } 44 45 private: 46 struct ParsedLine { 47 ParsedLine() 48 : has_status_code(false), 49 is_multiline(false), 50 is_complete(false), 51 status_code(FtpCtrlResponse::kInvalidStatusCode) { 52 } 53 54 // Indicates that this line begins with a valid 3-digit status code. 55 bool has_status_code; 56 57 // Indicates that this line has the dash (-) after the code, which 58 // means a multiline response. 59 bool is_multiline; 60 61 // Indicates that this line could be parsed as a complete and valid 62 // response line, without taking into account preceding lines (which 63 // may change its meaning into a continuation of the previous line). 64 bool is_complete; 65 66 // Part of response parsed as status code. 67 int status_code; 68 69 // Part of response parsed as status text. 70 std::string status_text; 71 72 // Text before parsing, without terminating CRLF. 73 std::string raw_text; 74 }; 75 76 static ParsedLine ParseLine(const std::string& line); 77 78 void ExtractFullLinesFromBuffer(); 79 80 // We keep not-yet-parsed data in a string buffer. 81 std::string buffer_; 82 83 std::queue<ParsedLine> lines_; 84 85 // True if we are in the middle of parsing a multi-line response. 86 bool multiline_; 87 88 // When parsing a multiline response, we don't know beforehand if a line 89 // will have a continuation. So always store last line of multiline response 90 // so we can append the continuation to it. 91 std::string line_buf_; 92 93 // Keep the response data while we add all lines to it. 94 FtpCtrlResponse response_buf_; 95 96 // As we read full responses (possibly multiline), we add them to the queue. 97 std::queue<FtpCtrlResponse> responses_; 98 99 DISALLOW_COPY_AND_ASSIGN(FtpCtrlResponseBuffer); 100 }; 101 102 } // namespace net 103 104 #endif // NET_FTP_FTP_CTRL_RESPONSE_BUFFER_H_ 105