~ubuntu-branches/ubuntu/vivid/unrar-nonfree/vivid

« back to all changes in this revision

Viewing changes to unicode.cpp

  • Committer: Package Import Robot
  • Author(s): Martin Meredith
  • Date: 2015-02-03 12:58:01 UTC
  • mfrom: (1.1.18) (5.1.18 sid)
  • Revision ID: package-import@ubuntu.com-20150203125801-od6ev8cqy1er51vz
Tags: 1:5.2.5-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
  if (WideCharToMultiByte(CP_ACP,0,Src,-1,Dest,(int)DestSize,NULL,NULL)==0)
27
27
    RetCode=false;
28
28
 
29
 
#elif defined(_APPLE)
 
29
// wcstombs is broken in Android NDK r9.
 
30
#elif defined(_APPLE) || defined(_ANDROID)
30
31
  WideToUtf(Src,Dest,DestSize);
31
32
 
32
33
#elif defined(MBFUNCTIONS)
33
34
  if (!WideToCharMap(Src,Dest,DestSize,RetCode))
34
35
  {
35
 
    size_t ResultingSize=wcstombs(Dest,Src,DestSize);
 
36
    mbstate_t ps; // Use thread safe external state based functions.
 
37
    memset (&ps, 0, sizeof(ps));
 
38
    const wchar *SrcParam=Src; // wcsrtombs can change the pointer.
 
39
    size_t ResultingSize=wcsrtombs(Dest,&SrcParam,DestSize,&ps);
36
40
    if (ResultingSize==(size_t)-1)
37
41
      RetCode=false;
38
42
    if (ResultingSize==0 && *Src!=0)
69
73
  if (MultiByteToWideChar(CP_ACP,0,Src,-1,Dest,(int)DestSize)==0)
70
74
    RetCode=false;
71
75
 
72
 
#elif defined(_APPLE)
 
76
// mbstowcs is broken in Android NDK r9.
 
77
#elif defined(_APPLE) || defined(_ANDROID)
73
78
  UtfToWide(Src,Dest,DestSize);
74
79
 
75
80
#elif defined(MBFUNCTIONS)
76
 
  size_t ResultingSize=mbstowcs(Dest,Src,DestSize);
 
81
  mbstate_t ps;
 
82
  memset (&ps, 0, sizeof(ps));
 
83
  const char *SrcParam=Src; // mbsrtowcs can change the pointer.
 
84
  size_t ResultingSize=mbsrtowcs(Dest,&SrcParam,DestSize,&ps);
77
85
  if (ResultingSize==(size_t)-1)
78
86
    RetCode=false;
79
87
  if (ResultingSize==0 && *Src!=0)
81
89
 
82
90
  if (RetCode==false && DestSize>1)
83
91
    CharToWideMap(Src,Dest,DestSize,RetCode);
84
 
 
85
92
#else
86
93
  for (int I=0;I<DestSize;I++)
87
94
  {
103
110
}
104
111
 
105
112
 
106
 
#if defined(_UNIX) && defined(MBFUNCTIONS)
 
113
#if defined(_UNIX) && defined(MBFUNCTIONS) && !defined(_ANDROID)
107
114
// Convert and restore mapped inconvertible Unicode characters. 
108
115
// We use it for extended ASCII names in Unix.
109
116
bool WideToCharMap(const wchar *Src,char *Dest,size_t DestSize,bool &Success)
133
140
      Dest[DestPos++]=char(uint(Src[SrcPos++])-MapAreaStart);
134
141
    else
135
142
    {
136
 
      ignore_result( wctomb(NULL,0) ); // Reset shift state.
137
 
      if (wctomb(Dest+DestPos,Src[SrcPos])==-1)
 
143
      mbstate_t ps;
 
144
      memset(&ps,0,sizeof(ps));
 
145
      if (wcrtomb(Dest+DestPos,Src[SrcPos],&ps)==-1)
138
146
        Success=false;
139
147
      SrcPos++;
140
 
      ignore_result( mblen(NULL,0) ); // Reset shift state.
141
 
      int Length=mblen(Dest+DestPos,MB_CUR_MAX);
 
148
      memset(&ps,0,sizeof(ps));
 
149
      int Length=mbrlen(Dest+DestPos,MB_CUR_MAX,&ps);
142
150
      DestPos+=Max(Length,1);
143
151
    }
144
152
  }
147
155
#endif
148
156
 
149
157
 
150
 
#if defined(_UNIX) && defined(MBFUNCTIONS)
 
158
#if defined(_UNIX) && defined(MBFUNCTIONS) && !defined(_ANDROID)
151
159
// Convert and map inconvertible Unicode characters. 
152
160
// We use it for extended ASCII names in Unix.
153
161
void CharToWideMap(const char *Src,wchar *Dest,size_t DestSize,bool &Success)
166
174
      Success=true;
167
175
      break;
168
176
    }
169
 
    ignore_result( mbtowc(NULL,NULL,0) ); // Reset shift state.
170
 
    if (mbtowc(Dest+DestPos,Src+SrcPos,MB_CUR_MAX)==-1)
 
177
    mbstate_t ps;
 
178
    memset(&ps,0,sizeof(ps));
 
179
    if (mbrtowc(Dest+DestPos,Src+SrcPos,MB_CUR_MAX,&ps)==-1)
171
180
    {
172
181
      // For security reasons we do not want to map low ASCII characters,
173
182
      // so we do not have additional .. and path separator codes.
187
196
    }
188
197
    else
189
198
    {
190
 
      ignore_result( mblen(NULL,0) ); // Reset shift state.
191
 
      int Length=mblen(Src+SrcPos,MB_CUR_MAX);
 
199
      memset(&ps,0,sizeof(ps));
 
200
      int Length=mbrlen(Src+SrcPos,MB_CUR_MAX,&ps);
192
201
      SrcPos+=Max(Length,1);
193
202
      DestPos++;
194
203
    }
373
382
#ifdef _WIN_ALL
374
383
  return CompareStringW(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,-1,s2,-1)-2;
375
384
#else
376
 
  while (towupper(*s1)==towupper(*s2))
 
385
  while (true)
377
386
  {
 
387
    wchar u1 = towupper(*s1);
 
388
    wchar u2 = towupper(*s2);
 
389
    if (u1 != u2)
 
390
      return u1 < u2 ? -1 : 1;
378
391
    if (*s1==0)
379
 
      return 0;
 
392
      break;
380
393
    s1++;
381
394
    s2++;
382
395
  }
383
 
  return s1 < s2 ? -1 : 1;
 
396
  return 0;
384
397
#endif
385
398
}
386
399
 
393
406
  // to real string length.
394
407
  size_t l1=Min(wcslen(s1)+1,n);
395
408
  size_t l2=Min(wcslen(s2)+1,n);
396
 
  return(CompareStringW(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,(int)l1,s2,(int)l2)-2);
 
409
  return CompareStringW(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,(int)l1,s2,(int)l2)-2;
397
410
#else
398
411
  if (n==0)
399
412
    return 0;
400
 
  while (towupper(*s1)==towupper(*s2))
 
413
  while (true)
401
414
  {
 
415
    wchar u1 = towupper(*s1);
 
416
    wchar u2 = towupper(*s2);
 
417
    if (u1 != u2)
 
418
      return u1 < u2 ? -1 : 1;
402
419
    if (*s1==0 || --n==0)
403
 
      return 0;
 
420
      break;
404
421
    s1++;
405
422
    s2++;
406
423
  }
407
 
  return s1 < s2 ? -1 : 1;
 
424
  return 0;
408
425
#endif
409
426
}
410
427
 
411
428
 
 
429
const wchar_t* wcscasestr(const wchar_t *str, const wchar_t *search)
 
430
{
 
431
  for (size_t i=0;str[i]!=0;i++)
 
432
    for (size_t j=0;;j++)
 
433
    {
 
434
      if (search[j]==0)
 
435
        return str+i;
 
436
      if (tolowerw(str[i+j])!=tolowerw(search[j]))
 
437
        break;
 
438
    }
 
439
  return NULL;
 
440
}
 
441
 
 
442
 
412
443
#ifndef SFX_MODULE
413
444
wchar* wcslower(wchar *s)
414
445
{
415
446
#ifdef _WIN_ALL
416
 
  CharLowerW(s);
 
447
  CharLower(s);
417
448
#else
418
449
  for (wchar *c=s;*c!=0;c++)
419
450
    *c=towlower(*c);
427
458
wchar* wcsupper(wchar *s)
428
459
{
429
460
#ifdef _WIN_ALL
430
 
  CharUpperW(s);
 
461
  CharUpper(s);
431
462
#else
432
463
  for (wchar *c=s;*c!=0;c++)
433
464
    *c=towupper(*c);
437
468
#endif
438
469
 
439
470
 
 
471
 
 
472
 
440
473
int toupperw(int ch)
441
474
{
442
475
#ifdef _WIN_ALL
443
 
  return (int)CharUpperW((wchar *)ch);
 
476
  // CharUpper is more reliable than towupper in Windows, which seems to be
 
477
  // C locale dependent even in Unicode version. For example, towupper failed
 
478
  // to convert lowercase Russian characters.
 
479
  return (int)CharUpper((wchar *)ch);
444
480
#else
445
481
  return towupper(ch);
446
482
#endif
450
486
int tolowerw(int ch)
451
487
{
452
488
#ifdef _WIN_ALL
453
 
  return (int)CharLowerW((wchar *)ch);
 
489
  // CharLower is more reliable than towlower in Windows.
 
490
  // See comment for towupper above.
 
491
  return (int)CharLower((wchar *)ch);
454
492
#else
455
493
  return towlower(ch);
456
494
#endif
457
495
}
458
496
 
459
497
 
460
 
uint atoiw(const wchar *s)
 
498
int atoiw(const wchar *s)
461
499
{
462
 
  return (uint)atoilw(s);
 
500
  return (int)atoilw(s);
463
501
}
464
502
 
465
503
 
466
 
uint64 atoilw(const wchar *s)
 
504
int64 atoilw(const wchar *s)
467
505
{
468
 
  uint64 n=0;
 
506
  int sign=1;
 
507
  if (*s=='-')
 
508
  {
 
509
    s++;
 
510
    sign=-1;
 
511
  }
 
512
  int64 n=0;
469
513
  while (*s>='0' && *s<='9')
470
514
  {
471
515
    n=n*10+(*s-'0');
472
516
    s++;
473
517
  }
474
 
  return n;
 
518
  return sign*n;
475
519
}
476
520
 
477
521