Add encode functions to check for NULL output buf and internal error state
diff --git a/inc/UsefulBuf.h b/inc/UsefulBuf.h
index 0bbe3b5..e8a937f 100644
--- a/inc/UsefulBuf.h
+++ b/inc/UsefulBuf.h
@@ -41,6 +41,7 @@
 
  when         who             what, where, why
  --------     ----            --------------------------------------------------
+ 5/16/2019    llundblade      Add UsefulOutBuf_IsBufferNULL().
  3/23/2019    llundblade      Big documentation & style update. No interface
                               change.
  3/6/2019     llundblade      Add UsefulBuf_IsValue()
@@ -1065,8 +1066,8 @@
 /**
  @brief Returns 1 if some number of bytes will fit in the @ref UsefulOutBuf.
 
- @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf
- @param[in] uLen  Number of bytes for which to check
+ @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf
+ @param[in] uLen      Number of bytes for which to check
 
  @return 1 if @c uLen bytes will fit, 0 if not.
 
@@ -1077,6 +1078,19 @@
 static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pUOutBuf, size_t uLen);
 
 
+ /**
+ @brief Returns 1 if buffer given to UsefulOutBuf_Init() was @c NULL.
+
+ @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf
+
+ @return 1 if buffer given to UsefulOutBuf_Init() was @c NULL.
+
+ Giving a @c NULL output buffer to UsefulOutBuf_Init() is used
+ when just calculating the length of the encoded data.
+ */
+static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pUOutBuf);
+
+
 /**
    @brief Returns the resulting valid data in a UsefulOutBuf
 
@@ -1709,6 +1723,11 @@
 }
 
 
+static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pMe)
+{
+   return pMe->UB.ptr == NULL;
+}
+
 
 
 static inline void UsefulInputBuf_Init(UsefulInputBuf *pMe, UsefulBufC UB)
diff --git a/inc/qcbor.h b/inc/qcbor.h
index edf3e98..2945192 100644
--- a/inc/qcbor.h
+++ b/inc/qcbor.h
@@ -43,6 +43,7 @@
 
  when       who             what, where, why
  --------   ----            ---------------------------------------------------
+ 05/26/19   llundblade      Add QCBOREncode_GetErrorState() and _IsBufferNULL().
  04/26/19   llundblade      Big documentation & style update. No interface change.
  02/16/19   llundblade      Redesign MemPool to fix memory access alignment bug.
  12/18/18   llundblade      Move decode malloc optional code to separate repository.
@@ -1827,7 +1828,34 @@
 QCBORError QCBOREncode_FinishGetSize(QCBOREncodeContext *pCtx, size_t *uEncodedLen);
 
 
+/**
+ @brief Indicate whether output buffer is NULL or not.
 
+ @param[in] pCtx  The encoding ontext.
+
+ @return 1 if the output buffer is @c NULL.
+
+ Sometimes a @c NULL input buffer is given to QCBOREncode_Init() so
+ that the size of the generated CBOR can be calculated without
+ allocating a buffer for it. This returns 1 when the output buffer is
+ NULL and 0 when it is not.
+*/
+static int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx);
+
+ /**
+ @brief Get the encoding error state.
+
+ @param[in] pCtx  The encoding ontext.
+
+ @return One of \ref QCBORError. See return values from
+         QCBOREncode_Finish()
+
+ Normally encoding errors need only be handled at the end of encoding
+ when QCBOREncode_Finish() is called. This can be called to get the
+ error result before finish should there be a need to halt encoding
+ before QCBOREncode_Finish().  is called.
+*/
+static QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx);
 
 
 
@@ -2459,13 +2487,13 @@
  */
 void  QCBOREncode_AddType7(QCBOREncodeContext *pCtx, size_t uSize, uint64_t uNum);
 
-    
+
 /**
  @brief Semi-private method to add only the type and length of a byte string.
- 
+
  @param[in] pCtx    The context to initialize.
  @param[in] Bytes   Pointer and length of the input data.
- 
+
  This is the same as QCBOREncode_AddBytes() except it only adds the
  CBOR encoding for the type and the length. It doesn't actually add
  the bytes. You can't actually produce correct CBOR with this and the
@@ -2476,7 +2504,7 @@
  separately and then the bytes is hashed. This makes it possible to
  implement COSE Sign1 with only one copy of the payload in the output
  buffer, rather than two, roughly cutting memory use in half.
- 
+
  This is only used for this odd case, but this is a supported
  tested function.
 */
@@ -2487,7 +2515,7 @@
 static inline void QCBOREncode_AddBytesLenOnlyToMapN(QCBOREncodeContext *pCtx, int64_t nLabel, UsefulBufC Bytes);
 
 
-   
+
 
 static inline void QCBOREncode_AddInt64ToMap(QCBOREncodeContext *pCtx, const char *szLabel, int64_t uNum)
 {
@@ -2975,6 +3003,17 @@
 }
 
 
+static inline int QCBOREncode_IsBufferNULL(QCBOREncodeContext *pCtx)
+{
+   return UsefulOutBuf_IsBufferNULL(&(pCtx->OutBuf));
+}
+
+static inline QCBORError QCBOREncode_GetErrorState(QCBOREncodeContext *pCtx)
+{
+   return pCtx->uError;
+}
+
+
 /* ===========================================================================
  END OF PRIVATE INLINE IMPLEMENTATION
 
diff --git a/test/UsefulBuf_Tests.c b/test/UsefulBuf_Tests.c
index 388f8cf..f53693a 100644
--- a/test/UsefulBuf_Tests.c
+++ b/test/UsefulBuf_Tests.c
@@ -238,6 +238,11 @@
       return "lengths near max size";
    }
 
+   UsefulOutBuf_Init(&UOB, (UsefulBuf){NULL, 100});
+   if(!UsefulOutBuf_IsBufferNULL(&UOB)) {
+      return "NULL check failed";
+   }
+
    return NULL;
 }
 
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index f08927c..458331c 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -1371,7 +1371,7 @@
 
 /*
  The expected encoding for first test in BstrWrapTest()
- 
+
  82           # array(2)
    19 01C3   # unsigned(451)
    43        # bytes(3)
@@ -1430,7 +1430,7 @@
    if(BStr.ptr != NULL || BStr.len != 3) {
       return -5;
    }
-   
+
    // Third, test QCBOREncode_AddBytesLenOnly() here as it is part of the
    // bstr wrapping use cases.
    UsefulBuf_MAKE_STACK_UB(StuffBuf, 50);
@@ -1910,7 +1910,7 @@
 
    // ------ Test for QCBOR_ERR_BUFFER_TOO_LARGE ------
    // Do all of these tests with NULL buffers so no actual large allocations are neccesary
-   UsefulBuf Buffer = (UsefulBuf){NULL, UINT32_MAX};
+   const UsefulBuf Buffer = (UsefulBuf){NULL, UINT32_MAX};
 
    // First verify no error from a big buffer
    QCBOREncode_Init(&EC, Buffer);
@@ -1925,10 +1925,15 @@
    }
 
    // Second verify error from an array in encoded output too large
+   // Also test fetching the error code before finish
    QCBOREncode_Init(&EC, Buffer);
    QCBOREncode_OpenArray(&EC);
    QCBOREncode_AddBytes(&EC, (UsefulBufC){NULL, UINT32_MAX-6});
    QCBOREncode_OpenArray(&EC); // Where QCBOR internally encounters and records error
+   if(QCBOREncode_GetErrorState(&EC) != QCBOR_ERR_BUFFER_TOO_LARGE) {
+      // Error fetch failed.
+      return -12;
+   }
    QCBOREncode_CloseArray(&EC);
    QCBOREncode_CloseArray(&EC);
    if(QCBOREncode_FinishGetSize(&EC, &xx) != QCBOR_ERR_BUFFER_TOO_LARGE) {
@@ -1950,7 +1955,7 @@
    // ----- QCBOR_ERR_BUFFER_TOO_SMALL --------------
    // Work close to the 4GB size limit for a better test
    const uint32_t uLargeSize =  UINT32_MAX - 1024;
-   UsefulBuf Large = (UsefulBuf){NULL,uLargeSize};
+   const UsefulBuf Large = (UsefulBuf){NULL,uLargeSize};
 
    QCBOREncode_Init(&EC, Large);
    QCBOREncode_OpenArray(&EC);
@@ -2038,6 +2043,13 @@
    /* QCBOR_ERR_ARRAY_TOO_LONG is not tested here as
     it would require a 64KB of RAM to test */
 
+
+   // ----- Test the check for NULL buffer ------
+   QCBOREncode_Init(&EC, Buffer);
+   if(QCBOREncode_IsBufferNULL(&EC) == 0) {
+      return -11;
+   }
+
    return 0;
 }