2 This file contains an 'Intel UEFI Application' and is
3 licensed for Intel CPUs and chipsets under the terms of your
4 license agreement with Intel or your vendor. This file may
5 be modified by the user, subject to additional terms of the
10 Copyright (c) 2011 Intel Corporation. All rights reserved
11 This software and associated documentation (if any) is furnished
12 under a license and may only be used or copied in accordance
13 with the terms of the license. Except as permitted by such
14 license, no part of this software or documentation may be
15 reproduced, stored in a retrieval system, or transmitted in any
16 form or by any means without the express written consent of
22 HTTP processing for the web server.
26 #include <WebServer.h>
29 Get a UTF-8 character from the buffer
31 @param [in] pData The address of the buffer containing the character
32 @param [out] ppData The address to receive the next character address
34 @returns The character value
49 // Verify that there is some data left
51 if ( NULL
== pData
) {
60 // Get the first portion of the character
67 // Append the rest of the character
69 if ( 0 != ( Control
& 0x80 )) {
70 while ( 0 != ( Control
& 0x40 )) {
75 Data
= *pData
++ & 0x3f;
76 if ( 0x80 != ( Data
& 0xc0 )) {
84 Character
|= Data
& 0x3f;
90 // Return the next character location and the character
98 Transmit a portion of the HTTP response
100 @param [in] SocketFD The socket's file descriptor to add to the list.
101 @param [in] pPort The WSDT_PORT structure address
103 @retval EFI_SUCCESS The request was successfully processed
121 Status
= EFI_SUCCESS
;
122 pBuffer
= &pPort
->TxBuffer
[0];
125 // Attempt to send the data
127 LengthInBytes
= send ( SocketFD
,
131 if ( -1 != LengthInBytes
) {
133 // Account for the data sent
135 pBuffer
+= LengthInBytes
;
136 pPort
->TxBytes
-= LengthInBytes
;
142 Status
= EFI_DEVICE_ERROR
;
145 } while ( 0 < pPort
->TxBytes
);
148 // Return the operation status
150 DBG_EXIT_STATUS ( Status
);
156 Convert the ANSI character to lower case
158 @param [in] Character The character to convert to lower case.
160 @returns The lower case character
169 // Determine if the character is upper case
171 if (( 'A' <= Character
) && ( 'Z' >= Character
)) {
172 Character
+= 'a' - 'A';
176 // Return the lower case value of the character
183 Match a Unicode string against a UTF-8 string
185 @param [in] pString A zero terminated Unicode string
186 @param [in] pData A zero terminated UTF-8 string
187 @param [in] bIgnoreCase TRUE if case is to be ignored
189 @returns The difference between the last two characters tested.
190 Returns -1 for error.
197 IN BOOLEAN bIgnoreCase
206 // Get the character from the comparison string
208 Character1
= *pString
++;
211 // Convert the character to lower case
214 Character1
= HttpLowerCase ( Character1
);
218 // Get the character from the request
220 Character2
= HttpCharGet ( pData
, &pData
);
221 if ( NULL
== pData
) {
223 // Error getting character
230 // Convert the character to lower case
233 Character2
= HttpLowerCase ( Character2
);
237 // Compare the characters
239 Difference
= Character1
- Character2
;
240 if ( 0 != Difference
) {
243 } while ( 0 != Character1
);
246 // Return the difference
253 Buffer the HTTP page header
255 @param [in] SocketFD The socket's file descriptor to add to the list.
256 @param [in] pPort The WSDT_PORT structure address
257 @param [in] pTitle A zero terminated Unicode title string
259 @retval EFI_SUCCESS The request was successfully processed
265 IN WSDT_PORT
* pPort
,
266 IN CONST CHAR16
* pTitle
274 // Build the page header
277 Status
= HttpSendAnsiString ( SocketFD
,
282 "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
283 "\"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );
284 if ( EFI_ERROR ( Status
)) {
287 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "<html lang=\"en-US\">\r\n" );
288 if ( EFI_ERROR ( Status
)) {
291 if ( NULL
!= pTitle
) {
292 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <head>\r\n" );
293 if ( EFI_ERROR ( Status
)) {
296 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <title>" );
297 if ( EFI_ERROR ( Status
)) {
300 Status
= HttpSendUnicodeString ( SocketFD
, pPort
, pTitle
);
301 if ( EFI_ERROR ( Status
)) {
304 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "</title>\r\n" );
305 if ( EFI_ERROR ( Status
)) {
308 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </head>\r\n" );
309 if ( EFI_ERROR ( Status
)) {
313 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <body>\r\n" );
318 // Return the operation status
320 DBG_EXIT_STATUS ( Status
);
326 Respond with an error indicating that the page was not found
328 @param [in] SocketFD The socket's file descriptor to add to the list.
329 @param [in] pPort The WSDT_PORT structure address
330 @param [out] pbDone Address to receive the request completion status
332 @retval EFI_SUCCESS The request was successfully processed
338 IN WSDT_PORT
* pPort
,
347 // Send the page not found
351 // Send the page header
353 Status
= HttpPageHeader ( SocketFD
, pPort
, L
"404 Not found" );
354 if ( EFI_ERROR ( Status
)) {
359 // Send the page body
361 Status
= HttpSendAnsiString ( SocketFD
,
363 "ERROR <b>404</b><br />"
364 "Requested page is not available\r\n" );
365 if ( EFI_ERROR ( Status
)) {
370 // Send the page trailer
372 Status
= HttpPageTrailer ( SocketFD
, pPort
, pbDone
);
377 // Return the operation status
379 DBG_EXIT_STATUS ( Status
);
385 Buffer and send the HTTP page trailer
387 @param [in] SocketFD The socket's file descriptor to add to the list.
388 @param [in] pPort The WSDT_PORT structure address
389 @param [out] pbDone Address to receive the request completion status
391 @retval EFI_SUCCESS The request was successfully processed
397 IN WSDT_PORT
* pPort
,
403 socklen_t LengthInBytes
;
404 struct sockaddr_in LocalAddress
;
405 struct sockaddr_in RemoteAddress
;
410 // Build the page header
413 LengthInBytes
= sizeof ( LocalAddress
);
414 RetVal
= getsockname ( SocketFD
, (struct sockaddr
*)&LocalAddress
, &LengthInBytes
);
416 RetVal
= getpeername ( SocketFD
, (struct sockaddr
*)&RemoteAddress
, &LengthInBytes
);
419 // Seperate the body from the trailer
421 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <hr>\r\n" );
422 if ( EFI_ERROR ( Status
)) {
427 // Display the system addresses and the page transfer direction
429 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &LocalAddress
);
430 if ( EFI_ERROR ( Status
)) {
433 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " --> " );
434 if ( EFI_ERROR ( Status
)) {
437 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &RemoteAddress
);
438 if ( EFI_ERROR ( Status
)) {
441 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "\r\n" );
442 if ( EFI_ERROR ( Status
)) {
449 // Terminate the page
451 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </body>\r\n" );
452 if ( EFI_ERROR ( Status
)) {
455 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </html>\r\n" );
456 if ( EFI_ERROR ( Status
)) {
461 // Send the page trailer
463 Status
= HttpFlush ( SocketFD
, pPort
);
464 if ( EFI_ERROR ( Status
)) {
469 // Mark the page as complete
476 // Return the operation status
478 DBG_EXIT_STATUS ( Status
);
484 Replace a space with a zero
486 @param [in] pData The request buffer address
487 @param [in] pEnd End of buffer address
489 @returns The next character location
502 while ( pEnd
> pData
) {
504 // Get the character from the request
506 Character
= HttpCharGet ( pData
, &pData
);
507 if ( ' ' == Character
) {
514 // Replace the space character with zero
516 ZeroMem ( pSpace
, pData
- pSpace
);
519 // Return the next character location
526 Process an HTTP request
528 @param [in] SocketFD The socket's file descriptor to add to the list.
529 @param [in] pPort The WSDT_PORT structure address
530 @param [out] pbDone Address to receive the request completion status
532 @retval EFI_SUCCESS The request was successfully processed
538 IN WSDT_PORT
* pPort
,
544 CONST DT_PAGE
* pPage
;
545 CONST DT_PAGE
* pPageEnd
;
554 // Assume the request is not finished
557 Status
= EFI_SUCCESS
;
561 // Attempt to parse the command
563 pData
= &pPort
->Request
[0];
564 pEnd
= &pData
[ pPort
->RequestLength
];
566 pWebPage
= HttpReplaceSpace ( pVerb
, pEnd
);
567 if ( pEnd
<= pWebPage
) {
570 pVersion
= HttpReplaceSpace ( pWebPage
, pEnd
);
571 if ( pEnd
<= pVersion
) {
576 // Validate the request
578 if ( 0 != HttpMatch ( L
"GET", pVerb
, TRUE
)) {
580 // Invalid request type
582 DEBUG (( DEBUG_REQUEST
,
583 "HTTP: Invalid verb\r\n" ));
584 Status
= EFI_NOT_FOUND
;
589 // Walk the page table
591 pPage
= &mPageList
[0];
592 pPageEnd
= &pPage
[ mPageCount
];
593 while ( pPageEnd
> pPage
) {
595 // Determine if the page was located
597 if ( 0 == HttpMatch ( pPage
->pPageName
, pWebPage
, FALSE
)) {
606 if ( pPageEnd
<= pPage
) {
608 // The page was not found
610 DEBUG (( DEBUG_REQUEST
,
611 "HTTP: Page not found in page table\r\n" ));
612 Status
= EFI_NOT_FOUND
;
617 // Respond with the page contents
619 Status
= pPage
->pfnResponse ( SocketFD
, pPort
, pbDone
);
624 // Return page not found if necessary
626 if ( EFI_NOT_FOUND
== Status
) {
627 Status
= HttpPageNotFound ( SocketFD
, pPort
, pbDone
);
631 // Return the operation status
633 DBG_EXIT_STATUS ( Status
);
639 Buffer data for sending
641 @param [in] SocketFD The socket's file descriptor to add to the list.
642 @param [in] pPort The WSDT_PORT structure address
643 @param [in] LengthInBytes Length of valid data in the buffer
644 @param [in] pBuffer Buffer of data to send
646 @retval EFI_SUCCESS The request was successfully processed
652 IN WSDT_PORT
* pPort
,
653 IN
size_t LengthInBytes
,
654 IN CONST UINT8
* pBuffer
664 Status
= EFI_SUCCESS
;
667 // Determine how much data fits into the buffer
669 MaxBytes
= sizeof ( pPort
->TxBuffer
);
670 DataBytes
= MaxBytes
- pPort
->TxBytes
;
671 if ( DataBytes
> LengthInBytes
)
673 DataBytes
= LengthInBytes
;
677 // Copy the data into the buffer
679 CopyMem ( &pPort
->TxBuffer
[ pPort
->TxBytes
],
684 // Account for the data copied
686 pPort
->TxBytes
+= DataBytes
;
687 LengthInBytes
-= DataBytes
;
690 // Transmit the buffer if it is full
692 if ( MaxBytes
<= pPort
->TxBytes
) {
693 Status
= HttpFlush ( SocketFD
, pPort
);
695 } while (( EFI_SUCCESS
== Status
) && ( 0 < LengthInBytes
));
698 // Return the operation status
707 @param [in] SocketFD The socket's file descriptor to add to the list.
708 @param [in] pPort The WSDT_PORT structure address
709 @param [in] pString A zero terminated Unicode string
711 @retval EFI_SUCCESS The request was successfully processed
717 IN WSDT_PORT
* pPort
,
718 IN CONST
char * pString
727 Status
= EFI_SUCCESS
;
730 // Walk the characters in he string
733 while ( 0 != *pData
) {
740 Status
= HttpSend ( SocketFD
,
743 (CONST UINT8
*)pString
);
746 // Return the operation status
755 @param [in] SocketFD The socket's file descriptor to add to the list.
756 @param [in] pPort The WSDT_PORT structure address
757 @param [in] Data The data byte to send
759 @retval EFI_SUCCESS The request was successfully processed
765 IN WSDT_PORT
* pPort
,
772 // Send the data byte
774 Status
= HttpSend ( SocketFD
,
780 // Return the operation status
789 @param [in] SocketFD The socket's file descriptor to add to the list.
790 @param [in] pPort The WSDT_PORT structure address
791 @param [in] Character Character to display
792 @param [in] pReplacement Replacement character string
794 @retval EFI_SUCCESS The request was successfully processed
800 IN WSDT_PORT
* pPort
,
802 IN CHAR8
* pReplacement
808 // Determine if this is a printable character
810 if (( 0x20 <= Character
) && ( 0x7f > Character
)) {
811 if ( '<' == Character
) {
813 // Replace with HTML equivalent
815 Status
= HttpSendAnsiString ( SocketFD
,
819 else if ( '>' == Character
) {
821 // Replace with HTML equivalent
823 Status
= HttpSendAnsiString ( SocketFD
,
827 else if ( '&' == Character
) {
829 // Replace with HTML equivalent
831 Status
= HttpSendAnsiString ( SocketFD
,
835 else if ( '\"' == Character
) {
837 // Replace with HTML equivalent
839 Status
= HttpSendAnsiString ( SocketFD
,
845 // Display the character
847 Status
= HttpSendByte ( SocketFD
,
854 // Not a displayable character
856 Status
= HttpSendAnsiString ( SocketFD
,
862 // Return the operation status
871 @param [in] SocketFD The socket's file descriptor to add to the list.
872 @param [in] pPort The WSDT_PORT structure address
873 @param [in] ByteCount The number of bytes to display
874 @param [in] pData Address of the byte array
876 @retval EFI_SUCCESS The request was successfully processed
882 IN WSDT_PORT
* pPort
,
884 IN CONST UINT8
* pData
891 CONST UINT8
* pDataEnd
;
897 // Use for/break instead of goto
901 // Start the field value
903 Status
= HttpSendAnsiString ( SocketFD
,
906 if ( EFI_ERROR ( Status
)) {
911 // Walk the bytes to be displayed
913 pEnd
= &pData
[ ByteCount
];
914 while ( pEnd
> pData
) {
916 // Display the address
918 Status
= HttpSendHexBits ( SocketFD
,
920 sizeof ( pData
) * 8,
922 if ( EFI_ERROR ( Status
)) {
927 // Separate the address and data
929 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
930 if ( EFI_ERROR ( Status
)) {
935 // Position the starting data correctly
937 InitialSpaces
= (UINTN
)pData
;
938 InitialSpaces
&= BYTES_ON_A_LINE
- 1;
939 for ( Index
= SPACES_ADDRESS_TO_DATA
940 + (( 2 + SPACES_BETWEEN_BYTES
)
942 0 < Index
; Index
-- ) {
943 Status
= HttpSendAnsiString ( SocketFD
,
946 if ( EFI_ERROR ( Status
)) {
950 if ( EFI_ERROR ( Status
)) {
957 BytesToDisplay
= pEnd
- pData
;
958 if (( BYTES_ON_A_LINE
- InitialSpaces
) < BytesToDisplay
) {
959 BytesToDisplay
= BYTES_ON_A_LINE
- InitialSpaces
;
961 pDataEnd
= &pData
[ BytesToDisplay
];
963 while ( pDataEnd
> pTemp
) {
964 Status
= HttpSendHexBits ( SocketFD
,
968 if ( EFI_ERROR ( Status
)) {
973 // Separate the data bytes
975 for ( Index
= SPACES_BETWEEN_BYTES
; 0 < Index
; Index
-- ) {
976 Status
= HttpSendAnsiString ( SocketFD
,
979 if ( EFI_ERROR ( Status
)) {
983 if ( EFI_ERROR ( Status
)) {
987 if ( EFI_ERROR ( Status
)) {
992 // Separate the data from the ASCII display
994 for ( Index
= (( 2 + SPACES_BETWEEN_BYTES
)
995 * ( BYTES_ON_A_LINE
- BytesToDisplay
- InitialSpaces
))
996 - SPACES_BETWEEN_BYTES
997 + SPACES_DATA_TO_ASCII
999 0 < Index
; Index
-- ) {
1000 Status
= HttpSendAnsiString ( SocketFD
,
1003 if ( EFI_ERROR ( Status
)) {
1007 if ( EFI_ERROR ( Status
)) {
1012 // Display the ASCII data
1014 while ( pDataEnd
> pData
) {
1015 Character
= *pData
++;
1016 Status
= HttpSendCharacter ( SocketFD
,
1020 if ( EFI_ERROR ( Status
)) {
1024 if ( EFI_ERROR ( Status
)) {
1029 // Terminate the line
1031 Status
= HttpSendAnsiString ( SocketFD
,
1034 if ( EFI_ERROR ( Status
)) {
1040 // Terminate the field value and row
1042 Status
= HttpSendAnsiString ( SocketFD
,
1049 // Return the operation status
1056 Display a row containing a GUID value
1058 @param [in] SocketFD The socket's file descriptor to add to the list.
1059 @param [in] pPort The WSDT_PORT structure address
1060 @param [in] pGuid Address of the GUID to display
1062 @retval EFI_SUCCESS The request was successfully processed
1068 IN WSDT_PORT
* pPort
,
1069 IN CONST EFI_GUID
* pGuid
1078 // Use for/break instead of goto
1082 // Display the GUID in a form found in the code
1084 // E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }
1088 // Display the first 32 bits
1090 Status
= HttpSendAnsiString ( SocketFD
,
1093 if ( EFI_ERROR ( Status
)) {
1096 Status
= HttpSendHexBits ( SocketFD
,
1100 if ( EFI_ERROR ( Status
)) {
1105 // Display the second 16 bits
1107 Status
= HttpSendAnsiString ( SocketFD
,
1110 if ( EFI_ERROR ( Status
)) {
1113 Status
= HttpSendHexBits ( SocketFD
,
1117 if ( EFI_ERROR ( Status
)) {
1122 // Display the thrid 16 bits
1124 Status
= HttpSendAnsiString ( SocketFD
,
1127 if ( EFI_ERROR ( Status
)) {
1130 Status
= HttpSendHexBits ( SocketFD
,
1134 if ( EFI_ERROR ( Status
)) {
1139 // Place the last 64 bits in braces
1141 Status
= HttpSendAnsiString ( SocketFD
,
1144 if ( EFI_ERROR ( Status
)) {
1147 for ( Index
= 0; 7 >= Index
; Index
++ ) {
1149 // Display the next 8 bits
1151 Status
= HttpSendHexBits ( SocketFD
,
1154 pGuid
->Data4
[ Index
]);
1155 if ( EFI_ERROR ( Status
)) {
1160 // Separate the bytes
1162 Status
= HttpSendAnsiString ( SocketFD
,
1164 ( 7 != Index
) ? ", 0x" : " }" );
1165 if ( EFI_ERROR ( Status
)) {
1173 // Return the operation status
1175 DBG_EXIT_STATUS ( Status
);
1181 Output a hex value to the HTML page
1183 @param [in] SocketFD Socket file descriptor
1184 @param [in] pPort The WSDT_PORT structure address
1185 @param [in] Bits Number of bits to display
1186 @param [in] Value Value to display
1188 @retval EFI_SUCCESS Successfully displayed the address
1193 IN WSDT_PORT
* pPort
,
1205 Status
= EFI_SUCCESS
;
1208 // Walk the list of divisors
1210 Shift
= (( Bits
+ 3 ) & ( ~3 )) - 4;
1211 while ( 0 <= Shift
) {
1213 // Determine the next digit
1215 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1216 if ( 10 <= Digit
) {
1217 Digit
+= 'A' - '0' - 10;
1221 // Display the digit
1223 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1224 if ( EFI_ERROR ( Status
)) {
1229 // Set the next shift
1235 // Return the operation status
1242 Output a hex value to the HTML page
1244 @param [in] SocketFD Socket file descriptor
1245 @param [in] pPort The WSDT_PORT structure address
1246 @param [in] Value Value to display
1248 @retval EFI_SUCCESS Successfully displayed the address
1253 IN WSDT_PORT
* pPort
,
1257 BOOLEAN bDisplayZeros
;
1265 Status
= EFI_SUCCESS
;
1268 // Walk the list of divisors
1270 bDisplayZeros
= FALSE
;
1274 // Determine the next digit
1276 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1277 if ( 10 <= Digit
) {
1278 Digit
+= 'A' - '0' - 10;
1282 // Suppress leading zeros
1284 if (( 0 != Digit
) || bDisplayZeros
|| ( 0 == Shift
)) {
1285 bDisplayZeros
= TRUE
;
1288 // Display the digit
1290 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1291 if ( EFI_ERROR ( Status
)) {
1297 // Set the next shift
1300 } while ( 0 <= Shift
);
1303 // Return the operation status
1310 Output an IP address to the HTML page
1312 @param [in] SocketFD Socket file descriptor
1313 @param [in] pPort The WSDT_PORT structure address
1314 @param [in] pAddress Address of the socket address
1316 @retval EFI_SUCCESS Successfully displayed the address
1321 IN WSDT_PORT
* pPort
,
1322 IN
struct sockaddr_in
* pAddress
1328 // Output the IPv4 address
1330 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)pAddress
->sin_addr
.s_addr
);
1331 if ( !EFI_ERROR ( Status
)) {
1332 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1333 if ( !EFI_ERROR ( Status
)) {
1334 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pAddress
->sin_addr
.s_addr
>> 8 ));
1335 if ( !EFI_ERROR ( Status
)) {
1336 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1337 if ( !EFI_ERROR ( Status
)) {
1338 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pAddress
->sin_addr
.s_addr
>> 16 ));
1339 if ( !EFI_ERROR ( Status
)) {
1340 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1341 if ( !EFI_ERROR ( Status
)) {
1342 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pAddress
->sin_addr
.s_addr
>> 24 ));
1343 if ( !EFI_ERROR ( Status
)) {
1345 // Output the port number
1347 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1348 if ( !EFI_ERROR ( Status
)) {
1349 Status
= HttpSendValue ( SocketFD
, pPort
, htons ( pAddress
->sin_port
));
1360 // Return the operation status
1367 Send a Unicode string
1369 @param [in] SocketFD The socket's file descriptor to add to the list.
1370 @param [in] pPort The WSDT_PORT structure address
1371 @param [in] pString A zero terminated Unicode string
1373 @retval EFI_SUCCESS The request was successfully processed
1377 HttpSendUnicodeString (
1379 IN WSDT_PORT
* pPort
,
1380 IN CONST UINT16
* pString
1390 Status
= EFI_SUCCESS
;
1393 // Walk the characters in he string
1395 while ( 0 != ( Character
= *pString
++ )) {
1397 // Convert the character to UTF-8
1399 if ( 0 != ( Character
& 0xf800 )) {
1401 // Send the upper 4 bits
1403 Data
= (UINT8
)(( Character
>> 12 ) & 0xf );
1405 Status
= HttpSendByte ( SocketFD
,
1408 if ( EFI_ERROR ( Status
)) {
1413 // Send the next 6 bits
1415 Data
= (UINT8
)(( Character
>> 6 ) & 0x3f );
1417 Status
= HttpSendByte ( SocketFD
,
1420 if ( EFI_ERROR ( Status
)) {
1425 // Send the last 6 bits
1427 Data
= (UINT8
)( Character
& 0x3f );
1430 else if ( 0 != ( Character
& 0x0780 )) {
1432 // Send the upper 5 bits
1434 Data
= (UINT8
)(( Character
>> 6 ) & 0x1f );
1436 Status
= HttpSendByte ( SocketFD
,
1439 if ( EFI_ERROR ( Status
)) {
1444 // Send the last 6 bits
1446 Data
= (UINT8
)( Character
& 0x3f );
1450 Data
= (UINT8
)( Character
& 0x7f );
1454 // Send the last data byte
1456 Status
= HttpSendByte ( SocketFD
,
1459 if ( EFI_ERROR ( Status
)) {
1465 // Return the operation status
1472 Output a value to the HTML page
1474 @param [in] SocketFD Socket file descriptor
1475 @param [in] pPort The WSDT_PORT structure address
1476 @param [in] Value Value to display
1478 @retval EFI_SUCCESS Successfully displayed the address
1483 IN WSDT_PORT
* pPort
,
1487 BOOLEAN bDisplayZeros
;
1489 CONST UINT64
* pEnd
;
1490 CONST UINT64
* pDivisor
;
1491 CONST UINT64 pDivisors
[ ] = {
1492 10000000000000000000L,
1493 1000000000000000000L,
1494 100000000000000000L,
1518 Status
= EFI_SUCCESS
;
1521 // Walk the list of divisors
1523 bDisplayZeros
= FALSE
;
1524 pDivisor
= &pDivisors
[0];
1525 pEnd
= &pDivisor
[ sizeof ( pDivisors
) / sizeof ( pDivisors
[0])];
1526 while ( pEnd
> pDivisor
) {
1528 // Determine the next digit
1530 Digit
= Value
/ *pDivisor
;
1533 // Suppress leading zeros
1535 if (( 0 != Digit
) || bDisplayZeros
) {
1536 bDisplayZeros
= TRUE
;
1539 // Display the digit
1541 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1542 if ( EFI_ERROR ( Status
)) {
1547 // Determine the remainder
1549 Temp
= *pDivisor
* Digit
;
1554 // Set the next divisor
1560 // Display the final digit
1562 if ( !EFI_ERROR ( Status
)) {
1563 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Value
));
1567 // Return the operation status