     buffer))
 
 (definterface+ IMikronByteBufferFactory
-  (^mikron.buffer.IMikronByteBuffer allocate* [^long size]    "Allocates a buffer with size `size`.")
-  (^mikron.buffer.IMikronByteBuffer wrap*     [^bytes binary] "Wraps a binary value `binary` with a buffer."))
+  (^mikron.buffer.IMikronByteBuffer -allocate [^long size]    "Allocates a buffer with size `size`.")
+  (^mikron.buffer.IMikronByteBuffer -wrap     [^bytes binary] "Wraps a binary value `binary` with a buffer."))
 
 (defn byte-buffer-factory?
   "Returns `true` if `value` is an instance of `IMikronByteBufferFactory`, `false` otherwise."

(defn allocate
  "Allocates a buffer with the size `size`."
  ^MikronBuffer [^long size]
  (->MikronBuffer (->MikronBitBuffer 0 0 -1) (allocate* byte-buffer-factory size)))

(defn wrap
  "Wraps a binary value `binary` with a buffer."
  ^MikronBuffer [^bytes binary]
  (->MikronBuffer (->MikronBitBuffer 0 0 -1) (wrap* byte-buffer-factory binary)))

(defn set-headers
  "Sets the headers of `buffer`."

  #?(:clj (:import [java.nio ByteBuffer ByteOrder])))

(definterface+ IMikronBitBuffer
  (^long   -get-bit-position []            "Gets the current position of the buffer.")
  (^Object -set-bit-position [^long value] "Sets the current position of the buffer.")

  (^long   -get-bit-index []            "Gets the current index of the buffer.")
  (^Object -set-bit-index [^long value] "Sets the current index of the buffer.")

  (^long   -get-bit-value []            "Gets the current value at the index.")
  (^Object -set-bit-value [^long value] "Sets the current value at the index."))

(deftype MikronBitBuffer [^long ^:unsynchronized-mutable value
                          ^long ^:unsynchronized-mutable index
                          ^long ^:unsynchronized-mutable position]
  IMikronBitBuffer
  (-get-bit-position [_]
    position)
  (-set-bit-position [_ value']
    (set! position (unchecked-long value')) nil)

  (-get-bit-index [_]
    index)
  (-set-bit-index [_ value']
    (set! index (unchecked-long value')) nil)

  (-get-bit-value [_]
    value)
  (-set-bit-value [_ value']
    (set! value (unchecked-long value')) nil))

(definterface+ IMikronByteBuffer
  (^long   -take-byte []            "Takes a byte from the buffer.")
  (^Object -put-byte  [^long value] "Puts a byte into the buffer.")

  (^long   -take-short []           "Takes a short from the buffer.")
  (^Object -put-short  [^long value] "Puts a short into the buffer.")

  (^long   -take-int []            "Takes an int from the buffer.")
  (^Object -put-int  [^long value] "Puts an int into the buffer.")

  (^long   -take-long []            "Takes a long from the buffer.")
  (^Object -put-long  [^long value] "Puts a long into the buffer.")

  (^double -take-float []               "Takes a float from the buffer.")
  (^Object -put-float  [^double value] "Puts a float into the buffer.")

  (^double -take-double []              "Takes a double from the buffer.")
  (^Object -put-double  [^double value] "Puts a double into the buffer.")

  (^bytes  -take-bytes [^long n]      "Takes a given number of bytes from the buffer.")
  (^Object -put-bytes  [^bytes value] "Puts a given number of bytes into the buffer.")

  (^bytes  -take-bytes-all [] "Takes all written bytes from the buffer.")

  (^long   -get-position []            "Gets the current positio of the buffer.")
  (^Object -set-position [^long value] "Sets the current position of the buffer.")

  (^Object -get-le []              "Gets the current endianness of the buffer.")
  (^Object -set-le [^Object value] "Sets the current endianness of the buffer."))

#?(:cljs
   (def NativeJsBuffer
