static void write_doc(bson_buffer* buffer, VALUE hash, VALUE check_keys) { int start_position = buffer->position; int length_location = buffer_save_bytes(buffer, 4); VALUE key = rb_str_new2("_id"); if (rb_funcall(hash, rb_intern("has_key?"), 1, key) == Qtrue) { VALUE id = rb_hash_aref(hash, key); write_element_allow_id(key, id, pack_extra(buffer, check_keys), 1); } key = ID2SYM(rb_intern("_id")); if (rb_funcall(hash, rb_intern("has_key?"), 1, key) == Qtrue) { VALUE id = rb_hash_aref(hash, key); write_element_allow_id(key, id, pack_extra(buffer, check_keys), 1); } // we have to check for an OrderedHash and handle that specially if (strcmp(rb_class2name(RBASIC(hash)->klass), "OrderedHash") == 0) { VALUE keys = rb_funcall(hash, rb_intern("keys"), 0); int i; for(i = 0; i < RARRAY_LEN(keys); i++) { VALUE key = RARRAY_PTR(keys)[i]; VALUE value = rb_hash_aref(hash, key); write_element(key, value, pack_extra(buffer, check_keys)); } } else { rb_hash_foreach(hash, write_element, pack_extra(buffer, check_keys)); } // write null byte and fill in length buffer_write_bytes(buffer, &zero, 1); int length = buffer->position - start_position; memcpy(buffer->buffer + length_location, &length, 4); }
static void write_doc(buffer_t buffer, VALUE hash, VALUE check_keys) { buffer_position start_position = buffer_get_position(buffer); buffer_position length_location = buffer_save_space(buffer, 4); buffer_position length; VALUE id_str = rb_str_new2("_id"); VALUE id_sym = ID2SYM(rb_intern("_id")); if (length_location == -1) { rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c"); } if (rb_funcall(hash, rb_intern("has_key?"), 1, id_str) == Qtrue) { VALUE id = rb_hash_aref(hash, id_str); write_element_allow_id(id_str, id, pack_extra(buffer, check_keys), 1); } else if (rb_funcall(hash, rb_intern("has_key?"), 1, id_sym) == Qtrue) { VALUE id = rb_hash_aref(hash, id_sym); write_element_allow_id(id_sym, id, pack_extra(buffer, check_keys), 1); } // we have to check for an OrderedHash and handle that specially if (strcmp(rb_class2name(RBASIC(hash)->klass), "OrderedHash") == 0) { VALUE keys = rb_funcall(hash, rb_intern("keys"), 0); int i; for(i = 0; i < RARRAY_LEN(keys); i++) { VALUE key = RARRAY_PTR(keys)[i]; VALUE value = rb_hash_aref(hash, key); write_element(key, value, pack_extra(buffer, check_keys)); } } else { rb_hash_foreach(hash, write_element, pack_extra(buffer, check_keys)); } // write null byte and fill in length SAFE_WRITE(buffer, &zero, 1); length = buffer_get_position(buffer) - start_position; // make sure that length doesn't exceed 4MB if (length > 4 * 1024 * 1024) { buffer_free(buffer); rb_raise(InvalidDocument, "Document too large: BSON documents are limited to 4MB."); return; } SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&length, 4); }
static int write_element(VALUE key, VALUE value, VALUE extra) { return write_element_allow_id(key, value, extra, 0); }