misc/libphysfs/physfs_unicode.c
changeset 12213 bb5522e88ab2
parent 8524 a65e9bcf0a03
equal deleted inserted replaced
12212:ea891871f481 12213:bb5522e88ab2
     2 #include "physfs_internal.h"
     2 #include "physfs_internal.h"
     3 
     3 
     4 
     4 
     5 /*
     5 /*
     6  * From rfc3629, the UTF-8 spec:
     6  * From rfc3629, the UTF-8 spec:
     7  *  http://www.ietf.org/rfc/rfc3629.txt
     7  *  https://www.ietf.org/rfc/rfc3629.txt
     8  *
     8  *
     9  *   Char. number range  |        UTF-8 octet sequence
     9  *   Char. number range  |        UTF-8 octet sequence
    10  *      (hexadecimal)    |              (binary)
    10  *      (hexadecimal)    |              (binary)
    11  *   --------------------+---------------------------------------------
    11  *   --------------------+---------------------------------------------
    12  *   0000 0000-0000 007F | 0xxxxxxx
    12  *   0000 0000-0000 007F | 0xxxxxxx
   445 
   445 
   446 
   446 
   447 static int utf8codepointcmp(const PHYSFS_uint32 cp1, const PHYSFS_uint32 cp2)
   447 static int utf8codepointcmp(const PHYSFS_uint32 cp1, const PHYSFS_uint32 cp2)
   448 {
   448 {
   449     PHYSFS_uint32 folded1[3], folded2[3];
   449     PHYSFS_uint32 folded1[3], folded2[3];
       
   450 
       
   451     if (cp1 == cp2)
       
   452         return 0;  /* obviously matches. */
       
   453 
   450     locate_case_fold_mapping(cp1, folded1);
   454     locate_case_fold_mapping(cp1, folded1);
   451     locate_case_fold_mapping(cp2, folded2);
   455     locate_case_fold_mapping(cp2, folded2);
   452     return ( (folded1[0] == folded2[0]) &&
   456 
   453              (folded1[1] == folded2[1]) &&
   457     if (folded1[0] < folded2[0])
   454              (folded1[2] == folded2[2]) );
   458         return -1;
       
   459     else if (folded1[0] > folded2[0])
       
   460         return 1;
       
   461     else if (folded1[1] < folded2[1])
       
   462         return -1;
       
   463     else if (folded1[1] > folded2[1])
       
   464         return 1;
       
   465     else if (folded1[2] < folded2[2])
       
   466         return -1;
       
   467     else if (folded1[2] > folded2[2])
       
   468         return 1;
       
   469 
       
   470     return 0;  /* complete match. */
   455 } /* utf8codepointcmp */
   471 } /* utf8codepointcmp */
   456 
   472 
   457 
   473 
   458 int __PHYSFS_utf8stricmp(const char *str1, const char *str2)
   474 int __PHYSFS_utf8stricmp(const char *str1, const char *str2)
   459 {
   475 {
   460     while (1)
   476     while (1)
   461     {
   477     {
   462         const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
   478         const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
   463         const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
   479         const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
   464         if (!utf8codepointcmp(cp1, cp2)) break;
   480         const int rc = utf8codepointcmp(cp1, cp2);
   465         if (cp1 == 0) return 1;
   481         if (rc != 0)
       
   482             return rc;
       
   483         else if (cp1 == 0)
       
   484             break;  /* complete match. */
   466     } /* while */
   485     } /* while */
   467 
   486 
   468     return 0;
   487     return 0;
   469 } /* __PHYSFS_utf8stricmp */
   488 } /* __PHYSFS_utf8stricmp */
   470 
   489 
   473 {
   492 {
   474     while (n > 0)
   493     while (n > 0)
   475     {
   494     {
   476         const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
   495         const PHYSFS_uint32 cp1 = utf8codepoint(&str1);
   477         const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
   496         const PHYSFS_uint32 cp2 = utf8codepoint(&str2);
   478         if (!utf8codepointcmp(cp1, cp2)) return 0;
   497         const int rc = utf8codepointcmp(cp1, cp2);
   479         if (cp1 == 0) return 1;
   498         if (rc != 0)
       
   499             return rc;
       
   500         else if (cp1 == 0)
       
   501             return 0;
   480         n--;
   502         n--;
   481     } /* while */
   503     } /* while */
   482 
   504 
   483     return 1;  /* matched to n chars. */
   505     return 0;  /* matched to n chars. */
   484 } /* __PHYSFS_utf8strnicmp */
   506 } /* __PHYSFS_utf8strnicmp */
   485 
   507 
   486 
   508 
   487 int __PHYSFS_stricmpASCII(const char *str1, const char *str2)
   509 int __PHYSFS_stricmpASCII(const char *str1, const char *str2)
   488 {
   510 {