⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nls.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
 * @name IntMultiByteToWideCharCP
 *
 * Internal version of MultiByteToWideChar for code page tables.
 *
 * @see MultiByteToWideChar
 * @todo Handle MB_PRECOMPOSED, MB_COMPOSITE, MB_USEGLYPHCHARS and
 *       DBCS codepages.
 */

static INT STDCALL
IntMultiByteToWideCharCP(UINT CodePage, DWORD Flags,
                         LPCSTR MultiByteString, INT MultiByteCount,
                         LPWSTR WideCharString, INT WideCharCount)
{
   PCODEPAGE_ENTRY CodePageEntry;
   PCPTABLEINFO CodePageTable;
   LPCSTR TempString;
   INT TempLength;

   /* Get code page table. */
   CodePageEntry = IntGetCodePageEntry(CodePage);
   if (CodePageEntry == NULL)
   {
      SetLastError(ERROR_INVALID_PARAMETER);
      return 0;
   }
   CodePageTable = &CodePageEntry->CodePageTable;

   /* Different handling for DBCS code pages. */
   if (CodePageTable->MaximumCharacterSize > 1)
   {
      /* FIXME */

      UCHAR Char;
      USHORT DBCSOffset;
      LPCSTR MbsEnd = MultiByteString + MultiByteCount;
      ULONG Count;

      /* Does caller query for output buffer size? */
      if (WideCharCount == 0)
      {
         for (; MultiByteString < MbsEnd; WideCharCount++)
         {
            Char = *MultiByteString++;

            if (Char < 0x80)
               continue;

            DBCSOffset = CodePageTable->DBCSOffsets[Char];

            if (!DBCSOffset)
               continue;

            if (MultiByteString < MbsEnd)
               MultiByteString++;
         }

         return WideCharCount;
      }

      for (Count = 0; Count < WideCharCount && MultiByteString < MbsEnd; Count++)
      {
         Char = *MultiByteString++;

         if (Char < 0x80)
         {
            *WideCharString++ = Char;
            continue;
         }

         DBCSOffset = CodePageTable->DBCSOffsets[Char];

         if (!DBCSOffset)
         {
            *WideCharString++ = CodePageTable->MultiByteTable[Char];
            continue;
         }

         if (MultiByteString < MbsEnd)
            *WideCharString++ =
               CodePageTable->DBCSOffsets[DBCSOffset + *(PUCHAR)MultiByteString++];
      }

      if (MultiByteString < MbsEnd)
         SetLastError(ERROR_INSUFFICIENT_BUFFER);

      return Count;
   }
   else /* Not DBCS code page */
   {
      /* Check for invalid characters. */
      if (Flags & MB_ERR_INVALID_CHARS)
      {
         for (TempString = MultiByteString, TempLength = MultiByteCount;
              TempLength > 0;
              TempString++, TempLength--)
         {
            if (CodePageTable->MultiByteTable[(UCHAR)*TempString] ==
                CodePageTable->UniDefaultChar &&
                *TempString != CodePageEntry->CodePageTable.DefaultChar)
            {
               SetLastError(ERROR_NO_UNICODE_TRANSLATION);
               return 0;
            }
         }
      }

      /* Does caller query for output buffer size? */
      if (WideCharCount == 0)
         return MultiByteCount;

      /* Adjust buffer size. Wine trick ;-) */
      if (WideCharCount < MultiByteCount)
      {
         MultiByteCount = WideCharCount;
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
      }

      for (TempLength = MultiByteCount;
           TempLength > 0;
           MultiByteString++, TempLength--)
      {
         *WideCharString++ = CodePageTable->MultiByteTable[(UCHAR)*MultiByteString];
      }

      return MultiByteCount;
   }
}

/**
 * @name IntWideCharToMultiByteUTF8
 *
 * Internal version of WideCharToMultiByte for UTF8.
 *
 * @see WideCharToMultiByte
 */

static INT STDCALL
IntWideCharToMultiByteUTF8(UINT CodePage, DWORD Flags,
                           LPCWSTR WideCharString, INT WideCharCount,
                           LPSTR MultiByteString, INT MultiByteCount,
                           LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
{
   INT TempLength;
   WCHAR Char;

   /* Does caller query for output buffer size? */
   if (MultiByteCount == 0)
   {
      for (TempLength = 0; WideCharCount;
           WideCharCount--, WideCharString++)
      {
         TempLength++;
         if (*WideCharString >= 0x80)
         {
            TempLength++;
            if (*WideCharString >= 0x800)
               TempLength++;
         }
      }
      return TempLength;
   }

   for (TempLength = MultiByteCount; WideCharCount;
        WideCharCount--, WideCharString++)
   {
      Char = *WideCharString;
      if (Char < 0x80)
      {
         if (!TempLength)
         {
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
            break;
         }
         TempLength--;
         *MultiByteString++ = (CHAR)Char;
         continue;
      }

      if (Char < 0x800)  /* 0x80-0x7ff: 2 bytes */
      {
         if (TempLength < 2)
         {
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
            break;
         }
         MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
         MultiByteString[0] = 0xc0 | Char;
         MultiByteString += 2;
         TempLength -= 2;
         continue;
      }

      /* 0x800-0xffff: 3 bytes */
      if (TempLength < 3)
      {
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
         break;
      }
      MultiByteString[2] = 0x80 | (Char & 0x3f); Char >>= 6;
      MultiByteString[1] = 0x80 | (Char & 0x3f); Char >>= 6;
      MultiByteString[0] = 0xe0 | Char;
      MultiByteString += 3;
      TempLength -= 3;
   }

   return MultiByteCount - TempLength;
}

/**
 * @name IntWideCharToMultiByteCP
 *
 * Internal version of WideCharToMultiByte for code page tables.
 *
 * @see WideCharToMultiByte
 * @todo Handle default characters and flags.
 */

static INT STDCALL
IntWideCharToMultiByteCP(UINT CodePage, DWORD Flags,
                         LPCWSTR WideCharString, INT WideCharCount,
                         LPSTR MultiByteString, INT MultiByteCount,
                         LPCSTR DefaultChar, LPBOOL UsedDefaultChar)
{
   PCODEPAGE_ENTRY CodePageEntry;
   PCPTABLEINFO CodePageTable;
   INT TempLength;

   /* Get code page table. */
   CodePageEntry = IntGetCodePageEntry(CodePage);
   if (CodePageEntry == NULL)
   {
      SetLastError(ERROR_INVALID_PARAMETER);
      return 0;
   }
   CodePageTable = &CodePageEntry->CodePageTable;

   /* Different handling for DBCS code pages. */
   if (CodePageTable->MaximumCharacterSize > 1)
   {
      /* FIXME */

      USHORT WideChar;
      USHORT MbChar;

      /* Does caller query for output buffer size? */
      if (MultiByteCount == 0)
      {
         for (TempLength = 0; WideCharCount; WideCharCount--, TempLength++)
         {
            WideChar = *WideCharString++;

            if (WideChar < 0x80)
               continue;

            MbChar = ((PWCHAR)CodePageTable->WideCharTable)[WideChar];

            if (!(MbChar & 0xff00))
               continue;

            TempLength++;
         }

         return TempLength;
      }

      for (TempLength = MultiByteCount; WideCharCount; WideCharCount--)
      {
         WideChar = *WideCharString++;

         if (WideChar < 0x80)
         {
            if (!TempLength)
            {
               SetLastError(ERROR_INSUFFICIENT_BUFFER);
               break;
            }
            TempLength--;

            *MultiByteString++ = (CHAR)WideChar;
            continue;
         }

         MbChar = ((PWCHAR)CodePageTable->WideCharTable)[WideChar];

         if (!(MbChar & 0xff00))
         {
            if (!TempLength)
            {
               SetLastError(ERROR_INSUFFICIENT_BUFFER);
               break;
            }
            TempLength--;

            *MultiByteString++ = (CHAR)MbChar;
            continue;;
         }

         if (TempLength >= 2)
         {
            MultiByteString[1] = (CHAR)MbChar; MbChar >>= 8;
            MultiByteString[0] = (CHAR)MbChar;
            MultiByteString += 2;
            TempLength -= 2;
         }
         else
         {
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
            break;
         }
      }

      return MultiByteCount - TempLength;
   }
   else /* Not DBCS code page */
   {
      /* Does caller query for output buffer size? */
      if (MultiByteCount == 0)
         return WideCharCount;

      /* Adjust buffer size. Wine trick ;-) */
      if (MultiByteCount < WideCharCount)
      {
         WideCharCount = MultiByteCount;
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
      }

      for (TempLength = WideCharCount;
           TempLength > 0;
           WideCharString++, TempLength--)
      {
         *MultiByteString++ = ((PCHAR)CodePageTable->WideCharTable)[*WideCharString];
      }

      /* FIXME */
      if (UsedDefaultChar != NULL)
         *UsedDefaultChar = FALSE;

      return WideCharCount;
   }
}

/** 
 * @name IntIsLeadByte
 *
 * Internal function to detect if byte is lead byte in specific character
 * table.
 */

static BOOL STDCALL
IntIsLeadByte(PCPTABLEINFO TableInfo, BYTE Byte)
{
   UINT LeadByteNo;

   if (TableInfo->MaximumCharacterSize == 2)
   {
      for (LeadByteNo = 0; LeadByteNo < MAXIMUM_LEADBYTES; LeadByteNo++)
      {
         if (TableInfo->LeadByte[LeadByteNo] == Byte)
            return TRUE;
      }
   }

   return FALSE;
}

/* PUBLIC FUNCTIONS ***********************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -