static bool _append_platform_field (bson_t *doc, const char *platform) { int max_platform_str_size; /* Compute space left for platform field */ max_platform_str_size = METADATA_MAX_SIZE - (doc->len + /* 1 byte for utf8 tag */ 1 + /* key size */ strlen (METADATA_PLATFORM_FIELD) + 1 + /* 4 bytes for length of string */ 4); if (max_platform_str_size <= 0) { return false; } max_platform_str_size = BSON_MIN (max_platform_str_size, strlen (platform) + 1); bson_append_utf8 (doc, METADATA_PLATFORM_FIELD, -1, platform, max_platform_str_size - 1); BSON_ASSERT (doc->len <= METADATA_MAX_SIZE); return true; }
static void _append_platform_field (bson_t *doc, const char *platform) { int max_platform_str_size; /* Compute space left for platform field */ max_platform_str_size = HANDSHAKE_MAX_SIZE - ((int) doc->len + /* 1 byte for utf8 tag */ 1 + /* key size */ (int) strlen (HANDSHAKE_PLATFORM_FIELD) + 1 + /* 4 bytes for length of string */ 4); if (max_platform_str_size <= 0) { return; } max_platform_str_size = BSON_MIN (max_platform_str_size, (int) strlen (platform) + 1); bson_append_utf8 ( doc, HANDSHAKE_PLATFORM_FIELD, -1, platform, max_platform_str_size - 1); BSON_ASSERT (doc->len <= HANDSHAKE_MAX_SIZE); }
void _mongoc_get_db_name (const char *ns, char *db /* OUT */) { size_t dblen; const char *dot; BSON_ASSERT (ns); dot = strstr (ns, "."); if (dot) { dblen = BSON_MIN (dot - ns + 1, MONGOC_NAMESPACE_MAX); bson_strncpy (db, ns, dblen); } else { bson_strncpy (db, ns, MONGOC_NAMESPACE_MAX); } }
static ssize_t _mongoc_stream_tls_writev (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; char buf[MONGOC_STREAM_TLS_BUFFER_SIZE]; ssize_t ret = 0; ssize_t child_ret; size_t i; size_t iov_pos = 0; /* There's a bit of a dance to coalesce vectorized writes into * MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls * packets. * * The basic idea is that we want to combine writes in the buffer if they're * smaller than the buffer, flushing as it gets full. For larger writes, or * the last write in the iovec array, we want to ignore the buffer and just * write immediately. We take care of doing buffer writes by re-invoking * ourself with a single iovec_t, pointing at our stack buffer. */ char *buf_head = buf; char *buf_tail = buf; char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE; size_t bytes; char *to_write = NULL; size_t to_write_len; BSON_ASSERT (tls); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); tls->timeout_msec = timeout_msec; for (i = 0; i < iovcnt; i++) { iov_pos = 0; while (iov_pos < iov[i].iov_len) { if (buf_head != buf_tail || ((i + 1 < iovcnt) && ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { /* If we have either of: * - buffered bytes already * - another iovec to send after this one and we don't have more * bytes to send than the size of the buffer. * * copy into the buffer */ bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); memcpy (buf_tail, iov[i].iov_base + iov_pos, bytes); buf_tail += bytes; iov_pos += bytes; if (buf_tail == buf_end) { /* If we're full, request send */ to_write = buf_head; to_write_len = buf_tail - buf_head; buf_tail = buf_head = buf; } } else { /* Didn't buffer, so just write it through */ to_write = (char *)iov[i].iov_base + iov_pos; to_write_len = iov[i].iov_len - iov_pos; iov_pos += to_write_len; } if (to_write) { /* We get here if we buffered some bytes and filled the buffer, or * if we didn't buffer and have to send out of the iovec */ child_ret = _mongoc_stream_tls_write (tls, to_write, to_write_len); if (child_ret < 0) { /* Buffer write failed, just return the error */ return child_ret; } ret += child_ret; if (child_ret < to_write_len) { /* we timed out, so send back what we could send */ return ret; } to_write = NULL; } } } if (buf_head != buf_tail) { /* If we have any bytes buffered, send */ child_ret = _mongoc_stream_tls_write (tls, buf_head, buf_tail - buf_head); if (child_ret < 0) { return child_ret; } ret += child_ret; } if (ret >= 0) { mongoc_counter_streams_egress_add (ret); } return ret; }