msgbuf: Add pldm_msgbuf_extract_array() for uint8

This is required for converting the
decode_get_pdr_repository_info_resp() function to pldm_msgbuf.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: If9afcaa83872969bcf8e4d0ecdeae2971e12248b
diff --git a/src/msgbuf.h b/src/msgbuf.h
index 551ce46..bf59388 100644
--- a/src/msgbuf.h
+++ b/src/msgbuf.h
@@ -285,6 +285,40 @@
 		 : pldm_msgbuf_extract_int32, real32_t                         \
 		 : pldm_msgbuf_extract_real32)(ctx, dst)
 
+static inline int pldm_msgbuf_extract_array_uint8(struct pldm_msgbuf *ctx,
+						  uint8_t *dst, size_t count)
+{
+	size_t len;
+
+	if (!ctx || !ctx->cursor || !dst) {
+		return PLDM_ERROR_INVALID_DATA;
+	}
+
+	if (!count) {
+		return PLDM_SUCCESS;
+	}
+
+	len = sizeof(*dst) * count;
+	if (len > SSIZE_MAX) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	ctx->remaining -= (ssize_t)len;
+	assert(ctx->remaining >= 0);
+	if (ctx->remaining < 0) {
+		return PLDM_ERROR_INVALID_LENGTH;
+	}
+
+	memcpy(dst, ctx->cursor, len);
+	ctx->cursor += len;
+
+	return PLDM_SUCCESS;
+}
+
+#define pldm_msgbuf_extract_array(ctx, dst, count)                             \
+	_Generic((*(dst)), uint8_t                                             \
+		 : pldm_msgbuf_extract_array_uint8)(ctx, dst, count)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/tests/msgbuf.cpp b/tests/msgbuf.cpp
index bf2f95e..ad7fe25 100644
--- a/tests/msgbuf.cpp
+++ b/tests/msgbuf.cpp
@@ -315,3 +315,42 @@
     EXPECT_NE(pldm_msgbuf_extract_real32(ctx, &val), PLDM_SUCCESS);
     EXPECT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
 }
+
+TEST(msgbuf, extract_array_uint8_buf0_req0)
+{
+    struct pldm_msgbuf _ctx;
+    struct pldm_msgbuf* ctx = &_ctx;
+    uint8_t buf[1] = {};
+    uint8_t arr[1];
+
+    ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, 0), PLDM_SUCCESS);
+    EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctx, arr, 0), PLDM_SUCCESS);
+    ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
+}
+
+TEST(msgbuf, extract_array_uint8_buf1_req1)
+{
+    struct pldm_msgbuf _ctx;
+    struct pldm_msgbuf* ctx = &_ctx;
+    uint8_t buf[1] = {};
+    uint8_t arr[1];
+
+    ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
+    EXPECT_EQ(pldm_msgbuf_extract_array_uint8(ctx, arr, sizeof(arr)),
+              PLDM_SUCCESS);
+    EXPECT_EQ(arr[0], 0);
+    ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_SUCCESS);
+}
+
+TEST(msgbuf, extract_array_uint8_buf1_req2)
+{
+    struct pldm_msgbuf _ctx;
+    struct pldm_msgbuf* ctx = &_ctx;
+    uint8_t buf[1] = {};
+    uint8_t arr[2];
+
+    ASSERT_EQ(pldm_msgbuf_init(ctx, 0, buf, sizeof(buf)), PLDM_SUCCESS);
+    EXPECT_NE(pldm_msgbuf_extract_array_uint8(ctx, arr, sizeof(arr)),
+              PLDM_SUCCESS);
+    ASSERT_EQ(pldm_msgbuf_destroy(ctx), PLDM_ERROR_INVALID_LENGTH);
+}
diff --git a/tests/msgbuf_generic.c b/tests/msgbuf_generic.c
index 9c3e1b9..d9d292a 100644
--- a/tests/msgbuf_generic.c
+++ b/tests/msgbuf_generic.c
@@ -129,13 +129,31 @@
     expect(pldm_msgbuf_destroy(ctx) == PLDM_SUCCESS);
 }
 
+static void test_msgbuf_extract_array_generic_uint8(void)
+{
+    struct pldm_msgbuf _ctx;
+    struct pldm_msgbuf* ctx = &_ctx;
+    uint32_t buf[1] = {0};
+    uint8_t arr[1];
+
+    expect(pldm_msgbuf_init(ctx, sizeof(buf), buf, sizeof(buf)) ==
+           PLDM_SUCCESS);
+    expect(pldm_msgbuf_extract_array(ctx, arr, 1) == PLDM_SUCCESS);
+    expect(arr[0] == 0);
+    expect(pldm_msgbuf_destroy(ctx) == PLDM_SUCCESS);
+}
+
 typedef void (*testfn)(void);
 
-static const testfn tests[] = {
-    test_msgbuf_extract_generic_uint8,  test_msgbuf_extract_generic_int8,
-    test_msgbuf_extract_generic_uint16, test_msgbuf_extract_generic_int16,
-    test_msgbuf_extract_generic_uint32, test_msgbuf_extract_generic_int32,
-    test_msgbuf_extract_generic_real32, NULL};
+static const testfn tests[] = {test_msgbuf_extract_generic_uint8,
+                               test_msgbuf_extract_generic_int8,
+                               test_msgbuf_extract_generic_uint16,
+                               test_msgbuf_extract_generic_int16,
+                               test_msgbuf_extract_generic_uint32,
+                               test_msgbuf_extract_generic_int32,
+                               test_msgbuf_extract_generic_real32,
+                               test_msgbuf_extract_array_generic_uint8,
+                               NULL};
 
 int main(void)
 {