| 1756 | } |
| 1757 | |
| 1758 | bool CouchbaseOperations::CouchbaseResponse::popVersion(std::string* version) { |
| 1759 | const size_t n = _buf.size(); |
| 1760 | policy::CouchbaseResponseHeader header; |
| 1761 | if (n < sizeof(header)) { |
| 1762 | butil::string_printf(&_err, "buffer is too small to contain a header"); |
| 1763 | return false; |
| 1764 | } |
| 1765 | _buf.copy_to(&header, sizeof(header)); |
| 1766 | if (header.command != policy::CB_BINARY_VERSION) { |
| 1767 | butil::string_printf(&_err, "not a VERSION response"); |
| 1768 | return false; |
| 1769 | } |
| 1770 | if (n < sizeof(header) + header.total_body_length) { |
| 1771 | butil::string_printf(&_err, "response=%u < header=%u + body=%u", |
| 1772 | (unsigned)n, (unsigned)sizeof(header), |
| 1773 | header.total_body_length); |
| 1774 | return false; |
| 1775 | } |
| 1776 | if (DBUG && header.extras_length != 0) { |
| 1777 | DEBUG_PRINT("VERSION response must not have flags"); |
| 1778 | } |
| 1779 | if (DBUG && header.key_length != 0) { |
| 1780 | DEBUG_PRINT("VERSION response must not have key"); |
| 1781 | } |
| 1782 | const int value_size = (int)header.total_body_length - |
| 1783 | (int)header.extras_length - (int)header.key_length; |
| 1784 | _buf.pop_front(sizeof(header) + header.extras_length + header.key_length); |
| 1785 | if (value_size < 0) { |
| 1786 | butil::string_printf(&_err, "value_size=%d is negative", value_size); |
| 1787 | return false; |
| 1788 | } |
| 1789 | if (header.status != (uint16_t)STATUS_SUCCESS) { |
| 1790 | if (value_size > 0) { |
| 1791 | std::string error_msg; |
| 1792 | _buf.cutn(&error_msg, value_size); |
| 1793 | _err = formatErrorMessage(header.status, "Version request", error_msg); |
| 1794 | } else { |
| 1795 | _err = formatErrorMessage(header.status, "Version request"); |
| 1796 | } |
| 1797 | return false; |
| 1798 | } |
| 1799 | if (version) { |
| 1800 | version->clear(); |
| 1801 | _buf.cutn(version, value_size); |
| 1802 | } |
| 1803 | _err.clear(); |
| 1804 | return true; |
| 1805 | } |
| 1806 | |
| 1807 | bool sendRequest(CouchbaseOperations::operation_type op_type, const std::string& key, |
| 1808 | const std::string& value, std::string collection_name, |