mongo_reply * mongo_read_response( mongo_connection * conn ){ mongo_header head; /* header from network */ mongo_reply_fields fields; /* header from network */ mongo_reply * out; /* native endian */ int len; looping_read(conn, &head, sizeof(head)); looping_read(conn, &fields, sizeof(fields)); bson_little_endian32(&len, &head.len); if (len < sizeof(head)+sizeof(fields) || len > 64*1024*1024) MONGO_THROW(MONGO_EXCEPT_NETWORK); /* most likely corruption */ out = (mongo_reply*)bson_malloc(len); out->head.len = len; bson_little_endian32(&out->head.id, &head.id); bson_little_endian32(&out->head.responseTo, &head.responseTo); bson_little_endian32(&out->head.op, &head.op); bson_little_endian32(&out->fields.flag, &fields.flag); bson_little_endian64(&out->fields.cursorID, &fields.cursorID); bson_little_endian32(&out->fields.start, &fields.start); bson_little_endian32(&out->fields.num, &fields.num); MONGO_TRY{ looping_read(conn, &out->objs, len-sizeof(head)-sizeof(fields)); }MONGO_CATCH{ free(out); MONGO_RETHROW(); } return out; }
static void looping_read(mongo_connection * conn, void* buf, int len){ char* cbuf = buf; while (len){ int sent = recv(conn->sock, cbuf, len, 0); if (sent == 0 || sent == -1) MONGO_THROW(MONGO_EXCEPT_NETWORK); cbuf += sent; len -= sent; } }
static void looping_write(mongo_connection * conn, const void* buf, int len){ const char* cbuf = buf; while (len){ int sent = send(conn->sock, cbuf, len, 0); if (sent == -1) MONGO_THROW(MONGO_EXCEPT_NETWORK); cbuf += sent; len -= sent; } }
static void looping_read(mongo_connection * conn, void* buf, int len){ apr_status_t rv; char* cbuf = buf; while (len){ apr_size_t sent=len; rv = apr_socket_recv( conn->socket, cbuf, &sent ); // int sent = recv(conn->sock, cbuf, len, 0); if (sent == 0 || sent == -1|| rv != APR_SUCCESS) MONGO_THROW(MONGO_EXCEPT_NETWORK); cbuf += sent; len -= sent; } }
static void looping_write(mongo_connection * conn, const void* buf, int len){ const char* cbuf = buf; apr_status_t rv; while (len){ apr_size_t nr_bytes= len; // int sent = send(conn->sock, cbuf, len, 0); rv = apr_socket_send( conn->socket, cbuf, &nr_bytes); if (nr_bytes == -1 || rv != APR_SUCCESS) MONGO_THROW(MONGO_EXCEPT_NETWORK); cbuf += nr_bytes; len -= nr_bytes; } }