bios_table: Add decode functions for attr table

Add some necessary decode functions to decode entry of
attribute table

Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I3549ea58d7837fdec91e99b09b37a0fd6c873aa0
diff --git a/libpldm/bios_table.c b/libpldm/bios_table.c
index 5eb6125..2f8d7f1 100644
--- a/libpldm/bios_table.c
+++ b/libpldm/bios_table.c
@@ -146,6 +146,12 @@
 	return le16toh(entry->attr_handle);
 }
 
+uint8_t pldm_bios_table_attr_entry_decode_attribute_type(
+    const struct pldm_bios_attr_table_entry *entry)
+{
+	return entry->attr_type;
+}
+
 uint16_t pldm_bios_table_attr_entry_decode_string_handle(
     const struct pldm_bios_attr_table_entry *entry)
 {
@@ -268,6 +274,21 @@
 	return PLDM_SUCCESS;
 }
 
+uint8_t pldm_bios_table_attr_entry_enum_decode_def_indices(
+    const struct pldm_bios_attr_table_entry *entry, uint8_t *def_indices,
+    uint8_t def_num)
+{
+	uint8_t num = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
+	num = num < def_num ? num : def_num;
+	uint8_t pv_num = pldm_bios_table_attr_entry_enum_decode_pv_num(entry);
+	const uint8_t *p = entry->metadata +
+			   sizeof(uint8_t) /* number of possible values*/
+			   + pv_num * sizeof(uint16_t) /* possible values */
+			   + sizeof(uint8_t); /* number of default values */
+	memcpy(def_indices, p, num);
+	return num;
+}
+
 /** @brief Get length of an enum attribute entry
  */
 static size_t attr_table_entry_length_enum(const void *entry)
@@ -396,6 +417,35 @@
 	return fields->string_type;
 }
 
+uint16_t pldm_bios_table_attr_entry_string_decode_max_length(
+    const struct pldm_bios_attr_table_entry *entry)
+{
+	struct attr_table_string_entry_fields *fields =
+	    (struct attr_table_string_entry_fields *)entry->metadata;
+	return le16toh(fields->max_length);
+}
+
+uint16_t pldm_bios_table_attr_entry_string_decode_min_length(
+    const struct pldm_bios_attr_table_entry *entry)
+{
+	struct attr_table_string_entry_fields *fields =
+	    (struct attr_table_string_entry_fields *)entry->metadata;
+	return le16toh(fields->min_length);
+}
+
+uint16_t pldm_bios_table_attr_entry_string_decode_def_string(
+    const struct pldm_bios_attr_table_entry *entry, char *buffer, size_t size)
+{
+	uint16_t length =
+	    pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
+	length = length < (size - 1) ? length : (size - 1);
+	struct attr_table_string_entry_fields *fields =
+	    (struct attr_table_string_entry_fields *)entry->metadata;
+	memcpy(buffer, fields->def_string, length);
+	buffer[length] = 0;
+	return length;
+}
+
 /** @brief Get length of a string attribute entry
  */
 static size_t attr_table_entry_length_string(const void *entry)
@@ -491,6 +541,18 @@
 	return PLDM_SUCCESS;
 }
 
+void pldm_bios_table_attr_entry_integer_decode(
+    const struct pldm_bios_attr_table_entry *entry, uint64_t *lower,
+    uint64_t *upper, uint32_t *scalar, uint64_t *def)
+{
+	struct attr_table_integer_entry_fields *fields =
+	    (struct attr_table_integer_entry_fields *)entry->metadata;
+	*lower = le64toh(fields->lower_bound);
+	*upper = le64toh(fields->upper_bound);
+	*scalar = le32toh(fields->scalar_increment);
+	*def = le64toh(fields->default_value);
+}
+
 static size_t attr_table_entry_length_integer(const void *entry)
 {
 	(void)entry;
diff --git a/libpldm/bios_table.h b/libpldm/bios_table.h
index 298ba7e..d0e06a4 100644
--- a/libpldm/bios_table.h
+++ b/libpldm/bios_table.h
@@ -171,6 +171,13 @@
 uint16_t pldm_bios_table_attr_entry_decode_attribute_handle(
     const struct pldm_bios_attr_table_entry *entry);
 
+/** @brief Get the attribute type of the attribute table entry
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @return Type of the attribute table entry
+ */
+uint8_t pldm_bios_table_attr_entry_decode_attribute_type(
+    const struct pldm_bios_attr_table_entry *entry);
+
 /** @brief Get the attribute name handle from the attribute table entry
  *  @param[in] entry - Pointer to bios attribute table entry
  *  @return handle to identify the name of the attribute, this handle points
@@ -290,6 +297,18 @@
     const struct pldm_bios_attr_table_entry *entry, uint16_t *pv_hdls,
     uint8_t pv_num);
 
+/** @brief Get Indices of default values
+ *  @param[in] entry - Pointer to bios attribute table entry
+ *  @param[out] def_indices - Pointer to a buffer to store
+ *                            default value indices
+ *  @param[in] def_num - Number of DefaultValues the buffer can
+ *                       store
+ *  @return Number of default values decoded
+ */
+uint8_t pldm_bios_table_attr_entry_enum_decode_def_indices(
+    const struct pldm_bios_attr_table_entry *entry, uint8_t *def_indices,
+    uint8_t def_num);
+
 /** @struct pldm_bios_table_attr_entry_string_info
  *
  *  An auxiliary structure for passing parameters to @ref
@@ -368,6 +387,30 @@
 uint8_t pldm_bios_table_attr_entry_string_decode_string_type(
     const struct pldm_bios_attr_table_entry *entry);
 
+/** @brief Get maximum length of the string from a bios attribute table entry in
+ * bytes
+ *  @param[in] entry - Pointer to a bios attribute table entry
+ *  @return Maximum length of the string
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_max_length(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get minimum length of the string from a bios attribute table entry in
+ * bytes
+ *  @param[in] entry - Pointer to a bios attribute table entry
+ *  @return Minimum length of the string
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_min_length(
+    const struct pldm_bios_attr_table_entry *entry);
+
+/** @brief Get the default string from a bios attribute table entry
+ *  @param[out] buffer - Pointer to a buffer to store the string
+ *  @param[in] size - Size of the buffer to store the string
+ *  @return Length of the string decoded
+ */
+uint16_t pldm_bios_table_attr_entry_string_decode_def_string(
+    const struct pldm_bios_attr_table_entry *entry, char *buffer, size_t size);
+
 /** @struct pldm_bios_table_attr_entry_integer_info
  *
  *  An auxiliary structure for passing parameters to @ref
@@ -421,6 +464,18 @@
     void *entry, size_t entry_length,
     const struct pldm_bios_table_attr_entry_integer_info *info);
 
+/** @brief Decode the specific fields(integer) of attribute table entry
+ *  @param[in] entry - Pointer to an entry of attribute table
+ *  @param[out] lower - The lower bound on the integer value
+ *  @param[out] upper - The upper bound on the integer value
+ *  @param[out] scalar - The scalar value that is used for the increments to
+ *                       this integer
+ *  @param[out] def - The default value of the integer
+ */
+void pldm_bios_table_attr_entry_integer_decode(
+    const struct pldm_bios_attr_table_entry *entry, uint64_t *lower,
+    uint64_t *upper, uint32_t *scalar, uint64_t *def);
+
 /** @brief Get the attribute handle from the attribute value table entry
  *  @param[in] entry - Pointer to bios attribute value table entry
  *  @return handle to identify the attribute in the attribute value table
diff --git a/test/libpldm_bios_table_test.cpp b/test/libpldm_bios_table_test.cpp
index 1f1655c..283425d 100644
--- a/test/libpldm_bios_table_test.cpp
+++ b/test/libpldm_bios_table_test.cpp
@@ -2,6 +2,7 @@
 #include <string.h>
 
 #include <cstring>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -50,6 +51,8 @@
         reinterpret_cast<struct pldm_bios_attr_table_entry*>(enumEntry.data());
     auto attrHandle = pldm_bios_table_attr_entry_decode_attribute_handle(entry);
     EXPECT_EQ(attrHandle, 2);
+    auto attrType = pldm_bios_table_attr_entry_decode_attribute_type(entry);
+    EXPECT_EQ(attrType, 0);
     auto stringHandle = pldm_bios_table_attr_entry_decode_string_handle(entry);
     EXPECT_EQ(stringHandle, 1);
 }
@@ -64,7 +67,7 @@
         2, 0, /* possible value handle */
         3, 0, /* possible value handle */
         1,    /* number of default value */
-        0     /* defaut value string handle index */
+        1     /* defaut value string handle index */
     };
 
     auto entry =
@@ -101,6 +104,12 @@
 
     uint8_t defNumber = pldm_bios_table_attr_entry_enum_decode_def_num(entry);
     EXPECT_EQ(defNumber, 1);
+    std::vector<uint8_t> defIndices(defNumber);
+    rc = pldm_bios_table_attr_entry_enum_decode_def_indices(
+        entry, defIndices.data(), defIndices.size());
+    EXPECT_EQ(rc, defNumber);
+    EXPECT_THAT(defIndices, ElementsAreArray({1}));
+
     defNumber = 0;
     rc =
         pldm_bios_table_attr_entry_enum_decode_def_num_check(entry, &defNumber);
@@ -195,29 +204,42 @@
     auto stringType =
         pldm_bios_table_attr_entry_string_decode_string_type(entry);
     EXPECT_EQ(stringType, 1);
+    auto minLength = pldm_bios_table_attr_entry_string_decode_min_length(entry);
+    EXPECT_EQ(minLength, 1);
+    auto maxLength = pldm_bios_table_attr_entry_string_decode_max_length(entry);
+    EXPECT_EQ(maxLength, 100);
 
-    uint16_t def_string_length =
+    uint16_t defStringLength =
         pldm_bios_table_attr_entry_string_decode_def_string_length(entry);
-    EXPECT_EQ(def_string_length, 3);
+    EXPECT_EQ(defStringLength, 3);
+    std::vector<char> defString(defStringLength + 1);
+    auto rc = pldm_bios_table_attr_entry_string_decode_def_string(
+        entry, defString.data(), defString.size());
+    EXPECT_EQ(rc, 3);
+    EXPECT_STREQ(defString.data(), "abc");
+    rc = pldm_bios_table_attr_entry_string_decode_def_string(
+        entry, defString.data(), defString.size() - 1);
+    EXPECT_EQ(rc, 2);
+    EXPECT_STREQ(defString.data(), "ab");
 
-    def_string_length = 0;
-    auto rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
-        entry, &def_string_length);
+    defStringLength = 0;
+    rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
+        entry, &defStringLength);
     EXPECT_EQ(rc, PLDM_SUCCESS);
-    EXPECT_EQ(def_string_length, 3);
+    EXPECT_EQ(defStringLength, 3);
 
     rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
         entry, nullptr);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
     rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
-        nullptr, &def_string_length);
+        nullptr, &defStringLength);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
     entry->attr_type = PLDM_BIOS_INTEGER;
     rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
-        entry, &def_string_length);
+        entry, &defStringLength);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
     rc = pldm_bios_table_attr_entry_string_decode_def_string_length_check(
-        nullptr, &def_string_length);
+        nullptr, &defStringLength);
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
 }
 
@@ -370,6 +392,30 @@
     EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
 }
 
+TEST(AttrTable, integerEntryDecodeTest)
+{
+    std::vector<uint8_t> integerEntry{
+        0,  0,                   /* attr handle */
+        3,                       /* attr type */
+        1,  0,                   /* attr name handle */
+        1,  0, 0, 0, 0, 0, 0, 0, /* lower bound */
+        10, 0, 0, 0, 0, 0, 0, 0, /* upper bound */
+        2,  0, 0, 0,             /* scalar increment */
+        3,  0, 0, 0, 0, 0, 0, 0, /* defaut value */
+    };
+
+    uint64_t lower, upper, def;
+    uint32_t scalar;
+    auto entry = reinterpret_cast<struct pldm_bios_attr_table_entry*>(
+        integerEntry.data());
+    pldm_bios_table_attr_entry_integer_decode(entry, &lower, &upper, &scalar,
+                                              &def);
+    EXPECT_EQ(lower, 1);
+    EXPECT_EQ(upper, 10);
+    EXPECT_EQ(scalar, 2);
+    EXPECT_EQ(def, 3);
+}
+
 TEST(AttrTable, ItearatorTest)
 {
     std::vector<uint8_t> enumEntry{