# HG changeset patch
# User Dustin Sallings <dustin@spy.net>
# Date 1200638196 28800
# Branch server
# Node ID 8a5482c4082cd1e83b8435534899211b03c79e90
# Parent  79529073da1a9d7a1e7fde5ccfa0486d8f1511ae
	Binary protocol updates for binary incr/decr response.

diff --git a/doc/binary-protocol-plan-v2.xml b/doc/binary-protocol-plan-v2.xml
--- a/doc/binary-protocol-plan-v2.xml
+++ b/doc/binary-protocol-plan-v2.xml
@@ -438,6 +438,21 @@
         </t>
 
         <t>
+      <figure>
+        <preamble>incr/decr response body:</preamble>
+          <artwork>
+    Byte/     0       |       1       |       2       |       3       |
+       /              |               |               |               |
+      |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
+      +---------------+---------------+---------------+---------------+
+     0| 64-bit unsigned response.                                     |
+      |                                                               |
+      +---------------+---------------+---------------+---------------+
+    Total 8 bytes
+      </artwork></figure>
+        </t>
+
+        <t>
           These commands will either add or remove the specified
           amount to the requested counter.
           
diff --git a/memcached.c b/memcached.c
--- a/memcached.c
+++ b/memcached.c
@@ -941,8 +941,8 @@ static void complete_incr_bin(conn *c) {
     int32_t exptime;
     char *key;
     size_t nkey;
-    int i,res;
-    char *responseBuf = c->wbuf + BIN_INCR_HDR_LEN;
+    int i;
+    uint64_t *responseBuf = (uint64_t*) c->wbuf + BIN_INCR_HDR_LEN;
 
     assert(c != NULL);
 
@@ -980,27 +980,27 @@ static void complete_incr_bin(conn *c) {
     it = item_get(key, nkey);
     if (it) {
         /* Weird magic in add_delta forces me to pad here */
-        memset(responseBuf, ' ', 32);
-        responseBuf[32]=0x00;
-        add_delta(it, c->cmd == CMD_INCR, delta, responseBuf);
-        res = strlen(responseBuf);
-        
-        assert(res > 0);
-        write_bin_response(c, responseBuf, BIN_INCR_HDR_LEN, res);
+        char tmpbuf[INCR_MAX_STORAGE_LEN];
+        uint64_t l=0;
+        memset(tmpbuf, ' ', INCR_MAX_STORAGE_LEN);
+        tmpbuf[INCR_MAX_STORAGE_LEN]=0x00;
+        add_delta(it, c->cmd == CMD_INCR, delta, tmpbuf);
+        *responseBuf=swap64(strtoull(tmpbuf, NULL, 10));
+
+        write_bin_response(c, responseBuf, BIN_INCR_HDR_LEN, INCR_RES_LEN);
         item_remove(it);         /* release our reference */
     } else {
         if(exptime >= 0) {
             /* Save some room for the response */
-            assert(c->wsize > BIN_INCR_HDR_LEN + 32);
-            snprintf(responseBuf, BIN_INCR_HDR_LEN + 32, "%llu", initial);
-            
-            res = strlen(responseBuf);
-            it = item_alloc(key, nkey, 0, realtime(exptime), res + 2);
-            
-            memcpy(ITEM_data(it), responseBuf, res);
-            
+            assert(c->wsize > BIN_INCR_HDR_LEN + BIN_DEL_HDR_LEN);
+            *responseBuf=swap64(initial);
+            it = item_alloc(key, nkey, 0, realtime(exptime),
+                INCR_MAX_STORAGE_LEN);
+            snprintf(ITEM_data(it), INCR_MAX_STORAGE_LEN, "%llu", initial);
+
             if(store_item(it, NREAD_SET)) {
-                write_bin_response(c, responseBuf, BIN_INCR_HDR_LEN, res);
+                write_bin_response(c, responseBuf, BIN_INCR_HDR_LEN,
+                    INCR_RES_LEN);
             } else {
                 write_bin_error(c, ERR_NOT_STORED, 0);
             }
diff --git a/memcached.h b/memcached.h
--- a/memcached.h
+++ b/memcached.h
@@ -49,6 +49,11 @@
 /* timeout:32 */
 #define BIN_DEL_HDR_LEN 4
 #define BIN_PKT_HDR_WORDS (MIN_BIN_PKT_LENGTH/sizeof(uint32_t))
+
+/* Body is a single 64-bit int */
+#define INCR_RES_LEN 8
+/* len(18446744073709551616) + 2 (or so) */
+#define INCR_MAX_STORAGE_LEN 24
 
 #define BIN_REQ_MAGIC 0x80
 #define BIN_RES_MAGIC 0x80
