Home | History | Annotate | Download | only in EfiCommonLib
      1 /*++
      2 
      3 Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 Module Name:
     13 
     14   String.c
     15 
     16 Abstract:
     17 
     18   Unicode string primatives
     19 
     20 --*/
     21 
     22 #include "Tiano.h"
     23 #include "EfiDriverLib.h"
     24 #include "EfiCommonLib.h"
     25 
     26 VOID
     27 EfiStrCpy (
     28   IN CHAR16   *Destination,
     29   IN CHAR16   *Source
     30   )
     31 /*++
     32 
     33 Routine Description:
     34   Copy the Unicode string Source to Destination.
     35 
     36 Arguments:
     37   Destination - Location to copy string
     38   Source      - String to copy
     39 
     40 Returns:
     41   NONE
     42 
     43 --*/
     44 {
     45   while (*Source) {
     46     *(Destination++) = *(Source++);
     47   }
     48   *Destination = 0;
     49 }
     50 
     51 VOID
     52 EfiStrnCpy (
     53   OUT CHAR16  *Dst,
     54   IN  CHAR16  *Src,
     55   IN  UINTN   Length
     56   )
     57 /*++
     58 
     59 Routine Description:
     60   Copy a string from source to destination
     61 
     62 Arguments:
     63   Dst              Destination string
     64   Src              Source string
     65   Length           Length of destination string
     66 
     67 Returns:
     68 
     69 --*/
     70 {
     71   UINTN Index;
     72   UINTN SrcLen;
     73 
     74   SrcLen = EfiStrLen (Src);
     75 
     76   Index = 0;
     77   while (Index < Length && Index < SrcLen) {
     78     Dst[Index] = Src[Index];
     79     Index++;
     80   }
     81   for (Index = SrcLen; Index < Length; Index++) {
     82     Dst[Index] = 0;
     83   }
     84 }
     85 
     86 UINTN
     87 EfiStrLen (
     88   IN CHAR16   *String
     89   )
     90 /*++
     91 
     92 Routine Description:
     93   Return the number of Unicode characters in String. This is not the same as
     94   the length of the string in bytes.
     95 
     96 Arguments:
     97   String - String to process
     98 
     99 Returns:
    100   Number of Unicode characters in String
    101 
    102 --*/
    103 {
    104   UINTN Length;
    105 
    106   for (Length=0; *String; String++, Length++);
    107   return Length;
    108 }
    109 
    110 
    111 UINTN
    112 EfiStrSize (
    113   IN CHAR16   *String
    114   )
    115 /*++
    116 
    117 Routine Description:
    118   Return the number bytes in the Unicode String. This is not the same as
    119   the length of the string in characters. The string size includes the NULL
    120 
    121 Arguments:
    122   String - String to process
    123 
    124 Returns:
    125   Number of bytes in String
    126 
    127 --*/
    128 {
    129   return ((EfiStrLen (String) + 1) * sizeof (CHAR16));
    130 }
    131 
    132 
    133 INTN
    134 EfiStrCmp (
    135   IN CHAR16   *String,
    136   IN CHAR16   *String2
    137   )
    138 /*++
    139 
    140 Routine Description:
    141   Compare the Unicode string pointed by String to the string pointed by String2.
    142 
    143 Arguments:
    144   String - String to process
    145 
    146   String2 - The other string to process
    147 
    148 Returns:
    149   Return a positive integer if String is lexicall greater than String2; Zero if
    150   the two strings are identical; and a negative integer if String is lexically
    151   less than String2.
    152 
    153 --*/
    154 {
    155   while (*String) {
    156     if (*String != *String2) {
    157       break;
    158     }
    159 
    160     String += 1;
    161     String2 += 1;
    162   }
    163 
    164   return *String - *String2;
    165 }
    166 
    167 INTN
    168 EfiStrnCmp (
    169   IN CHAR16   *String,
    170   IN CHAR16   *String2,
    171   IN UINTN    Length
    172   )
    173 /*++
    174 
    175 Routine Description:
    176   This function compares the Unicode string String to the Unicode
    177   string String2 for len characters.  If the first len characters
    178   of String is identical to the first len characters of String2,
    179   then 0 is returned.  If substring of String sorts lexicographically
    180   after String2, the function returns a number greater than 0. If
    181   substring of String sorts lexicographically before String2, the
    182   function returns a number less than 0.
    183 
    184 Arguments:
    185   String  - Compare to String2
    186   String2 - Compare to String
    187   Length  - Number of Unicode characters to compare
    188 
    189 Returns:
    190   0     - The substring of String and String2 is identical.
    191   > 0   - The substring of String sorts lexicographically after String2
    192   < 0   - The substring of String sorts lexicographically before String2
    193 
    194 --*/
    195 {
    196   while (*String && Length != 0) {
    197     if (*String != *String2) {
    198       break;
    199     }
    200     String  += 1;
    201     String2 += 1;
    202     Length  -= 1;
    203   }
    204   return Length > 0 ? *String - *String2 : 0;
    205 }
    206 
    207 VOID
    208 EfiStrCat (
    209   IN CHAR16   *Destination,
    210   IN CHAR16   *Source
    211   )
    212 /*++
    213 
    214 Routine Description:
    215   Concatinate Source on the end of Destination
    216 
    217 Arguments:
    218   Destination - String to added to the end of.
    219   Source      - String to concatinate.
    220 
    221 Returns:
    222   NONE
    223 
    224 --*/
    225 {
    226   EfiStrCpy (Destination + EfiStrLen (Destination), Source);
    227 }
    228 
    229 VOID
    230 EfiStrnCat (
    231   IN CHAR16   *Dest,
    232   IN CHAR16   *Src,
    233   IN UINTN    Length
    234   )
    235 /*++
    236 
    237 Routine Description:
    238   Concatinate Source on the end of Destination
    239 
    240 Arguments:
    241   Dst              Destination string
    242   Src              Source string
    243   Length           Length of destination string
    244 
    245 Returns:
    246 
    247 --*/
    248 {
    249   EfiStrnCpy (Dest + EfiStrLen (Dest), Src, Length);
    250 }
    251 
    252 UINTN
    253 EfiAsciiStrLen (
    254   IN CHAR8   *String
    255   )
    256 /*++
    257 
    258 Routine Description:
    259   Return the number of Ascii characters in String. This is not the same as
    260   the length of the string in bytes.
    261 
    262 Arguments:
    263   String - String to process
    264 
    265 Returns:
    266   Number of Ascii characters in String
    267 
    268 --*/
    269 {
    270   UINTN Length;
    271 
    272   for (Length=0; *String; String++, Length++);
    273   return Length;
    274 }
    275 
    276 
    277 CHAR8 *
    278 EfiAsciiStrCpy (
    279   IN CHAR8    *Destination,
    280   IN CHAR8    *Source
    281   )
    282 /*++
    283 
    284 Routine Description:
    285   Copy the Ascii string Source to Destination.
    286 
    287 Arguments:
    288   Destination - Location to copy string
    289   Source      - String to copy
    290 
    291 Returns:
    292   Pointer just pass the end of Destination
    293 
    294 --*/
    295 {
    296   while (*Source) {
    297     *(Destination++) = *(Source++);
    298   }
    299   *Destination = 0;
    300   return Destination + 1;
    301 }
    302 
    303 VOID
    304 EfiAsciiStrnCpy (
    305   OUT CHAR8    *Dst,
    306   IN  CHAR8    *Src,
    307   IN  UINTN    Length
    308   )
    309 /*++
    310 
    311 Routine Description:
    312   Copy the Ascii string from source to destination
    313 
    314 Arguments:
    315   Dst              Destination string
    316   Src              Source string
    317   Length           Length of destination string
    318 
    319 Returns:
    320 
    321 --*/
    322 {
    323   UINTN Index;
    324   UINTN SrcLen;
    325 
    326   SrcLen = EfiAsciiStrLen (Src);
    327 
    328   Index = 0;
    329   while (Index < Length && Index < SrcLen) {
    330     Dst[Index] = Src[Index];
    331     Index++;
    332   }
    333   for (Index = SrcLen; Index < Length; Index++) {
    334     Dst[Index] = 0;
    335   }
    336 }
    337 
    338 UINTN
    339 EfiAsciiStrSize (
    340   IN CHAR8   *String
    341   )
    342 /*++
    343 
    344 Routine Description:
    345   Return the number bytes in the Ascii String. This is not the same as
    346   the length of the string in characters. The string size includes the NULL
    347 
    348 Arguments:
    349   String - String to process
    350 
    351 Returns:
    352   Number of bytes in String
    353 
    354 --*/
    355 {
    356   return (EfiAsciiStrLen (String) + 1);
    357 }
    358 
    359 
    360 INTN
    361 EfiAsciiStrCmp (
    362   IN CHAR8   *String,
    363   IN CHAR8   *String2
    364   )
    365 /*++
    366 
    367 Routine Description:
    368   Compare the Ascii string pointed by String to the string pointed by String2.
    369 
    370 Arguments:
    371   String - String to process
    372 
    373   String2 - The other string to process
    374 
    375 Returns:
    376   Return a positive integer if String is lexicall greater than String2; Zero if
    377   the two strings are identical; and a negative integer if String is lexically
    378   less than String2.
    379 --*/
    380 {
    381   while (*String) {
    382     if (*String != *String2) {
    383       break;
    384     }
    385 
    386     String += 1;
    387     String2 += 1;
    388   }
    389 
    390   return *String - *String2;
    391 }
    392 
    393 INTN
    394 EfiAsciiStrnCmp (
    395   IN CHAR8    *String,
    396   IN CHAR8    *String2,
    397   IN UINTN    Length
    398   )
    399 {
    400   if (Length == 0) {
    401     return 0;
    402   }
    403 
    404   while ((*String != '\0') &&
    405          (*String == *String2) &&
    406          (Length > 1)) {
    407     String++;
    408     String2++;
    409     Length--;
    410   }
    411   return *String - *String2;
    412 }
    413 
    414 VOID
    415 EfiAsciiStrCat (
    416   IN CHAR8   *Destination,
    417   IN CHAR8   *Source
    418   )
    419 /*++
    420 
    421 Routine Description:
    422   Concatinate Source on the end of Destination
    423 
    424 Arguments:
    425   Destination - String to added to the end of.
    426   Source      - String to concatinate.
    427 
    428 Returns:
    429   NONE
    430 
    431 --*/
    432 {
    433   EfiAsciiStrCpy (Destination + EfiAsciiStrLen (Destination), Source);
    434 }
    435 
    436 VOID
    437 EfiAsciiStrnCat (
    438   IN CHAR8   *Destination,
    439   IN CHAR8   *Source,
    440   IN UINTN   Length
    441   )
    442 /*++
    443 
    444 Routine Description:
    445   Concatinate Source on the end of Destination
    446 
    447 Arguments:
    448   Destination - String to added to the end of.
    449   Source      - String to concatinate.
    450 
    451 Returns:
    452   NONE
    453 
    454 --*/
    455 {
    456   EfiAsciiStrnCpy (Destination + EfiAsciiStrLen (Destination), Source, Length);
    457 }
    458 
    459 BOOLEAN
    460 IsHexDigit (
    461   OUT UINT8      *Digit,
    462   IN  CHAR16      Char
    463   )
    464 /*++
    465 
    466   Routine Description:
    467     Determines if a Unicode character is a hexadecimal digit.
    468     The test is case insensitive.
    469 
    470   Arguments:
    471     Digit - Pointer to byte that receives the value of the hex character.
    472     Char  - Unicode character to test.
    473 
    474   Returns:
    475     TRUE  - If the character is a hexadecimal digit.
    476     FALSE - Otherwise.
    477 
    478 --*/
    479 {
    480   if ((Char >= L'0') && (Char <= L'9')) {
    481     *Digit = (UINT8) (Char - L'0');
    482     return TRUE;
    483   }
    484 
    485   if ((Char >= L'A') && (Char <= L'F')) {
    486     *Digit = (UINT8) (Char - L'A' + 0x0A);
    487     return TRUE;
    488   }
    489 
    490   if ((Char >= L'a') && (Char <= L'f')) {
    491     *Digit = (UINT8) (Char - L'a' + 0x0A);
    492     return TRUE;
    493   }
    494 
    495   return FALSE;
    496 }
    497 
    498 CHAR16
    499 NibbleToHexChar (
    500   IN UINT8      Nibble
    501   )
    502 /*++
    503 
    504   Routine Description:
    505     Converts the low nibble of a byte  to hex unicode character.
    506 
    507   Arguments:
    508     Nibble - lower nibble of a byte.
    509 
    510   Returns:
    511     Hex unicode character.
    512 
    513 --*/
    514 {
    515   Nibble &= 0x0F;
    516   if (Nibble <= 0x9) {
    517     return (CHAR16)(Nibble + L'0');
    518   }
    519 
    520   return (CHAR16)(Nibble - 0xA + L'A');
    521 }
    522 
    523 EFI_STATUS
    524 HexStringToBuf (
    525   IN OUT UINT8                     *Buf,
    526   IN OUT UINTN                    *Len,
    527   IN     CHAR16                    *Str,
    528   OUT    UINTN                     *ConvertedStrLen  OPTIONAL
    529   )
    530 /*++
    531 
    532   Routine Description:
    533     Converts Unicode string to binary buffer.
    534     The conversion may be partial.
    535     The first character in the string that is not hex digit stops the conversion.
    536     At a minimum, any blob of data could be represented as a hex string.
    537 
    538   Arguments:
    539     Buf    - Pointer to buffer that receives the data.
    540     Len    - Length in bytes of the buffer to hold converted data.
    541                 If routine return with EFI_SUCCESS, containing length of converted data.
    542                 If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
    543     Str    - String to be converted from.
    544     ConvertedStrLen - Length of the Hex String consumed.
    545 
    546   Returns:
    547     EFI_SUCCESS: Routine Success.
    548     EFI_BUFFER_TOO_SMALL: The buffer is too small to hold converted data.
    549     EFI_
    550 
    551 --*/
    552 {
    553   UINTN       HexCnt;
    554   UINTN       Idx;
    555   UINTN       BufferLength;
    556   UINT8       Digit;
    557   UINT8       Byte;
    558 
    559   //
    560   // Find out how many hex characters the string has.
    561   //
    562   for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
    563 
    564   if (HexCnt == 0) {
    565     *Len = 0;
    566     return EFI_SUCCESS;
    567   }
    568   //
    569   // Two Unicode characters make up 1 buffer byte. Round up.
    570   //
    571   BufferLength = (HexCnt + 1) / 2;
    572 
    573   //
    574   // Test if  buffer is passed enough.
    575   //
    576   if (BufferLength > (*Len)) {
    577     *Len = BufferLength;
    578     return EFI_BUFFER_TOO_SMALL;
    579   }
    580 
    581   *Len = BufferLength;
    582 
    583   for (Idx = 0; Idx < HexCnt; Idx++) {
    584 
    585     IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
    586 
    587     //
    588     // For odd charaters, write the lower nibble for each buffer byte,
    589     // and for even characters, the upper nibble.
    590     //
    591     if ((Idx & 1) == 0) {
    592       Byte = Digit;
    593     } else {
    594       Byte = Buf[Idx / 2];
    595       Byte &= 0x0F;
    596       Byte = (UINT8)(Byte | (Digit << 4));
    597     }
    598 
    599     Buf[Idx / 2] = Byte;
    600   }
    601 
    602   if (ConvertedStrLen != NULL) {
    603     *ConvertedStrLen = HexCnt;
    604   }
    605 
    606   return EFI_SUCCESS;
    607 }
    608 
    609 EFI_STATUS
    610 BufToHexString (
    611   IN OUT CHAR16                    *Str,
    612   IN OUT UINTN                     *HexStringBufferLength,
    613   IN     UINT8                     *Buf,
    614   IN     UINTN                      Len
    615   )
    616 /*++
    617 
    618   Routine Description:
    619     Converts binary buffer to Unicode string.
    620     At a minimum, any blob of data could be represented as a hex string.
    621 
    622   Arguments:
    623     Str - Pointer to the string.
    624     HexStringBufferLength - Length in bytes of buffer to hold the hex string. Includes tailing '\0' character.
    625                                         If routine return with EFI_SUCCESS, containing length of hex string buffer.
    626                                         If routine return with EFI_BUFFER_TOO_SMALL, containg length of hex string buffer desired.
    627     Buf - Buffer to be converted from.
    628     Len - Length in bytes of the buffer to be converted.
    629 
    630   Returns:
    631     EFI_SUCCESS: Routine success.
    632     EFI_BUFFER_TOO_SMALL: The hex string buffer is too small.
    633 
    634 --*/
    635 {
    636   UINTN       Idx;
    637   UINT8       Byte;
    638   UINTN       StrLen;
    639 
    640   //
    641   // Make sure string is either passed or allocate enough.
    642   // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
    643   // Plus the Unicode termination character.
    644   //
    645   StrLen = Len * 2;
    646   if (StrLen > ((*HexStringBufferLength) - 1)) {
    647     *HexStringBufferLength = StrLen + 1;
    648     return EFI_BUFFER_TOO_SMALL;
    649   }
    650 
    651   *HexStringBufferLength = StrLen + 1;
    652   //
    653   // Ends the string.
    654   //
    655   Str[StrLen] = L'\0';
    656 
    657   for (Idx = 0; Idx < Len; Idx++) {
    658 
    659     Byte = Buf[Idx];
    660     Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);
    661     Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));
    662   }
    663 
    664   return EFI_SUCCESS;
    665 }
    666 
    667 VOID
    668 EfiStrTrim (
    669   IN OUT CHAR16   *str,
    670   IN     CHAR16   CharC
    671   )
    672 /*++
    673 
    674 Routine Description:
    675 
    676   Removes (trims) specified leading and trailing characters from a string.
    677 
    678 Arguments:
    679 
    680   str     - Pointer to the null-terminated string to be trimmed. On return,
    681             str will hold the trimmed string.
    682   CharC       - Character will be trimmed from str.
    683 
    684 Returns:
    685 
    686 --*/
    687 {
    688   CHAR16  *p1;
    689   CHAR16  *p2;
    690 
    691   if (*str == 0) {
    692     return;
    693   }
    694 
    695   //
    696   // Trim off the leading and trailing characters c
    697   //
    698   for (p1 = str; *p1 && *p1 == CharC; p1++) {
    699     ;
    700   }
    701 
    702   p2 = str;
    703   if (p2 == p1) {
    704     while (*p1) {
    705       p2++;
    706       p1++;
    707     }
    708   } else {
    709     while (*p1) {
    710     *p2 = *p1;
    711     p1++;
    712     p2++;
    713     }
    714     *p2 = 0;
    715   }
    716 
    717 
    718   for (p1 = str + EfiStrLen(str) - 1; p1 >= str && *p1 == CharC; p1--) {
    719     ;
    720   }
    721   if  (p1 !=  str + EfiStrLen(str) - 1) {
    722     *(p1 + 1) = 0;
    723   }
    724 }
    725 CHAR16*
    726 EfiStrStr (
    727    IN  CHAR16  *String,
    728    IN  CHAR16  *StrCharSet
    729    )
    730 /*++
    731 
    732 Routine Description:
    733 
    734   Find a substring.
    735 
    736 Arguments:
    737 
    738   String      - Null-terminated string to search.
    739   StrCharSet  - Null-terminated string to search for.
    740 
    741 Returns:
    742   The address of the first occurrence of the matching substring if successful, or NULL otherwise.
    743 --*/
    744 {
    745   CHAR16 *Src;
    746   CHAR16 *Sub;
    747 
    748   Src = String;
    749   Sub = StrCharSet;
    750 
    751   while ((*String != L'\0') && (*StrCharSet != L'\0')) {
    752     if (*String++ != *StrCharSet) {
    753       String = ++Src;
    754       StrCharSet = Sub;
    755     } else {
    756       StrCharSet++;
    757     }
    758   }
    759   if (*StrCharSet == L'\0') {
    760     return Src;
    761   } else {
    762     return NULL;
    763   }
    764 }
    765 
    766 CHAR8*
    767 EfiAsciiStrStr (
    768   IN  CHAR8  *String,
    769   IN  CHAR8  *StrCharSet
    770   )
    771 /*++
    772 
    773 Routine Description:
    774 
    775   Find a Ascii substring.
    776 
    777 Arguments:
    778 
    779   String      - Null-terminated Ascii string to search.
    780   StrCharSet  - Null-terminated Ascii string to search for.
    781 
    782 Returns:
    783   The address of the first occurrence of the matching Ascii substring if successful, or NULL otherwise.
    784 --*/
    785 {
    786   CHAR8 *Src;
    787   CHAR8 *Sub;
    788 
    789   Src = String;
    790   Sub = StrCharSet;
    791 
    792   while ((*String != '\0') && (*StrCharSet != '\0')) {
    793     if (*String++ != *StrCharSet) {
    794       String = ++Src;
    795       StrCharSet = Sub;
    796     } else {
    797       StrCharSet++;
    798     }
    799   }
    800   if (*StrCharSet == '\0') {
    801     return Src;
    802   } else {
    803     return NULL;
    804   }
    805 }
    806 
    807