utf8.c

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

C
760
字号
/*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#ifdef DEBUGstatic const char CVS_ID[] = "@(#) $RCSfile: utf8.c,v $ $Revision: 1.3 $ $Date: 2000/05/12 18:43:28 $ $Name: NSS_3_1_1_RTM $";#endif /* DEBUG *//* * utf8.c * * This file contains some additional utility routines required for * handling UTF8 strings. */#ifndef BASE_H#include "base.h"#endif /* BASE_H */#include "plstr.h"/* * NOTES: * * There's an "is hex string" function in pki1/atav.c.  If we need * it in more places, pull that one out. *//* * nssUTF8_CaseIgnoreMatch *  * Returns true if the two UTF8-encoded strings pointed to by the  * two specified NSSUTF8 pointers differ only in typcase. * * The error may be one of the following values: *  NSS_ERROR_INVALID_POINTER * * Return value: *  PR_TRUE if the strings match, ignoring case *  PR_FALSE if they don't *  PR_FALSE upon error */NSS_IMPLEMENT PRBoolnssUTF8_CaseIgnoreMatch(  const NSSUTF8 *a,  const NSSUTF8 *b,  PRStatus *statusOpt){#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 */  if( (PRStatus *)NULL != statusOpt ) {    *statusOpt = PR_SUCCESS;  }  /*   * XXX fgmr   *   * This is, like, so wrong!   */  if( 0 == PL_strcasecmp((const char *)a, (const char *)b) ) {    return PR_TRUE;  } else {    return PR_FALSE;  }}/* * nssUTF8_PrintableMatch * * Returns true if the two Printable strings pointed to by the  * two specified NSSUTF8 pointers match when compared with the  * rules for Printable String (leading and trailing spaces are  * disregarded, extents of whitespace match irregardless of length,  * and case is not significant), then PR_TRUE will be returned. * Otherwise, PR_FALSE will be returned.  Upon failure, PR_FALSE * will be returned.  If the optional statusOpt argument is not * NULL, then PR_SUCCESS or PR_FAILURE will be stored in that * location. * * The error may be one of the following values: *  NSS_ERROR_INVALID_POINTER * * Return value: *  PR_TRUE if the strings match, ignoring case *  PR_FALSE if they don't *  PR_FALSE upon error */NSS_IMPLEMENT PRBoolnssUTF8_PrintableMatch(  const NSSUTF8 *a,  const NSSUTF8 *b,  PRStatus *statusOpt){  PRUint8 *c;  PRUint8 *d;#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 */  if( (PRStatus *)NULL != statusOpt ) {    *statusOpt = PR_SUCCESS;  }  c = (PRUint8 *)a;  d = (PRUint8 *)b;  while( ' ' == *c ) {    c++;  }  while( ' ' == *d ) {    d++;  }  while( ('\0' != *c) && ('\0' != *d) ) {    PRUint8 e, f;    e = *c;    f = *d;        if( ('a' <= e) && (e <= 'z') ) {      e -= ('a' - 'A');    }    if( ('a' <= f) && (f <= 'z') ) {      f -= ('a' - 'A');    }    if( e != f ) {      return PR_FALSE;    }    c++;    d++;    if( ' ' == *c ) {      while( ' ' == *c ) {        c++;      }      c--;    }    if( ' ' == *d ) {      while( ' ' == *d ) {        d++;      }      d--;    }  }  while( ' ' == *c ) {    c++;  }  while( ' ' == *d ) {    d++;  }  if( *c == *d ) {    /* And both '\0', btw */    return PR_TRUE;  } else {    return PR_FALSE;  }}/* * nssUTF8_Duplicate * * This routine duplicates the UTF8-encoded string pointed to by the * specified NSSUTF8 pointer.  If the optional arenaOpt argument is * not null, the memory required will be obtained from that arena; * otherwise, the memory required will be obtained from the heap. * A pointer to the new string will be returned.  In case of error, * an error will be placed on the error stack and NULL will be  * returned. * * The error may be one of the following values: *  NSS_ERROR_INVALID_POINTER *  NSS_ERROR_INVALID_ARENA *  NSS_ERROR_NO_MEMORY */NSS_IMPLEMENT NSSUTF8 *nssUTF8_Duplicate(  const NSSUTF8 *s,  NSSArena *arenaOpt){  NSSUTF8 *rv;  PRUint32 len;#ifdef NSSDEBUG  if( (const NSSUTF8 *)NULL == s ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    return (NSSUTF8 *)NULL;  }  if( (NSSArena *)NULL != arenaOpt ) {    if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) {      return (NSSUTF8 *)NULL;    }  }#endif /* NSSDEBUG */  len = PL_strlen((const char *)s);#ifdef PEDANTIC  if( '\0' != ((const char *)s)[ len ] ) {    /* must have wrapped, e.g., too big for PRUint32 */    nss_SetError(NSS_ERROR_NO_MEMORY);    return (NSSUTF8 *)NULL;  }#endif /* PEDANTIC */  len++; /* zero termination */  rv = nss_ZAlloc(arenaOpt, len);  if( (void *)NULL == rv ) {    return (NSSUTF8 *)NULL;  }  (void)nsslibc_memcpy(rv, s, len);  return rv;}/* * nssUTF8_Size * * This routine returns the length in bytes (including the terminating * null) of the UTF8-encoded string pointed to by the specified * NSSUTF8 pointer.  Zero is returned on error. * * The error may be one of the following values: *  NSS_ERROR_INVALID_POINTER *  NSS_ERROR_VALUE_TOO_LARGE * * Return value: *  0 on error *  nonzero length of the string. */NSS_IMPLEMENT PRUint32nssUTF8_Size(  const NSSUTF8 *s,  PRStatus *statusOpt){  PRUint32 sv;#ifdef NSSDEBUG  if( (const NSSUTF8 *)NULL == s ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    if( (PRStatus *)NULL != statusOpt ) {      *statusOpt = PR_FAILURE;    }    return 0;  }#endif /* NSSDEBUG */  sv = PL_strlen((const char *)s) + 1;#ifdef PEDANTIC  if( '\0' != ((const char *)s)[ sv-1 ] ) {    /* wrapped */    nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);    if( (PRStatus *)NULL != statusOpt ) {      *statusOpt = PR_FAILURE;    }    return 0;  }#endif /* PEDANTIC */  if( (PRStatus *)NULL != statusOpt ) {    *statusOpt = PR_SUCCESS;  }  return sv;}/* * nssUTF8_Length * * This routine returns the length in characters (not including the * terminating null) of the UTF8-encoded string pointed to by the * specified NSSUTF8 pointer. * * The error may be one of the following values: *  NSS_ERROR_INVALID_POINTER *  NSS_ERROR_VALUE_TOO_LARGE *  NSS_ERROR_INVALID_STRING * * Return value: *  length of the string (which may be zero) *  0 on error */NSS_IMPLEMENT PRUint32nssUTF8_Length(  const NSSUTF8 *s,  PRStatus *statusOpt){  PRUint32 l = 0;  const PRUint8 *c = (const PRUint8 *)s;#ifdef NSSDEBUG  if( (const NSSUTF8 *)NULL == s ) {    nss_SetError(NSS_ERROR_INVALID_POINTER);    goto loser;  }#endif /* NSSDEBUG */  /*   * From RFC 2044:   *   * UCS-4 range (hex.)           UTF-8 octet sequence (binary)   * 0000 0000-0000 007F   0xxxxxxx   * 0000 0080-0000 07FF   110xxxxx 10xxxxxx   * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx   * 0001 0000-001F FFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx   * 0020 0000-03FF FFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx   * 0400 0000-7FFF FFFF   1111110x 10xxxxxx ... 10xxxxxx   */    while( 0 != *c ) {    PRUint32 incr;    if( (*c & 0x80) == 0 ) {

⌨️ 快捷键说明

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