OpenBytes() is mostly working and somewhat tested
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index 748bc56..f5149a5 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
@@ -41,6 +41,7 @@
 
  when        who          what, where, why
  --------    ----         ---------------------------------------------------
+ 4/11/2022    llundblade  Add GetOutPlace and Advance to UsefulOutBuf
  3/6/2021     mcr/llundblade  Fix warnings related to --Wcast-qual
  01/28/2020  llundblade   Refine integer signedness to quiet static analysis.
  01/08/2020  llundblade   Documentation corrections & improved code formatting.
@@ -309,49 +310,53 @@
 void UsefulOutBuf_Advance(UsefulOutBuf *pMe, size_t uAmount)
 {
    /* This function is a trimmed down version of
-      UsefulOutBuf_InsertUsefulBuf() */
+    * UsefulOutBuf_InsertUsefulBuf(). This could be combined with the
+    * code in UsefulOutBuf_InsertUsefulBuf(), but that would make
+    * UsefulOutBuf_InsertUsefulBuf() bigger and this will be very
+    * rarely used.
+    */
 
    if(pMe->err) {
-       /* Already in error state. */
-       return;
-    }
+      /* Already in error state. */
+      return;
+   }
 
-    /* 0. Sanity check the UsefulOutBuf structure
-     *
-     * A "counter measure". If magic number is not the right number it
-     * probably means me was not initialized or it was
-     * corrupted. Attackers can defeat this, but it is a hurdle and
-     * does good with very little code.
-     */
-    if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
-       pMe->err = 1;
-       return;  /* Magic number is wrong due to uninitalization or corrption */
-    }
+   /* 0. Sanity check the UsefulOutBuf structure
+    *
+    * A "counter measure". If magic number is not the right number it
+    * probably means me was not initialized or it was
+    * corrupted. Attackers can defeat this, but it is a hurdle and
+    * does good with very little code.
+    */
+   if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
+      pMe->err = 1;
+      return;  /* Magic number is wrong due to uninitalization or corrption */
+   }
 
-    /* Make sure valid data is less than buffer size. This would only
-     * occur if there was corruption of me, but it is also part of the
-     * checks to be sure there is no pointer arithmatic
-     * under/overflow.
-     */
-    if(pMe->data_len > pMe->UB.len) {  // Check #1
-       pMe->err = 1;
-       /* Offset of valid data is off the end of the UsefulOutBuf due
-        * to uninitialization or corruption.
-        */
-       return;
-    }
+   /* Make sure valid data is less than buffer size. This would only
+    * occur if there was corruption of me, but it is also part of the
+    * checks to be sure there is no pointer arithmatic
+    * under/overflow.
+    */
+   if(pMe->data_len > pMe->UB.len) {  // Check #1
+      pMe->err = 1;
+      /* Offset of valid data is off the end of the UsefulOutBuf due
+       * to uninitialization or corruption.
+       */
+      return;
+   }
 
-    /* 1. Will it fit?
-     *
-     * WillItFit() is the same as: NewData.len <= (me->UB.len -
-     * me->data_len) Check #1 makes sure subtraction in RoomLeft will
-     * not wrap around
-     */
-    if(! UsefulOutBuf_WillItFit(pMe, uAmount)) { /* Check #2 */
-       /* The new data will not fit into the the buffer. */
-       pMe->err = 1;
-       return;
-    }
+   /* 1. Will it fit?
+    *
+    * WillItFit() is the same as: NewData.len <= (me->UB.len -
+    * me->data_len) Check #1 makes sure subtraction in RoomLeft will
+    * not wrap around
+    */
+   if(! UsefulOutBuf_WillItFit(pMe, uAmount)) { /* Check #2 */
+      /* The new data will not fit into the the buffer. */
+      pMe->err = 1;
+      return;
+   }
 
    pMe->data_len += uAmount;
 }
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 760de0e..6cfeb8b 100644
--- a/src/qcbor_encode.c
+++ b/src/qcbor_encode.c
@@ -1,6 +1,6 @@
 /*==============================================================================
  Copyright (c) 2016-2018, The Linux Foundation.
- Copyright (c) 2018-2021, Laurence Lundblade.
+ Copyright (c) 2018-2022, Laurence Lundblade.
  Copyright (c) 2021, Arm Limited.
  All rights reserved.
 
@@ -541,6 +541,9 @@
       }
    }
 #endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+   if(uMajorType == CBOR_MAJOR_NONE_TYPE_OPEN_BSTR) {
+      uMajorType = CBOR_MAJOR_TYPE_BYTE_STRING;
+   }
 
    /* A stack buffer large enough for a CBOR head */
    UsefulBuf_MAKE_STACK_UB(pBufferForEncodedHead, QCBOR_HEAD_BUFFER_SIZE);
@@ -931,51 +934,30 @@
 }
 
 
+/*
+ * Public function for opening a byte string. See qcbor/qcbor_encode.h
+ */
 void QCBOREncode_OpenBytes(QCBOREncodeContext *pMe, UsefulBuf *pPlace)
 {
-   /* Add one item to the nesting level we are in for the new map or array */
-   IncrementMapOrArrayCount(pMe);
-
-   /* The offset where the length of an array or map will get written
-    * is stored in a uint32_t, not a size_t to keep stack usage
-    * smaller. This checks to be sure there is no wrap around when
-    * recording the offset.  Note that on 64-bit machines CBOR larger
-    * than 4GB can be encoded as long as no array/map offsets occur
-    * past the 4GB mark, but the public interface says that the
-    * maximum is 4GB to keep the discussion simpler.
-    */
-   size_t uEndPosition = UsefulOutBuf_GetEndPosition(&(pMe->OutBuf));
-
-   /* QCBOR_MAX_ARRAY_OFFSET is slightly less than UINT32_MAX so this
-    * code can run on a 32-bit machine and tests can pass on a 32-bit
-    * machine. If it was exactly UINT32_MAX, then this code would not
-    * compile or run on a 32-bit machine and an #ifdef or some machine
-    * size detection would be needed reducing portability.
-    */
-   if(uEndPosition >= QCBOR_MAX_ARRAY_OFFSET) {
-      pMe->uError = QCBOR_ERR_BUFFER_TOO_LARGE;
-
-      *pPlace = NULLUsefulBuf;
-
-   } else {
-      /* Increase nesting level because this is a map or array.  Cast
-       * from size_t to uin32_t is safe because of check above.
-       */
-      // TODO: proper type constant
-      pMe->uError = Nesting_Increase(&(pMe->nesting), 200, (uint32_t)uEndPosition);
-
-      *pPlace = UsefulOutBuf_Stuff(&(pMe->OutBuf));
+   *pPlace = UsefulOutBuf_GetOutPlace(&(pMe->OutBuf));
+   if(!UsefulBuf_IsNULL(*pPlace)){
+      QCBOREncode_OpenMapOrArray(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR);
    }
 }
 
 
+/*
+ * Public function for closing a byte string. See qcbor/qcbor_encode.h
+ */
 void QCBOREncode_CloseBytes(QCBOREncodeContext *pMe, size_t uAmount)
 {
-   UsefulOutBuf_StuffDone(&(pMe->OutBuf), uAmount);
-   // TODO: sort out the major type
-   InsertCBORHead(pMe,
-                  CBOR_MAJOR_TYPE_BYTE_STRING,
-                  uAmount);
+   UsefulOutBuf_Advance(&(pMe->OutBuf), uAmount);
+   if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
+      pMe->uError = QCBOR_ERR_ADVANCE_TOO_FAR;
+      return;
+   }
+
+   InsertCBORHead(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR, uAmount);
 }