Add getting un decoded arrays and maps (#117)

This adds QCBORDecode_GetArray() and QCBORDecode_GetMap() plus friends. They return undecoded arrays and maps so they can be passed on to other decoder instances or such.

This also adds UsefulBuf_OffsetToPointer() and UsefulInputBuf_PointerToOffset() to UsefulBuf.

Consume no longer validates standard tags like big floats when it is consuming stuff. It still checks for CBOR that is not well formed.

There was some internal restructuring of array and map processing, but the tests are thorough and they are all passing.

This is to address #112



* getting started on returning arrays

* progress...

* returning maps and arrays mostly working

* Checkpoint progress

* Checkpoint: mostly working

* checkpoint -- it is working

* OffsetToPtr documentation and test

* test and documentation

* Fix Get() of nested indef arrays and maps

* Test tags; doc fixes

* Fix #ifdef test fan out

* Last bit of documentation update

---------

Co-authored-by: Laurence Lundblade <lgl@securitytheory.com>
diff --git a/inc/qcbor/UsefulBuf.h b/inc/qcbor/UsefulBuf.h
index 5f53044..b322e39 100644
--- a/inc/qcbor/UsefulBuf.h
+++ b/inc/qcbor/UsefulBuf.h
@@ -1,6 +1,6 @@
 /* =========================================================================
  * Copyright (c) 2016-2018, The Linux Foundation.
- * Copyright (c) 2018-2022, Laurence Lundblade.
+ * Copyright (c) 2018-2024, Laurence Lundblade.
  * Copyright (c) 2021, Arm Limited. All rights reserved.
  * All rights reserved.
  *
@@ -43,6 +43,7 @@
 
  when         who             what, where, why
  --------     ----            --------------------------------------------------
+ 10/05/2024   llundblade      Add Xxx_OffsetToPointer.
  19/12/2022   llundblade      Document that adding empty data is allowed.
  4/11/2022    llundblade      Add GetOutPlace and Advance to UsefulOutBuf.
  9/21/2021    llundbla        Clarify UsefulOutBuf size calculation mode
@@ -647,16 +648,27 @@
 
 
 /**
- @brief Convert a pointer to an offset with bounds checking.
-
- @param[in] UB  Pointer to the UsefulInputBuf.
- @param[in] p   Pointer to convert to offset.
-
- @return SIZE_MAX if @c p is out of range, the byte offset if not.
+ * @brief Convert a pointer to an offset with bounds checking.
+ *
+ * @param[in] UB  A UsefulBuf.
+ * @param[in] p   Pointer to convert to offset.
+ *
+ * @return SIZE_MAX if @c p is out of range, the byte offset if not.
 */
 static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p);
 
 
+/**
+ * @brief Convert an offset to a pointer with bounds checking.
+ *
+ * @param[in] UB       A UsefulBuf.
+ * @param[in] uOffset  Offset in @c pUInBuf.
+ *
+ * @return @c NULL if @c uOffset is out of range, a pointer into the buffer if not.
+ */
+static inline const void *UsefulBuf_OffsetToPointer(UsefulBufC UB, size_t uOffset);
+
+
 #ifndef USEFULBUF_DISABLE_DEPRECATED
 /** Deprecated macro; use @ref UsefulBuf_FROM_SZ_LITERAL instead */
 #define SZLiteralToUsefulBufC(szString)  UsefulBuf_FROM_SZ_LITERAL(szString)
@@ -1491,7 +1503,18 @@
  *
  * @return SIZE_MAX if @c p is out of range, the byte offset if not.
  */
-static inline size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p);
+static size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p);
+
+
+/**
+ * @brief Convert an offset to a pointer with bounds checking.
+ *
+ * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
+ * @param[in] uOffset  Offset in @c pUInBuf.
+ *
+ * @return @c NULL if @c uOffset is out of range, a pointer into the buffer if not.
+ */
+static const void *UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset);
 
 
 /**
@@ -1857,6 +1880,18 @@
 }
 
 
+static inline const void *UsefulBuf_OffsetToPointer(UsefulBufC UB, size_t uOffset)
+{
+   if(UsefulBuf_IsNULLC(UB) || uOffset >= UB.len) {
+      return NULL;
+   }
+
+   return (const uint8_t *)UB.ptr + uOffset;
+}
+
+
+
+
 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
 static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
 {
@@ -2263,6 +2298,12 @@
 }
 
 
+static inline const void *UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset)
+ {
+    return UsefulBuf_OffsetToPointer(pUInBuf->UB, uOffset);
+ }
+
+
 static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pMe, size_t uNum)
 {
    const void *pResult = UsefulInputBuf_GetBytes(pMe, uNum);