+\r
+/**\r
+ Create a HTTP_IO_HEADER to hold the HTTP header items.\r
+\r
+ @param[in] MaxHeaderCount The maximun number of HTTP header in this holder.\r
+\r
+ @return A pointer of the HTTP header holder or NULL if failed.\r
+\r
+**/\r
+HTTP_IO_HEADER *\r
+HttpIoCreateHeader (\r
+ UINTN MaxHeaderCount\r
+ )\r
+{\r
+ HTTP_IO_HEADER *HttpIoHeader;\r
+\r
+ if (MaxHeaderCount == 0) {\r
+ return NULL;\r
+ }\r
+\r
+ HttpIoHeader = AllocateZeroPool (sizeof (HTTP_IO_HEADER) + MaxHeaderCount * sizeof (EFI_HTTP_HEADER));\r
+ if (HttpIoHeader == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ HttpIoHeader->MaxHeaderCount = MaxHeaderCount;\r
+ HttpIoHeader->Headers = (EFI_HTTP_HEADER *) (HttpIoHeader + 1);\r
+\r
+ return HttpIoHeader;\r
+}\r
+\r
+/**\r
+ Destroy the HTTP_IO_HEADER and release the resources.\r
+\r
+ @param[in] HttpIoHeader Point to the HTTP header holder to be destroyed.\r
+\r
+**/\r
+VOID\r
+HttpIoFreeHeader (\r
+ IN HTTP_IO_HEADER *HttpIoHeader\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ if (HttpIoHeader != NULL) {\r
+ if (HttpIoHeader->HeaderCount != 0) {\r
+ for (Index = 0; Index < HttpIoHeader->HeaderCount; Index++) {\r
+ FreePool (HttpIoHeader->Headers[Index].FieldName);\r
+ ZeroMem (HttpIoHeader->Headers[Index].FieldValue, AsciiStrSize (HttpIoHeader->Headers[Index].FieldValue));\r
+ FreePool (HttpIoHeader->Headers[Index].FieldValue);\r
+ }\r
+ }\r
+ FreePool (HttpIoHeader);\r
+ }\r
+}\r
+\r
+/**\r
+ Set or update a HTTP header with the field name and corresponding value.\r
+\r
+ @param[in] HttpIoHeader Point to the HTTP header holder.\r
+ @param[in] FieldName Null terminated string which describes a field name.\r
+ @param[in] FieldValue Null terminated string which describes the corresponding field value.\r
+\r
+ @retval EFI_SUCCESS The HTTP header has been set or updated.\r
+ @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
+ @retval EFI_OUT_OF_RESOURCES Insufficient resource to complete the operation.\r
+ @retval Other Unexpected error happened.\r
+\r
+**/\r
+EFI_STATUS\r
+HttpIoSetHeader (\r
+ IN HTTP_IO_HEADER *HttpIoHeader,\r
+ IN CHAR8 *FieldName,\r
+ IN CHAR8 *FieldValue\r
+ )\r
+{\r
+ EFI_HTTP_HEADER *Header;\r
+ UINTN StrSize;\r
+ CHAR8 *NewFieldValue;\r
+\r
+ if (HttpIoHeader == NULL || FieldName == NULL || FieldValue == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Header = HttpFindHeader (HttpIoHeader->HeaderCount, HttpIoHeader->Headers, FieldName);\r
+ if (Header == NULL) {\r
+ //\r
+ // Add a new header.\r
+ //\r
+ if (HttpIoHeader->HeaderCount >= HttpIoHeader->MaxHeaderCount) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ Header = &HttpIoHeader->Headers[HttpIoHeader->HeaderCount];\r
+\r
+ StrSize = AsciiStrSize (FieldName);\r
+ Header->FieldName = AllocatePool (StrSize);\r
+ if (Header->FieldName == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (Header->FieldName, FieldName, StrSize);\r
+ Header->FieldName[StrSize -1] = '\0';\r
+\r
+ StrSize = AsciiStrSize (FieldValue);\r
+ Header->FieldValue = AllocatePool (StrSize);\r
+ if (Header->FieldValue == NULL) {\r
+ FreePool (Header->FieldName);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (Header->FieldValue, FieldValue, StrSize);\r
+ Header->FieldValue[StrSize -1] = '\0';\r
+\r
+ HttpIoHeader->HeaderCount++;\r
+ } else {\r
+ //\r
+ // Update an existing one.\r
+ //\r
+ StrSize = AsciiStrSize (FieldValue);\r
+ NewFieldValue = AllocatePool (StrSize);\r
+ if (NewFieldValue == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (NewFieldValue, FieldValue, StrSize);\r
+ NewFieldValue[StrSize -1] = '\0';\r
+\r
+ if (Header->FieldValue != NULL) {\r
+ FreePool (Header->FieldValue);\r
+ }\r
+ Header->FieldValue = NewFieldValue;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r