static void
test_write (void)
{
   mongoc_gridfs_t *gridfs;
   mongoc_gridfs_file_t *file;
   mongoc_client_t *client;
   bson_error_t error;
   ssize_t r;
   char buf[] = "foo bar";
   char buf2[] = " baz";
   char buf3[1000];
   mongoc_gridfs_file_opt_t opt = { 0 };
   mongoc_iovec_t iov[2];
   mongoc_iovec_t riov;
   int len = sizeof buf + sizeof buf2 - 2;

   iov [0].iov_base = buf;
   iov [0].iov_len = sizeof (buf) - 1;
   iov [1].iov_base = buf2;
   iov [1].iov_len = sizeof (buf2) - 1;

   riov.iov_base = buf3;
   riov.iov_len = sizeof (buf3);

   opt.chunk_size = 2;

   client = mongoc_client_new (gTestUri);
   assert (client);

   gridfs = get_test_gridfs (client, "write", &error);
   assert (gridfs);

   mongoc_gridfs_drop (gridfs, &error);

   file = mongoc_gridfs_create_file (gridfs, &opt);
   assert (file);
   assert (mongoc_gridfs_file_save (file));

   r = mongoc_gridfs_file_writev (file, iov, 2, 0);
   assert (r == len);
   assert (mongoc_gridfs_file_save (file));

   r = mongoc_gridfs_file_seek (file, 0, SEEK_SET);
   assert (!r);

   r = mongoc_gridfs_file_tell (file);
   assert (r == 0);

   r = mongoc_gridfs_file_readv (file, &riov, 1, len, 0);
   assert (r == len);
   assert (memcmp (buf3, "foo bar baz", len) == 0);

   mongoc_gridfs_file_destroy (file);

   drop_collections (gridfs, &error);
   mongoc_gridfs_destroy (gridfs);

   mongoc_client_destroy (client);
}
/** create a gridfs file from a stream
 *
 * The stream is fully consumed in creating the file
 */
mongoc_gridfs_file_t *
mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t          *gridfs,
                                       mongoc_stream_t          *stream,
                                       mongoc_gridfs_file_opt_t *opt)
{
   mongoc_gridfs_file_t *file;
   ssize_t r;
   uint8_t buf[MONGOC_GRIDFS_STREAM_CHUNK];
   mongoc_iovec_t iov;
   int timeout;

   ENTRY;

   BSON_ASSERT (gridfs);
   BSON_ASSERT (stream);

   iov.iov_base = (void *)buf;
   iov.iov_len = 0;

   file = _mongoc_gridfs_file_new (gridfs, opt);
   timeout = gridfs->client->cluster.sockettimeoutms;

   for (;; ) {
      r = mongoc_stream_read (stream, iov.iov_base, MONGOC_GRIDFS_STREAM_CHUNK,
                              0, timeout);

      if (r > 0) {
         iov.iov_len = r;
         mongoc_gridfs_file_writev (file, &iov, 1, timeout);
      } else if (r == 0) {
         break;
      } else {
         mongoc_gridfs_file_destroy (file);
         RETURN (NULL);
      }
   }

   mongoc_stream_failed (stream);

   mongoc_gridfs_file_seek (file, 0, SEEK_SET);

   RETURN (file);
}
Example #3
0
/**
 * _mongoc_gridfs_file_extend:
 *
 *      Extend a GridFS file to the current position pointer. Zeros will be
 *      appended to the end of the file until file->length is even with
 * file->pos.
 *
 *      If file->length >= file->pos, the function exits successfully with no
 *      operation performed.
 *
 * Parameters:
 *      @file: A mongoc_gridfs_file_t.
 *
 * Returns:
 *      The number of zero bytes written, or -1 on failure.
 */
static ssize_t
_mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file)
{
   int64_t target_length;
   ssize_t diff;

   ENTRY;

   BSON_ASSERT (file);

   if (file->length >= file->pos) {
      RETURN (0);
   }

   diff = (ssize_t) (file->pos - file->length);
   target_length = file->pos;
   if (-1 == mongoc_gridfs_file_seek (file, 0, SEEK_END)) {
      RETURN (-1);
   }

   while (true) {
      if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) {
         RETURN (-1);
      }

      /* Set bytes until we reach the limit or fill a page */
      file->pos += _mongoc_gridfs_file_page_memset0 (file->page,
                                                     target_length - file->pos);

      if (file->pos == target_length) {
         /* We're done */
         break;
      } else if (!_mongoc_gridfs_file_flush_page (file)) {
         /* We tried to flush a full buffer, but an error occurred */
         RETURN (-1);
      }
   }

   file->length = target_length;
   file->is_dirty = true;

   RETURN (diff);
}
Example #4
0
static void *
background_mongoc_gridfs_file_seek (void *data)
{
   future_t *future = (future_t *) data;
   future_value_t return_value;

   return_value.type = future_value_int_type;

   future_value_set_int (
      &return_value,
      mongoc_gridfs_file_seek (
         future_value_get_mongoc_gridfs_file_t_ptr (future_get_param (future, 0)),
         future_value_get_int64_t (future_get_param (future, 1)),
         future_value_get_int (future_get_param (future, 2))
      ));

   future_resolve (future, return_value);

   return NULL;
}
/** create a gridfs file from a stream
 *
 * The stream is fully consumed in creating the file
 */
mongoc_gridfs_file_t *
mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t          *gridfs,
                                       mongoc_stream_t          *stream,
                                       mongoc_gridfs_file_opt_t *opt)
{
   mongoc_gridfs_file_t *file;
   ssize_t r;
   bson_uint8_t buf[MONGOC_GRIDFS_STREAM_CHUNK];
   struct iovec iov = { buf, 0 };

   ENTRY;

   BSON_ASSERT (gridfs);
   BSON_ASSERT (stream);

   file = _mongoc_gridfs_file_new (gridfs, opt);

   for (;; ) {
      r = mongoc_stream_read (stream, iov.iov_base, MONGOC_GRIDFS_STREAM_CHUNK,
                              0, 0);

      if (r > 0) {
         iov.iov_len = r;
         mongoc_gridfs_file_writev (file, &iov, 1, 0);
      } else if (r == 0) {
         break;
      } else {
         mongoc_gridfs_file_destroy (file);
         RETURN (NULL);
      }
   }

   mongoc_stream_destroy (stream);

   mongoc_gridfs_file_seek (file, 0, SEEK_SET);

   RETURN (file);
}