| 145 | }; |
| 146 | |
| 147 | bool response::parse(const char* p, std::size_t len) { |
| 148 | m_p = p; |
| 149 | m_len = len; |
| 150 | if( m_len < BINARY_HEADER_SIZE ) |
| 151 | return false; |
| 152 | cybozu_assert( *m_p == '\x81' ); |
| 153 | std::uint32_t total_len; |
| 154 | cybozu::ntoh(m_p + 8, total_len); |
| 155 | if( m_len < (BINARY_HEADER_SIZE + total_len) ) |
| 156 | return false; |
| 157 | m_response_len = BINARY_HEADER_SIZE + total_len; |
| 158 | |
| 159 | m_command = (binary_command)*(unsigned char*)(m_p + 1); |
| 160 | std::uint16_t key_len; |
| 161 | cybozu::ntoh(m_p + 2, key_len); |
| 162 | std::uint8_t extras_len = *(unsigned char*)(m_p + 4); |
| 163 | cybozu_assert( total_len >= (key_len + extras_len) ); |
| 164 | if( key_len > 0 ) { |
| 165 | m_key = item(m_p + (BINARY_HEADER_SIZE + extras_len), key_len); |
| 166 | } else { |
| 167 | m_key = item(nullptr, 0); |
| 168 | } |
| 169 | |
| 170 | std::uint16_t i_status; |
| 171 | cybozu::ntoh(m_p + 6, i_status); |
| 172 | m_status = (binary_status)i_status; |
| 173 | cybozu::ntoh(m_p + 16, m_cas_unique); |
| 174 | |
| 175 | std::size_t data_len = total_len - key_len - extras_len; |
| 176 | if( data_len > 0 ) { |
| 177 | m_data = item(m_p + (BINARY_HEADER_SIZE + extras_len + key_len), |
| 178 | data_len); |
| 179 | } else { |
| 180 | m_data = item(nullptr, 0); |
| 181 | } |
| 182 | |
| 183 | if( extras_len > 0 ) { |
| 184 | cybozu_assert( extras_len == 4 ); |
| 185 | cybozu::ntoh(m_p + BINARY_HEADER_SIZE, m_flags); |
| 186 | } |
| 187 | |
| 188 | if( (m_command == binary_command::Increment || |
| 189 | m_command == binary_command::Decrement) && |
| 190 | m_status == binary_status::OK ) { |
| 191 | cybozu_assert( data_len == 8 ); |
| 192 | if( data_len == 8 ) { |
| 193 | cybozu::ntoh(m_p + BINARY_HEADER_SIZE + key_len + extras_len, |
| 194 | m_value); |
| 195 | } |
| 196 | } |
| 197 | return true; |
| 198 | } |
| 199 | |
| 200 | |
| 201 | class client { |
no test coverage detected