/** writev against a gridfs file */
ssize_t
mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file,
                           mongoc_iovec_t       *iov,
                           size_t                iovcnt,
                           uint32_t              timeout_msec)
{
   uint32_t bytes_written = 0;
   int32_t r;
   size_t i;
   uint32_t iov_pos;

   ENTRY;

   BSON_ASSERT (file);
   BSON_ASSERT (iov);
   BSON_ASSERT (iovcnt);
   BSON_ASSERT (timeout_msec <= INT_MAX);

   /* TODO: we should probably do something about timeout_msec here */

   for (i = 0; i < iovcnt; i++) {
      iov_pos = 0;

      for (;; ) {
         if (!file->page) {
            _mongoc_gridfs_file_refresh_page (file);
         }

         r = _mongoc_gridfs_file_page_write (file->page,
                                            (uint8_t *)iov[i].iov_base + iov_pos,
                                            (uint32_t)(iov[i].iov_len - iov_pos));
         BSON_ASSERT (r >= 0);

         iov_pos += r;
         file->pos += r;
         bytes_written += r;

         file->length = BSON_MAX (file->length, (int64_t)file->pos);

         if (iov_pos == iov[i].iov_len) {
            /** filled a bucket, keep going */
            break;
         } else {
            /** flush the buffer, the next pass through will bring in a new page
             *
             * Our file pointer is now on the new page, so push it back one so
             * that flush knows to flush the old page rather than a new one.
             * This is a little hacky
             */
            file->pos--;
            _mongoc_gridfs_file_flush_page (file);
            file->pos++;
         }
      }
   }

   file->is_dirty = 1;

   RETURN (bytes_written);
}
Exemplo n.º 2
0
/** writev against a gridfs file
 *  timeout_msec is unused */
ssize_t
mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file,
                           const mongoc_iovec_t *iov,
                           size_t iovcnt,
                           uint32_t timeout_msec)
{
   uint32_t bytes_written = 0;
   int32_t r;
   size_t i;
   uint32_t iov_pos;

   ENTRY;

   BSON_ASSERT (file);
   BSON_ASSERT (iov);
   BSON_ASSERT (iovcnt);

   /* Pull in the correct page */
   if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) {
      return -1;
   }

   /* When writing past the end-of-file, fill the gap with zeros */
   if (file->pos > file->length && !_mongoc_gridfs_file_extend (file)) {
      return -1;
   }

   for (i = 0; i < iovcnt; i++) {
      iov_pos = 0;

      for (;;) {
         if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) {
            return -1;
         }

         /* write bytes until an iov is exhausted or the page is full */
         r = _mongoc_gridfs_file_page_write (
            file->page,
            (uint8_t *) iov[i].iov_base + iov_pos,
            (uint32_t) (iov[i].iov_len - iov_pos));
         BSON_ASSERT (r >= 0);

         iov_pos += r;
         file->pos += r;
         bytes_written += r;

         file->length = BSON_MAX (file->length, (int64_t) file->pos);

         if (iov_pos == iov[i].iov_len) {
            /** filled a bucket, keep going */
            break;
         } else {
            /** flush the buffer, the next pass through will bring in a new page
             */
            if (!_mongoc_gridfs_file_flush_page (file)) {
               return -1;
            }
         }
      }
   }

   file->is_dirty = 1;

   RETURN (bytes_written);
}