1313#ifndef  LLDB_HOST_JSONTRANSPORT_H
1414#define  LLDB_HOST_JSONTRANSPORT_H 
1515
16- #include  " lldb/Host/MainLoopBase.h" 
1716#include  " lldb/lldb-forward.h" 
18- #include  " llvm/ADT/FunctionExtras.h" 
1917#include  " llvm/ADT/StringRef.h" 
2018#include  " llvm/Support/Error.h" 
2119#include  " llvm/Support/FormatVariadic.h" 
2220#include  " llvm/Support/JSON.h" 
23- #include  < string > 
21+ #include  < chrono > 
2422#include  < system_error> 
25- #include  < vector> 
2623
2724namespace  lldb_private  {
2825
@@ -31,33 +28,27 @@ class TransportEOFError : public llvm::ErrorInfo<TransportEOFError> {
3128  static  char  ID;
3229
3330  TransportEOFError () = default ;
34-   void  log (llvm::raw_ostream &OS) const  override  { OS << " transport EOF"  ; }
31+ 
32+   void  log (llvm::raw_ostream &OS) const  override  {
33+     OS << " transport end of file reached"  ;
34+   }
3535  std::error_code convertToErrorCode () const  override  {
36-     return  std::make_error_code (std::errc::io_error );
36+     return  llvm::inconvertibleErrorCode ( );
3737  }
3838};
3939
40- class  TransportUnhandledContentsError 
41-     : public llvm::ErrorInfo<TransportUnhandledContentsError> {
40+ class  TransportTimeoutError  : public  llvm ::ErrorInfo<TransportTimeoutError> {
4241public: 
4342  static  char  ID;
4443
45-   explicit  TransportUnhandledContentsError (std::string unhandled_contents)
46-       : m_unhandled_contents(unhandled_contents) {}
44+   TransportTimeoutError () = default ;
4745
4846  void  log (llvm::raw_ostream &OS) const  override  {
49-     OS << " transport EOF with unhandled contents  "  << m_unhandled_contents ;
47+     OS << " transport operation timed out "  ;
5048  }
5149  std::error_code convertToErrorCode () const  override  {
52-     return  std::make_error_code (std::errc::bad_message );
50+     return  std::make_error_code (std::errc::timed_out );
5351  }
54- 
55-   const  std::string &getUnhandledContents () const  {
56-     return  m_unhandled_contents;
57-   }
58- 
59- private: 
60-   std::string m_unhandled_contents;
6152};
6253
6354class  TransportInvalidError  : public  llvm ::ErrorInfo<TransportInvalidError> {
@@ -77,11 +68,6 @@ class TransportInvalidError : public llvm::ErrorInfo<TransportInvalidError> {
7768// / A transport class that uses JSON for communication.
7869class  JSONTransport  {
7970public: 
80-   using  ReadHandleUP = MainLoopBase::ReadHandleUP;
81-   template  <typename  T>
82-   using  Callback =
83-       llvm::unique_function<void (MainLoopBase &, const  llvm::Expected<T>)>;
84- 
8571  JSONTransport (lldb::IOObjectSP input, lldb::IOObjectSP output);
8672  virtual  ~JSONTransport () = default ;
8773
@@ -97,69 +83,24 @@ class JSONTransport {
9783    return  WriteImpl (message);
9884  }
9985
100-   // / Registers  the transport with  the MainLoop .
86+   // / Reads  the next message from  the input stream .
10187  template  <typename  T>
102-   llvm::Expected<ReadHandleUP> RegisterReadObject (MainLoopBase &loop,
103-                                                   Callback<T> callback) {
104-     Status error;
105-     ReadHandleUP handle = loop.RegisterReadObject (
106-         m_input,
107-         [&](MainLoopBase &loop) {
108-           char  buffer[kReadBufferSize ];
109-           size_t  len = sizeof (buffer);
110-           if  (llvm::Error error = m_input->Read (buffer, len).takeError ()) {
111-             callback (loop, std::move (error));
112-             return ;
113-           }
114- 
115-           if  (len)
116-             m_buffer.append (std::string (buffer, len));
117- 
118-           //  If the buffer has contents, try parsing any pending messages.
119-           if  (!m_buffer.empty ()) {
120-             llvm::Expected<std::vector<std::string>> messages = Parse ();
121-             if  (llvm::Error error = messages.takeError ()) {
122-               callback (loop, std::move (error));
123-               return ;
124-             }
125- 
126-             for  (const  auto  &message : *messages)
127-               if  constexpr  (std::is_same<T, std::string>::value)
128-                 callback (loop, message);
129-               else 
130-                 callback (loop, llvm::json::parse<T>(message));
131-           }
132- 
133-           //  On EOF, notify the callback after the remaining messages were
134-           //  handled.
135-           if  (len == 0 ) {
136-             if  (m_buffer.empty ())
137-               callback (loop, llvm::make_error<TransportEOFError>());
138-             else 
139-               callback (loop, llvm::make_error<TransportUnhandledContentsError>(
140-                                  m_buffer));
141-           }
142-         },
143-         error);
144-     if  (error.Fail ())
145-       return  error.takeError ();
146-     return  handle;
88+   llvm::Expected<T> Read (const  std::chrono::microseconds &timeout) {
89+     llvm::Expected<std::string> message = ReadImpl (timeout);
90+     if  (!message)
91+       return  message.takeError ();
92+     return  llvm::json::parse<T>(/* JSON=*/  *message);
14793  }
14894
14995protected: 
150-   template  <typename ... Ts> inline  auto  Logv (const  char  *Fmt, Ts &&...Vals) {
151-     Log (llvm::formatv (Fmt, std::forward<Ts>(Vals)...).str ());
152-   }
15396  virtual  void  Log (llvm::StringRef message);
15497
15598  virtual  llvm::Error WriteImpl (const  std::string &message) = 0;
156-   virtual  llvm::Expected<std::vector<std::string>> Parse () = 0;
99+   virtual  llvm::Expected<std::string>
100+   ReadImpl (const  std::chrono::microseconds &timeout) = 0 ;
157101
158102  lldb::IOObjectSP m_input;
159103  lldb::IOObjectSP m_output;
160-   std::string m_buffer;
161- 
162-   static  constexpr  size_t  kReadBufferSize  = 1024 ;
163104};
164105
165106// / A transport class for JSON with a HTTP header.
@@ -170,13 +111,14 @@ class HTTPDelimitedJSONTransport : public JSONTransport {
170111  virtual  ~HTTPDelimitedJSONTransport () = default ;
171112
172113protected: 
173-   llvm::Error WriteImpl (const  std::string &message) override ;
174-   llvm::Expected<std::vector<std::string>> Parse () override ;
175- 
176-   static  constexpr  llvm::StringLiteral kHeaderContentLength  = " Content-Length"  ;
177-   static  constexpr  llvm::StringLiteral kHeaderFieldSeparator  = " :"  ;
178-   static  constexpr  llvm::StringLiteral kHeaderSeparator  = " \r\n "  ;
179-   static  constexpr  llvm::StringLiteral kEndOfHeader  = " \r\n\r\n "  ;
114+   virtual  llvm::Error WriteImpl (const  std::string &message) override ;
115+   virtual  llvm::Expected<std::string>
116+   ReadImpl (const  std::chrono::microseconds &timeout) override ;
117+ 
118+   //  FIXME: Support any header.
119+   static  constexpr  llvm::StringLiteral kHeaderContentLength  =
120+       " Content-Length: "  ;
121+   static  constexpr  llvm::StringLiteral kHeaderSeparator  = " \r\n\r\n "  ;
180122};
181123
182124// / A transport class for JSON RPC.
@@ -187,8 +129,9 @@ class JSONRPCTransport : public JSONTransport {
187129  virtual  ~JSONRPCTransport () = default ;
188130
189131protected: 
190-   llvm::Error WriteImpl (const  std::string &message) override ;
191-   llvm::Expected<std::vector<std::string>> Parse () override ;
132+   virtual  llvm::Error WriteImpl (const  std::string &message) override ;
133+   virtual  llvm::Expected<std::string>
134+   ReadImpl (const  std::chrono::microseconds &timeout) override ;
192135
193136  static  constexpr  llvm::StringLiteral kMessageSeparator  = " \n "  ;
194137};
0 commit comments