New encode feature allows direct writing of byte string value (#137)

New features for UsefulBuf and for QCBOREncode allows direct writing to the output buffer. For QCBOREncode, this is the direct writing of the value of a byte string. This allows it to be written in chunks or be the output buffer of some function like symmetric encryption.


* fix grammer in security policy

* Half-way start a encoding feature to write byte string values into output

* Add documentation for OpenBstr

* UsefulBuf_Advance mostly working and testing

* OpenBytes() is mostly working and somewhat tested

* Finish up OpenBytes -- error handing, documentation...

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/src/qcbor_encode.c b/src/qcbor_encode.c
index 7f9c169..af0e38b 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);
@@ -932,6 +935,41 @@
 
 
 /*
+ * Public function for opening a byte string. See qcbor/qcbor_encode.h
+ */
+void QCBOREncode_OpenBytes(QCBOREncodeContext *pMe, UsefulBuf *pPlace)
+{
+   *pPlace = UsefulOutBuf_GetOutPlace(&(pMe->OutBuf));
+   if(!UsefulBuf_IsNULL(*pPlace)){
+#ifndef QCBOR_DISABLE_ENCODE_USAGE_GUARDS
+      uint8_t uMajorType = Nesting_GetMajorType(&(pMe->nesting));
+      if(uMajorType == CBOR_MAJOR_NONE_TYPE_OPEN_BSTR) {
+         pMe->uError = QCBOR_ERR_OPEN_BYTE_STRING;
+         return;
+      }
+#endif /* QCBOR_DISABLE_ENCODE_USAGE_GUARDS */
+
+   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, const size_t uAmount)
+{
+   UsefulOutBuf_Advance(&(pMe->OutBuf), uAmount);
+   if(UsefulOutBuf_GetError(&(pMe->OutBuf))) {
+      /* Advance too far. Normal off-end error handling in effect here. */
+      return;
+   }
+
+   InsertCBORHead(pMe, CBOR_MAJOR_NONE_TYPE_OPEN_BSTR, uAmount);
+}
+
+
+/*
  * Public function for closing arrays and maps. See qcbor/qcbor_encode.h
  */
 void QCBOREncode_CloseMapOrArrayIndefiniteLength(QCBOREncodeContext *me, uint8_t uMajorType)