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 @return 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 @return 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 @return 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 @return 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
) {
672 DataBytes
= LengthInBytes
;
676 // Copy the data into the buffer
678 CopyMem ( &pPort
->TxBuffer
[ pPort
->TxBytes
],
683 // Account for the data copied
685 pPort
->TxBytes
+= DataBytes
;
686 LengthInBytes
-= DataBytes
;
689 // Transmit the buffer if it is full
691 if ( MaxBytes
<= pPort
->TxBytes
) {
692 Status
= HttpFlush ( SocketFD
, pPort
);
694 } while (( EFI_SUCCESS
== Status
) && ( 0 < LengthInBytes
));
697 // Return the operation status
706 @param [in] SocketFD The socket's file descriptor to add to the list.
707 @param [in] pPort The WSDT_PORT structure address
708 @param [in] pString A zero terminated Unicode string
710 @retval EFI_SUCCESS The request was successfully processed
716 IN WSDT_PORT
* pPort
,
717 IN CONST
char * pString
726 Status
= EFI_SUCCESS
;
729 // Walk the characters in he string
732 while ( 0 != *pData
) {
739 Status
= HttpSend ( SocketFD
,
742 (CONST UINT8
*)pString
);
745 // Return the operation status
754 @param [in] SocketFD The socket's file descriptor to add to the list.
755 @param [in] pPort The WSDT_PORT structure address
756 @param [in] Data The data byte to send
758 @retval EFI_SUCCESS The request was successfully processed
764 IN WSDT_PORT
* pPort
,
771 // Send the data byte
773 Status
= HttpSend ( SocketFD
,
779 // Return the operation status
788 @param [in] SocketFD The socket's file descriptor to add to the list.
789 @param [in] pPort The WSDT_PORT structure address
790 @param [in] Character Character to display
791 @param [in] pReplacement Replacement character string
793 @retval EFI_SUCCESS The request was successfully processed
799 IN WSDT_PORT
* pPort
,
801 IN CHAR8
* pReplacement
807 // Determine if this is a printable character
809 if (( 0x20 <= Character
) && ( 0x7f > Character
)) {
810 if ( '<' == Character
) {
812 // Replace with HTML equivalent
814 Status
= HttpSendAnsiString ( SocketFD
,
818 else if ( '>' == Character
) {
820 // Replace with HTML equivalent
822 Status
= HttpSendAnsiString ( SocketFD
,
826 else if ( '&' == Character
) {
828 // Replace with HTML equivalent
830 Status
= HttpSendAnsiString ( SocketFD
,
834 else if ( '\"' == Character
) {
836 // Replace with HTML equivalent
838 Status
= HttpSendAnsiString ( SocketFD
,
844 // Display the character
846 Status
= HttpSendByte ( SocketFD
,
853 // Not a displayable character
855 Status
= HttpSendAnsiString ( SocketFD
,
861 // Return the operation status
870 @param [in] SocketFD The socket's file descriptor to add to the list.
871 @param [in] pPort The WSDT_PORT structure address
872 @param [in] ByteCount The number of bytes to display
873 @param [in] pData Address of the byte array
875 @retval EFI_SUCCESS The request was successfully processed
881 IN WSDT_PORT
* pPort
,
883 IN CONST UINT8
* pData
890 CONST UINT8
* pDataEnd
;
896 // Use for/break instead of goto
900 // Start the field value
902 Status
= HttpSendAnsiString ( SocketFD
,
905 if ( EFI_ERROR ( Status
)) {
910 // Walk the bytes to be displayed
912 pEnd
= &pData
[ ByteCount
];
913 while ( pEnd
> pData
) {
915 // Display the address
917 Status
= HttpSendHexBits ( SocketFD
,
919 sizeof ( pData
) * 8,
921 if ( EFI_ERROR ( Status
)) {
926 // Separate the address and data
928 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
929 if ( EFI_ERROR ( Status
)) {
934 // Position the starting data correctly
936 InitialSpaces
= (UINTN
)pData
;
937 InitialSpaces
&= BYTES_ON_A_LINE
- 1;
938 for ( Index
= SPACES_ADDRESS_TO_DATA
939 + (( 2 + SPACES_BETWEEN_BYTES
)
941 0 < Index
; Index
-- ) {
942 Status
= HttpSendAnsiString ( SocketFD
,
945 if ( EFI_ERROR ( Status
)) {
949 if ( EFI_ERROR ( Status
)) {
956 BytesToDisplay
= pEnd
- pData
;
957 if (( BYTES_ON_A_LINE
- InitialSpaces
) < BytesToDisplay
) {
958 BytesToDisplay
= BYTES_ON_A_LINE
- InitialSpaces
;
960 pDataEnd
= &pData
[ BytesToDisplay
];
962 while ( pDataEnd
> pTemp
) {
963 Status
= HttpSendHexBits ( SocketFD
,
967 if ( EFI_ERROR ( Status
)) {
972 // Separate the data bytes
974 for ( Index
= SPACES_BETWEEN_BYTES
; 0 < Index
; Index
-- ) {
975 Status
= HttpSendAnsiString ( SocketFD
,
978 if ( EFI_ERROR ( Status
)) {
982 if ( EFI_ERROR ( Status
)) {
986 if ( EFI_ERROR ( Status
)) {
991 // Separate the data from the ASCII display
993 for ( Index
= (( 2 + SPACES_BETWEEN_BYTES
)
994 * ( BYTES_ON_A_LINE
- BytesToDisplay
- InitialSpaces
))
995 - SPACES_BETWEEN_BYTES
996 + SPACES_DATA_TO_ASCII
998 0 < Index
; Index
-- ) {
999 Status
= HttpSendAnsiString ( SocketFD
,
1002 if ( EFI_ERROR ( Status
)) {
1006 if ( EFI_ERROR ( Status
)) {
1011 // Display the ASCII data
1013 while ( pDataEnd
> pData
) {
1014 Character
= *pData
++;
1015 Status
= HttpSendCharacter ( SocketFD
,
1019 if ( EFI_ERROR ( Status
)) {
1023 if ( EFI_ERROR ( Status
)) {
1028 // Terminate the line
1030 Status
= HttpSendAnsiString ( SocketFD
,
1033 if ( EFI_ERROR ( Status
)) {
1039 // Terminate the field value and row
1041 Status
= HttpSendAnsiString ( SocketFD
,
1048 // Return the operation status
1055 Display a row containing a GUID value
1057 @param [in] SocketFD The socket's file descriptor to add to the list.
1058 @param [in] pPort The WSDT_PORT structure address
1059 @param [in] pGuid Address of the GUID to display
1061 @retval EFI_SUCCESS The request was successfully processed
1067 IN WSDT_PORT
* pPort
,
1068 IN CONST EFI_GUID
* pGuid
1077 // Use for/break instead of goto
1081 // Display the GUID in a form found in the code
1083 // E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }
1087 // Display the first 32 bits
1089 Status
= HttpSendAnsiString ( SocketFD
,
1092 if ( EFI_ERROR ( Status
)) {
1095 Status
= HttpSendHexBits ( SocketFD
,
1099 if ( EFI_ERROR ( Status
)) {
1104 // Display the second 16 bits
1106 Status
= HttpSendAnsiString ( SocketFD
,
1109 if ( EFI_ERROR ( Status
)) {
1112 Status
= HttpSendHexBits ( SocketFD
,
1116 if ( EFI_ERROR ( Status
)) {
1121 // Display the thrid 16 bits
1123 Status
= HttpSendAnsiString ( SocketFD
,
1126 if ( EFI_ERROR ( Status
)) {
1129 Status
= HttpSendHexBits ( SocketFD
,
1133 if ( EFI_ERROR ( Status
)) {
1138 // Place the last 64 bits in braces
1140 Status
= HttpSendAnsiString ( SocketFD
,
1143 if ( EFI_ERROR ( Status
)) {
1146 for ( Index
= 0; 7 >= Index
; Index
++ ) {
1148 // Display the next 8 bits
1150 Status
= HttpSendHexBits ( SocketFD
,
1153 pGuid
->Data4
[ Index
]);
1154 if ( EFI_ERROR ( Status
)) {
1159 // Separate the bytes
1161 Status
= HttpSendAnsiString ( SocketFD
,
1163 ( 7 != Index
) ? ", 0x" : " }" );
1164 if ( EFI_ERROR ( Status
)) {
1172 // Return the operation status
1174 DBG_EXIT_STATUS ( Status
);
1180 Output a hex value to the HTML page
1182 @param [in] SocketFD Socket file descriptor
1183 @param [in] pPort The WSDT_PORT structure address
1184 @param [in] Bits Number of bits to display
1185 @param [in] Value Value to display
1187 @retval EFI_SUCCESS Successfully displayed the address
1192 IN WSDT_PORT
* pPort
,
1204 Status
= EFI_SUCCESS
;
1207 // Walk the list of divisors
1209 Shift
= (( Bits
+ 3 ) & ( ~3 )) - 4;
1210 while ( 0 <= Shift
) {
1212 // Determine the next digit
1214 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1215 if ( 10 <= Digit
) {
1216 Digit
+= 'A' - '0' - 10;
1220 // Display the digit
1222 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1223 if ( EFI_ERROR ( Status
)) {
1228 // Set the next shift
1234 // Return the operation status
1241 Output a hex value to the HTML page
1243 @param [in] SocketFD Socket file descriptor
1244 @param [in] pPort The WSDT_PORT structure address
1245 @param [in] Value Value to display
1247 @retval EFI_SUCCESS Successfully displayed the address
1252 IN WSDT_PORT
* pPort
,
1256 BOOLEAN bDisplayZeros
;
1264 Status
= EFI_SUCCESS
;
1267 // Walk the list of divisors
1269 bDisplayZeros
= FALSE
;
1273 // Determine the next digit
1275 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1276 if ( 10 <= Digit
) {
1277 Digit
+= 'A' - '0' - 10;
1281 // Suppress leading zeros
1283 if (( 0 != Digit
) || bDisplayZeros
|| ( 0 == Shift
)) {
1284 bDisplayZeros
= TRUE
;
1287 // Display the digit
1289 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1290 if ( EFI_ERROR ( Status
)) {
1296 // Set the next shift
1299 } while ( 0 <= Shift
);
1302 // Return the operation status
1309 Output an IP address to the HTML page
1311 @param [in] SocketFD Socket file descriptor
1312 @param [in] pPort The WSDT_PORT structure address
1313 @param [in] pAddress Address of the socket address
1315 @retval EFI_SUCCESS Successfully displayed the address
1320 IN WSDT_PORT
* pPort
,
1321 IN
struct sockaddr_in
* pAddress
1327 // Output the IPv4 address
1329 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)pAddress
->sin_addr
.s_addr
);
1330 if ( !EFI_ERROR ( Status
)) {
1331 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1332 if ( !EFI_ERROR ( Status
)) {
1333 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pAddress
->sin_addr
.s_addr
>> 8 ));
1334 if ( !EFI_ERROR ( Status
)) {
1335 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1336 if ( !EFI_ERROR ( Status
)) {
1337 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pAddress
->sin_addr
.s_addr
>> 16 ));
1338 if ( !EFI_ERROR ( Status
)) {
1339 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1340 if ( !EFI_ERROR ( Status
)) {
1341 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pAddress
->sin_addr
.s_addr
>> 24 ));
1342 if ( !EFI_ERROR ( Status
)) {
1344 // Output the port number
1346 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1347 if ( !EFI_ERROR ( Status
)) {
1348 Status
= HttpSendValue ( SocketFD
, pPort
, htons ( pAddress
->sin_port
));
1359 // Return the operation status
1366 Send a Unicode string
1368 @param [in] SocketFD The socket's file descriptor to add to the list.
1369 @param [in] pPort The WSDT_PORT structure address
1370 @param [in] pString A zero terminated Unicode string
1372 @retval EFI_SUCCESS The request was successfully processed
1376 HttpSendUnicodeString (
1378 IN WSDT_PORT
* pPort
,
1379 IN CONST UINT16
* pString
1389 Status
= EFI_SUCCESS
;
1392 // Walk the characters in he string
1394 while ( 0 != ( Character
= *pString
++ )) {
1396 // Convert the character to UTF-8
1398 if ( 0 != ( Character
& 0xf800 )) {
1400 // Send the upper 4 bits
1402 Data
= (UINT8
)(( Character
>> 12 ) & 0xf );
1404 Status
= HttpSendByte ( SocketFD
,
1407 if ( EFI_ERROR ( Status
)) {
1412 // Send the next 6 bits
1414 Data
= (UINT8
)(( Character
>> 6 ) & 0x3f );
1416 Status
= HttpSendByte ( SocketFD
,
1419 if ( EFI_ERROR ( Status
)) {
1424 // Send the last 6 bits
1426 Data
= (UINT8
)( Character
& 0x3f );
1429 else if ( 0 != ( Character
& 0x0780 )) {
1431 // Send the upper 5 bits
1433 Data
= (UINT8
)(( Character
>> 6 ) & 0x1f );
1435 Status
= HttpSendByte ( SocketFD
,
1438 if ( EFI_ERROR ( Status
)) {
1443 // Send the last 6 bits
1445 Data
= (UINT8
)( Character
& 0x3f );
1449 Data
= (UINT8
)( Character
& 0x7f );
1453 // Send the last data byte
1455 Status
= HttpSendByte ( SocketFD
,
1458 if ( EFI_ERROR ( Status
)) {
1464 // Return the operation status
1471 Output a value to the HTML page
1473 @param [in] SocketFD Socket file descriptor
1474 @param [in] pPort The WSDT_PORT structure address
1475 @param [in] Value Value to display
1477 @retval EFI_SUCCESS Successfully displayed the address
1482 IN WSDT_PORT
* pPort
,
1486 BOOLEAN bDisplayZeros
;
1488 CONST UINT64
* pEnd
;
1489 CONST UINT64
* pDivisor
;
1490 CONST UINT64 pDivisors
[ ] = {
1491 10000000000000000000L,
1492 1000000000000000000L,
1493 100000000000000000L,
1517 Status
= EFI_SUCCESS
;
1520 // Walk the list of divisors
1522 bDisplayZeros
= FALSE
;
1523 pDivisor
= &pDivisors
[0];
1524 pEnd
= &pDivisor
[ sizeof ( pDivisors
) / sizeof ( pDivisors
[0])];
1525 while ( pEnd
> pDivisor
) {
1527 // Determine the next digit
1529 Digit
= Value
/ *pDivisor
;
1532 // Suppress leading zeros
1534 if (( 0 != Digit
) || bDisplayZeros
) {
1535 bDisplayZeros
= TRUE
;
1538 // Display the digit
1540 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1541 if ( EFI_ERROR ( Status
)) {
1546 // Determine the remainder
1548 Temp
= *pDivisor
* Digit
;
1553 // Set the next divisor
1559 // Display the final digit
1561 if ( !EFI_ERROR ( Status
)) {
1562 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Value
));
1566 // Return the operation status