Home | History | Annotate | Download | only in uefi
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Permission is hereby granted, free of charge, to any person
      5  * obtaining a copy of this software and associated documentation
      6  * files (the "Software"), to deal in the Software without
      7  * restriction, including without limitation the rights to use, copy,
      8  * modify, merge, publish, distribute, sublicense, and/or sell copies
      9  * of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be
     13  * included in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
     19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
     20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  */
     24 
     25 #include "uefi_avb_util.h"
     26 
     27 bool uefi_avb_utf8_to_ucs2(const uint8_t* utf8_data,
     28                            size_t utf8_num_bytes,
     29                            uint16_t* ucs2_data,
     30                            size_t ucs2_data_capacity_num_bytes,
     31                            size_t* out_ucs2_data_num_bytes) {
     32   uint32_t i8 = 0;
     33   uint32_t i2 = 0;
     34 
     35   do {
     36     if (i2 >= ucs2_data_capacity_num_bytes) {
     37       break;
     38     }
     39 
     40     // cannot represent this character, too long
     41     if ((utf8_data[i8] & 0xF8) == 0xF0) {
     42       return false;
     43     } else if ((utf8_data[i8] & 0xF0) == 0xE0) {
     44       ucs2_data[i2] = (uint16_t)((uint16_t)utf8_data[i8] << 12) |
     45                       (uint16_t)(((uint16_t)utf8_data[i8 + 1] << 6) & 0x0FC0) |
     46                       (uint16_t)((uint16_t)utf8_data[i8 + 2] & 0x003F);
     47       i8 += 3;
     48     } else if ((utf8_data[i8] & 0xE0) == 0XC0) {
     49       ucs2_data[i2] = (uint16_t)(((uint16_t)utf8_data[i8] << 6) & 0x07C0) |
     50                       (uint16_t)((uint16_t)utf8_data[i8 + 1] & 0x003F);
     51       i8 += 2;
     52     } else if (!(utf8_data[i8] >> 7)) {
     53       ucs2_data[i2] = (uint16_t)((uint16_t)utf8_data[i8] & 0x00FF);
     54       i8++;
     55     } else {
     56       // invalid utf-8
     57       return false;
     58     }
     59     i2++;
     60   } while (i8 < utf8_num_bytes);
     61 
     62   if (out_ucs2_data_num_bytes != NULL) {
     63     *out_ucs2_data_num_bytes = i2 * 2;
     64   }
     65   return true;
     66 }
     67