Indentation has been corrected in all of the files. LibC/Locale/multibyte_Utf8.c LibC/Uefi/SysCalls.c Clarify and improve comments. Include/sys/termios.h Add parameter names to function prototypes as referenced in the comments. StdLibPrivateInternalFiles\Include\kfile.h Add comment for the fo_close fileop. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Daryl McDaniel <edk2-lists@mc2research.org> Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19588 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1011 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1011 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Copyright (c) 2016, Daryl McDaniel. All rights reserved.<BR>
 | 
						|
  Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
**/
 | 
						|
#include  <assert.h>
 | 
						|
#include  <string.h>
 | 
						|
#include  <errno.h>
 | 
						|
#include  <stdlib.h>
 | 
						|
#include  <wchar.h>
 | 
						|
#include  <sys/types.h>
 | 
						|
#include  <limits.h>
 | 
						|
 | 
						|
typedef int      ch_UCS4;
 | 
						|
 | 
						|
static  mbstate_t     LocalConvState = {0};
 | 
						|
 | 
						|
/** Map a UTF-8 encoded prefix byte to a sequence length.
 | 
						|
    Zero means illegal prefix, but valid surrogate if < 0xC0.
 | 
						|
    One indicates an ASCII-7 equivalent character.
 | 
						|
    Two, three, and four are the first byte for 2, 3, and 4 byte sequences, respectively.
 | 
						|
    See RFC 3629 for details.
 | 
						|
 | 
						|
  TABLE ENCODING:
 | 
						|
    Low Nibble decodes the first byte into the number of bytes in the sequence.
 | 
						|
      A value of zero indicates an invalid byte.
 | 
						|
    The High Nibble encodes a bit mask to be used to match against the high nibble of the second byte.
 | 
						|
 | 
						|
    example:
 | 
						|
      SequenceLength = code[c0] & 0x0F;
 | 
						|
      Mask           = 0x80 | code[c0];
 | 
						|
 | 
						|
      Surrogate bytes are valid if: code[cX] & Mask > 0x80;
 | 
						|
 | 
						|
*/
 | 
						|
static
 | 
						|
UINT8 utf8_code_length[256] = {
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* 00-0F */
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 | 
						|
  0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* 70-7F */
 | 
						|
  0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, /* 80-8F */
 | 
						|
  0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, /* 90-9F */
 | 
						|
  0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* A0-AF */
 | 
						|
  0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* B0-BF */
 | 
						|
  0x00, 0x00, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, /* C0-C1 + C2-CF */
 | 
						|
  0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, /* D0-DF */
 | 
						|
  0x43, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x33, 0x73, 0x73, /* E0-EF */
 | 
						|
  0x64, 0x74, 0x74, 0x74, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  /* F0-F4 + F5-FF */
 | 
						|
};
 | 
						|
 | 
						|
/** Process one byte of a multibyte character.
 | 
						|
 | 
						|
    @param[in]      ch    One byte of a multibyte character.
 | 
						|
    @param[in,out]  ps    Pointer to a conversion state object.
 | 
						|
 | 
						|
    @retval   -2      ch is an incomplete but potentially valid character.
 | 
						|
    @retval   -1      ch is not valid in this context.
 | 
						|
    @retval   1:4     The length, in bytes, of the character ch just completed.
 | 
						|
**/
 | 
						|
static
 | 
						|
int
 | 
						|
ProcessOneByte(unsigned char ch, mbstate_t *ps)
 | 
						|
{
 | 
						|
  UINT32    Mask;
 | 
						|
  UINT32    Length;
 | 
						|
  int       RetVal = 0;
 | 
						|
 | 
						|
  if(ps->A > 3) {
 | 
						|
    // We are in an invalid state
 | 
						|
    ps->A = 0;    // Initial State
 | 
						|
  }
 | 
						|
  ps->C[ps->A] = ch;  // Save the current byte
 | 
						|
  Mask = utf8_code_length[ch];
 | 
						|
 | 
						|
  if(ps->A == 0) {    // Initial State.  First byte of sequence.
 | 
						|
    ps->E   = Mask | 0x80;
 | 
						|
    Length  = Mask & 0xF;
 | 
						|
    switch(Length) {
 | 
						|
      case 0:                       // State 0, Code 0
 | 
						|
        errno = EILSEQ;
 | 
						|
        RetVal = -1;
 | 
						|
        ps->E = 1;        // Consume this byte
 | 
						|
        break;
 | 
						|
      case 1:                       // State 0, Code 1
 | 
						|
        // ASCII-7 Character
 | 
						|
        ps->B = ps->D[0] = ch;
 | 
						|
        RetVal = 1;
 | 
						|
        break;
 | 
						|
      default:                      // State 0, Code 2, 3, 4
 | 
						|
        ps->A = 1;    // Next state is State-1
 | 
						|
        RetVal = -2;  // Incomplete but potentially valid character
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    // We are in state 1, 2, or 3 and processing a surrogate byte
 | 
						|
    Length  = ps->E & 0xF;
 | 
						|
    if((Mask & ps->E) > 0x80) {
 | 
						|
      // This byte is valid
 | 
						|
      switch(ps->A) {   // Process based upon our current state
 | 
						|
        case 1:             // Second byte of the sequence.
 | 
						|
          if(Length == 2) {         // State 1, Code 2
 | 
						|
            Length = ((ps->C[0] & 0x1f) << 6) + (ps->C[1] & 0x3f);
 | 
						|
            assert ((Length > 0x007F) && (Length <= 0x07FF));
 | 
						|
            ps->B = ps->D[0] = (UINT16)Length;
 | 
						|
            ps->A = 0;      // Next state is State-0
 | 
						|
            RetVal = 2;
 | 
						|
          }
 | 
						|
          else {    // This isn't the last byte, get more.  State 1, Code 3 or 4
 | 
						|
            ps->A = 2;
 | 
						|
            RetVal = -2;
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        case 2:             // Third byte of the sequence
 | 
						|
          if(Length == 3) {
 | 
						|
            Length = ((ps->C[0] & 0x0f) << 12) + ((ps->C[1] & 0x3f) << 6) + (ps->C[2] & 0x3f);
 | 
						|
            assert ((Length > 0x07FF) && (Length <= 0xFFFF));
 | 
						|
            ps->B = ps->D[0] = (UINT16)Length;
 | 
						|
            ps->A = 0;      // Next state is State-0
 | 
						|
            RetVal = 3;
 | 
						|
          }
 | 
						|
          else {
 | 
						|
            ps->A = 3;
 | 
						|
            RetVal = -2;
 | 
						|
          }
 | 
						|
          break;
 | 
						|
        case 3:             // Fourth byte of the sequence
 | 
						|
          if(Length == 4) {
 | 
						|
            Length = ((ps->C[0] & 0x7) << 18) + ((ps->C[1] & 0x3f) << 12) +
 | 
						|
                     ((ps->C[2] & 0x3f) << 6) + (ps->C[3] & 0x3f);
 | 
						|
            ps->B = Length;
 | 
						|
            assert ((Length > 0xFFFF) && (Length <= 0x10ffff));
 | 
						|
 | 
						|
            /*  compute and append the two surrogates: */
 | 
						|
 | 
						|
            /*  translate from 10000..10FFFF to 0..FFFF */
 | 
						|
            Length -= 0x10000;
 | 
						|
 | 
						|
            /*  high surrogate = top 10 bits added to D800 */
 | 
						|
            ps->D[0] = (UINT16)(0xD800 + (Length >> 10));
 | 
						|
 | 
						|
            /*  low surrogate = bottom 10 bits added to DC00 */
 | 
						|
            ps->D[1] = (UINT16)(0xDC00 + (Length & 0x03FF));
 | 
						|
            ps->A = 0;      // Next state is State-0
 | 
						|
            RetVal = 4;
 | 
						|
          }
 | 
						|
          else {
 | 
						|
            errno = EILSEQ;
 | 
						|
            ps->A = 0;
 | 
						|
            RetVal = -1;
 | 
						|
            ps->E = 4;      // Can't happen, but consume this byte anyway
 | 
						|
          }
 | 
						|
          break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else {                // Invalid surrogate byte
 | 
						|
      errno = EILSEQ;
 | 
						|
      ps->A = 0;          // Next is State-0
 | 
						|
      RetVal = -1;
 | 
						|
      ps->E = 0;            // Don't Consume, it may be an initial byte
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Convert one Multibyte sequence.
 | 
						|
 | 
						|
    @param[out]   Dest      Pointer to output location, or NULL
 | 
						|
    @param[in]    Src       Multibyte Source (UTF8)
 | 
						|
    @param[in]    Len       Max Number of bytes to convert
 | 
						|
    @param[in]    pS        Pointer to State struct., or NULL
 | 
						|
 | 
						|
    @retval   -2      Bytes processed comprise an incomplete, but potentially valid, character.
 | 
						|
    @retval   -1      An encoding error was encountered.  ps->E indicates the number of bytes consumed.
 | 
						|
    @retval   0       Either Src is NULL or it points to a NUL character.
 | 
						|
    @retval   1:N     N bytes were consumed producing a valid wide character.
 | 
						|
**/
 | 
						|
int
 | 
						|
DecodeOneStateful(
 | 
						|
  wchar_t    *Dest,       // Pointer to output location, or NULL
 | 
						|
  const char *Src,        // Multibyte Source (UTF8)
 | 
						|
  ssize_t     Len,        // Max Number of bytes to convert
 | 
						|
  mbstate_t  *pS          // Pointer to State struct., or NULL
 | 
						|
  )
 | 
						|
{
 | 
						|
  const char   *SrcEnd;
 | 
						|
  int           NumConv;
 | 
						|
  unsigned char ch;
 | 
						|
 | 
						|
  if(pS == NULL) {
 | 
						|
    pS = &LocalConvState;
 | 
						|
  }
 | 
						|
  NumConv = 0;
 | 
						|
  if(Src != NULL) {
 | 
						|
    if(*Src != 0) {
 | 
						|
      SrcEnd  = Src + Len;
 | 
						|
      while(Src < SrcEnd) {
 | 
						|
        ch = (unsigned char)*Src++;
 | 
						|
        NumConv = ProcessOneByte(ch, pS);
 | 
						|
        if(NumConv != -2) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else if(Dest != NULL) {
 | 
						|
      *Dest = 0;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if((NumConv > 0) && (Dest != NULL)) {
 | 
						|
    Dest[0] = pS->D[0];
 | 
						|
    if(NumConv == 4) {
 | 
						|
      Dest[1] = pS->D[1];
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return NumConv;
 | 
						|
}
 | 
						|
 | 
						|
/*  Determine the number of bytes needed to represent a Wide character
 | 
						|
    as a MBCS character.
 | 
						|
 | 
						|
    A single wide character may convert into a one, two, three, or four byte
 | 
						|
    narrow (MBCS or UTF-8) character.  The number of MBCS bytes can be determined
 | 
						|
    as follows.
 | 
						|
 | 
						|
    If WCS char      < 0x00000080      One Byte
 | 
						|
    Else if WCS char < 0x0000D800      Two Bytes
 | 
						|
    Else                               Three Bytes
 | 
						|
 | 
						|
    Since UEFI only supports the Unicode Base Multilingual Plane (BMP),
 | 
						|
    Four-byte characters are not supported.
 | 
						|
 | 
						|
    @param[in]    InCh      Wide character to test.
 | 
						|
 | 
						|
    @retval     -1      Improperly formed character
 | 
						|
    @retval      0      InCh is 0x0000
 | 
						|
    @retval     >0      Number of bytes needed for the MBCS character
 | 
						|
*/
 | 
						|
int
 | 
						|
EFIAPI
 | 
						|
OneWcToMcLen(const wchar_t InCh)
 | 
						|
{
 | 
						|
  ssize_t   NumBytes;
 | 
						|
 | 
						|
  if(InCh == 0) {             //    Is this a NUL, 0x0000 ?
 | 
						|
    NumBytes = 0;
 | 
						|
  }
 | 
						|
  else if(InCh < 0x0080) {    //    Is this a 1-byte character?
 | 
						|
    NumBytes = 1;
 | 
						|
  }
 | 
						|
  else if(InCh < 0x0800) {    //    Is this a 2-byte character?
 | 
						|
    NumBytes = 2;
 | 
						|
  }
 | 
						|
  else if((InCh >= 0xD800) && (InCh < 0xE000)) {    //    Is this a surrogate?
 | 
						|
    NumBytes = -1;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    NumBytes = 3;             //    Otherwise, it must be a 3-byte character.
 | 
						|
  }
 | 
						|
  return (int)NumBytes;      // Return extimate of required bytes.
 | 
						|
}
 | 
						|
 | 
						|
/*  Determine the number of bytes needed to represent a Wide character string
 | 
						|
    as a MBCS string of given maximum length.  Will optionally return the number
 | 
						|
    of wide characters that would be consumed.
 | 
						|
 | 
						|
    A single wide character may convert into a one, two, three, or four byte
 | 
						|
    narrow (MBCS or UTF-8) character.  The number of MBCS bytes can be determined
 | 
						|
    as follows.
 | 
						|
 | 
						|
    If WCS char      < 0x00000080      One Byte
 | 
						|
    Else if WCS char < 0x00000800      Two Bytes
 | 
						|
    Else if WCS char < 0x00010000      Three Bytes
 | 
						|
    Else                               Four Bytes
 | 
						|
 | 
						|
    Since UEFI only supports the Unicode Base Multilingual Plane (BMP),
 | 
						|
    Four-byte characters should not be encountered.
 | 
						|
 | 
						|
    @param[in]    Src       Pointer to a wide character string.
 | 
						|
    @param[in]    Limit     Maximum number of bytes the converted string may occupy.
 | 
						|
    @param[out]   NumChar   Pointer to where to store the number of wide characters
 | 
						|
                            consumed, or NULL.
 | 
						|
 | 
						|
    @return     The number of bytes required to convert Src to MBCS,
 | 
						|
                not including the terminating NUL.  If NumChar is not NULL, the number
 | 
						|
                of characters represented by the return value will be written to
 | 
						|
                where it points.
 | 
						|
*/
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
EstimateWtoM(const wchar_t * Src, size_t Limit, size_t *NumChar)
 | 
						|
{
 | 
						|
  ssize_t    Estimate;
 | 
						|
  size_t    CharCount;
 | 
						|
  ssize_t   NumBytes;
 | 
						|
  wchar_t   EChar;
 | 
						|
 | 
						|
  Estimate  = 0;
 | 
						|
  CharCount = 0;
 | 
						|
  EChar = *Src++;               // Get the initial character and point to next
 | 
						|
  while(((NumBytes = OneWcToMcLen(EChar)) > 0)  &&
 | 
						|
        ((size_t)(Estimate + NumBytes) < Limit))
 | 
						|
  {                             // Until one of the source characters is NUL
 | 
						|
    ++CharCount;                //    Count this character.
 | 
						|
    Estimate += NumBytes;       //    Count the Bytes for this character
 | 
						|
    EChar = *Src++;             //    Get the next source character and point to the next.
 | 
						|
  }
 | 
						|
  if(NumChar != NULL) {
 | 
						|
    *NumChar = CharCount;
 | 
						|
  }
 | 
						|
  return (size_t)Estimate;      // Return esimate of required bytes.
 | 
						|
}
 | 
						|
 | 
						|
/*  Determine the number of characters in a MBCS string.
 | 
						|
    MBCS characters are one to four bytes long.  By examining the first byte
 | 
						|
    of a MBCS character, one can determine the number of bytes comprising the
 | 
						|
    character.
 | 
						|
 | 
						|
    0x00 - 0x7F     One
 | 
						|
    0xC0 - 0xDF     Two
 | 
						|
    0xE0 - 0xEF     Three
 | 
						|
    0xF0 - 0xF7     Four
 | 
						|
 | 
						|
    Since UEFI only supports the Unicode Base Multilingual Plane (BMP),
 | 
						|
    Four-byte characters should not be encountered.
 | 
						|
 | 
						|
    @param[in]    Src     The string to examine
 | 
						|
 | 
						|
    @return   The number of characters represented by the MBCS string.
 | 
						|
**/
 | 
						|
size_t
 | 
						|
EFIAPI
 | 
						|
CountMbcsChars(const char *Src)
 | 
						|
{
 | 
						|
  size_t      Count;
 | 
						|
  char        EChar;
 | 
						|
 | 
						|
  Count = 0;
 | 
						|
  EChar = *Src++;
 | 
						|
  while(EChar != 0) {
 | 
						|
    if(EChar < 0x80) {
 | 
						|
      ++Count;
 | 
						|
    }
 | 
						|
    else if(EChar < 0xE0) {
 | 
						|
      Count += 2;
 | 
						|
      ++Src;
 | 
						|
    }
 | 
						|
    else if(EChar < 0xF0) {
 | 
						|
      Count += 3;
 | 
						|
      Src += 2;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      // Ill-formed character
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return Count;
 | 
						|
}
 | 
						|
 | 
						|
/** Convert a wide character (UTF16) into a multibyte character (UTF8)
 | 
						|
 | 
						|
    Converts a wide character into a corresponding multibyte character that
 | 
						|
    begins in the conversion state described by the object pointed to by ps.
 | 
						|
    If dst is not a null pointer, the converted character is then stored into
 | 
						|
    the array pointed to by dst.
 | 
						|
 | 
						|
    It is the caller's responsibility to ensure that Dest is large enough to
 | 
						|
    hold the resulting MBCS sequence.
 | 
						|
 | 
						|
    @param  s       Pointer to the wide-character string to convert
 | 
						|
    @param  Dest    Pointer to the buffer in which to place the converted sequence, or NULL.
 | 
						|
 | 
						|
    @retval   -1    An error occurred.  The error reason is in errno.
 | 
						|
    @retval   >=0   The number of bytes stored into Dest.
 | 
						|
**/
 | 
						|
ssize_t
 | 
						|
EncodeUtf8(char *Dest, wchar_t ch)
 | 
						|
{
 | 
						|
  char       *p;              /* next free byte in build buffer */
 | 
						|
  int         NumInBuff;      // number of bytes in Buff
 | 
						|
  char        Buff[4];        // Buffer into which each character is built
 | 
						|
 | 
						|
    p = Buff;
 | 
						|
 | 
						|
  NumInBuff = 0;
 | 
						|
  if (ch < 0x80) {
 | 
						|
    /* Encode ASCII -- One Byte */
 | 
						|
    *p++ = (char) ch;
 | 
						|
    NumInBuff = 1;
 | 
						|
  }
 | 
						|
  else if (ch < 0x0800) {
 | 
						|
    /* Encode Latin-1 -- Two Byte */
 | 
						|
    *p++ = (char)(0xc0 | (ch >> 6));
 | 
						|
    *p++ = (char)(0x80 | (ch & 0x3f));
 | 
						|
    NumInBuff = 2;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
      /* Encode UCS2 Unicode ordinals -- Three Byte */
 | 
						|
    /* Special case: check for surrogate -- Shouldn't happen in UEFI */
 | 
						|
    if (0xD800 <= ch && ch < 0xE000) {
 | 
						|
      errno = EILSEQ;
 | 
						|
      return -1;
 | 
						|
      }
 | 
						|
    else {
 | 
						|
      *p++ = (char)(0xe0 | (ch >> 12));
 | 
						|
      *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
 | 
						|
      *p++ = (char)(0x80 | (ch & 0x3f));
 | 
						|
      NumInBuff = 3;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  /*  At this point, Buff holds the converted character which is NumInBuff bytes long.
 | 
						|
      NumInBuff is the value 1, 2, 3, or 4
 | 
						|
  */
 | 
						|
  if(Dest != NULL) {        // Save character if Dest is not NULL
 | 
						|
    memcpy(Dest, Buff, NumInBuff);
 | 
						|
  }
 | 
						|
  return NumInBuff;             // Tell the caller
 | 
						|
}
 | 
						|
 | 
						|
// ########################  Narrow to Wide Conversions #######################
 | 
						|
 | 
						|
/** If ps is not a null pointer, the mbsinit function determines whether the
 | 
						|
    pointed-to mbstate_t object describes an initial conversion state.
 | 
						|
 | 
						|
    @param[in]  ps    Pointer to the conversion state object to test.
 | 
						|
 | 
						|
    @return     The mbsinit function returns nonzero if ps is a null pointer
 | 
						|
                or if the pointed-to object describes an initial conversion
 | 
						|
                state; otherwise, it returns zero.
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
int
 | 
						|
mbsinit(const mbstate_t *ps)
 | 
						|
{
 | 
						|
  if((ps == NULL) || (ps->A == 0)) {
 | 
						|
    return 1;
 | 
						|
  }
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/** The mbrlen function is equivalent to the call:<BR>
 | 
						|
@verbatim
 | 
						|
    mbrtowc(NULL, s, n, ps != NULL ? ps : &internal)
 | 
						|
@endverbatim
 | 
						|
    where internal is the mbstate_t object for the mbrlen function, except that
 | 
						|
    the expression designated by ps is evaluated only once.
 | 
						|
 | 
						|
    @param[in]  s     Pointer to a multibyte character sequence.
 | 
						|
    @param[in]  n     Maximum number of bytes to examine.
 | 
						|
    @param[in]  pS    Pointer to the conversion state object.
 | 
						|
 | 
						|
    @retval   0       The next n or fewer characters complete a NUL.
 | 
						|
    @retval   1..n    The number of bytes that complete the multibyte character.
 | 
						|
    @retval   -2      The next n bytes contribute to an incomplete (but potentially valid) multibyte character.
 | 
						|
    @retval   -1      An encoding error occurred.
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
size_t
 | 
						|
mbrlen(
 | 
						|
  const char *s,
 | 
						|
  size_t n,
 | 
						|
  mbstate_t *pS
 | 
						|
  )
 | 
						|
{
 | 
						|
  return mbrtowc(NULL, s, n, pS);
 | 
						|
}
 | 
						|
 | 
						|
/** Determine the number of bytes comprising a multibyte character.
 | 
						|
 | 
						|
  If S is not a null pointer, the mblen function determines the number of bytes
 | 
						|
  contained in the multibyte character pointed to by S. Except that the
 | 
						|
  conversion state of the mbtowc function is not affected, it is equivalent to
 | 
						|
    mbtowc((wchar_t *)0, S, N);
 | 
						|
 | 
						|
  @param[in]  S   NULL to query whether multibyte characters have
 | 
						|
                  state-dependent encodings.  Otherwise, points to a
 | 
						|
                  multibyte character.
 | 
						|
  @param[in]  N   The maximum number of bytes in a multibyte character.
 | 
						|
 | 
						|
  @return   If S is a null pointer, the mblen function returns a nonzero or
 | 
						|
            zero value, if multibyte character encodings, respectively, do
 | 
						|
            or do not have state-dependent encodings. If S is not a null
 | 
						|
            pointer, the mblen function either returns 0 (if S points to the
 | 
						|
            null character), or returns the number of bytes that are contained
 | 
						|
            in the multibyte character (if the next N or fewer bytes form a
 | 
						|
            valid multibyte character), or returns -1 (if they do not form a
 | 
						|
            valid multibyte character).
 | 
						|
 | 
						|
    Declared in: stdlib.h
 | 
						|
**/
 | 
						|
int
 | 
						|
mblen(
 | 
						|
  const char *s,
 | 
						|
  size_t n
 | 
						|
  )
 | 
						|
{
 | 
						|
  return (int)mbrlen(s, n, NULL);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
If S is a null pointer, the mbrtowc function is equivalent to the call:<BR>
 | 
						|
@verbatim
 | 
						|
        mbrtowc(NULL, "", 1, ps)
 | 
						|
@endverbatim
 | 
						|
 | 
						|
In this case, the values of the parameters pwc and n are ignored.
 | 
						|
 | 
						|
If S is not a null pointer, the mbrtowc function inspects at most n bytes beginning with
 | 
						|
the byte pointed to by S to determine the number of bytes needed to complete the next
 | 
						|
multibyte character (including any shift sequences). If the function determines that the
 | 
						|
next multibyte character is complete and valid, it determines the value of the
 | 
						|
corresponding wide character and then, if pwc is not a null pointer, stores that value in
 | 
						|
the object pointed to by pwc. If the corresponding wide character is the null wide
 | 
						|
character, the resulting state described is the initial conversion state.
 | 
						|
 | 
						|
    @param[out]   pwc   Pointer to where the resulting wide character is to be stored.
 | 
						|
    @param[in]     s    Pointer to a multibyte character "string".
 | 
						|
    @param[in]     n    The maximum number of bytes to inspect.
 | 
						|
    @param[in]     ps   Pointer to a conversion state object.
 | 
						|
 | 
						|
    @retval   0             if the next n or fewer bytes complete the multibyte
 | 
						|
                            character that corresponds to the null wide
 | 
						|
                            character (which is the value stored).
 | 
						|
    @retval   between_1_and_n_inclusive   if the next n or fewer bytes complete
 | 
						|
                            a valid multibyte character (which is the value
 | 
						|
                            stored); the value returned is the number of bytes
 | 
						|
                            that complete the multibyte character.
 | 
						|
    @retval   (size_t)(-2)  if the next n bytes contribute to an incomplete
 | 
						|
                            (but potentially valid) multibyte character, and
 | 
						|
                            all n bytes have been processed (no value is stored).
 | 
						|
    @retval   (size_t)(-1)  if an encoding error occurs, in which case the next
 | 
						|
                            n or fewer bytes do not contribute to a complete and
 | 
						|
                            valid multibyte character (no value is stored); the
 | 
						|
                            value of the macro EILSEQ is stored in errno, and
 | 
						|
                            the conversion state is unspecified.
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
size_t
 | 
						|
mbrtowc(
 | 
						|
  wchar_t *pwc,
 | 
						|
  const char *s,
 | 
						|
  size_t n,
 | 
						|
  mbstate_t *ps
 | 
						|
  )
 | 
						|
{
 | 
						|
  int     RetVal;
 | 
						|
 | 
						|
  RetVal = DecodeOneStateful(pwc, s, (ssize_t)n, ps);
 | 
						|
  return (size_t)RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Convert a multibyte character into a wide character.
 | 
						|
 | 
						|
    If S is not a null pointer, the mbtowc function inspects at most N bytes
 | 
						|
    beginning with the byte pointed to by S to determine the number of bytes
 | 
						|
    needed to complete the next multibyte character (including any shift
 | 
						|
    sequences). If the function determines that the next multibyte character
 | 
						|
    is complete and valid, it determines the value of the corresponding wide
 | 
						|
    character and then, if Pwc is not a null pointer, stores that value in
 | 
						|
    the object pointed to by Pwc. If the corresponding wide character is the
 | 
						|
    null wide character, the function is left in the initial conversion state.
 | 
						|
 | 
						|
    @param[out]   Pwc Pointer to a wide-character object to receive the converted character.
 | 
						|
    @param[in]    S   Pointer to a multibyte character to convert.
 | 
						|
    @param[in]    N   Maximum number of bytes in a multibyte character.
 | 
						|
 | 
						|
    @return   If S is a null pointer, the mbtowc function returns a nonzero or
 | 
						|
              zero value, if multibyte character encodings, respectively, do
 | 
						|
              or do not have state-dependent encodings. If S is not a null
 | 
						|
              pointer, the mbtowc function either returns 0 (if S points to
 | 
						|
              the null character), or returns the number of bytes that are
 | 
						|
              contained in the converted multibyte character (if the next N or
 | 
						|
              fewer bytes form a valid multibyte character), or returns -1
 | 
						|
              (if they do not form a valid multibyte character).
 | 
						|
 | 
						|
              In no case will the value returned be greater than N or the value
 | 
						|
              of the MB_CUR_MAX macro.
 | 
						|
 | 
						|
    Declared in: stdlib.h
 | 
						|
**/
 | 
						|
int
 | 
						|
mbtowc(
 | 
						|
  wchar_t *pwc,
 | 
						|
  const char *s,
 | 
						|
  size_t n
 | 
						|
  )
 | 
						|
{
 | 
						|
  return (int)mbrtowc(pwc, s, n, NULL);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
The mbsrtowcs function converts a sequence of multibyte characters that begins in the
 | 
						|
conversion state described by the object pointed to by ps, from the array indirectly
 | 
						|
pointed to by src into a sequence of corresponding wide characters. If dst is not a null
 | 
						|
pointer, the converted characters are stored into the array pointed to by dst. Conversion
 | 
						|
continues up to and including a terminating null character, which is also stored.
 | 
						|
Conversion stops earlier in two cases: when a sequence of bytes is encountered that does
 | 
						|
not form a valid multibyte character, or (if dst is not a null pointer) when len wide
 | 
						|
characters have been stored into the array pointed to by dst. Each conversion takes
 | 
						|
place as if by a call to the mbrtowc function.
 | 
						|
 | 
						|
If dst is not a null pointer, the pointer object pointed to by src is assigned either a null
 | 
						|
pointer (if conversion stopped due to reaching a terminating null character) or the address
 | 
						|
just past the last multibyte character converted (if any). If conversion stopped due to
 | 
						|
reaching a terminating null character and if dst is not a null pointer, the resulting state
 | 
						|
described is the initial conversion state.
 | 
						|
 | 
						|
    @param[out]   dst   Pointer to where the resulting wide character sequence is stored.
 | 
						|
    @param[in]    src   Pointer to a pointer to the multibyte character sequence to convert.
 | 
						|
    @param[in]    len   Maximum number of wide characters to be stored into dst.
 | 
						|
    @param[in]    ps    Pointer to a conversion state object.
 | 
						|
 | 
						|
    @return   If the input conversion encounters a sequence of bytes that do
 | 
						|
              not form a valid multibyte character, an encoding error occurs:
 | 
						|
              the mbsrtowcs function stores the value of the macro EILSEQ in
 | 
						|
              errno and returns (size_t)(-1); the conversion state is
 | 
						|
              unspecified. Otherwise, it returns the number of multibyte
 | 
						|
              characters successfully converted, not including the terminating
 | 
						|
              null character (if any).
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
size_t
 | 
						|
mbsrtowcs(
 | 
						|
  wchar_t      *dst,
 | 
						|
  const char  **src,
 | 
						|
  size_t        len,
 | 
						|
  mbstate_t    *ps
 | 
						|
  )
 | 
						|
{
 | 
						|
  int           x;
 | 
						|
  size_t        RetVal = 0;
 | 
						|
  const char   *MySrc;
 | 
						|
 | 
						|
  if((src == NULL) || (*src == NULL)) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  MySrc = *src;
 | 
						|
  for(x = 1 ; (len != 0) && (x > 0); --len) {
 | 
						|
    x = DecodeOneStateful(dst, MySrc, MB_LEN_MAX, ps);
 | 
						|
    switch(x) {
 | 
						|
      case -2:    // Incomplete character
 | 
						|
      case -1:    // Encoding error
 | 
						|
        RetVal = (size_t)x;
 | 
						|
        break;
 | 
						|
      case 0:     // Encountered NUL character: done.
 | 
						|
        if(dst != NULL) {
 | 
						|
          *dst = 0;
 | 
						|
          *src = NULL;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      default:    // Successfully decoded a character, continue with next
 | 
						|
        MySrc += x;
 | 
						|
        if(dst != NULL) {
 | 
						|
          ++dst;
 | 
						|
          if(x == 4) {
 | 
						|
            ++dst;
 | 
						|
          }
 | 
						|
          *src = MySrc;
 | 
						|
        }
 | 
						|
        ++RetVal;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Convert a multibyte character string into a wide-character string.
 | 
						|
 | 
						|
    The mbstowcs function converts a sequence of multibyte characters that
 | 
						|
    begins in the initial shift state from the array pointed to by Src into
 | 
						|
    a sequence of corresponding wide characters and stores not more than limit
 | 
						|
    wide characters into the array pointed to by Dest.  No multibyte
 | 
						|
    characters that follow a null character (which is converted into a null
 | 
						|
    wide character) will be examined or converted. Each multibyte character
 | 
						|
    is converted as if by a call to the mbtowc function, except that the
 | 
						|
    conversion state of the mbtowc function is not affected.
 | 
						|
 | 
						|
    No more than Limit elements will be modified in the array pointed to by Dest.
 | 
						|
    If copying takes place between objects that overlap,
 | 
						|
    the behavior is undefined.
 | 
						|
 | 
						|
    @param[out]   Dest    Pointer to the array to receive the converted string.
 | 
						|
    @param[in]    Src     Pointer to the string to be converted.
 | 
						|
    @param[in]    Limit   Maximum number of elements to be written to Dest.
 | 
						|
 | 
						|
    @return   If an invalid multibyte character is encountered, the mbstowcs
 | 
						|
              function returns (size_t)(-1). Otherwise, the mbstowcs function
 | 
						|
              returns the number of array elements modified, not including a
 | 
						|
              terminating null wide character, if any.
 | 
						|
 | 
						|
    Declared in: stdlib.h
 | 
						|
**/
 | 
						|
size_t
 | 
						|
mbstowcs(
 | 
						|
  wchar_t *Dest,
 | 
						|
  const char *Src,
 | 
						|
  size_t Limit
 | 
						|
  )
 | 
						|
{
 | 
						|
 | 
						|
  /* Dest may be NULL */
 | 
						|
  /* Src may be NULL */
 | 
						|
 | 
						|
  return mbsrtowcs(Dest, &Src, Limit, NULL);
 | 
						|
}
 | 
						|
 | 
						|
/** The btowc function determines whether C constitutes a valid single-byte
 | 
						|
    character in the initial shift state.
 | 
						|
 | 
						|
    @param[in]    C   A narrow character to test or convert to wide.
 | 
						|
 | 
						|
    @return   The btowc function returns WEOF if c has the value EOF or if
 | 
						|
              (unsigned char)C does not constitute a valid single-byte
 | 
						|
              character in the initial shift state. Otherwise, it returns the
 | 
						|
              wide character representation of that character.
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
wint_t
 | 
						|
btowc(int c)
 | 
						|
{
 | 
						|
  int       x;
 | 
						|
  wchar_t   Dest;
 | 
						|
  wint_t    RetVal = WEOF;
 | 
						|
 | 
						|
  if (c == EOF)
 | 
						|
    return WEOF;
 | 
						|
  x = DecodeOneStateful(&Dest, (const char *)&c, 1, NULL);
 | 
						|
  if(x == 0) {
 | 
						|
    RetVal = 0;
 | 
						|
  }
 | 
						|
  else if(x == 1) {
 | 
						|
    RetVal = (wint_t)Dest;
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
// ########################  Wide to Narrow Conversions #######################
 | 
						|
 | 
						|
/**
 | 
						|
If S is a null pointer, the wcrtomb function is equivalent to the call:<BR>
 | 
						|
@verbatim
 | 
						|
        wcrtomb(buf, L'\0', ps)
 | 
						|
@endverbatim
 | 
						|
where buf is an internal buffer.
 | 
						|
 | 
						|
If S is not a null pointer, the wcrtomb function determines the number of bytes needed
 | 
						|
to represent the multibyte character that corresponds to the wide character given by wc
 | 
						|
(including any shift sequences), and stores the multibyte character representation in the
 | 
						|
array whose first element is pointed to by S. At most MB_CUR_MAX bytes are stored. If
 | 
						|
wc is a null wide character, a null byte is stored, preceded by any shift sequence needed
 | 
						|
to restore the initial shift state; the resulting state described is the initial conversion state.
 | 
						|
 | 
						|
    @param[out]     Dest    Pointer to the location in which to store the resulting
 | 
						|
                            multibyte character.  Otherwise, NULL to reset the
 | 
						|
                            conversion state.
 | 
						|
    @param[in]      wchar   The wide character to convert.
 | 
						|
    @param[in,out]  pS      Pointer to a conversion state object, or NULL.
 | 
						|
 | 
						|
    @return   The wcrtomb function returns the number of bytes stored in the
 | 
						|
              array object (including any shift sequences). When wc is not a
 | 
						|
              valid wide character, an encoding error occurs: the function
 | 
						|
              stores the value of the macro EILSEQ in errno and
 | 
						|
              returns (size_t)(-1); the conversion state is unspecified.
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
size_t
 | 
						|
wcrtomb(
 | 
						|
  char *Dest,
 | 
						|
  wchar_t wchar,
 | 
						|
  mbstate_t *pS
 | 
						|
  )
 | 
						|
{
 | 
						|
  size_t    RetVal;
 | 
						|
 | 
						|
  /* Dest may be NULL */
 | 
						|
  if (Dest == NULL) {
 | 
						|
    RetVal = 1;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    if (wchar == L'\0') {
 | 
						|
      *Dest = '\0';
 | 
						|
      RetVal = 1;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      RetVal = EncodeUtf8(Dest, wchar);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if(pS == NULL) {
 | 
						|
    pS = &LocalConvState;
 | 
						|
  }
 | 
						|
  pS->A = 0;      // Set ps to the initial conversion state
 | 
						|
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Convert a wide character into a multibyte character.
 | 
						|
 | 
						|
    The wctomb function determines the number of bytes needed to represent the
 | 
						|
    multibyte character corresponding to the wide character given by WC
 | 
						|
    (including any shift sequences), and stores the multibyte character
 | 
						|
    representation in the array whose first element is pointed to by S (if S is
 | 
						|
    not a null pointer). At most MB_CUR_MAX characters are stored. If WC is a
 | 
						|
    null wide character, a null byte is stored, preceded by any shift sequence
 | 
						|
    needed to restore the initial shift state, and the function is left in the
 | 
						|
    initial conversion state.
 | 
						|
 | 
						|
    @param[out]   S   Pointer to the object to receive the converted multibyte character.
 | 
						|
    @param[in]    WC  Wide character to be converted.
 | 
						|
 | 
						|
    @return   If S is a null pointer, the wctomb function returns a nonzero or
 | 
						|
              zero value, if multibyte character encodings, respectively, do or
 | 
						|
              do not have state-dependent encodings. If S is not a null pointer,
 | 
						|
              the wctomb function returns -1 if the value of WC does not
 | 
						|
              correspond to a valid multibyte character, or returns the number
 | 
						|
              of bytes that are contained in the multibyte character
 | 
						|
              corresponding to the value of WC.
 | 
						|
 | 
						|
              In no case will the value returned be greater than the value of
 | 
						|
              the MB_CUR_MAX macro.
 | 
						|
 | 
						|
    Declared in: stdlib.h
 | 
						|
**/
 | 
						|
int
 | 
						|
wctomb(
 | 
						|
  char *s,
 | 
						|
  wchar_t wchar
 | 
						|
  )
 | 
						|
{
 | 
						|
  /*
 | 
						|
    If s is NULL just return whether MB Characters have state
 | 
						|
    dependent encodings -- they don't.
 | 
						|
  */
 | 
						|
  if (s == NULL)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  return (int)wcrtomb(s, wchar, NULL);
 | 
						|
}
 | 
						|
 | 
						|
/** The wcsrtombs function converts a sequence of wide characters from the array
 | 
						|
    indirectly pointed to by Src into a sequence of corresponding multibyte
 | 
						|
    characters that begins in the conversion state described by the object
 | 
						|
    pointed to by ps.
 | 
						|
 | 
						|
    If Dest is not a null pointer, the converted characters are stored into the
 | 
						|
    array pointed to by Dest.  Conversion continues up to and including a
 | 
						|
    terminating null wide character, which is also stored. Conversion stops
 | 
						|
    earlier in two cases: when a wide character is reached that does not
 | 
						|
    correspond to a valid multibyte character, or (if Dest is not a null
 | 
						|
    pointer) when the next multibyte character would exceed the limit of Limit
 | 
						|
    total bytes to be stored into the array pointed to by Dest. Each conversion
 | 
						|
    takes place as if by a call to the wcrtomb function.)
 | 
						|
 | 
						|
    If Dest is not a null pointer, the pointer object pointed to by Src is
 | 
						|
    assigned either a null pointer (if conversion stopped due to reaching
 | 
						|
    a terminating null wide character) or the address just past the last wide
 | 
						|
    character converted (if any). If conversion stopped due to reaching a
 | 
						|
    terminating null wide character, the resulting state described is the
 | 
						|
    initial conversion state.
 | 
						|
 | 
						|
    @param[in]      Dest
 | 
						|
    @param[in,out]  Src
 | 
						|
    @param[in]      Limit   Max number of bytes to store in Dest.
 | 
						|
    @param[in,out]  ps
 | 
						|
 | 
						|
    @return     If conversion stops because a wide character is reached that
 | 
						|
                does not correspond to a valid multibyte character, an
 | 
						|
                encoding error occurs: the wcsrtombs function stores the
 | 
						|
                value of the macro EILSEQ in errno and returns (size_t)(-1);
 | 
						|
                the conversion state is unspecified. Otherwise, it returns
 | 
						|
                the number of bytes in the resulting multibyte character
 | 
						|
                sequence, not including the terminating null character (if any).
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
size_t
 | 
						|
wcsrtombs(
 | 
						|
  char           *Dest,
 | 
						|
  const wchar_t **Src,
 | 
						|
  size_t          Limit,
 | 
						|
  mbstate_t      *ps
 | 
						|
)
 | 
						|
{
 | 
						|
  size_t  NumStored;
 | 
						|
  ssize_t MaxBytes;
 | 
						|
  int     count;
 | 
						|
  wchar_t InCh;
 | 
						|
 | 
						|
  NumStored = 0;
 | 
						|
  MaxBytes  = (ssize_t)Limit;
 | 
						|
 | 
						|
  /* Dest may be NULL */
 | 
						|
  /* Src may be NULL */
 | 
						|
  /* ps appears to be unused */
 | 
						|
 | 
						|
  if (Src == NULL || *Src == NULL)
 | 
						|
    return (0);
 | 
						|
 | 
						|
  if (Dest == NULL) {
 | 
						|
    NumStored = EstimateWtoM(*Src, ASCII_STRING_MAX, NULL);
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    if((MaxBytes < 0) || (MaxBytes > ASCII_STRING_MAX)) {
 | 
						|
      MaxBytes = ASCII_STRING_MAX;
 | 
						|
    }
 | 
						|
    while ((MaxBytes > 0) && (OneWcToMcLen(InCh = *(*Src)++) <= MaxBytes)) {
 | 
						|
      if(InCh == 0) {
 | 
						|
        *Src = NULL;
 | 
						|
        *Dest = 0;      // NUL terminate Dest string, but don't count the NUL
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      count = (int)wcrtomb(Dest, InCh, NULL);
 | 
						|
      if(count >= 0) {
 | 
						|
        Dest += count;
 | 
						|
        MaxBytes -= count;
 | 
						|
        NumStored += count;
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        NumStored = (size_t)(-1);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  return NumStored;
 | 
						|
}
 | 
						|
 | 
						|
/** Convert a wide-character string into a multibyte character string.
 | 
						|
 | 
						|
    The wcstombs function converts a sequence of wide characters from the
 | 
						|
    array pointed to by Src into a sequence of corresponding multibyte
 | 
						|
    characters that begins in the initial shift state, and stores these
 | 
						|
    multibyte characters into the array pointed to by Dest, stopping if a
 | 
						|
    multibyte character would exceed the limit of Limit total bytes or if a
 | 
						|
    null character is stored. Each wide character is converted as if by
 | 
						|
    a call to the wctomb function, except that the conversion state of
 | 
						|
    the wctomb function is not affected.
 | 
						|
 | 
						|
    No more than Limit bytes will be modified in the array pointed to by Dest.
 | 
						|
    If copying takes place between objects that overlap,
 | 
						|
    the behavior is undefined.
 | 
						|
 | 
						|
    @param[out]   Dest    Pointer to the array to receive the converted string.
 | 
						|
    @param[in]    Src     Pointer to the string to be converted.
 | 
						|
    @param[in]    Limit   Maximum number of elements to be written to Dest.
 | 
						|
 | 
						|
    @return   If a wide character is encountered that does not correspond to a
 | 
						|
              valid multibyte character, the wcstombs function returns
 | 
						|
              (size_t)(-1). Otherwise, the wcstombs function returns the number
 | 
						|
              of bytes in the resulting multibyte character sequence,
 | 
						|
              not including the terminating null character (if any).
 | 
						|
 | 
						|
    Declared in: stdlib.h
 | 
						|
**/
 | 
						|
size_t
 | 
						|
wcstombs(
 | 
						|
  char           *Dest,
 | 
						|
  const wchar_t  *Src,
 | 
						|
  size_t          Limit
 | 
						|
)
 | 
						|
{
 | 
						|
  /* Dest may be NULL */
 | 
						|
  return wcsrtombs(Dest, &Src, Limit, NULL);
 | 
						|
}
 | 
						|
 | 
						|
/** The wctob function determines whether C corresponds to a member of the extended
 | 
						|
    character set whose multibyte character representation is a single byte when in the initial
 | 
						|
    shift state.
 | 
						|
 | 
						|
    wctob needs to be consistent with wcrtomb.
 | 
						|
    If wcrtomb says that a character is representable in 1 byte,
 | 
						|
    then wctob needs to also represent the character as 1 byte.
 | 
						|
 | 
						|
    @return     The wctob function returns EOF if C does not correspond to a multibyte
 | 
						|
                character with length one in the initial shift state. Otherwise, it
 | 
						|
                returns the single-byte representation of that character as an
 | 
						|
                unsigned char converted to an int.
 | 
						|
 | 
						|
    Declared in: wchar.h
 | 
						|
**/
 | 
						|
int
 | 
						|
wctob(wint_t c)
 | 
						|
{
 | 
						|
  int   RetVal;
 | 
						|
 | 
						|
  RetVal = EOF;
 | 
						|
  if(c == 0) {
 | 
						|
    RetVal = 0;
 | 
						|
  }
 | 
						|
  else if (OneWcToMcLen((const wchar_t)c) == 1) {
 | 
						|
    RetVal = (int)(c & 0xFF);
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 |