Reactos
at master 133 lines 4.3 kB view raw
1/*** 2*mbsnbicmp.c - Compare n bytes of strings, ignoring case (MBCS) 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* Compare n bytes of strings, ignoring case (MBCS) 8* 9*******************************************************************************/ 10#ifndef _MBCS 11 #error This file should only be compiled with _MBCS defined 12#endif 13 14#include <corecrt_internal_mbstring.h> 15#include <locale.h> 16#include <string.h> 17 18#pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018 19 20/*** 21* _mbsnbicmp - Compare n bytes of strings, ignoring case (MBCS) 22* 23*Purpose: 24* Compares up to n bytes of two strings for ordinal order. 25* Strings are compared on a character basis, not a byte basis. 26* Case of characters is not considered. 27* 28*Entry: 29* unsigned char *s1, *s2 = strings to compare 30* size_t n = maximum number of bytes to compare 31* 32*Exit: 33* Returns <0 if s1 < s2 34* Returns 0 if s1 == s2 35* Returns >0 if s1 > s2 36* Returns _NLSCMPERROR is something went wrong 37* 38*Exceptions: 39* Input parameters are validated. Refer to the validation section of the function. 40* 41*******************************************************************************/ 42 43int __cdecl _mbsnbicmp_l( 44 const unsigned char *s1, 45 const unsigned char *s2, 46 size_t n, 47 _locale_t plocinfo 48 ) 49{ 50 unsigned short c1, c2; 51 _LocaleUpdate _loc_update(plocinfo); 52 53 if (n==0) 54 return(0); 55 56 if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0) 57 return _strnicmp((const char *)s1, (const char *)s2, n); 58 59 /* validation section */ 60 _VALIDATE_RETURN(s1 != nullptr, EINVAL, _NLSCMPERROR); 61 _VALIDATE_RETURN(s2 != nullptr, EINVAL, _NLSCMPERROR); 62 63 while (n--) { 64 65 c1 = *s1++; 66 if ( _ismbblead_l(c1, _loc_update.GetLocaleT()) ) 67 { 68 if (n==0) 69 { 70 c1 = 0; /* 'naked' lead - end of string */ 71 c2 = _ismbblead_l(*s2, _loc_update.GetLocaleT()) ? 0 : *s2; 72 goto test; 73 } 74 if (*s1 == '\0') 75 c1 = 0; 76 else { 77 c1 = ((c1<<8) | *s1++); 78 79 if ( ((c1 >= _MBUPPERLOW1_MT(_loc_update.GetLocaleT())) && 80 (c1 <= _MBUPPERHIGH1_MT(_loc_update.GetLocaleT()))) ) 81 c1 += _MBCASEDIFF1_MT(_loc_update.GetLocaleT()); 82 else if ( ((c1 >= _MBUPPERLOW2_MT(_loc_update.GetLocaleT())) && 83 (c1 <= _MBUPPERHIGH2_MT(_loc_update.GetLocaleT()))) ) 84 c1 += _MBCASEDIFF2_MT(_loc_update.GetLocaleT()); 85 } 86 } 87 else 88 c1 = _mbbtolower_l(c1, _loc_update.GetLocaleT()); 89 90 c2 = *s2++; 91 if ( _ismbblead_l(c2, _loc_update.GetLocaleT()) ) 92 { 93 if (n==0) 94 { 95 c2 = 0; /* 'naked' lead - end of string */ 96 goto test; 97 } 98 n--; 99 if (*s2 == '\0') 100 c2 = 0; 101 else { 102 c2 = ((c2<<8) | *s2++); 103 104 if ( ((c2 >= _MBUPPERLOW1_MT(_loc_update.GetLocaleT())) && 105 (c2 <= _MBUPPERHIGH1_MT(_loc_update.GetLocaleT()))) ) 106 c2 += _MBCASEDIFF1_MT(_loc_update.GetLocaleT()); 107 else if ( ((c2 >= _MBUPPERLOW2_MT(_loc_update.GetLocaleT())) && 108 (c2 <= _MBUPPERHIGH2_MT(_loc_update.GetLocaleT()))) ) 109 c2 += _MBCASEDIFF2_MT(_loc_update.GetLocaleT()); 110 } 111 } 112 else 113 c2 = _mbbtolower_l(c2, _loc_update.GetLocaleT()); 114 115test: 116 if (c1 != c2) 117 return( (c1 > c2) ? 1 : -1); 118 119 if (c1 == 0) 120 return(0); 121 } 122 123 return(0); 124} 125 126int (__cdecl _mbsnbicmp)( 127 const unsigned char *s1, 128 const unsigned char *s2, 129 size_t n 130 ) 131{ 132 return _mbsnbicmp_l(s1, s2, n, nullptr); 133}