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