<?xml version="1.0"?>
<page xmlns="http://projectmallard.org/1.0/"
      type="topic"
      style="function"
      xmlns:api="http://projectmallard.org/experimental/api/"
      xmlns:ui="http://projectmallard.org/experimental/ui/"
      id="bson_reserve_buffer">
  <info>
    <link type="guide" xref="bson_t" group="function"/>
  </info>
  <title>bson_reserve_buffer()</title>

  <section id="synopsis">
    <title>Synopsis</title>
    <synopsis><code mime="text/x-csrc"><![CDATA[uint8_t *
bson_reserve_buffer (bson_t   *bson,
                     uint32_t  size);]]></code></synopsis>
  </section>

  <section id="parameters">
    <title>Parameters</title>
    <table>
      <tr><td><p>bson</p></td><td><p>An initialized <code xref="bson_t">bson_t</code>.</p></td></tr>
      <tr><td><p>size</p></td><td><p>The length in bytes of the new buffer.</p></td></tr>
    </table>
  </section>

  <section id="description">
    <title>Description</title>
    <p>Grow the internal buffer of <code>bson</code> to <code>size</code> and set the document length to <code>size</code>. Useful for eliminating copies when reading BSON bytes from a stream.</p>
    <p>First, initialize <code>bson</code> with <code xref="bson_init">bson_init</code> or <code xref="bson_new">bson_new</code>, then call this function. After it returns, the length of <code>bson</code> is set to <code>size</code> but its contents are uninitialized memory: you must fill the contents with a BSON document of the correct length before any other operations.</p>
    <p>The document must be freed with <code xref="bson_destroy">bson_destroy</code>.</p>
  </section>

  <section id="return">
    <title>Returns</title>
    <p>A pointer to the internal buffer, which is at least <code>size</code> bytes, or NULL if the space could not be allocated.</p>
  </section>

  <section id="example">
    <title>Example</title>
    <p>Use <code>bson_reserve_buffer</code> to write a function that takes a <code xref="bson_t">bson_t</code> pointer and reads a file into it directly:</p>
    <code mime="text/x-csrc"><![CDATA[#include <stdio.h>
#include <bson.h>

bool
read_into (bson_t   *bson,
           FILE     *fp)
{
   uint8_t *buffer;
   long size;

   if (fseek(fp, 0L, SEEK_END) < 0) {
      perror ("Couldn't get file size");
      return 1;
   }

   size = ftell (fp);
   if (size == EOF) {
      perror ("Couldn't get file size");
      return 1;
   }

   if (size > INT32_MAX) {
      fprintf (stderr, "File too large\n");
      return 1;
   }

   /* reserve buffer space - bson is temporarily invalid */
   buffer = bson_reserve_buffer (bson, (uint32_t) size);
   if (!buffer) {
      fprintf (stderr, "Couldn't reserve %ld bytes", size);
      return false;
   }

   /* read file directly into the buffer */
   rewind(fp);
   if (fread ((void *) buffer, 1, (size_t) size, fp) < (size_t) size) {
      perror ("Couldn't read file");
      return false;
   }

   return true;
}

int
main ()
{
   FILE *fp;
   char *json;

   /* stack-allocated, initialized bson_t */
   bson_t bson = BSON_INITIALIZER;

   if (!(fp = fopen ("document.bson", "rb"))) {
      perror ("Couldn't read file");
      return 1;
   }

   read_into (&bson, fp);
   fclose (fp);

   json = bson_as_json (&bson, NULL);
   printf ("%s\n", json);

   bson_free (json);
   bson_destroy (&bson);

   return 0;
}]]></code>
    <p>See also <code xref="bson_steal">bson_steal</code> and <code xref="bson_destroy_with_steal">bson_destroy_with_steal</code>.</p>
  </section>
</page>
