1 /*
2   Copyright (c) DataStax, Inc.
3 
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7 
8   http://www.apache.org/licenses/LICENSE-2.0
9 
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15 */
16 
17 #ifndef DATASTAX_INTERNAL_RESPONSE_HPP
18 #define DATASTAX_INTERNAL_RESPONSE_HPP
19 
20 #include "allocated.hpp"
21 #include "constants.hpp"
22 #include "decoder.hpp"
23 #include "hash_table.hpp"
24 #include "macros.hpp"
25 #include "ref_counted.hpp"
26 #include "utils.hpp"
27 
28 #include <uv.h>
29 
30 #define CHECK_RESULT(result) \
31   if (!(result)) return false;
32 
33 namespace datastax { namespace internal { namespace core {
34 
35 class Response : public RefCounted<Response> {
36 public:
37   typedef SharedRefPtr<Response> Ptr;
38 
39   Response(uint8_t opcode);
40 
~Response()41   virtual ~Response() {}
42 
opcode() const43   uint8_t opcode() const { return opcode_; }
44 
data() const45   char* data() const { return buffer_->data(); }
46 
buffer() const47   const RefBuffer::Ptr& buffer() const { return buffer_; }
48 
set_buffer(size_t size)49   void set_buffer(size_t size) { buffer_ = RefBuffer::Ptr(RefBuffer::create(size)); }
50 
51   bool has_tracing_id() const;
52 
tracing_id() const53   const CassUuid& tracing_id() const { return tracing_id_; }
54 
custom_payload() const55   const CustomPayloadVec& custom_payload() const { return custom_payload_; }
56 
warnings() const57   const WarningVec& warnings() const { return warnings_; }
58 
59   bool decode_trace_id(Decoder& decoder);
60 
61   bool decode_custom_payload(Decoder& decoder);
62 
63   bool decode_warnings(Decoder& decoder);
64 
65   virtual bool decode(Decoder& decoder) = 0;
66 
67 private:
68   uint8_t opcode_;
69   RefBuffer::Ptr buffer_;
70   CassUuid tracing_id_;
71   CustomPayloadVec custom_payload_;
72   WarningVec warnings_;
73 
74 private:
75   DISALLOW_COPY_AND_ASSIGN(Response);
76 };
77 
78 class ResponseMessage : public Allocated {
79 public:
ResponseMessage()80   ResponseMessage()
81       : version_(0)
82       , flags_(0)
83       , stream_(0)
84       , opcode_(0)
85       , length_(0)
86       , received_(0)
87       , header_size_(0)
88       , is_header_received_(false)
89       , header_buffer_pos_(header_buffer_)
90       , is_body_ready_(false)
91       , is_body_error_(false)
92       , body_buffer_pos_(NULL) {}
93 
flags() const94   uint8_t flags() const { return flags_; }
95 
opcode() const96   uint8_t opcode() const { return opcode_; }
97 
stream() const98   int16_t stream() const { return stream_; }
99 
response_body()100   const Response::Ptr& response_body() { return response_body_; }
101 
is_body_ready() const102   bool is_body_ready() const { return is_body_ready_; }
103 
104   ssize_t decode(const char* input, size_t size);
105 
106 private:
107   bool allocate_body(int8_t opcode);
108 
109 private:
110   uint8_t version_;
111   uint8_t flags_;
112   int16_t stream_;
113   uint8_t opcode_;
114   int32_t length_;
115   size_t received_;
116   size_t header_size_;
117 
118   bool is_header_received_;
119   char header_buffer_[CASS_HEADER_SIZE_V3];
120   char* header_buffer_pos_;
121 
122   bool is_body_ready_;
123   bool is_body_error_;
124   Response::Ptr response_body_;
125   char* body_buffer_pos_;
126 
127 private:
128   DISALLOW_COPY_AND_ASSIGN(ResponseMessage);
129 };
130 
131 }}} // namespace datastax::internal::core
132 
133 #endif
134