utf8.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 760 行 · 第 1/2 页

C
760
字号
      incr = 1;    } else if( (*c & 0xE0) == 0xC0 ) {      incr = 2;    } else if( (*c & 0xF0) == 0xE0 ) {      incr = 3;    } else if( (*c & 0xF8) == 0xF0 ) {      incr = 4;    } else if( (*c & 0xFC) == 0xF8 ) {      incr = 5;    } else if( (*c & 0xFE) == 0xFC ) {      incr = 6;    } else {      nss_SetError(NSS_ERROR_INVALID_STRING);      goto loser;    }    l += incr;#ifdef PEDANTIC    if( l < incr ) {      /* Wrapped-- too big */      nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);      goto loser;    }    {      PRUint8 *d;      for( d = &c[1]; d < &c[incr]; d++ ) {        if( (*d & 0xC0) != 0xF0 ) {          nss_SetError(NSS_ERROR_INVALID_STRING);          goto loser;        }      }    }#endif /* PEDANTIC */    c += incr;  }  if( (PRStatus *)NULL != statusOpt ) {    *statusOpt = PR_SUCCESS;  }  return l; loser:  if( (PRStatus *)NULL != statusOpt ) {    *statusOpt = PR_FAILURE;  }  return 0;}/* * nssUTF8_Create * * This routine creates a UTF8 string from a string in some other * format.  Some types of string may include embedded null characters, * so for them the length parameter must be used.  For string types * that are null-terminated, the length parameter is optional; if it * is zero, it will be ignored.  If the optional arena argument is * non-null, the memory used for the new string will be obtained from * that arena, otherwise it will be obtained from the heap.  This * routine may return NULL upon error, in which case it will have * placed an error on the error stack. * * The error may be one of the following: *  NSS_ERROR_INVALID_POINTER *  NSS_ERROR_NO_MEMORY *  NSS_ERROR_UNSUPPORTED_TYPE * * Return value: *  NULL upon error *  A non-null pointer to a new UTF8 string otherwise */extern const NSSError NSS_ERROR_INTERNAL_ERROR; /* XXX fgmr */NSS_IMPLEMENT NSSUTF8 *nssUTF8_Create(  NSSArena *arenaOpt,  nssStringType type,  const void *inputString,  PRUint32 size /* in bytes, not characters */){  NSSUTF8 *rv = NULL;#ifdef NSSDEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSUTF8 *)NULL;    }  }  if( (const void *)NULL == inputString ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSUTF8 *)NULL;  }#endif /* NSSDEBUG */  switch( type ) {  case nssStringType_DirectoryString:    /* This is a composite type requiring BER */    nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);    break;  case nssStringType_TeletexString:    /*     * draft-ietf-pkix-ipki-part1-11 says in part:     *     * In addition, many legacy implementations support names encoded      * in the ISO 8859-1 character set (Latin1String) but tag them as      * TeletexString.  The Latin1String includes characters used in      * Western European countries which are not part of the      * TeletexString charcter set.  Implementations that process      * TeletexString SHOULD be prepared to handle the entire ISO      * 8859-1 character set.[ISO 8859-1].     */    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_PrintableString:    /*     * PrintableString consists of A-Za-z0-9 ,()+,-./:=?     * This is a subset of ASCII, which is a subset of UTF8.     * So we can just duplicate the string over.     */    if( 0 == size ) {      rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt);    } else {      rv = nss_ZAlloc(arenaOpt, size+1);      if( (NSSUTF8 *)NULL == rv ) {        return (NSSUTF8 *)NULL;      }      (void)nsslibc_memcpy(rv, inputString, size);    }    break;  case nssStringType_UniversalString:    /* 4-byte unicode */    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_BMPString:    /* Base Multilingual Plane of Unicode */    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_UTF8String:    if( 0 == size ) {      rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt);    } else {      rv = nss_ZAlloc(arenaOpt, size+1);      if( (NSSUTF8 *)NULL == rv ) {        return (NSSUTF8 *)NULL;      }      (void)nsslibc_memcpy(rv, inputString, size);    }    break;  case nssStringType_PHGString:    /*      * PHGString is an IA5String (with case-insensitive comparisons).     * IA5 is ~almost~ ascii; ascii has dollar-sign where IA5 has     * currency symbol.     */    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_GeneralString:    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  default:    nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);    break;  }  return rv;}NSS_IMPLEMENT NSSItem *nssUTF8_GetEncoding(  NSSArena *arenaOpt,  NSSItem *rvOpt,  nssStringType type,  NSSUTF8 *string){  NSSItem *rv = (NSSItem *)NULL;  PRStatus status = PR_SUCCESS;#ifdef NSSDEBUG  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSItem *)NULL;    }  }  if( (NSSUTF8 *)NULL == string ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSItem *)NULL;  }#endif /* NSSDEBUG */  switch( type ) {  case nssStringType_DirectoryString:    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_TeletexString:    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_PrintableString:    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_UniversalString:    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_BMPString:    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  case nssStringType_UTF8String:    {      NSSUTF8 *dup = nssUTF8_Duplicate(string, arenaOpt);      if( (NSSUTF8 *)NULL == dup ) {        return (NSSItem *)NULL;      }      if( (NSSItem *)NULL == rvOpt ) {        rv = nss_ZNEW(arenaOpt, NSSItem);        if( (NSSItem *)NULL == rv ) {          (void)nss_ZFreeIf(dup);          return (NSSItem *)NULL;        }      } else {        rv = rvOpt;      }      rv->data = dup;      dup = (NSSUTF8 *)NULL;      rv->size = nssUTF8_Size(rv->data, &status);      if( (0 == rv->size) && (PR_SUCCESS != status) ) {        if( (NSSItem *)NULL == rvOpt ) {          (void)nss_ZFreeIf(rv);        }        return (NSSItem *)NULL;      }    }    break;  case nssStringType_PHGString:    nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */    break;  default:    nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);    break;  }  return rv;}/* * nssUTF8_CopyIntoFixedBuffer * * This will copy a UTF8 string into a fixed-length buffer, making  * sure that the all characters are valid.  Any remaining space will * be padded with the specified ASCII character, typically either  * null or space. * * Blah, blah, blah. */NSS_IMPLEMENT PRStatusnssUTF8_CopyIntoFixedBuffer(  NSSUTF8 *string,  char *buffer,  PRUint32 bufferSize,  char pad){  PRUint32 stringSize = 0;#ifdef NSSDEBUG  if( (char *)NULL == buffer ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return PR_FALSE;  }  if( 0 == bufferSize ) {    nss_SetError(NSS_ERROR_INVALID_ARGUMENT);    return PR_FALSE;  }  if( (pad & 0x80) != 0x00 ) {    nss_SetError(NSS_ERROR_INVALID_ARGUMENT);    return PR_FALSE;  }#endif /* NSSDEBUG */  if( (NSSUTF8 *)NULL == string ) {    string = (unsigned char*) "";  }  stringSize = nssUTF8_Size(string, (PRStatus *)NULL);  stringSize--; /* don't count the trailing null */  if( stringSize > bufferSize ) {    PRUint32 bs = bufferSize;    (void)nsslibc_memcpy(buffer, string, bufferSize);        if( (            ((buffer[ bs-1 ] & 0x80) == 0x00)) ||        ((bs > 1) && ((buffer[ bs-2 ] & 0xE0) == 0xC0)) ||        ((bs > 2) && ((buffer[ bs-3 ] & 0xF0) == 0xE0)) ||        ((bs > 3) && ((buffer[ bs-4 ] & 0xF8) == 0xF0)) ||        ((bs > 4) && ((buffer[ bs-5 ] & 0xFC) == 0xF8)) ||        ((bs > 5) && ((buffer[ bs-6 ] & 0xFE) == 0xFC)) ) {      /* It fit exactly */      return PR_SUCCESS;    }    /* Too long.  We have to trim the last character */    for( bs; bs > 0; bs-- ) {      if( (buffer[bs-1] & 0xC0) != 0x80 ) {        buffer[bs-1] = pad;        break;      } else {        buffer[bs-1] = pad;      }    }        } else {    (void)nsslibc_memset(buffer, pad, bufferSize);    (void)nsslibc_memcpy(buffer, string, stringSize);  }  return PR_SUCCESS;}/* * nssUTF8_Equal * */NSS_IMPLEMENT PRBoolnssUTF8_Equal(  const NSSUTF8 *a,  const NSSUTF8 *b,  PRStatus *statusOpt){  PRUint32 la, lb;#ifdef NSSDEBUG  if( ((const NSSUTF8 *)NULL == a) ||      ((const NSSUTF8 *)NULL == b) ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    if( (PRStatus *)NULL != statusOpt ) {      *statusOpt = PR_FAILURE;    }    return PR_FALSE;  }#endif /* NSSDEBUG */  la = nssUTF8_Size(a, statusOpt);  if( 0 == la ) {    return PR_FALSE;  }  lb = nssUTF8_Size(b, statusOpt);  if( 0 == lb ) {    return PR_FALSE;  }  if( la != lb ) {    return PR_FALSE;  }  return nsslibc_memequal(a, b, la, statusOpt);}

⌨️ 快捷键说明

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