sizeof(wchar) is changed to 4 (32 bits) to support non BMP unicode characters

This might bring some incompatibilities in the code that expects wchar to be 16 bit, which
  escpecially involves dealing with Win32 (and to lesser extend MacOS) APIs, so if your application
  is doing that, please check all instances of WCHAR (UniChar on MacOS) or even wchar
  especially type casts.

  To support host APIs, char16 is introduced (but there is no 16-bit String varian).

  Use ToSystemCharsetW, FromSystemCharsetW to convert texts to Win32 API.

- Support of drawing non-BMP characters in GUI
- Vastly improved character font replacement code (when drawing characters missing with requested font, replacement font is used)
- Last instances of Win32 ANSI calls (those ending with A) are removed
- UTF handling routines are refactored and their's naming is unified
- RTF is now being able to handle non-BMP characters (RTF is used as clipboard format for RichText)

Other minor changes:

- fixed TryRealloc issue
- improved MemoryCheck
- Removed MemoryAlloc48/MemoryFree48
- In theide Background parsing should less often cause delays in the main thread
This commit is contained in:
Mirek Fidler 2021-12-02 12:03:19 +01:00
parent a6a071a16c
commit 34ff691308
149 changed files with 2373 additions and 1446 deletions

View file

@ -82,7 +82,7 @@ CONSOLE_APP_MAIN
ASSERT(comb == UnicodeDecompose(code));
Vector<dword> h = UnicodeDecompose(code, true);
WString h = UnicodeDecompose(code, true);
if(h.GetCount() > 1) {
DUMP(h);
ASSERT(code == UnicodeCompose(h));

View file

@ -1,103 +1,139 @@
* C:\upp\out\autotest\CLANGx64.Debug.Debug_Full\WStringSerialize.exe 13.10.2021 09:17:22, user: cxl
* C:\upp\out\wchar_autotest\CLANGx64.Debug.Debug_Full\WStringSerialize.exe 13.10.2021 10:00:28, user: cxl
x:
[0] = x
[1] = xx
[2] = xxx
[3] = xxxx
[4] = xxxxx
[5] = xxxxxx
[6] = xxxxxxx
[7] = xxxxxxxx
[8] = xxxxxxxxx
[9] = xxxxxxxxxx
[10] = xxxxxxxxxxx
[11] = xxxxxxxxxxxx
[12] = xxxxxxxxxxxxx
[13] = xxxxxxxxxxxxxx
[14] = xxxxxxxxxxxxxxx
[15] = xxxxxxxxxxxxxxxx
[16] = xxxxxxxxxxxxxxxxx
[17] = xxxxxxxxxxxxxxxxxx
[18] = xxxxxxxxxxxxxxxxxxx
[19] = xxxxxxxxxxxxxxxxxxxx
[20] = xxxxxxxxxxxxxxxxxxxxx
[21] = xxxxxxxxxxxxxxxxxxxxxx
[22] = xxxxxxxxxxxxxxxxxxxxxxx
[23] = xxxxxxxxxxxxxxxxxxxxxxxx
[24] = xxxxxxxxxxxxxxxxxxxxxxxxx
[25] = xxxxxxxxxxxxxxxxxxxxxxxxxx
[26] = xxxxxxxxxxxxxxxxxxxxxxxxxxx
[27] = xxxxxxxxxxxxxxxxxxxxxxxxxxxx
[28] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[29] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[30] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[31] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[32] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[33] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[34] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[35] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[36] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[37] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[38] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[39] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[40] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[41] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[42] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[43] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[44] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[45] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[46] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[47] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[48] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[49] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[50] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[51] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[52] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[53] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[54] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[55] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[56] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[57] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[58] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[59] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[60] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[61] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[62] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[63] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[64] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[65] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[66] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[67] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[68] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[69] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[70] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[71] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[72] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[73] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[74] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[75] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[76] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[77] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[78] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[79] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[80] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[81] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[82] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[83] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[84] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[85] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[86] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[87] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[88] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[89] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[90] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[91] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[92] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[93] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[94] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[95] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[96] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[97] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[98] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[99] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[0] = 0
[1] = 01
[2] = 012
[3] = 0123
[4] = 01234
[5] = 012345
[6] = 0123456
[7] = 01234567
[8] = 012345678
[9] = 0123456789
[10] = 012345678910
[11] = 01234567891011
[12] = 0123456789101112
[13] = 012345678910111213
[14] = 01234567891011121314
[15] = 0123456789101112131415
[16] = 012345678910111213141516
[17] = 01234567891011121314151617
[18] = 0123456789101112131415161718
[19] = 012345678910111213141516171819
[20] = 01234567891011121314151617181920
[21] = 0123456789101112131415161718192021
[22] = 012345678910111213141516171819202122
[23] = 01234567891011121314151617181920212223
[24] = 0123456789101112131415161718192021222324
[25] = 012345678910111213141516171819202122232425
[26] = 01234567891011121314151617181920212223242526
[27] = 0123456789101112131415161718192021222324252627
[28] = 012345678910111213141516171819202122232425262728
[29] = 01234567891011121314151617181920212223242526272829
[30] = 0123456789101112131415161718192021222324252627282930
[31] = 012345678910111213141516171819202122232425262728293031
[32] = 01234567891011121314151617181920212223242526272829303132
[33] = 0123456789101112131415161718192021222324252627282930313233
[34] = 012345678910111213141516171819202122232425262728293031323334
[35] = 01234567891011121314151617181920212223242526272829303132333435
[36] = 0123456789101112131415161718192021222324252627282930313233343536
[37] = 012345678910111213141516171819202122232425262728293031323334353637
[38] = 01234567891011121314151617181920212223242526272829303132333435363738
[39] = 0123456789101112131415161718192021222324252627282930313233343536373839
[40] = 012345678910111213141516171819202122232425262728293031323334353637383940
[41] = 01234567891011121314151617181920212223242526272829303132333435363738394041
[42] = 0123456789101112131415161718192021222324252627282930313233343536373839404142
[43] = 012345678910111213141516171819202122232425262728293031323334353637383940414243
[44] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344
[45] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445
[46] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546
[47] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647
[48] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
[49] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
[50] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
[51] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
[52] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
[53] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
[54] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
[55] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
[56] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
[57] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
[58] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
[59] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
[60] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
[61] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
[62] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
[63] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
[64] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
[65] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
[66] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
[67] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
[68] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
[69] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
[70] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
[71] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
[72] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
[73] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
[74] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
[75] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
[76] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
[77] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
[78] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
[79] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
[80] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
[81] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
[82] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
[83] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
[84] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
[85] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
[86] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
[87] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
[88] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
[89] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
[90] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
[91] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
[92] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
[93] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
[94] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
[95] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
[96] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
[97] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
[98] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
[99] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
[100] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
[101] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
[102] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
[103] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
[104] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
[105] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
[106] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
[107] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
[108] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
[109] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
[110] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
[111] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
[112] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
[113] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
[114] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
[115] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
[116] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
[117] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
[118] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
[119] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
[120] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
[121] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
[122] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
[123] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
[124] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
[125] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
[126] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
[127] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
[128] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
[129] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
[130] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
[131] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
[132] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
[133] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
[134] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
[135] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135

View file

@ -7,6 +7,6 @@ CONSOLE_APP_MAIN
Vector<WString> x;
LoadFromFile(x, GetDataFile("wstring.bin"));
DDUMPC(x);
ASSERT(StoreAsString(x) == LoadDataFile("wstring.bin"));
CheckLogEtalon();
RLOG("================= OK");
}

View file

@ -0,0 +1,25 @@
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_COUT|LOG_FILE);
DDUMP(sizeof(wchar_t));
WString x;
x.Cat(48);
x.Cat(48000);
x.Cat(70000);
std::wstring w = x;
DDUMP(w.size());
WString y = w;
ASSERT(x == y);
DLOG("============= OK");
}

View file

@ -0,0 +1,9 @@
uses
Core;
file
std_wstring.cpp;
mainconfig
"" = "";

View file

@ -0,0 +1,17 @@
#include <Core/Core.h>
using namespace Upp;
// TEST IN RELEASE MODE!
CONSOLE_APP_MAIN
{
for(int q = 5; q < 500*1024*1024; q = q + 1 + q / 10) {
size_t sz = q;
void *ptr = MemoryAllocSz(sz);
DLOG("Requested " << q << ", allocated " << sz << ", GetMemoryBlockSize " << GetMemoryBlockSize(ptr));
if(sz != GetMemoryBlockSize(ptr))
Panic("FAILED!");
MemoryFree(ptr);
}
}

View file

@ -0,0 +1,9 @@
uses
Core;
file
GetMemoryBlockSize.cpp;
mainconfig
"" = "DEBUGCODE";

View file

@ -0,0 +1,17 @@
#include <Core/Core.h>
using namespace Upp;
// TEST IN RELEASE MODE!
CONSOLE_APP_MAIN
{
for(int q = 5; q < 500*1024*1024; q = q + 1 + q / 10) {
size_t sz = q;
void *ptr = MemoryAllocSz(sz);
DLOG("Requested " << q << ", allocated " << sz << ", GetMemoryBlockSize " << GetMemoryBlockSize(ptr));
if(sz != GetMemoryBlockSize(ptr))
Panic("FAILED!");
MemoryFree(ptr);
}
}

View file

@ -0,0 +1,9 @@
uses
Core;
file
MemorySize.cpp;
mainconfig
"" = "DEBUGCODE";

View file

@ -0,0 +1,13 @@
#include <Core/Core.h>
using namespace Upp;
Vector<ValueMap> g_turbine_data; // one for turbine*scenario
CONSOLE_APP_MAIN
{
String data = LoadFile("D:/xxx/td.bin");
RDUMP(data.GetCount());
LoadFromString(g_turbine_data, data);
RDUMP(g_turbine_data);
}

View file

@ -0,0 +1,9 @@
uses
Core;
file
WeirdBug.cpp;
mainconfig
"" = "DEBUGCODE";

View file

@ -34,10 +34,11 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon
double sina, cosa;
Draw::SinCos(angle, sina, cosa);
Size offset;
::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, (const WCHAR *)text, n, dx);
::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL,
ToSystemCharsetW(text), n, dx);
}
else
::ExtTextOutW(handle, x, y + ascent, 0, NULL, (const WCHAR *)text,
::ExtTextOutW(handle, x, y + ascent, 0, NULL, ToSystemCharsetW(text),
n, dx);
::SelectObject(handle, orgfont);
}

View file

@ -78,7 +78,7 @@ void TopWindow::SyncTitle0()
#ifndef PLATFORM_WINCE
if(hwnd)
if(IsWindowUnicode(hwnd))
::SetWindowTextW(hwnd, (const WCHAR*)~title);
::SetWindowTextW(hwnd, ToSystemCharsetW(title));
else
#endif
::SetWindowText(hwnd, ToSystemCharset(title.ToString()));

View file

@ -2,7 +2,7 @@ description "GLCtrl widget example\377";
uses
GLCtrl,
CodeEditor;
CtrlLib;
file
main.cpp;

View file

@ -1,21 +1,31 @@
#include "TypeReader.h"
#define LLOG(x) // LOG(x)
#define LDUMP(x) // LLOG(#x << " = " << x);
#define LDUMP(x) // LOG(#x << " = " << x);
int FontTypeReader::Error()
{
throw Fail(); return 0;
}
int FontTypeReader::Error()
{
throw Fail(); return 0;
}
int FontTypeReader::Peek8(const char *s)
{
return s + 1 < font.end() ? (byte)*s : Error();
return s + 1 < data.end() ? (byte)*s : Error();
}
int FontTypeReader::Peek16(const char *s)
{
return s + 2 < font.end() ? Peek16be(s) : Error();
return s + 2 < data.end() ? Peek16be(s) : Error();
}
int FontTypeReader::Peek32(const char *s)
{
return s + 4 < font.end() ? Peek32be(s) : Error();
return s + 4 < data.end() ? Peek32be(s) : Error();
}
int FontTypeReader::Peek8(const char *s, int i)
@ -54,45 +64,11 @@ int FontTypeReader::Read32(const char *&s)
return q;
}
const char *FontTypeReader::Seek(const char *tab, int& len)
{
ASSERT(strlen(tab) == 4);
int q = table.Find(tab);
if(q < 0)
Error();
len = table[q].length;
return ~font + table[q].offset;
}
const char *FontTypeReader::Seek(const char *tab)
{
int dummy;
return Seek(tab, dummy);
}
bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck)
bool FontTypeReader::Open(Font font, bool symbol, bool justcheck)
{
// DDUMP(fnt.GetCount());
try {
int i;
table.Clear();
font = fnt;
const char *s = fnt;
int q = Read32(s);
if(q != 0x74727565 && q != 0x00010000)
Error();
int n = Read16(s);
s += 6;
while(n--) {
// DDUMP(String(s, 4));
Table& t = table.Add(String(s, 4));
s += 8; // skip checksum
t.offset = Read32(s);
// DDUMP(t.offset);
t.length = Read32(s);
// DDUMP(t.length);
// DLOG("----");
}
#if 0
for(i = 0; i < table.GetCount(); i++)
LLOG("table: " << table.GetKey(i) << " offset: " << table[i].offset << " length: " << table[i].length);
@ -124,35 +100,40 @@ bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck)
<< ", offset: " << glyphinfo[i].offset << ", size: " << glyphinfo[i].size);
#endif
data = font.GetData("OS/2");
panose.Clear();
if(data.GetCount() > 32 + 10)
panose = data.Mid(32, 10);
bool found = false;
data = font.GetData("cmap");
for(int pass = 0; pass < 2; pass++) {
const char *s = Seek("cmap");
const char *p = s;
const char *p = data;
// LOGHEXDUMP(p, 256);
p += 2;
n = Read16(p);
int n = Read16(p);
// DDUMP(n);
while(n--) {
int pid = Read16(p);
int psid = Read16(p);
int offset = Read32(p);
if(offset < 0 || offset > font.GetLength())
if(offset < 0 || offset > data.GetCount())
Error();
int format = Peek16(s + offset);
int format = Peek16(~data + offset);
LLOG("cmap pid: " << pid << " psid: " << psid << " format: " << format);
//Test with Symbol font !!!; improve - Unicode first, 256 bytes later..., symbol...
if(symbol) {
if(pid == 1 && psid == 0 && Peek16(s + offset) == 0) {
if(pid == 1 && psid == 0 && Peek16(~data + offset) == 0) {
LLOG("Reading symbol table");
p = s + offset + 6;
p = ~data + offset + 6;
for(int i = 0; i < 256; i++);
//SetGlyph(i, (byte)p[i]);
goto done;
}
}
else
if(pid == 3 && psid == 10 && format == 12 && pass == 0) {
const char *p = s + offset;
if((pid == 3 && psid == 10) || (pid == 0 && psid == 4) && format == 12 && pass == 0) {
const char *p = ~data + offset;
int ngroups = Peek32(p + 12);
p += 16; // pointer to groups table
for(int i = 0; i < ngroups; i++) {
@ -163,8 +144,8 @@ bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck)
goto done;
}
else
if(pid == 3 && psid == 1 && format == 4 && pass == 1) {
const char *p = s + offset;
if((pid == 3 && psid == 1) || (pid == 0 && psid == 3) && format == 4 && pass == 1) {
const char *p = ~data + offset;
int n = Peek16(p + 6) >> 1;
LLOG("Found UNICODE encoding, offset " << offset << ", segments " << n);
const char *seg_end = p + 14;
@ -199,35 +180,38 @@ bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck)
}
}
}
done:
int len;
const char *strings = Seek("name", len);
s = strings + 2;
int count = Read16(s);
strings += (word)Read16(s);
for(int i = 0; i < count; i++) {
int platform = Read16(s);
s += 4;
if(Read16(s) == 6) {
int len = Read16(s);
int offset = Read16(s);
if(platform == 1)
ps_name = String(strings + offset, len);
else {
s = strings + offset;
len >>= 1;
while(len--)
ps_name.Cat(Read16(s));
done:;
#if 0
String names = font.GetData("name");
if(names.GetCount()) {
const char *strings = names;
const char *s = strings + 2;
int count = Read16(s);
strings += (word)Read16(s);
for(int i = 0; i < count; i++) {
int platform = Read16(s);
s += 4;
if(Read16(s) == 6) {
int len = Read16(s);
int offset = Read16(s);
if(platform == 1)
ps_name = String(strings + offset, len);
else {
s = strings + offset;
len >>= 1;
while(len--)
ps_name.Cat(Read16(s));
}
break;
}
break;
s += 4;
}
s += 4;
}
DDUMP(ps_name);
#endif
}
catch(Fail) {
DLOG("ERROR");
LLOG("ERROR");
return false;
}

View file

@ -6,7 +6,7 @@
using namespace Upp;
class FontTypeReader {
String font;
String data;
struct Table : Moveable<Table> {
int offset;
@ -15,7 +15,7 @@ class FontTypeReader {
VectorMap<String, Table> table;
struct Fail {};
static int Error() { throw Fail(); return 0; }
static int Error();
int Peek8(const char *s);
int Peek16(const char *s);
@ -27,17 +27,14 @@ class FontTypeReader {
int Read16(const char *&s);
int Read32(const char *&s);
const char *Seek(const char *tab, int& len);
const char *Seek(const char *tab);
// void Seek(const char *tab, TTFStreamIn& s);
String GetTable(const char *tab);
public:
String ps_name;
Array<Tuple<int, int>> ranges;
bool Open(const String& fnt, bool symbol = false, bool justcheck = false);
String panose;
bool Open(Font font, bool symbol = false, bool justcheck = false);
};
#endif

View file

@ -8,6 +8,8 @@ using namespace Upp;
#define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
#ifdef PLATFORM_WIN32
namespace Upp {
HFONT GetWin32Font(Font fnt, int angle);
};
@ -34,20 +36,70 @@ String GetFontDataSys(Font font, dword table)
return r;
}
#endif
String ReadFontTable(Stream& in, const char *table, int fonti = 0)
{
in.Seek(0);
int q = in.Get32be();
if(q == 0x74746366) { // true type collection
in.Get32(); // skip major/minor version
int nfonts = in.Get32be();
if(fonti >= nfonts)
return Null;
in.SeekCur(fonti * 4);
int offset = in.Get32be();
if(offset < 0 || offset >= in.GetSize())
return Null;
in.Seek(offset);
q = in.Get32be();
}
if(q != 0x74727565 && q != 0x00010000)
return Null;
int n = in.Get16be();
in.Get32();
in.Get16();
while(n--) {
if(in.IsError() || in.IsEof()) return Null;
String tab = in.Get(4);
in.Get32();
int offset = in.Get32be();
int length = in.Get32be();
if(tab == table) {
if(offset < 0 || length < 0 || offset + length > in.GetSize())
return Null;
in.Seek(offset);
return in.Get(length);
}
}
return Null;
}
GUI_APP_MAIN
{
// FileIn in("C:/Windows/Fonts/arial.ttf");
/*
FileIn in("D:\\xxx\\msyh.ttc");
DDUMPHEX(ReadFontTable(in, "cmap", 0));
DDUMPHEX(ReadFontTable(in, "cmap", 1));
DDUMPHEX(ReadFontTable(in, "cmap", 2));
return;
*/
#if 0
// Font font(Font::FindFaceNameIndex("Microsoft JhengHei"), 20);
Font font = StdFont();
Font font(Font::FindFaceNameIndex("Noto Serif CJK KR"), 20);
// Font font = Roman(20);
// SaveFile("d:/xxx/font.bin", GetFontDataSys(font, 0));
String cmap = GetFontDataSys(font, CMAP);
LOGHEXDUMP(~cmap, 256);
// String cmap = GetFontDataSys(font, CMAP);
// LOGHEXDUMP(~cmap, 256);
FontTypeReader r;
// r.Open(Arial(20).GetData());
r.Open(font.GetData());
DDUMP(font.GetFaceName());
r.Open(font);
DDUMPHEX(r.panose);
return;
@ -55,34 +107,52 @@ GUI_APP_MAIN
#endif
Progress pi;
pi.SetTotal(Font::GetFaceCount());
for(int i = 0; i < Font::GetFaceCount(); i++) {
Vector<String> name;
for(int i = 0; i < Font::GetFaceCount(); i++)
name.Add(Font::GetFaceName(i));
for(int i : GetSortOrder(name)) {
String f = Font::GetFaceName(i);
pi.SetText(f);
if(pi.StepCanceled())
break;
Font fnt;
fnt.FaceName(f);
DLOG("===========");
DDUMP(f);
FontTypeReader r;
// r.Open(Arial(20).GetData());
r.Open(fnt.GetData());
Sort(r.ranges, [](Tuple<int, int> a, Tuple<int, int> b) { return a.a < b.a; });
DDUMP(r.ranges);
while(r.ranges.GetCount() > 8) {
int mini = 0;
int mind = INT_MAX;
for(int i = 0; i < r.ranges.GetCount() - 1; i++) {
int d = r.ranges[i + 1].a - r.ranges[i].b;
if(d < mind) {
mind = d;
mini = i;
r.Open(fnt);
if(r.panose.GetCount() == 10) {
dword h[8] = {0};
for(auto r : r.ranges) {
for(int c = r.a; c <= r.b; c++) {
c = max(c, 0);
if(c < 2048)
h[0] |= 0x80000000 >> (c >> 6);
else {
int bi = clamp(c - 2048, 0, 7*32*1024 - 1) >> 10;
ASSERT((bi >> 5) + 1 < 8);
h[(bi >> 5) + 1] |= 0x80000000 >> (bi & 31);
}
}
}
r.ranges[mini].b = r.ranges[mini + 1].b;
r.ranges.Remove(mini + 1);
String l;
l << "{ " << AsCString(f);
l << ", { ";
bool first = true;
for(int h : r.panose) {
if(first)
first = false;
else
l << ",";
l << h;
}
l << " }, { ";
for(int i = 0; i < 8; i++) {
if(i) l << ",";
l << Format("0x%08x", (int)h[i]);
}
l << " } },";
LOG(l);
}
DDUMP(r.ranges);
}
// r.Open(Font(Font::FindFaceNameIndex("Segoe UI Emoji"), 20).GetData());

View file

@ -218,8 +218,8 @@ bool CodeEditor::RegExpFind(int64 pos, bool block)
for(int i = 0; i < regex.GetCount(); i++)
SetFound(i, WILDANY, regex.GetString(i).ToWString());
int off = regex.GetOffset();
int len = utf8len(~ln + off, regex.GetLength());
pos = GetPos64(line, utf8len(~ln, off) + (int)pos);
int len = Utf32Len(~ln + off, regex.GetLength());
pos = GetPos64(line, Utf32Len(~ln, off) + (int)pos);
foundtext = GetW(pos, len);
if(!block) {
foundsel = true;

View file

@ -59,7 +59,7 @@ String GetHomeDirectory() {
String GetEnv(const char *id)
{
return WString(_wgetenv(WString(id))).ToString();
return WString(_wgetenv(ToSystemCharsetW(id))).ToString();
}
String GetExeFilePath()
@ -500,27 +500,27 @@ void AppInitEnvironment__()
int nArgs;
LPWSTR *szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
if(szArglist) {
strcpy(Argv0__, WString(szArglist[0]).ToString());
strcpy(Argv0__, FromSystemCharsetW(szArglist[0]));
for(int i = 1; i < nArgs; i++)
coreCmdLine__().Add(szArglist[i]);
coreCmdLine__().Add(FromSystemCharsetW(szArglist[i]).ToWString());
LocalFree(szArglist);
}
wchar *env = GetEnvironmentStringsW();
for(wchar *ptr = env; *ptr; ptr++)
WCHAR *env = GetEnvironmentStringsW();
for(WCHAR *ptr = env; *ptr; ptr++)
{
const wchar *b = ptr;
const WCHAR *b = ptr;
if(*ptr)
ptr++;
while(*ptr && *ptr != '=')
ptr++;
WString varname(b, ptr);
WString varname = ToUtf32(b, int(ptr - b));
if(*ptr)
ptr++;
b = ptr;
while(*ptr)
ptr++;
EnvMap().GetAdd(ToUpper(varname)) = WString(b, ptr);
EnvMap().GetAdd(ToUpper(varname)) = ToUtf32(b, int(ptr - b));
}
FreeEnvironmentStringsW(env);
@ -556,16 +556,16 @@ void LaunchWebBrowser(const String& url)
#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE)
static auxthread_t auxthread__ sShellExecuteOpen(void *str)
{
ShellExecuteW(NULL, L"open", (wchar *)str, NULL, L".", SW_SHOWDEFAULT);
ShellExecuteW(NULL, L"open", (WCHAR *)str, NULL, L".", SW_SHOWDEFAULT);
free(str);
return 0;
}
void LaunchWebBrowser(const String& url)
{
WString wurl = ToSystemCharsetW(url);
Vector<WCHAR> wurl = ToSystemCharsetW(url);
if ((int64)(ShellExecuteW(NULL, L"open", wurl, NULL, L".", SW_SHOWDEFAULT)) <= 32) {
int l = sizeof(wchar) * wurl.GetLength() + 1;
int l = sizeof(wchar) * wurl.GetCount() + 1;
char *curl = (char *)malloc(l);
memcpy(curl, wurl, l);
StartAuxThread(sShellExecuteOpen, curl);
@ -619,27 +619,29 @@ String LoadDataFile(const char *filename)
String GetComputerName()
{
char temp[256];
*temp = 0;
#if defined(PLATFORM_WIN32)
WCHAR temp[256];
*temp = 0;
dword w = 255;
::GetComputerNameA(temp, &w);
::GetComputerNameW(temp, &w);
#else
char temp[256];
gethostname(temp, sizeof(temp));
#endif
return FromSystemCharset(temp);
return temp;
}
String GetUserName()
{
char temp[256];
*temp = 0;
#if defined(PLATFORM_WIN32)
WCHAR temp[256];
*temp = 0;
dword w = 255;
::GetUserNameA(temp, &w);
return FromSystemCharset(temp);
::GetUserNameW(temp, &w);
return temp;
#else
return Nvl(GetEnv("USER"), "boot");
char temp[256];
return Nvl(GetEnv("USER"), "root");
#endif
}
@ -661,9 +663,9 @@ String GetDesktopManager()
String GetShellFolder(int clsid)
{
wchar path[MAX_PATH];
WCHAR path[MAX_PATH];
if(SHGetFolderPathW(NULL, clsid, NULL, /*SHGFP_TYPE_CURRENT*/0, path) == S_OK)
return FromUnicodeBuffer(path);
return FromSystemCharsetW(path);
return Null;
}
@ -691,7 +693,7 @@ String GetDownloadFolder()
if(SHGetKnownFolderPath) {
PWSTR path = NULL;
if(SHGetKnownFolderPath(&MY_FOLDERID_Downloads, 0, NULL, &path) == S_OK && path) {
String s = FromUnicodeBuffer(path, wstrlen(path));
String s = FromSystemCharsetW(path);
CoTaskMemFree(path);
return s;
}

View file

@ -35,7 +35,7 @@ static void sLoadBom(Stream& in, String *t, WString *wt, byte def_charset)
byte *h = (byte *)&header;
if(h[0] == 0xef && h[1] == 0xbb && c == 0xbf) {
if(wt)
*wt = FromUtf8(LoadStream(in));
*wt = ToUtf32(LoadStream(in));
else
*t = ToCharset(CHARSET_DEFAULT, LoadStream(in), CHARSET_UTF8);
return;

View file

@ -1998,12 +1998,6 @@ int ToAscii(int c, byte charset)
return cs.FromUnicode(ToAscii(cs.ToUnicode(c)));
}
word UnicodeCombine(word chr, word combine)
{
dword h[2] = { chr, combine };
return (word)UnicodeCompose(h, 2);
}
void ToUpper(char *t, const char *s, int len, byte charset)
{
charset = ResolveCharset(charset);
@ -2050,7 +2044,7 @@ WString ToUnicode(const char *src, int l, byte charset)
{
charset = ResolveCharset(charset);
if(charset == CHARSET_UTF8)
return FromUtf8(src, l);
return ToUtf32(src, l);
WStringBuffer result(l);
ToUnicode(result, src, l, charset);
return WString(result);
@ -2073,7 +2067,7 @@ String FromUnicodeBuffer(const wchar *src, int len, byte charset, int defchar)
String FromUnicodeBuffer(const wchar *src)
{
return FromUnicodeBuffer(src, wstrlen(src));
return FromUnicodeBuffer(src, strlen__(src));
}
String FromUnicode(const WString& src, byte charset, int defchar)
@ -2089,7 +2083,7 @@ String ToCharset(byte charset, const String& src, byte scharset, int def)
return src;
int slen = src.GetLength();
if(scharset == CHARSET_UTF8)
return FromUnicode(FromUtf8(src, slen), charset, def);
return FromUnicode(ToUtf32(src, slen), charset, def);
if(charset == CHARSET_UTF8)
return ToUtf8(ToUnicode(src, scharset));
StringBuffer result(slen);
@ -2161,7 +2155,7 @@ String ToUpper(const char *s, byte charset)
{
charset = ResolveCharset(charset);
if(charset == CHARSET_UTF8)
return ToUtf8(ToUpper(FromUtf8(s)));
return ToUtf8(ToUpper(ToUtf32(s)));
int l = (int)strlen(s);
StringBuffer r(l);
ToUpper(r, s, l, charset);
@ -2172,7 +2166,7 @@ String ToLower(const char *s, byte charset)
{
charset = ResolveCharset(charset);
if(charset == CHARSET_UTF8)
return ToUtf8(ToLower(FromUtf8(s)));
return ToUtf8(ToLower(ToUtf32(s)));
int l = (int)strlen(s);
StringBuffer r(l);
ToLower(r, s, l, charset);
@ -2183,7 +2177,7 @@ String ToAscii(const char *s, byte charset)
{
charset = ResolveCharset(charset);
if(charset == CHARSET_UTF8)
return ToUtf8(ToAscii(FromUtf8(s)));
return ToUtf8(ToAscii(ToUtf32(s)));
int l = (int)strlen(s);
StringBuffer r(l);
ToAscii(r, s, l, charset);
@ -2194,7 +2188,7 @@ String ToUpper(const String& s, byte charset)
{
charset = ResolveCharset(charset);
if(charset == CHARSET_UTF8)
return ToUtf8(ToUpper(FromUtf8(s)));
return ToUtf8(ToUpper(ToUtf32(s)));
int l = s.GetLength();
StringBuffer r(l);
ToUpper(r, s, l, charset);
@ -2205,7 +2199,7 @@ String ToLower(const String& s, byte charset)
{
charset = ResolveCharset(charset);
if(charset == CHARSET_UTF8)
return ToUtf8(ToLower(FromUtf8(s)));
return ToUtf8(ToLower(ToUtf32(s)));
int l = s.GetLength();
StringBuffer r(l);
ToLower(r, s, l, charset);

View file

@ -8,6 +8,7 @@ enum {
#undef CHRSET_
#define CHARSET_TOASCII 253
#define CHARSET_UTF32 254 // auxilary
#define CHARSET_UTF8 255
#define CHARSET_UNICODE 255
@ -23,86 +24,83 @@ enum {
#include "Utf.hpp"
int strlen32(const dword *s);
inline bool IsUtf8Lead(int c) { return (c & 0xc0) != 0x80; }
inline bool IsUtf8Lead(int c)
{
return (c & 0xc0) != 0x80;
}
wchar ReadSurrogatePair(const char16 *s, const char16 *lim);
dword FetchUtf8(const char *&s, const char *lim, bool& ok);
inline dword FetchUtf8(const char *&s, const char *lim) { bool ok; return FetchUtf8(s, lim, ok); }
wchar FetchUtf8(const char *&s, const char *lim, bool& ok);
inline wchar FetchUtf8(const char *&s, const char *lim) { bool ok; return FetchUtf8(s, lim, ok); }
dword FetchUtf8(const char *&s, bool& ok);
inline wchar FetchUtf8(const char *&s) { bool ok; return FetchUtf8(s, ok); }
bool CheckUtf8(const char *s, int len);
inline bool CheckUtf8(const char *s) { return CheckUtf8(s, (int)strlen(s)); }
inline bool CheckUtf8(const char *s) { return CheckUtf8(s, (int)strlen8(s)); }
inline bool CheckUtf8(const String& s) { return CheckUtf8(~s, s.GetCount()); }
int Utf8Len(const dword *s, int len);
inline int Utf8Len(const dword *s) { return Utf8Len(s, strlen32(s)); }
inline int Utf8Len(const Vector<dword>& s) { return Utf8Len(s, s.GetCount()); }
inline int Utf8Len(dword code) { return Utf8Len(&code, 1); }
int Utf8Len(const wchar *s, int len);
inline int Utf8Len(const wchar *s) { return Utf8Len(s, wstrlen(s)); }
inline int Utf8Len(const wchar *s) { return Utf8Len(s, strlen32(s)); }
inline int Utf8Len(wchar code) { return Utf8Len(&code, 1); }
inline int Utf8Len(const WString& s) { return Utf8Len(~s, s.GetCount()); }
void ToUtf8(char *t, const dword *s, int len);
String ToUtf8(const dword *s, int len);
inline String ToUtf8(const dword *s) { return ToUtf8(s, strlen32(s)); }
inline String ToUtf8(const Vector<dword>& s) { return ToUtf8(s, s.GetCount()); }
inline String ToUtf8(dword code) { return ToUtf8(&code, 1); }
int Utf8Len(const char16 *s, int len);
inline int Utf8Len(const char16 *s) { return Utf8Len(s, strlen16(s)); }
inline int Utf8Len(const Vector<char16>& s) { return Utf8Len(s, s.GetCount()); }
void ToUtf8(char *t, const wchar *s, int len);
String ToUtf8(const wchar *s, int len);
inline String ToUtf8(const wchar *s) { return ToUtf8(s, wstrlen(s)); }
inline String ToUtf8(const wchar *s) { return ToUtf8(s, strlen32(s)); }
inline String ToUtf8(wchar code) { return ToUtf8(&code, 1); }
inline String ToUtf8(const WString& s) { return ToUtf8(~s, s.GetCount()); }
int Utf16Len(const dword *s, int len);
inline int Utf16Len(const dword *s) { return Utf16Len(s, strlen32(s)); }
inline int Utf16Len(const Vector<dword>& s) { return Utf16Len(s, s.GetCount()); }
inline int Utf16Len(dword code) { return Utf16Len(&code, 1); }
void ToUtf8(char *t, const char16 *s, int len);
String ToUtf8(const char16 *s, int len);
inline String ToUtf8(const char16 *s) { return ToUtf8(s, strlen16(s)); }
inline String ToUtf8(const Vector<char16>& s) { return ToUtf8(s, s.GetCount()); }
int Utf16Len(const wchar *s, int len);
inline int Utf16Len(const wchar *s) { return Utf16Len(s, strlen32(s)); }
inline int Utf16Len(const WString& s) { return Utf16Len(s, s.GetCount()); }
inline int Utf16Len(wchar code) { return Utf16Len(&code, 1); }
int Utf16Len(const char *s, int len);
inline int Utf16Len(const char *s) { return Utf16Len(s, (int)strlen(s)); }
inline int Utf16Len(const char *s) { return Utf16Len(s, (int)strlen8(s)); }
inline int Utf16Len(const String& s) { return Utf16Len(~s, s.GetCount()); }
void ToUtf16(wchar *t, const dword *s, int len);
WString ToUtf16(const dword *s, int len);
inline WString ToUtf16(const dword *s) { return ToUtf16(s, strlen32(s)); }
inline WString ToUtf16(const Vector<dword>& s) { return ToUtf16(s, s.GetCount()); }
inline WString ToUtf16(dword code) { return ToUtf16(&code, 1); }
int ToUtf16(char16 *t, const wchar *s, int len);
Vector<char16> ToUtf16(const wchar *s, int len);
inline Vector<char16> ToUtf16(const wchar *s) { return ToUtf16(s, strlen32(s)); }
inline Vector<char16> ToUtf16(const WString& s) { return ToUtf16(s, s.GetCount()); }
inline Vector<char16> ToUtf16(wchar code) { return ToUtf16(&code, 1); }
void ToUtf16(wchar *t, const char *s, int len);
WString ToUtf16(const char *s, int len);
inline WString ToUtf16(const char *s) { return ToUtf16(s, (int)strlen(s)); }
inline WString ToUtf16(const String& s) { return ToUtf16(~s, s.GetCount()); }
int ToUtf16(char16 *t, const char *s, int len);
Vector<char16> ToUtf16(const char *s, int len);
inline Vector<char16> ToUtf16(const char *s) { return ToUtf16(s, (int)strlen8(s)); }
inline Vector<char16> ToUtf16(const String& s) { return ToUtf16(~s, s.GetCount()); }
int Utf32Len(const wchar *s, int len);
inline int Utf32Len(const wchar *s) { return Utf32Len(s, wstrlen(s)); }
inline int Utf32Len(const WString& s) { return Utf32Len(~s, s.GetCount()); }
int Utf32Len(const char16 *s, int len);
inline int Utf32Len(const char16 *s) { return Utf32Len(s, strlen16(s)); }
inline int Utf32Len(const Vector<char16>& s) { return Utf32Len(s, s.GetCount()); }
int Utf32Len(const char *s, int len);
inline int Utf32Len(const char *s) { return Utf32Len(s, (int)strlen(s)); }
inline int Utf32Len(const char *s) { return Utf32Len(s, (int)strlen8(s)); }
inline int Utf32Len(const String& s) { return Utf32Len(~s, s.GetCount()); }
dword ReadSurrogatePair(const wchar *s, const wchar *lim);
void ToUtf32(wchar *t, const char16 *s, int len);
WString ToUtf32(const char16 *s, int len);
inline WString ToUtf32(const char16 *s) { return ToUtf32(s, strlen16(s)); }
inline WString ToUtf32(const Vector<char16>& s) { return ToUtf32(s, s.GetCount()); }
void ToUtf32(dword *t, const wchar *s, int len);
Vector<dword> ToUtf32(const wchar *s, int len);
inline Vector<dword> ToUtf32(const wchar *s) { return ToUtf32(s, wstrlen(s)); }
inline Vector<dword> ToUtf32(const WString& s) { return ToUtf32(~s, s.GetCount()); }
void ToUtf32(dword *t, const char *s, int len);
Vector<dword> ToUtf32(const char *s, int len);
inline Vector<dword> ToUtf32(const char *s) { return ToUtf32(s, (int)strlen(s)); }
inline Vector<dword> ToUtf32(const String& s) { return ToUtf32(~s, s.GetCount()); }
void ToUtf32(wchar *t, const char *s, int len);
WString ToUtf32(const char *s, int len);
inline WString ToUtf32(const char *s) { return ToUtf32(s, (int)strlen8(s)); }
inline WString ToUtf32(const String& s) { return ToUtf32(~s, s.GetCount()); }
enum { MAX_DECOMPOSED = 18 };
int UnicodeDecompose(dword codepoint, dword t[MAX_DECOMPOSED], bool only_canonical = false);
Vector<dword> UnicodeDecompose(dword codepoint, bool only_canonical = false);
dword UnicodeCompose(const dword *t, int count);
inline dword UnicodeCompose(const Vector<dword>& t) { return UnicodeCompose(t, t.GetCount()); }
int UnicodeDecompose(wchar codepoint, wchar t[MAX_DECOMPOSED], bool only_canonical = false);
WString UnicodeDecompose(wchar codepoint, bool only_canonical = false);
wchar UnicodeCompose(const WString& t);
void SetDefaultCharset(byte charset);
byte GetDefaultCharset();
@ -127,62 +125,62 @@ extern byte unicode_fast_info__[2048];
extern byte unicode_fast_upper_ascii__[];
extern byte unicode_fast_lower_ascii__[];
dword ToUpperRest_(dword c);
dword ToLowerRest_(dword c);
char ToAsciiRest_(dword c);
bool IsRTL_(dword c);
bool IsMark_(dword c);
bool IsLetter_(dword c);
bool IsUpper_(dword c);
bool IsLower_(dword c);
wchar ToUpperRest_(wchar c);
wchar ToLowerRest_(wchar c);
char ToAsciiRest_(wchar c);
bool IsRTL_(wchar c);
bool IsMark_(wchar c);
bool IsLetter_(wchar c);
bool IsUpper_(wchar c);
bool IsLower_(wchar c);
inline dword ToUpper(dword c) { return c < 2048 ? unicode_fast_upper__[c] : ToUpperRest_(c); }
inline dword ToLower(dword c) { return c < 2048 ? unicode_fast_lower__[c] : ToLowerRest_(c); }
inline char ToAscii(dword c) { return c < 2048 ? unicode_fast_ascii__[c] : ToAsciiRest_(c); }
inline char ToUpperAscii(dword c){ return c < 2048 ? unicode_fast_upper_ascii__[c] : (char)ToUpper(ToAsciiRest_(c)); }
inline char ToLowerAscii(dword c){ return c < 2048 ? unicode_fast_lower_ascii__[c] : (char)ToLower(ToAsciiRest_(c)); }
inline bool IsLower(dword c) { return c < 2048 ? unicode_fast_info__[c] & 1 : IsLower_(c); }
inline bool IsUpper(dword c) { return c < 2048 ? unicode_fast_info__[c] & 2 : IsUpper_(c); }
inline bool IsLetter(dword c) { return c < 2048 ? unicode_fast_info__[c] & 4 : IsLetter_(c); }
inline wchar ToUpper(wchar c) { return c < 2048 ? unicode_fast_upper__[c] : ToUpperRest_(c); }
inline wchar ToLower(wchar c) { return c < 2048 ? unicode_fast_lower__[c] : ToLowerRest_(c); }
inline char ToAscii(wchar c) { return c < 2048 ? unicode_fast_ascii__[c] : ToAsciiRest_(c); }
inline char ToUpperAscii(wchar c){ return c < 2048 ? unicode_fast_upper_ascii__[c] : (char)ToUpper(ToAsciiRest_(c)); }
inline char ToLowerAscii(wchar c){ return c < 2048 ? unicode_fast_lower_ascii__[c] : (char)ToLower(ToAsciiRest_(c)); }
inline bool IsLower(wchar c) { return c < 2048 ? unicode_fast_info__[c] & 1 : IsLower_(c); }
inline bool IsUpper(wchar c) { return c < 2048 ? unicode_fast_info__[c] & 2 : IsUpper_(c); }
inline bool IsLetter(wchar c) { return c < 2048 ? unicode_fast_info__[c] & 4 : IsLetter_(c); }
inline bool IsRTL(dword c) { return (dword)c >= 1470 && IsRTL_(c); }
inline bool IsMark(dword c) { return c < 0x300 ? false : c <= 0x36f ? true : IsMark_(c); }
inline bool IsRTL(wchar c) { return (wchar)c >= 1470 && IsRTL_(c); }
inline bool IsMark(wchar c) { return c < 0x300 ? false : c <= 0x36f ? true : IsMark_(c); }
inline bool IsLetter(int c) { return IsLetter((dword) c); }
inline bool IsUpper(int c) { return IsUpper((dword) c); }
inline bool IsLower(int c) { return IsLower((dword) c); }
inline int ToUpper(int c) { return ToUpper((dword) c); }
inline int ToLower(int c) { return ToLower((dword) c); }
inline char ToAscii(int c) { return ToAscii((dword) c); }
inline char ToUpperAscii(int c) { return ToUpperAscii((dword) c); }
inline char ToLowerAscii(int c) { return ToUpperAscii((dword) c); }
inline bool IsLetter(int c) { return IsLetter((wchar) c); }
inline bool IsUpper(int c) { return IsUpper((wchar) c); }
inline bool IsLower(int c) { return IsLower((wchar) c); }
inline int ToUpper(int c) { return ToUpper((wchar) c); }
inline int ToLower(int c) { return ToLower((wchar) c); }
inline char ToAscii(int c) { return ToAscii((wchar) c); }
inline char ToUpperAscii(int c) { return ToUpperAscii((wchar) c); }
inline char ToLowerAscii(int c) { return ToUpperAscii((wchar) c); }
inline bool IsLetter(char c) { return IsLetter((dword)(byte) c); }
inline bool IsUpper(char c) { return IsUpper((dword)(byte) c); }
inline bool IsLower(char c) { return IsLower((dword)(byte) c); }
inline dword ToUpper(char c) { return ToUpper((dword)(byte) c); }
inline dword ToLower(char c) { return ToLower((dword)(byte) c); }
inline char ToAscii(char c) { return ToAscii((dword)(byte) c); }
inline char ToUpperAscii(char c) { return ToUpperAscii((dword)(byte) c); }
inline char ToLowerAscii(char c) { return ToLowerAscii((dword)(byte) c); }
inline bool IsLetter(char c) { return IsLetter((wchar)(byte) c); }
inline bool IsUpper(char c) { return IsUpper((wchar)(byte) c); }
inline bool IsLower(char c) { return IsLower((wchar)(byte) c); }
inline wchar ToUpper(char c) { return ToUpper((wchar)(byte) c); }
inline wchar ToLower(char c) { return ToLower((wchar)(byte) c); }
inline char ToAscii(char c) { return ToAscii((wchar)(byte) c); }
inline char ToUpperAscii(char c) { return ToUpperAscii((wchar)(byte) c); }
inline char ToLowerAscii(char c) { return ToLowerAscii((wchar)(byte) c); }
inline bool IsLetter(signed char c) { return IsLetter((dword)(byte) c); }
inline bool IsUpper(signed char c) { return IsUpper((dword)(byte) c); }
inline bool IsLower(signed char c) { return IsLower((dword)(byte) c); }
inline dword ToUpper(signed char c) { return ToUpper((dword)(byte) c); }
inline dword ToLower(signed char c) { return ToLower((dword)(byte) c); }
inline char ToAscii(signed char c) { return ToAscii((dword)(byte) c); }
inline char ToUpperAscii(signed char c) { return ToUpperAscii((dword)(byte) c); }
inline char ToLowerAscii(signed char c) { return ToLowerAscii((dword)(byte) c); }
inline bool IsLetter(signed char c) { return IsLetter((wchar)(byte) c); }
inline bool IsUpper(signed char c) { return IsUpper((wchar)(byte) c); }
inline bool IsLower(signed char c) { return IsLower((wchar)(byte) c); }
inline wchar ToUpper(signed char c) { return ToUpper((wchar)(byte) c); }
inline wchar ToLower(signed char c) { return ToLower((wchar)(byte) c); }
inline char ToAscii(signed char c) { return ToAscii((wchar)(byte) c); }
inline char ToUpperAscii(signed char c) { return ToUpperAscii((wchar)(byte) c); }
inline char ToLowerAscii(signed char c) { return ToLowerAscii((wchar)(byte) c); }
inline bool IsLetter(wchar c) { return IsLetter((dword) c); }
inline bool IsUpper(wchar c) { return IsUpper((dword) c); }
inline bool IsLower(wchar c) { return IsLower((dword) c); }
inline dword ToUpper(wchar c) { return ToUpper((dword) c); }
inline dword ToLower(wchar c) { return ToLower((dword) c); }
inline char ToAscii(wchar c) { return ToAscii((dword) c); }
inline char ToUpperAscii(wchar c) { return ToUpperAscii((dword) c); }
inline char ToLowerAscii(wchar c) { return ToLowerAscii((dword) c); }
inline bool IsLetter(char16 c) { return IsLetter((wchar) c); }
inline bool IsUpper(char16 c) { return IsUpper((wchar) c); }
inline bool IsLower(char16 c) { return IsLower((wchar) c); }
inline wchar ToUpper(char16 c) { return ToUpper((wchar) c); }
inline wchar ToLower(char16 c) { return ToLower((wchar) c); }
inline char ToAscii(char16 c) { return ToAscii((wchar) c); }
inline char ToUpperAscii(char16 c) { return ToUpperAscii((wchar) c); }
inline char ToLowerAscii(char16 c) { return ToLowerAscii((wchar) c); }
inline bool IsDigit(int c) { return c >= '0' && c <= '9'; }
inline bool IsAlpha(int c) { return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'; }
@ -198,13 +196,13 @@ String Utf8ToAscii(const String& src);
String Utf8ToUpperAscii(const String& src);
String Utf8ToLowerAscii(const String& src);
void ToUpper(wchar *t, const wchar *s, int len);
void ToLower(wchar *t, const wchar *s, int len);
void ToAscii(wchar *t, const wchar *s, int len);
void ToUpper(char16 *t, const char16 *s, int len);
void ToLower(char16 *t, const char16 *s, int len);
void ToAscii(char16 *t, const char16 *s, int len);
void ToUpper(wchar *s, int len);
void ToLower(wchar *s, int len);
void ToAscii(wchar *s, int len);
void ToUpper(char16 *s, int len);
void ToLower(char16 *s, int len);
void ToAscii(char16 *s, int len);
bool IsLetter(int c, byte charset);
bool IsUpper(int c, byte charset);
@ -253,32 +251,11 @@ bool SaveFileBOMUtf8(const char *path, const String& data);
bool Utf8BOM(Stream& in);
// Deprecated
word UnicodeCombine(word chr, word combine);
inline bool IsCJKIdeograph(int c) { return c >= 0x2e80 && c <= 0xdfaf || c >= 0xf900 && c <= 0xfaff; }
int ToUnicode(int chr, byte charset);
int FromUnicode(wchar wchr, byte charset, int defchar = DEFAULTCHAR);
void ToUnicode(wchar *ws, const char *s, int n, byte charset);
void FromUnicode(char *s, const wchar *ws, int n, byte charset, int defchar = DEFAULTCHAR);
WString ToUnicode(const String& src, byte charset);
WString ToUnicode(const char *src, int n, byte charset);
String FromUnicodeBuffer(const wchar *src, int len, byte charset = CHARSET_DEFAULT, int defchar = DEFAULTCHAR);
String FromUnicodeBuffer(const wchar *src);
String FromUnicode(const WString& src, byte charset = CHARSET_DEFAULT, int defchar = DEFAULTCHAR);
inline WString FromUtf8(const char *s, int len) { return ToUtf16(s, len); }
inline WString FromUtf8(const char *s) { return ToUtf16(s); }
inline WString FromUtf8(const String& s) { return ToUtf16(s); }
inline bool utf8check(const char *s, int len) { return CheckUtf8(s, len); }
inline int utf8len(const char *s, int len) { return Utf16Len(s, len); }
inline int utf8len(const char *s) { return Utf16Len(s); }
inline int lenAsUtf8(const wchar *s, int len) { return Utf8Len(s, len); }
inline int lenAsUtf8(const wchar *s) { return Utf8Len(s); }
int ToUnicode(int chr, byte charset);
int FromUnicode(wchar wchr, byte charset, int defchar = DEFAULTCHAR);

View file

@ -1,7 +1,7 @@
#ifndef CORE_H
#define CORE_H
#define UPP_VERSION 0x20200200
#define UPP_VERSION 0x20210900
#ifndef flagMT
#define flagMT // MT is now always on
@ -63,6 +63,11 @@
#ifdef CPU_X86
#include <immintrin.h>
#ifdef PLATFORM_WIN32
#include <intrin.h>
#endif
#endif
#if defined(PLATFORM_POSIX)
@ -306,7 +311,6 @@ class JsonIO;
#include "String.h"
#include "TimeDate.h"
#include "Path.h"
#include "Stream.h"
#include "Diag.h"
@ -324,6 +328,8 @@ class JsonIO;
#include "CharSet.h"
#include "Path.h"
#include "SplitMerge.h"
#include "Other.h"

View file

@ -1,12 +1,8 @@
#include "Core.h"
#ifdef CPU_X86
#ifdef COMPILER_MSC
#include <intrin.h>
#else
#if !(defined(CPU_X86) && defined(COMPILER_MSC))
#include <cpuid.h>
#endif
#endif
#ifdef PLATFORM_FREEBSD
#include <sys/vmmeter.h>

View file

@ -167,7 +167,7 @@ int FormatDoubleDigits(const sF128& w, char *digits, int precision)
}
};
auto D1 = [&](dword u) { *digits++ = u + '0'; };
auto D1 = [&](dword u) { *digits++ = char(u + '0'); };
auto D2 = [&](dword u) { memcpy(digits, s100 + 2 * u, 2); digits += 2; };
auto D3 = [&](dword u) { int q = (5243 * u) >> 19; D1(q); D2(u - 100 * q); }; // bit faster than / % here
@ -182,24 +182,24 @@ int FormatDoubleDigits(const sF128& w, char *digits, int precision)
auto U16 = [&] { u1 = u / 10000000000000000; u = u % 10000000000000000; };
switch(precision) {
case 1: FP(10); D1(u); break;
case 2: FP(100); D2(u); break;
case 3: FP(1000); D3(u); break;
case 4: FP(10000); D4(u); break;
case 5: FP(100000); D5(u); break;
case 6: FP(1000000); D6(u); break;
case 7: FP(10000000); D7(u); break;
case 8: FP(100000000); D8(u); break;
case 9: FP(1000000000); U8(); D1(u1); D8(u); break;
case 10: FP(10000000000); U8(); D2(u1); D8(u); break;
case 11: FP(100000000000); U8(); D3(u1); D8(u); break;
case 12: FP(1000000000000); U8(); D4(u1); D8(u); break;
case 13: FP(10000000000000); U8(); D5(u1); D8(u); break;
case 14: FP(100000000000000); U8(); D6(u1); D8(u); break;
case 15: FP(1000000000000000); U8(); D7(u1); D8(u); break;
case 16: FP(10000000000000000); U8(); D8(u1); D8(u); break;
case 17: FP(100000000000000000); U16(); D1(u1); U8(); D8(u1); D8(u); break;
case 18: FP(1000000000000000000u); U16(); D2(u1); U8(); D8(u1); D8(u); break;
case 1: FP(10); D1((dword)u); break;
case 2: FP(100); D2((dword)u); break;
case 3: FP(1000); D3((dword)u); break;
case 4: FP(10000); D4((dword)u); break;
case 5: FP(100000); D5((dword)u); break;
case 6: FP(1000000); D6((dword)u); break;
case 7: FP(10000000); D7((dword)u); break;
case 8: FP(100000000); D8((dword)u); break;
case 9: FP(1000000000); U8(); D1((dword)u1); D8((dword)u); break;
case 10: FP(10000000000); U8(); D2((dword)u1); D8((dword)u); break;
case 11: FP(100000000000); U8(); D3((dword)u1); D8((dword)u); break;
case 12: FP(1000000000000); U8(); D4((dword)u1); D8((dword)u); break;
case 13: FP(10000000000000); U8(); D5((dword)u1); D8((dword)u); break;
case 14: FP(100000000000000); U8(); D6((dword)u1); D8((dword)u); break;
case 15: FP(1000000000000000); U8(); D7((dword)u1); D8((dword)u); break;
case 16: FP(10000000000000000); U8(); D8((dword)u1); D8((dword)u); break;
case 17: FP(100000000000000000); U16(); D1((dword)u1); U8(); D8((dword)u1); D8((dword)u); break;
case 18: FP(1000000000000000000u); U16(); D2((dword)u1); U8(); D8((dword)u1); D8((dword)u); break;
}
return -e10;
}

View file

@ -145,14 +145,16 @@ typedef short unsigned uint16;
typedef unsigned long dword;
typedef long int32;
typedef unsigned long uint32;
typedef WCHAR wchar;
typedef WCHAR char16;
#else
typedef unsigned int dword;
typedef int int32;
typedef unsigned int uint32;
typedef word wchar;
typedef word char16;
#endif
typedef uint32 wchar;
#ifdef COMPILER_MSC
typedef __int64 int64;

View file

@ -47,7 +47,7 @@ bool FileMapping::Open(const char *file, bool delete_share)
write = false;
#ifdef PLATFORM_WIN32
hfile = CreateFileW(ToSystemCharsetW(file), GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | (delete_share && IsWinNT() ? FILE_SHARE_DELETE : 0),
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(hfile == INVALID_HANDLE_VALUE)
return false;

View file

@ -559,7 +559,7 @@ String DoubleFormatter(const Formatting& f)
dword n;
bool overflow = false;
s = ScanUint<char, byte, dword, 10>(n, s, overflow);
if(overflow || !s || n > (wd ? 1000 : 100))
if(overflow || !s || n > (wd ? 1000u : 100u))
return Null;
(wd ? width : precision) = n;
}

View file

@ -23,9 +23,6 @@ void *MemoryAlloc(size_t size);
void MemoryFree(void *ptr);
void *MemoryAlloc32();
void MemoryFree32(void *ptr);
void *MemoryAlloc48();
void MemoryFree48(void *ptr);
void MemoryFreeThread();
void MemoryCheck();
void MemoryDumpLarge();
void MemoryDumpHuge();

View file

@ -410,7 +410,7 @@ struct Heap : BlkHeap<HugeHeapDetail, 4096> {
void Init();
static int CheckFree(FreeLink *l, int k);
static int CheckFree(FreeLink *l, int k, bool page = true);
void Check();
static void DblCheck(Page *p);
static void AssertLeaks(bool b);

View file

@ -68,9 +68,9 @@ public:
WString GetIndexLetter(const wchar *text) const { return (*getindexletter)(text, language); }
int Compare(const wchar *a, int alen, const wchar *b, int blen) const { return (*compare)(a, alen, b, blen, language); }
int Compare(const wchar *a, const wchar *b) const { return Compare(a, wstrlen(a), b, wstrlen(b)); }
int Compare(const wchar *a, const wchar *b) const { return Compare(a, strlen__(a), b, strlen__(b)); }
int Compare(WString a, WString b) const { return Compare(a, a.GetLength(), b, b.GetLength()); }
int Compare(const char *a, const char *b) const { return Compare(ToUnicode(a, CHARSET_DEFAULT), ToUnicode(b, CHARSET_DEFAULT)); }
int Compare(const char *a, const char *b) const { return Compare(ToUtf32(a), ToUtf32(b)); }
int Compare(String a, String b) const { return Compare(a.ToWString(), b.ToWString()); }
bool operator()(const wchar *a, const wchar *b) const { return Compare(a, b) < 0; }

View file

@ -193,14 +193,14 @@ int CSCZLanguageCompare(const wchar *a, int a_length, const wchar *b, int b_leng
String GetLocaleInfoA(LCID lcid, LCTYPE lctype)
{
wchar cbuf[1000];
WCHAR cbuf[1000];
::GetLocaleInfoW(lcid, lctype, cbuf, __countof(cbuf));
return FromSystemCharsetW(cbuf);
return cbuf;
}
WString GetLocaleInfoW(LCID lcid, LCTYPE lctype)
{
wchar wbuf[1000];
WCHAR wbuf[1000];
Zero(wbuf);
if(::GetLocaleInfoW(lcid, lctype, (WCHAR *)wbuf, __countof(wbuf)))
return wbuf;

View file

@ -68,14 +68,11 @@ static void sNoBlock(int fd)
#ifdef PLATFORM_WIN32
bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& si, PROCESS_INFORMATION& pi, const char *cd)
{ // provides conversion of charset for cmdline and envptr
WString wcmd(command);
int n = wcmd.GetCount() + 1;
WString wcd(cd);
Buffer<wchar> cmd(n);
memcpy(cmd, wcmd, n * sizeof(wchar));
Vector<WCHAR> cmd = ToSystemCharsetW(command);
cmd.Add(0);
#if 0 // unicode environment not necessary for now
wchar wenvptr = NULL;
Buffer<wchar> env(n);
Buffer<WCHAR> env(n);
if(envptr) {
int len = 0;
while(envptr[len] || envptr[len + 1])
@ -85,7 +82,8 @@ bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& s
memcpy(env, wenv, (len + 2) * sizeof(wchar));
}
#endif
return CreateProcessW(NULL, cmd, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, (void *)envptr, cd ? ~wcd : NULL, &si, &pi);
return CreateProcessW(NULL, cmd, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, (void *)envptr,
cd ? ToSystemCharsetW(cd).begin() : NULL, &si, &pi);
}
#endif

View file

@ -641,4 +641,22 @@ int inline_memcmp_aligned(const char *a, const char *b, size_t count)
}
#endif
template <class T>
bool memeq_t(const T *p, const T *q, size_t count)
{
if((sizeof(T) & 15) == 0)
return memeq128(p, q, count * (sizeof(T) >> 4));
else
if((sizeof(T) & 7) == 0)
return memeq64(p, q, count * (sizeof(T) >> 3));
else
if((sizeof(T) & 3) == 0)
return memeq32(p, q, count * (sizeof(T) >> 2));
else
if((sizeof(T) & 1) == 0)
return memeq16(p, q, count * (sizeof(T) >> 1));
else
return memeq8(p, q, count * sizeof(T));
}
hash_t memhash(const void *ptr, size_t count);

View file

@ -12,10 +12,10 @@ NetNode::NetNode()
NetNode& NetNode::operator=(const NetNode& s)
{
net = s.net;
local = s.local;
remote = s.remote;
comment = s.comment;
provider = s.provider;
local = clone(s.local);
remote = clone(s.remote);
comment = clone(s.comment);
provider = clone(s.provider);
name = s.name;
path = s.path;
SetPtrs();
@ -30,25 +30,23 @@ String DosInitCaps(const char *name)
return InitCaps(name);
}
void NetNode::SetPtr(String& s, char *& ptr)
{
if(ptr) ptr = (char *)~s;
}
void NetNode::SetPtrs()
{
auto SetPtr = [](Vector<char16>& s, char16 *& ptr) { if(ptr) ptr = s; };
SetPtr(local, net.lpLocalName);
SetPtr(remote, net.lpRemoteName);
SetPtr(comment, net.lpComment);
SetPtr(provider, net.lpProvider);
}
/*
void NetNode::Serialize(Stream& s)
{
s % net.dwScope % net.dwType % net.dwDisplayType % net.dwUsage;
s % local % remote % comment % provider % name % path;
SetPtrs();
}
*/
Array<NetNode> NetNode::Enum() const
{
@ -78,34 +76,35 @@ Array<NetNode> NetNode::Enum0(HANDLE hEnum)
{
Array<NetNode> r;
DWORD cEntries = (DWORD)-1, cbBuffer = 0x4000;
Buffer<NETRESOURCE> lpnr(cbBuffer);
while(::WNetEnumResource(hEnum, &cEntries, lpnr, &cbBuffer) == 0) {
Buffer<NETRESOURCEW> lpnr(cbBuffer);
while(::WNetEnumResourceW(hEnum, &cEntries, lpnr, &cbBuffer) == 0) {
for(int i = 0; i < (int)cEntries; i++) {
NETRESOURCE& sn = lpnr[i];
const char *s = sn.lpRemoteName;
NETRESOURCEW& sn = lpnr[i];
const WCHAR *s = sn.lpRemoteName;
NetNode& nn = r.Add();
NETRESOURCE& n = nn.net;
NETRESOURCEW& n = nn.net;
n = sn;
nn.local = n.lpLocalName;
nn.remote = n.lpRemoteName;
nn.comment = n.lpComment;
nn.provider = n.lpProvider;
auto get = [](const char16 *s) { Vector<char16> x; while(s && *s) x.Add(*s++); x.Add(0); return x; };
nn.local = get(n.lpLocalName);
nn.remote = get(n.lpRemoteName);
nn.comment = get(n.lpComment);
nn.provider = get(n.lpProvider);
nn.SetPtrs();
if(s) {
if(s[0] == '\\' && s[1] == '\\')
nn.name = FromSystemCharset(DosInitCaps(GetFileName(s)));
nn.name = DosInitCaps(GetFileName(FromSystemCharsetW(s)));
else
nn.name = FromSystemCharset(s);
nn.name = FromSystemCharsetW(s);
}
if(n.lpComment && *n.lpComment) {
if(nn.name.GetCount())
nn.name = String().Cat() << FromSystemCharset(n.lpComment)
nn.name = String().Cat() << FromSystemCharsetW(n.lpComment)
<< " (" << nn.name << ")";
else
nn.name = FromSystemCharset(n.lpComment);
nn.name = FromSystemCharsetW(n.lpComment);
}
if(!(n.dwUsage & RESOURCEUSAGE_CONTAINER))
nn.path = FromSystemCharset(n.lpRemoteName);
nn.path = FromSystemCharsetW(n.lpRemoteName);
}
}
::WNetCloseEnum(hEnum);

View file

@ -233,8 +233,6 @@ byte addc64(uint64& result, const uint64& value, byte carry) {
#elif defined(COMPILER_MSC) && defined(CPU_64)
#include <intrin.h>
inline
uint64 mul64(uint64 a, uint64 b, uint64& hi)
{

View file

@ -187,7 +187,7 @@ bool PathIsEqual(const char *p1, const char *p2)
#ifndef PLATFORM_WINCE
String GetCurrentDirectory() {
#if defined(PLATFORM_WIN32)
wchar h[MAX_PATH];
WCHAR h[MAX_PATH];
GetCurrentDirectoryW(MAX_PATH, h);
return FromSystemCharsetW(h);
#elif defined(PLATFORM_POSIX)
@ -211,7 +211,7 @@ bool SetCurrentDirectory(const char *path)
String GetTempPath()
{
wchar h[MAX_PATH];
WCHAR h[MAX_PATH];
GetTempPathW(MAX_PATH, h);
return FromSystemCharsetW(h);
}
@ -253,7 +253,7 @@ String ToUnixName(const char* fn, const char* stop = NULL) {
String GetFullPath(const char *file) {
#ifdef PLATFORM_WIN32
String ufn = FromUnixName(file);
wchar h[MAX_PATH];
WCHAR h[MAX_PATH];
GetFullPathNameW(ToSystemCharsetW(ufn), MAX_PATH, h, 0);
return FromSystemCharsetW(h);
#else
@ -364,10 +364,10 @@ static bool sGetSymLinkPath0(const char *linkpath, String *path)
{
bool ret = false;
HRESULT hres;
IShellLink* psl;
IShellLinkW* psl;
IPersistFile* ppf;
CoInitialize(NULL);
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW,
(PVOID *) &psl);
if(SUCCEEDED(hres)) {
hres = psl->QueryInterface(IID_IPersistFile, (PVOID *) &ppf);
@ -375,9 +375,9 @@ static bool sGetSymLinkPath0(const char *linkpath, String *path)
hres = ppf->Load(ToSystemCharsetW(linkpath), STGM_READ);
if(SUCCEEDED(hres)) {
if(path) {
char fileW[_MAX_PATH] = {0};
WCHAR fileW[_MAX_PATH] = {0};
psl->GetPath(fileW, _MAX_PATH, NULL, 0);
*path = FromSystemCharset(fileW);
*path = fileW;
}
else
ret = true;
@ -950,20 +950,20 @@ Array<FileSystemInfo::FileInfo> FileSystemInfo::Find(String mask, int max_count,
f.filename = "\\";
f.root_style = ROOT_FIXED;
#elif defined(PLATFORM_WIN32)
char drive[4] = "?:\\";
WCHAR drive[4] = L"?:\\";
for(int c = 'A'; c <= 'Z'; c++) {
*drive = c;
int n = GetDriveType(drive);
int n = GetDriveTypeW(drive);
if(n == DRIVE_NO_ROOT_DIR)
continue;
FileInfo& f = fi.Add();
f.filename = drive;
char name[256], system[256];
WCHAR name[256], system[256];
DWORD d;
if(c != 'A' && c != 'B' && n != DRIVE_UNKNOWN) {
bool b = GetVolumeInformation(drive, name, 256, &d, &d, &d, system, 256);
bool b = GetVolumeInformationW(drive, name, 256, &d, &d, &d, system, 256);
if(b) {
if(*name) f.root_desc << " " << FromSystemCharset(name);
if(*name) f.root_desc << " " << FromSystemCharsetW(name);
}
else if(n == DRIVE_REMOVABLE || n == DRIVE_CDROM) {
if(unmounted) {

View file

@ -315,15 +315,14 @@ FileSystemInfo& StdFileSystemInfo();
#ifdef PLATFORM_WIN32
class NetNode : Moveable<NetNode> {
NETRESOURCE net;
String local, remote, comment, provider;
NETRESOURCEW net;
Vector<char16> local, remote, comment, provider;
String name;
String path;
String name;
String path;
static void Copy(String& t, char *s);
static Array<NetNode> Enum0(HANDLE hEnum);
static void SetPtr(String& s, char *& ptr);
void SetPtrs();
@ -334,14 +333,12 @@ public:
String GetName() const { return name; }
String GetPath() const { return path; }
int GetDisplayType() const;
String GetRemote() const { return remote; }
String GetLocal() const { return local; }
String GetProvider() const { return provider; }
String GetComment() const { return comment; }
String GetRemote() const { return ToUtf8(remote); }
String GetLocal() const { return ToUtf8(local); }
String GetProvider() const { return ToUtf8(provider); }
String GetComment() const { return ToUtf8(comment); }
Array<NetNode> Enum() const;
void Serialize(Stream& s);
static Array<NetNode> EnumRoot();
static Array<NetNode> EnumRemembered();

View file

@ -6,28 +6,25 @@ namespace Upp {
static int64 UPP_SSL_alloc = 0;
static void *SslAlloc0(size_t size)
{
LLOG("Alloc " << size);
size_t alloc = size + sizeof(int64);
int64 *aptr = (int64 *)MemoryAllocSz(alloc);
*aptr++ = (int64)alloc;
UPP_SSL_alloc += alloc;
LLOG("UPP_SSL_MALLOC(" << (int64)size << ", alloc " << alloc << ") -> " << FormatIntHex(aptr) << ", total = " << UPP_SSL_alloc);
return aptr;
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
static void *SslAlloc(size_t size, const char *, int)
static void *SslAlloc(size_t size, const char *file, int line)
#else
static void *SslAlloc(size_t size)
#endif
{
return SslAlloc0(size);
size_t alloc = size + sizeof(int64);
int64 *aptr = (int64 *)MemoryAllocSz(alloc);
*aptr++ = (int64)alloc;
UPP_SSL_alloc += alloc;
LLOG("UPP_SSL_MALLOC(" << (int64)size << ", size " << size
<< ", " << file << " " << line
<< ") -> " << aptr << ", MemorySize: " << GetMemoryBlockSize(aptr)
<< ", total = " << UPP_SSL_alloc << ", thread: " << Thread::GetCurrentId());
return aptr;
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
static void SslFree(void *ptr, const char *, int)
static void SslFree(void *ptr, const char *file, int line)
#else
static void SslFree(void *ptr)
#endif
@ -36,35 +33,46 @@ static void SslFree(void *ptr)
return;
int64 *aptr = (int64 *)ptr - 1;
UPP_SSL_alloc -= *aptr;
LLOG("UPP_SSL_FREE(" << ptr << ", alloc " << *aptr << "), total = " << UPP_SSL_alloc);
LLOG("UPP_SSL_FREE(" << ptr << ", size " << *aptr
<< ", " << file << " " << line
<< "), MemorySize: " << GetMemoryBlockSize(aptr) << ", total = " << UPP_SSL_alloc << ", thread: " << Thread::GetCurrentId());
if(*aptr != GetMemoryBlockSize(aptr))
Panic("SslFree corrupted");
MemoryFree(aptr);
}
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
static void *SslRealloc(void *ptr, size_t size, const char *, int)
static void *SslRealloc(void *ptr, size_t size, const char *file, int line)
#else
static void *SslRealloc(void *ptr, size_t size)
#endif
{
LLOG("SslRealloc " << ptr << ", " << size);
if(!ptr)
return SslAlloc0(size);
if(!ptr) {
LLOG("UPP_SSL_REALLOC by Alloc:");
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
return SslAlloc(size, file, line);
#else
return SslAlloc(size);
#endif
}
int64 *aptr = (int64 *)ptr - 1;
if((int64)(size + sizeof(int64)) <= *aptr) {
LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << *aptr << ") -> keep same block");
if((int64)(size + sizeof(int64)) <= *aptr) { // TODO: Do we really want this?
LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << *aptr << ") -> keep same block" << ", thread: " << Thread::GetCurrentId());
return ptr;
}
size_t newalloc = size + sizeof(int64);
int64 *newaptr = (int64 *)MemoryAllocSz(newalloc);
if(!newaptr) {
LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc << ") -> fail");
LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc << ") -> fail" << ", thread: " << Thread::GetCurrentId());
return NULL;
}
*newaptr++ = newalloc;
memcpy(newaptr, ptr, min<int>((int)(*aptr - sizeof(int64)), (int)size));
UPP_SSL_alloc += newalloc - *aptr;
LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc << ") -> "
<< FormatIntHex(newaptr) << ", total = " << UPP_SSL_alloc);
LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc
<< ", " << file << " " << line
<< ") -> " << newaptr << ", total = " << UPP_SSL_alloc << ", thread: " << Thread::GetCurrentId());
MemoryFree(aptr);
return newaptr;
}
@ -74,7 +82,7 @@ void TcpSocketInit();
INITIALIZER(SSL)
{
MemoryIgnoreLeaksBlock __;
LLOG("SSL init");
LLOG("SslInit");
TcpSocketInit();
CRYPTO_set_mem_functions(SslAlloc, SslRealloc, SslFree);
SSL_library_init();

View file

@ -167,7 +167,7 @@ Speller *sGetSpeller(int lang)
while(!user.IsEof()) {
String s = user.GetLine();
if(!s.IsEmpty())
f.user.Add(FromUtf8(s));
f.user.Add(ToUtf32(s));
}
if(in.Get() != 255)
f.SetOld(LoadFile(path));

View file

@ -138,7 +138,7 @@ Vector<WString> Split(int maxcount, const wchar *s, const wchar *text, bool igno
{
SplitDelimWText delim;
delim.ds = text;
delim.l = wstrlen(text);
delim.l = strlen__(text);
return delim.l ? SplitGeneric<WString>(maxcount, delim, s, ignoreempty) : Vector<WString>();
}

View file

@ -2,11 +2,20 @@
namespace Upp {
int wstrlen(const wchar *s)
int strlen16(const char16 *s)
{
const wchar *q = s;
while(*q) q++;
return (int)(q - s);
if(!s) return 0;
const char16 *s0 = s;
while(*s) s++;
return int(s - s0);
}
int strlen32(const wchar *s)
{
if(!s) return 0;
const wchar *s0 = s;
while(*s) s++;
return int(s - s0);
}
unsigned ctoi(int c)
@ -32,7 +41,7 @@ int CharFilterAscii128(int c)
int CharFilterUnicode(int c)
{
return c >= 32 && c < 65536 ? c : 0;
return c >= 32 && c < 0x10FFFF ? c : 0;
}
int CharFilterDigit(int c)

View file

@ -629,36 +629,29 @@ Stream& Stream::operator/(String& s) {
return *this;
}
Stream& Stream::operator%(WString& s) {
Stream& Stream::operator%(WString& s)
{ // we do not support BE here anymore
if(IsError()) return *this;
if(IsLoading()) {
dword len;
Pack(len);
if(len < 256 * 1024) {
WStringBuffer sb(len);
SerializeRaw((byte*)~sb, len * sizeof(wchar));
s = sb;
}
else {
String h = GetAll(len * sizeof(wchar));
if(h.IsVoid())
LoadError();
else {
WStringBuffer sb(len);
memcpy8(~sb, ~h, len * sizeof(wchar));
s = sb;
}
}
dword len = Get();
if(len == 0xff)
len = Get32le();
String h = GetAll(len * sizeof(char16));
if(h.IsVoid())
LoadError();
else
s = ToUtf32((const char16 *)~h, len);
}
else {
dword len = s.GetLength();
Vector<char16> x = ToUtf16(s);
dword len = x.GetCount();
if(len < 0xff)
Put(len);
else {
Put(0xff);
Put32le(len);
}
SerializeRaw((byte*)~s, len * sizeof(wchar));
SerializeRaw((byte*)x.begin(), len * sizeof(char16));
}
return *this;
}
@ -667,7 +660,7 @@ Stream& Stream::operator/(WString& s) {
if(IsError()) return *this;
String h = ToUtf8(s);
*this / h;
s = FromUtf8(h);
s = ToUtf32(h);
return *this;
}
@ -1082,32 +1075,28 @@ Stream& NilStream()
return Single<NilStreamClass>();
}
#ifdef PLATFORM_WIN32
bool IsCoutUTF8;
#endif
void CoutUTF8()
{
#ifdef PLATFORM_WIN32
IsCoutUTF8 = true;
SetConsoleOutputCP(65001);
#endif
}
#ifndef PLATFORM_WINCE
class CoutStream : public Stream {
#ifdef PLATFORM_WIN32
String buffer;
void Flush() {
ONCELOCK {
SetConsoleOutputCP(65001); // set console to UTF8 mode
}
static HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
dword dummy;
WriteFile(h, ~buffer, buffer.GetCount(), &dummy, NULL);
buffer.Clear();
}
#endif
void Put0(int w) {
#ifdef PLATFORM_WIN32
buffer.Cat(w);
if(CheckUtf8(buffer)) { // TODO: Use W api
String ws = ToSystemCharset(buffer, GetConsoleOutputCP());
static HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
dword dummy;
WriteFile(h, ~ws, ws.GetCount(), &dummy, NULL);
buffer.Clear();
}
if(CheckUtf8(buffer) || buffer.GetCount() > 8)
Flush();
#else
putchar(w);
#endif

View file

@ -178,10 +178,6 @@ public:
void PutLine(const char *s);
void PutLine(const String& s);
void PutW(const wchar *s, int count) { Put(s, count * 2); }
dword GetW(wchar *s, int count) { return Get(s, count * 2) / 2; }
bool GetAllW(wchar *s, int count) { return GetAll(s, count * 2); }
void Put(Stream& s, int64 size = INT64_MAX, dword click = 4096);
// Stream as serialization streamer
@ -253,6 +249,9 @@ public:
void PutIL(int c) { Put32le(c); }
void PutMW(int c) { Put16be(c); }
void PutML(int c) { Put32be(c); }
void PutW(const char16 *s, int count) { Put(s, count * 2); }
dword GetW(char16 *s, int count) { return Get(s, count * 2) / 2; }
bool GetAllW(char16 *s, int count) { return GetAll(s, count * 2); }
#endif
private: // No copy
Stream(const Stream& s);

View file

@ -216,9 +216,12 @@ WString String::ToWString() const
int String::GetCharCount() const
{
return GetDefaultCharset() == CHARSET_UTF8 ? utf8len(Begin(), GetCount()) : GetCount();
return GetDefaultCharset() == CHARSET_UTF8 ? Utf32Len(Begin(), GetCount()) : GetCount();
}
String::String(char16 *s) : String(ToUtf8(s)) {}
String::String(wchar *s) : String(ToUtf8(s)) {}
String::String(StringBuffer& b)
{
Zero();
@ -354,26 +357,14 @@ struct StringICompare__
StringICompare__(int e) : encoding(e) {}
};
int CompareNoCase(const String& a, const String& b, byte encoding)
int CompareNoCase(const String& a, const String& b)
{
if(encoding == CHARSET_DEFAULT) encoding = GetDefaultCharset();
if(encoding == CHARSET_UTF8) return CompareNoCase(FromUtf8(a), FromUtf8(b));
#ifdef DEPRECATED
return IterCompare(a.Begin(), a.End(), b.Begin(), b.End(), StringICompare__(encoding));
#else
return CompareRanges(a, b, StringICompare__(encoding));
#endif
return CompareNoCase(ToUtf32(a), ToUtf32(b));
}
int CompareNoCase(const String& a, const char *b, byte encoding)
int CompareNoCase(const String& a, const char *b)
{
if(encoding == CHARSET_DEFAULT) encoding = GetDefaultCharset();
if(encoding == CHARSET_UTF8) return CompareNoCase(FromUtf8(a), FromUtf8(b, (int)strlen(b)));
#ifdef DEPRECATED
return IterCompare(a.Begin(), a.End(), b, b + strlen(b), StringICompare__(encoding));
#else
return CompareRanges(a, SubRange(b, b + strlen(b)), StringICompare__(encoding));
#endif
return CompareNoCase(ToUtf32(a), ToUtf32(b, (int)strlen(b)));
}
}

View file

@ -1,6 +1,8 @@
class Nuller;
int wstrlen(const wchar *s);
inline int strlen8(const char *s) { return s ? (int)strlen(s) : 0; }
int strlen16(const char16 *s);
int strlen32(const wchar *s);
#ifdef PLATFORM_POSIX
inline int stricmp(const char *a, const char *b) { return strcasecmp(a, b); }
@ -12,12 +14,11 @@ inline int stricmp(const char *a, const char *b) { return _stricmp(a, b)
inline int strnicmp(const char *a, const char *b, int n) { return _strnicmp(a, b, n); }
#endif
force_inline int strlen__(const char *s) { return s ? (int)strlen(s) : 0; }
inline int strlen__(const wchar *s) { return s ? (int)wstrlen(s) : 0; }
force_inline int strlen__(const char *s) { return strlen8(s); }
inline int strlen__(const wchar *s) { return strlen32(s); }
inline int cmpval__(char x) { return (byte)x; }
inline int cmpval__(wchar x) { return (word)x; }
inline int cmpval__(wchar x) { return x; }
int find(const char *text, int len, const char *needle, int nlen, int from);
int find(const wchar *text, int len, const wchar *needle, int nlen, int from);
@ -391,6 +392,10 @@ public:
String(int chr, int count) { String0::Zero(); Cat(chr, count); }
String(StringBuffer& b);
String(char16 *s);
String(wchar *s);
WString ToWString() const;
const String& ToString() const { return *this; }
@ -618,12 +623,12 @@ inline String AsString(const String& s) { return s; }
template<>
inline hash_t GetHashValue(const String& s) { return s.GetHashValue(); }
int CompareNoCase(const String& a, const String& b, byte encoding = 0);
int CompareNoCase(const String& a, const char *b, byte encoding = 0);
int CompareNoCase(const String& a, const String& b);
int CompareNoCase(const String& a, const char *b);
inline
int CompareNoCase(const char *a, const String& b, byte encoding = 0) {
return -CompareNoCase(b, a, encoding);
int CompareNoCase(const char *a, const String& b) {
return -CompareNoCase(b, a);
}
String TrimLeft(const String& s);
@ -774,8 +779,8 @@ public:
int GetAlloc() const { return alloc; }
hash_t GetHashValue() const { return memhash(ptr, length * sizeof(wchar)); }
bool IsEqual(const WString0& s) const { return s.length == length && memeq16(ptr, s.ptr, length); }
bool IsEqual(const wchar *s) const { int l = wstrlen(s); return l == GetCount() && memeq16(begin(), s, l); }
bool IsEqual(const WString0& s) const { return s.length == length && memeq_t(ptr, s.ptr, length); }
bool IsEqual(const wchar *s) const { int l = strlen__(s); return l == GetCount() && memeq_t(begin(), s, l); }
int Compare(const WString0& s) const;
void Remove(int pos, int count = 1);
@ -835,6 +840,8 @@ public:
WString(const char *s, int n);
WString(const char *s, const char *lim);
WString(const char16 *s);
static WString GetVoid();
bool IsVoid() const { return alloc < 0; }
@ -845,13 +852,13 @@ public:
#ifndef _HAVE_NO_STDWSTRING
WString(const std::wstring& s);
operator std::wstring() const;
std::wstring ToStd() const { return std::wstring(Begin(), End()); }
operator std::wstring() const { return ToStd(); }
std::wstring ToStd() const;
#endif
};
#ifndef _HAVE_NO_STDWSTRING
inline std::wstring to_string(const WString& s) { return std::wstring(s.Begin(), s.End()); }
inline std::wstring to_string(const WString& s) { return s.ToStd(); }
#endif
class WStringBuffer : NoCopy {
@ -885,7 +892,7 @@ public:
void SetCount(int l) { SetLength(l); }
int GetLength() const { return (int)(pend - pbegin); }
int GetCount() const { return GetLength(); }
void Strlen() { SetLength(wstrlen(pbegin)); }
void Strlen() { SetLength(strlen__(pbegin)); }
void Clear() { Free(); Zero(); }
void Reserve(int r) { int l = GetLength(); SetLength(l + r); SetLength(l); }
@ -893,7 +900,7 @@ public:
void Cat(int c, int count);
void Cat(const wchar *s, int l);
void Cat(const wchar *s, const wchar *e) { Cat(s, int(e - s)); }
void Cat(const wchar *s) { Cat(s, wstrlen(s)); }
void Cat(const wchar *s) { Cat(s, strlen__(s)); }
void Cat(const WString& s) { Cat(s, s.GetLength()); }
void Cat(const char *s) { Cat(WString(s)); }

View file

@ -123,8 +123,8 @@ int find(const char *text, int len, const char *needle, int nlen, int from)
int find(const wchar *text, int len, const wchar *needle, int nlen, int from)
{
int q = t_find<2>((const char *)text, 2 * len, (const char *)needle, 2 * nlen, 2 * from);
return q < 0 ? q : q / 2;
int q = t_find<sizeof(wchar)>((const char *)text, sizeof(wchar) * len, (const char *)needle, sizeof(wchar) * nlen, sizeof(wchar) * from);
return q < 0 ? q : q / sizeof(wchar);
}
#else

View file

@ -76,12 +76,12 @@ struct UnicodeInfo {
}
};
Index<dword> composed;
Index<String> decomposed; // using String as the vessel for dwords
Index<wchar> composed;
Index<WString> decomposed;
int canonical_count;
Index<dword> lower;
Index<dword> upper;
Index<wchar> lower;
Index<wchar> upper;
CharBits rtl;
CharBits letter;
CharBits islower;
@ -130,8 +130,8 @@ UnicodeInfo::UnicodeInfo()
count += data[1];
for(int i = 0; i < count; i++) {
composed.Add(data[i + 2]);
String h;
auto put = [&](dword c) { if(c) h.Cat((char *)&c, 4); };
WString h;
auto put = [&](dword c) { if(c) h.Cat(c); };
put(data[i + count + 2]);
put(data[i + 2 * count + 2]);
put(data[i + 3 * count + 2]);
@ -143,11 +143,11 @@ UnicodeInfo::UnicodeInfo()
int offset = 4 * count + 2;
while(data[offset]) {
dword code = data[offset++];
wchar code = data[offset++];
int ii = composed.Find(code);
String h = decomposed[ii];
WString h = decomposed[ii];
while(data[offset])
h.Cat((char *)&data[offset++], 4);
h.Cat(data[offset++]);
decomposed.Set(ii, h);
offset++;
}
@ -169,54 +169,54 @@ UnicodeInfo::UnicodeInfo()
Load(data, ismark, offset);
}
static int sUnicodeDecompose(dword codepoint, dword *t, Vector<dword> *r, bool only_canonical)
static int sUnicodeDecompose(wchar codepoint, wchar *t, WString *r, bool only_canonical)
{ // TODO: Add hangul support
const UnicodeInfo& f = Single<UnicodeInfo>();
int q = f.composed.Find(codepoint);
if(q >= 0 && (!only_canonical || q < f.canonical_count)) {
String s = f.decomposed[q];
const WString& s = f.decomposed[q];
if(r)
r->SetCount(s.GetCount() >> 2);
int i;
for(i = 0; 4 * i < s.GetCount(); i++)
(r ? (*r)[i] : t[i]) = ((const dword *)~s)[i];
return i;
*r = s;
if(t)
memcpy(t, s, sizeof(wchar) * s.GetCount());
return s.GetCount();
}
return 0;
}
int UnicodeDecompose(dword codepoint, dword t[MAX_DECOMPOSED], bool only_canonical)
int UnicodeDecompose(wchar codepoint, wchar t[MAX_DECOMPOSED], bool only_canonical)
{
return sUnicodeDecompose(codepoint, t, NULL, only_canonical);
}
Vector<dword> UnicodeDecompose(dword codepoint, bool only_canonical)
WString UnicodeDecompose(wchar codepoint, bool only_canonical)
{
Vector<dword> r;
WString r;
sUnicodeDecompose(codepoint, NULL, &r, only_canonical);
return r;
}
dword UnicodeCompose(const dword *t, int count)
wchar UnicodeCompose(const WString& s)
{
int count = s.GetCount();
if(count < 1 || count > 3)
return 0;
if(count == 1)
return t[0];
String s((byte *)t, sizeof(dword) * count);
return *s;
const UnicodeInfo& f = Single<UnicodeInfo>();
int q = f.decomposed.Find(s);
return q >= 0 && q < f.canonical_count ? f.composed[q] : 0;
}
dword ToUpperRest_(dword c)
wchar ToUpperRest_(wchar c)
{
const UnicodeInfo& f = Single<UnicodeInfo>();
int q = f.lower.Find(c);
return q >= 0 ? f.upper[q] : c;
}
dword ToLowerRest_(dword c)
wchar ToLowerRest_(wchar c)
{
if(c == 0x1e9e) // Capital sharp S -> small sharp S (but not reverse direction)
return 0xdf;
@ -233,7 +233,7 @@ dword ToLowerRest_(dword c)
return q >= 0 ? f.lower[q] : c;
}
char ToAsciiRest_(dword c)
char ToAsciiRest_(wchar c)
{
const UnicodeInfo& f = Single<UnicodeInfo>();
int q = f.composed.Find(c);
@ -243,27 +243,27 @@ char ToAsciiRest_(dword c)
return ch >= ' ' && ch < 128 ? ch : ' ';
}
bool IsRTL_(dword c)
bool IsRTL_(wchar c)
{
return Single<UnicodeInfo>().rtl.Get(c);
}
bool IsLetter_(dword c)
bool IsLetter_(wchar c)
{
return Single<UnicodeInfo>().letter.Get(c);
}
bool IsLower_(dword c)
bool IsLower_(wchar c)
{
return c != (dword)ToUpper((int)c) || Single<UnicodeInfo>().islower.Get(c);
}
bool IsUpper_(dword c)
bool IsUpper_(wchar c)
{
return c != (dword)ToLower((int)c) || Single<UnicodeInfo>().isupper.Get(c);
}
bool IsMark_(dword c)
bool IsMark_(wchar c)
{
return Single<UnicodeInfo>().ismark.Get(c);
}

View file

@ -2,138 +2,142 @@
namespace Upp {
int strlen32(const dword *s)
{
const dword *s0 = s;
while(*s) s++;
return int(s - s0);
}
bool CheckUtf8(const char *s, int len)
{
return FromUtf8_([](const byte *, dword){}, s, len);
}
int Utf8Len(const dword *s, int len)
{
int rlen = 0;
for(const dword *lim = s + len; s < lim; s++)
ToUtf8_([&](char) { rlen++; }, *s);
return rlen;
}
void ToUtf8(char *t, const dword *s, int len)
{
for(const dword *lim = s + len; s < lim; s++)
ToUtf8_([&](char c) { *t++ = c; }, *s);
}
String ToUtf8(const dword *s, int len)
{
String r;
for(const dword *lim = s + len; s < lim; s++)
ToUtf8_([&](char c) { r.Cat(c); }, *s);
return r;
return FromUtf8_([](wchar) {}, s, len);
}
int Utf8Len(const wchar *s, int len)
{
int rlen = 0;
FromUtf16_([&](const wchar *, dword code) { ToUtf8_([&](char c) { rlen++; }, code); }, s, len);
for(const wchar *lim = s + len; s < lim; s++)
ToUtf8_([&](char) { rlen++; }, *s);
return rlen;
}
void ToUtf8(char *t, const wchar *s, int len)
{
FromUtf16_([&](const wchar *, dword code) { ToUtf8_([&](char c) { *t++ = c; }, code); }, s, len);
for(const wchar *lim = s + len; s < lim; s++)
ToUtf8_([&](char c) { *t++ = c; }, *s);
}
String ToUtf8(const wchar *s, int len)
{
StringBuffer r;
r.Reserve(len);
FromUtf16_([&](const wchar *, dword code) { ToUtf8_([&](char c) { r.Cat(c); }, code); }, s, len);
return String(r);
String r;
for(const wchar *lim = s + len; s < lim; s++)
ToUtf8_([&](char c) { r.Cat(c); }, *s);
return r;
}
int Utf16Len(const dword *s, int len)
int Utf8Len(const char16 *s, int len)
{
int rlen = 0;
for(const dword *lim = s + len; s < lim; s++)
ToUtf16_([&](wchar) { rlen++; }, *s);
FromUtf16_([&](wchar code) { ToUtf8_([&](char c) { rlen++; }, code); }, s, len);
return rlen;
}
void ToUtf16(wchar *t, const dword *s, int len)
void ToUtf8(char *t, const char16 *s, int len)
{
for(const dword *lim = s + len; s < lim; s++)
ToUtf16_([&](wchar c) { *t++ = c; }, *s);
FromUtf16_([&](wchar code) { ToUtf8_([&](char c) { *t++ = c; }, code); }, s, len);
}
WString ToUtf16(const dword *s, int len)
String ToUtf8(const char16 *s, int len)
{
WStringBuffer r;
StringBuffer r;
r.Reserve(len);
for(const dword *lim = s + len; s < lim; s++)
ToUtf16_([&](wchar c) { r.Cat(c); }, *s);
return WString(r);
FromUtf16_([&](wchar code) { ToUtf8_([&](char c) { r.Cat(c); }, code); }, s, len);
return String(r);
}
int Utf16Len(const wchar *s, int len)
{
int rlen = 0;
for(const wchar *lim = s + len; s < lim; s++)
ToUtf16_([&](char16) { rlen++; }, *s);
return rlen;
}
int ToUtf16(char16 *t, const wchar *s, int len)
{
char16 *t0 = t;
for(const wchar *lim = s + len; s < lim; s++)
ToUtf16_([&](char16 c) { *t++ = c; }, *s);
return int(t - t0);
}
Vector<char16> ToUtf16(const wchar *s, int len)
{
Vector<char16> r;
r.Reserve(len);
for(const wchar *lim = s + len; s < lim; s++)
ToUtf16_([&](char16 c) { r.Add(c); }, *s);
return r;
}
int Utf16Len(const char *s, int len)
{
int rlen = 0;
FromUtf8_([&](const byte *, dword code) { ToUtf16_([&](wchar c) { rlen++; }, code); }, s, len);
FromUtf8_([&](wchar code) {
ToUtf16_([&](char16) { rlen++; }, code);
}, s, len);
return rlen;
}
void ToUtf16(wchar *t, const char *s, int len)
int ToUtf16(char16 *t, const char *s, int len)
{
FromUtf8_([&](const byte *, dword code) { ToUtf16_([&](wchar c) { *t++ = c; }, code); }, s, len);
char16 *t0 = t;
FromUtf8_([&](wchar code) {
ToUtf16_([&](char16 c) { *t++ = c; }, code);
}, s, len);
return int(t - t0);
}
WString ToUtf16(const char *s, int len)
Vector<char16> ToUtf16(const char *s, int len)
{
WStringBuffer r;
FromUtf8_([&](const byte *, dword code) { ToUtf16_([&](wchar c) { r.Cat(c); }, code); }, s, len);
return WString(r);
Vector<char16> r;
FromUtf8_([&](wchar code) {
ToUtf16_([&](char16 c) { r.Add(c); } , code);
}, s, len);
return r;
}
int Utf32Len(const char *s, int len)
{
int rlen = 0;
FromUtf8_([&](const byte *, dword) { rlen++; }, s, len);
FromUtf8_([&](wchar) { rlen++; }, s, len);
return rlen;
}
void ToUtf32(dword *t, const char *s, int len)
void ToUtf32(wchar *t, const char *s, int len)
{
FromUtf8_([&](const byte *, dword c) { *t++ = c; }, s, len);
FromUtf8_([&](wchar c) { *t++ = c; }, s, len);
}
Vector<dword> ToUtf32(const char *s, int len)
WString ToUtf32(const char *s, int len)
{
Vector<dword> r;
FromUtf8_([&](const byte *, dword c) { r.Add(c); }, s, len);
return r;
WStringBuffer r;
FromUtf8_([&](wchar c) { r.Cat(c); }, s, len);
return WString(r);
}
int Utf32Len(const wchar *s, int len)
int Utf32Len(const char16 *s, int len)
{
int rlen = 0;
FromUtf16_([&](const wchar *, dword) { rlen++; }, s, len);
FromUtf16_([&](wchar) { rlen++; }, s, len);
return rlen;
}
void ToUtf32(dword *t, const wchar *s, int len)
void ToUtf32(wchar *t, const char16 *s, int len)
{
FromUtf16_([&](const wchar *, dword c) { *t++ = c; }, s, len);
FromUtf16_([&](wchar c) { *t++ = c; }, s, len);
}
Vector<dword> ToUtf32(const wchar *s, int len)
WString ToUtf32(const char16 *s, int len)
{
Vector<dword> r;
FromUtf16_([&](const wchar *, dword c) { r.Add(c); }, s, len);
return r;
WStringBuffer r;
r.Reserve(len);
FromUtf16_([&](wchar c) { r.Cat(c); }, s, len);
return WString(r);
}
String Utf8ToAscii(const String& src)

View file

@ -1,5 +1,5 @@
template <class Target>
force_inline bool ToUtf8_(Target t, dword codepoint)
force_inline bool ToUtf8_(Target t, wchar codepoint)
{
if(codepoint < 0x80)
t((char)codepoint);
@ -29,7 +29,7 @@ force_inline bool ToUtf8_(Target t, dword codepoint)
return true;
}
force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok)
force_inline dword FetchUtf8(const char *&_s, bool nolim, const char *_lim, bool& ok)
{
const byte *s = (const byte *)_s;
const byte *lim = (const byte *)_lim;
@ -41,14 +41,14 @@ force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok)
else
if(code >= 0xC2) {
dword c;
if(code < 0xE0 && s + 1 < lim &&
if(code < 0xE0 && (nolim || s + 1 < lim) &&
s[1] >= 0x80 && s[1] < 0xc0 &&
(c = ((code - 0xC0) << 6) + s[1] - 0x80) >= 0x80 && c < 0x800) {
_s += 2;
return c;
}
else
if(code < 0xF0 && s + 2 < lim &&
if(code < 0xF0 && (nolim || s + 2 < lim) &&
s[1] >= 0x80 && s[1] < 0xc0 && s[2] >= 0x80 && s[2] < 0xc0 &&
(c = ((code - 0xE0) << 12) + ((s[1] - 0x80) << 6) + s[2] - 0x80) >= 0x800 &&
!(c >= 0xEE00 && c <= 0xEEFF)) {
@ -56,7 +56,7 @@ force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok)
return c;
}
else
if(code < 0xF8 && s + 3 < lim &&
if(code < 0xF8 && (nolim || s + 3 < lim) &&
s[1] >= 0x80 && s[1] < 0xc0 && s[2] >= 0x80 && s[2] < 0xc0 && s[3] >= 0x80 && s[3] < 0xc0 &&
(c = ((code - 0xF0) << 18) + ((s[1] - 0x80) << 12) + ((s[2] - 0x80) << 6) + s[3] - 0x80) >= 0x10000 &&
c < 0x110000) {
@ -69,13 +69,23 @@ force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok)
return 0xEE00 + code; // ERROR ESCAPE
}
force_inline dword FetchUtf8(const char *&s, const char *lim, bool& ok)
{
return FetchUtf8(s, false, lim, ok);
}
force_inline dword FetchUtf8(const char *&s, bool& ok)
{
return FetchUtf8(s, true, NULL, ok);
}
template <class Target>
force_inline bool FromUtf8_(Target t, const char *s, size_t len)
{
bool ok = true;
const char *lim = s + len;
while(s < lim)
t((const byte *)s, FetchUtf8(s, lim, ok));
t(FetchUtf8(s, lim, ok));
return ok;
}
@ -83,36 +93,36 @@ template <class Target>
force_inline bool ToUtf16_(Target t, size_t codepoint)
{
if(codepoint < 0x10000)
t((wchar)codepoint);
t((char16)codepoint);
else
if(codepoint < 0x110000) {
codepoint -= 0x10000;
t(wchar(0xD800 + (0x3ff & (codepoint >> 10))));
t(wchar(0xDC00 + (0x3ff & codepoint)));
t(char16(0xD800 + (0x3ff & (codepoint >> 10))));
t(char16(0xDC00 + (0x3ff & codepoint)));
}
else
return false;
return true;
}
force_inline dword ReadSurrogatePair(const wchar *s, const wchar *lim)
force_inline wchar ReadSurrogatePair(const char16 *s, const char16 *lim)
{
return (*s & 0XFC00) == 0xD800 && s + 1 < lim && (s[1] & 0xFC00) == 0xDC00 ?
((dword(s[0] & 0x3ff) << 10) | (s[1] & 0x3ff)) + 0x10000 : 0;
((wchar(s[0] & 0x3ff) << 10) | (s[1] & 0x3ff)) + 0x10000 : 0;
}
template <class Target>
force_inline void FromUtf16_(Target t, const wchar *s, size_t len)
force_inline void FromUtf16_(Target t, const char16 *s, size_t len)
{
const wchar *lim = s + len;
const char16 *lim = s + len;
while(s < lim) {
dword c = ReadSurrogatePair(s, lim);
wchar c = ReadSurrogatePair(s, lim);
if(c) {
t(s, c);
t(c);
s += 2;
}
else {
t(s, *s);
t(*s);
s++;
}
}

View file

@ -577,25 +577,13 @@ int ChNoInvalid(int c)
return c == DEFAULTCHAR ? '_' : c;
}
#ifdef PLATFORM_WINCE
WString ToSystemCharset(const String& src)
{
return src.ToWString();
}
String FromSystemCharset(const WString& src)
{
return src.ToString();
}
#else
#ifdef PLATFORM_WIN32
String ToSystemCharset(const String& src, int cp)
{
WString s = src.ToWString();
int l = s.GetLength() * 5;
Vector<char16> s = ToUtf16(src);
int l = s.GetCount() * 8;
StringBuffer b(l);
int q = WideCharToMultiByte(cp, 0, (const WCHAR *)~s, s.GetLength(), b, l, NULL, NULL);
int q = WideCharToMultiByte(cp, 0, s, s.GetCount(), b, l, NULL, NULL);
if(q <= 0)
return src;
b.SetCount(q);
@ -609,12 +597,11 @@ String ToSystemCharset(const String& src)
String FromWin32Charset(const String& src, int cp)
{
WStringBuffer b(src.GetLength());
int q = MultiByteToWideChar(cp, MB_PRECOMPOSED, ~src, src.GetLength(), (WCHAR*)~b, src.GetLength());
Buffer<char16> b(src.GetLength());
int q = MultiByteToWideChar(cp, MB_PRECOMPOSED, ~src, src.GetLength(), b, src.GetLength());
if(q <= 0)
return src;
b.SetCount(q);
return WString(b).ToString();
return ToUtf8(b, q);
}
String FromOEMCharset(const String& src)
@ -627,16 +614,6 @@ String FromSystemCharset(const String& src)
return FromWin32Charset(src, CP_ACP);
}
WString ToSystemCharsetW(const char *src)
{
return String(src).ToWString();
}
String FromSystemCharsetW(const wchar *src)
{
return WString(src).ToString();
}
#else
String ToSystemCharset(const String& src)
{
@ -649,8 +626,39 @@ String FromSystemCharset(const String& src)
return IsMainRunning() ? Filter(ToCharset(CHARSET_DEFAULT, src, GetLNGCharset(GetSystemLNG())), ChNoInvalid) : src;
}
#endif
#endif
Vector<char16> ToSystemCharsetW(const WString& src)
{
Vector<char16> h = ToUtf16(src);
h.Add(0);
return h;
}
Vector<char16> ToSystemCharsetW(const String& src)
{
Vector<char16> h = ToUtf16(src);
h.Add(0);
return h;
}
Vector<char16> ToSystemCharsetW(const wchar *src)
{
Vector<char16> h = ToUtf16(src);
h.Add(0);
return h;
}
Vector<char16> ToSystemCharsetW(const char *src)
{
Vector<char16> h = ToUtf16(src);
h.Add(0);
return h;
}
String FromSystemCharsetW(const char16 *src)
{
return ToUtf8(src);
}
static StaticMutex sGCfgLock;

View file

@ -158,17 +158,17 @@ String HexDecode(const char *s, const char *lim);
inline String HexDecode(const char *s, int len) { return HexDecode(s, s + len); }
inline String HexDecode(const String& s) { return HexDecode(~s, s.GetCount()); }
#ifdef PLATFORM_WINCE
WString ToSystemCharset(const String& src);
String FromSystemCharset(const WString& src);
#else
String ToSystemCharset(const String& src, int cp);
String ToSystemCharset(const String& src);
String FromWin32Charset(const String& src, int cp);
String FromSystemCharset(const String& src);
WString ToSystemCharsetW(const char *src);
String FromSystemCharsetW(const wchar *src);
#endif
Vector<char16> ToSystemCharsetW(const WString& src);
Vector<char16> ToSystemCharsetW(const String& src);
Vector<char16> ToSystemCharsetW(const wchar *src);
Vector<char16> ToSystemCharsetW(const char *src);
String FromSystemCharsetW(const char16 *src);
#ifdef PLATFORM_WIN32
String FromOEMCharset(const String& src);

View file

@ -289,21 +289,13 @@ bool ValueMap::Data::IsNull() const {
}
void ValueMap::Data::Serialize(Stream& s) {
#if !defined(_MSC_VER) || _MSC_VER > 1310
s % key % value;
#else
throw 0;
#endif
}
void ValueMap::Data::Xmlize(XmlIO& xio)
{
#if !defined(_MSC_VER) || _MSC_VER > 1310
Upp::Xmlize(xio, key);
Upp::Xmlize(xio, value);
#else
throw 0;
#endif
}
void ValueMap::Data::Jsonize(JsonIO& jio)

View file

@ -6,13 +6,13 @@ wchar *WString0::Alloc(int& count)
{
if(count <= SMALL) {
count = SMALL;
wchar *p = (wchar *)MemoryAlloc48();
wchar *p = (wchar *)MemoryAlloc((SMALL + 1) * sizeof(wchar));
return p;
}
size_t sz = sizeof(Atomic) + ((size_t)count + 1) * sizeof(wchar);
Atomic *rc = (Atomic *)MemoryAllocSz(sz);
if(count != INT_MAX)
count = int(((sz - sizeof(Atomic)) >> 1) - 1);
count = int(((sz - sizeof(Atomic)) / sizeof(wchar)) - 1);
*rc = 1;
return (wchar *)(rc + 1);
}
@ -26,7 +26,7 @@ void WString0::Free()
MemoryFree(&rc);
}
else
MemoryFree48(ptr);
MemoryFree(ptr);
}
}
@ -94,15 +94,8 @@ void WString0::Set0(const WString0& src)
AtomicInc(Rc());
}
else {
ptr = (wchar *)MemoryAlloc48();
qword *t = (qword *)ptr;
qword *s = (qword *)src.ptr;
t[0] = s[0];
t[1] = s[1];
t[2] = s[2];
t[3] = s[3];
t[4] = s[4];
t[5] = s[5];
ptr = (wchar *)MemoryAlloc((SMALL + 1) * sizeof(wchar));
memcpy(ptr, src.ptr, sizeof(wchar) * (SMALL + 1));
}
Dsyn();
}
@ -224,6 +217,11 @@ WString::WString(const char *s) {
*this = ToUnicode(s, s ? (int)strlen(s) : 0, CHARSET_DEFAULT);
}
WString::WString(const char16 *s) {
Zero();
*this = ToUtf32(s);
}
WString::WString(const char *s, int n) {
Zero();
*this = ToUnicode(s, n, CHARSET_DEFAULT);
@ -249,30 +247,26 @@ WString WString::GetVoid()
}
#ifndef _HAVE_NO_STDWSTRING
static_assert(sizeof(wchar_t) == 4 || sizeof(wchar_t) == 2, "Invalid wchar_t size");
WString::WString(const std::wstring& s)
{
if(sizeof(std::wstring::value_type) == sizeof(wchar)) {
WString0::Set0((wchar *)s.c_str(), (int)s.length());
}
else {
WString0::Zero();
std::wstring::const_iterator i = s.begin();
while(i < s.end())
Cat(*i++);
}
WString0::Zero();
if(sizeof(wchar_t) == 4)
*this = WString((const wchar *)s.c_str(), (int)s.size());
if(sizeof(wchar_t) == 2)
*this = ToUtf32((char16 *)s.c_str(), (int)s.size());
}
WString::operator std::wstring() const
std::wstring WString::ToStd() const
{
if(sizeof(std::wstring::value_type) == sizeof(wchar))
return std::wstring((std::wstring::value_type *)Begin(),
(std::wstring::value_type *)End());
else {
std::wstring r;
const wchar *s = Begin();
while(s < End())
r += *s++;
return r;
if(sizeof(wchar_t) == 4) {
const wchar *s = begin();
return std::wstring((const wchar_t *)begin(), GetCount());
}
if(sizeof(wchar_t) == 2) {
Vector<char16> h = ToUtf16(*this);
return std::wstring((const wchar_t *)h.begin(), h.GetCount());
}
}
#endif
@ -286,14 +280,14 @@ void WStringBuffer::Zero()
wchar *WStringBuffer::Alloc(int count, int& alloc)
{
if(count <= 23) {
wchar *s = (wchar *)MemoryAlloc48();
wchar *s = (wchar *)MemoryAlloc(24 * sizeof(wchar));
alloc = WString0::SMALL;
return s;
}
else {
size_t sz = sizeof(Atomic) + ((size_t)count + 1) * sizeof(wchar);
Atomic *rc = (Atomic *)MemoryAlloc(sz);
alloc = (int)min((size_t)INT_MAX, ((sz - sizeof(Atomic)) >> 1) - 1);
alloc = (int)min((size_t)INT_MAX, ((sz - sizeof(Atomic)) / sizeof(wchar)) - 1);
ASSERT(alloc >= 0);
*rc = 1;
return (wchar *)(rc + 1);
@ -304,7 +298,7 @@ void WStringBuffer::Free()
{
int all = (int)(limit - pbegin);
if(all == WString0::SMALL)
MemoryFree48(pbegin);
MemoryFree(pbegin);
if(all > WString0::SMALL)
MemoryFree((Atomic *)pbegin - 1);
}
@ -357,7 +351,7 @@ void WStringBuffer::Cat(int c, int l)
{
if(pend + l > limit)
Expand(max(GetLength(), l) + GetLength(), NULL, l);
memset16(pend, c, l);
memset32(pend, c, l);
pend += l;
}
@ -408,9 +402,9 @@ int CompareNoCase(const WString& a, const WString& b)
int CompareNoCase(const WString& a, const wchar *b)
{
#ifdef DEPRECATED
return IterCompare(a.Begin(), a.End(), b, b + wstrlen(b), WStringICompare__());
return IterCompare(a.Begin(), a.End(), b, b + strlen__(b), WStringICompare__());
#else
return CompareRanges(a, SubRange(b, b + wstrlen(b)), WStringICompare__());
return CompareRanges(a, SubRange(b, b + strlen__(b)), WStringICompare__());
#endif
}

View file

@ -158,14 +158,14 @@ void DeleteWinReg(const String& key, HKEY base, dword wow) {
}
String GetSystemDirectory() {
char temp[MAX_PATH];
WCHAR temp[MAX_PATH];
*temp = 0;
::GetSystemDirectory(temp, sizeof(temp));
return FromSystemCharset(temp);
::GetSystemDirectoryW(temp, sizeof(temp));
return FromSystemCharsetW(temp);
}
String GetWindowsDirectory() {
wchar temp[MAX_PATH];
WCHAR temp[MAX_PATH];
*temp = 0;
GetWindowsDirectoryW(temp, sizeof(temp));
return FromSystemCharsetW(temp);
@ -179,7 +179,7 @@ void *GetDllFn(const char *dll, const char *fn)
}
String GetModuleFileName(HINSTANCE instance) {
wchar h[_MAX_PATH];
WCHAR h[_MAX_PATH];
GetModuleFileNameW(instance, h, _MAX_PATH);
return FromSystemCharsetW(h);
}

View file

@ -31,12 +31,12 @@ void Xmlize(XmlIO& xml, WString& var)
h = ToUtf8(var);
Xmlize(xml, h);
if(xml.IsLoading())
var = FromUtf8(h);
var = ToUtf32(h);
}
template<> void XmlAttrLoad(WString& var, const String& text)
{
var = FromUtf8(text);
var = ToUtf32(text);
}
template<> String XmlAttrStore(const WString& var)

View file

@ -185,4 +185,6 @@
#define CPP_11
#endif
#define WCHAR32 1 // this version of U++ has 32 bit wchar
#endif

View file

@ -125,11 +125,37 @@ void Heap::DblCheck(Page *p)
while(p != l);
}
int Heap::CheckFree(FreeLink *l, int k)
int Heap::CheckFree(FreeLink *l, int k, bool pg)
{
char h[200];
int n = 0;
Page *page = GetPage(l);
if(l && page->klass != k) {
sprintf(h, "Invalid freelist block at 0x%p sz: %d (klass mismatch)", l, Ksz(k));
Panic(h);
}
while(l) {
if(l->next) {
Page *lp = GetPage(l->next);
if(pg && lp != page) {
sprintf(h, "Invalid freelist block at 0x%p sz: %d (out of page) (-> 0x%p)", l, Ksz(k), l->next);
Panic(h);
}
if((4096 - ((uintptr_t)(l->next) & (uintptr_t)4095)) % Ksz(k) != 0) {
sprintf(h, "Invalid freelist block at 0x%p sz: %d (invalid address)", l, Ksz(k));
Panic(h);
}
if(lp->klass != k) {
sprintf(h, "Invalid freelist block at 0x%p sz: %d (next klass mismatch)", l, Ksz(k));
Panic(h);
}
}
DbgFreeCheckK(l, k);
l = l->next;
n++;
}
@ -167,7 +193,7 @@ void Heap::Check() {
break;
p = p->next;
}
CheckFree(cache[i], i);
CheckFree(cache[i], i, false);
}
DLink *l = large->next;

View file

@ -174,8 +174,6 @@ size_t GetMemoryBlockSize(void *ptr)
void *MemoryAlloc32() { return MemoryAlloc(32); }
void MemoryFree32(void *ptr) { return MemoryFree(ptr); }
void *MemoryAlloc48() { return MemoryAlloc(48); }
void MemoryFree48(void *ptr) { return MemoryFree(ptr); }
void MemoryCheckDebug()
{

View file

@ -220,19 +220,21 @@ bool Heap::TryRealloc(void *ptr, size_t& newsize)
}
}
// TODO: When small block fits, we could still return true
return false;
}
size_t Heap::LGetBlockSize(void *ptr) {
LBlkHeader *h = (LBlkHeader *)ptr - 1;
BlkPrefix *h = (BlkPrefix *)ptr - 1;
if(h->heap == NULL) { // huge block
Mutex::Lock __(mutex);
DLink *h = (DLink *)ptr - 1;
return h->size;
DLink *hh = (DLink *)h - 1;
return hh->size;
}
return h->GetSize();
return ((int)h->GetSize() * LUNIT) - sizeof(BlkPrefix);
}
#endif

View file

@ -388,6 +388,8 @@ struct HeapMutexLock {
~HeapMutexLock() { LeaveHeapMutex(); }
};
void MemoryFreeThread();
struct HeapExitThreadGuard {
void Used() {}
~HeapExitThreadGuard() { MemoryFreeThread(); }
@ -608,31 +610,6 @@ void MemoryFree32_i(void *ptr)
void MemoryFree32(void *ptr) { MemoryFree32_i(ptr); }
void *MemoryAlloc48()
{
LTIMING("MemoryAlloc48");
Heap *heap = heap_tls__;
if(heap)
return LogAlloc(heap->Alloc48(), 48);
else {
HeapMutexLock __;
return LogAlloc(MakeHeap()->Alloc48(), 48);
}
}
void MemoryFree48(void *ptr)
{
LTIMING("MemoryFree48");
LogFree(ptr);
Heap *heap = heap_tls__;
if(heap)
heap->Free48(ptr);
else {
HeapMutexLock __;
MakeHeap()->Free48(ptr);
}
}
#endif
void MemoryFreeThread()

View file

@ -58,18 +58,6 @@ This has the same functionality as MemoryFree([%-*@3 ptr]), but
is slightly faster.&]
[s3;%% &]
[s4; &]
[s5;:Upp`:`:MemoryAlloc48`(`): [@(0.0.255) void]_`*[* MemoryAlloc48]()&]
[s2;%% Allocates memory block of exactly 48 bytes. This has the same
functionality as MemoryAlloc(32), but is slightly faster.&]
[s3; &]
[s4; &]
[s5;:Upp`:`:MemoryFree48`(void`*`): [@(0.0.255) void]_[* MemoryFree48]([@(0.0.255) void]_`*
[*@3 ptr])&]
[s2;%% Frees a memory block previously allocated by MemoryAlloc48.
This has the same functionality as MemoryFree([%-*@3 ptr]), but
is slightly faster.&]
[s3;%% &]
[s4; &]
[s5;:Upp`:`:MemoryTryRealloc`(void`*`,size`_t`&`): [@(0.0.255) bool]_[* MemoryTryRealloc](
[@(0.0.255) void]_`*[*@3 ptr], [_^size`_t^ size`_t][@(0.0.255) `&]_[*@3 newsize])&]
[s2;%% Attempts to change the size of block at [%-*@3 ptr] to something

View file

@ -1,5 +1,4 @@
topic "Stream utilities";
[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,0#27521748481378242620020725143825:desc]
[0 $$3,0#96390100711032703541132217272105:end]
@ -9,6 +8,7 @@ topic "Stream utilities";
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
[b42;2 $$9,9#13035079074754324216151401829390:normal]
[2 $$0,0#00000000000000000000000000000000:Default]
[{_}
[ {{10000@(113.42.0) [s0;%% [*@2;4 Stream helpers]]}}&]
[s0;%% &]
@ -40,16 +40,9 @@ stream. Returns the actual number of bytes copied. With default
[%-*@3 count] value it copies all data from [%-*@3 src] until EOF.&]
[s3; &]
[s4; &]
[s5;:CoutUTF8`(`): [@(0.0.255) void]_[* CoutUTF8]()&]
[s2;%% In Win32, setups console output for UTF8. NOP in POSIX.&]
[s3; &]
[s4; &]
[s5;:Cout`(`): [_^Stream^ Stream][@(0.0.255) `&]_[* Cout]()&]
[s2;%% Returns special output stream representing console output.
Data written to this stream are displayed as characters in console.
In Win32, encoding is converted to default console encoding,
or is not convereted at all if CoutUTF8 was called.&]
[s7;%% [*/ Return value]-|Console stream.&]
Data written to this stream are displayed as characters in console.&]
[s3; &]
[s4; &]
[s5;:Cerr`(`): [_^Stream^ Stream][@(0.0.255) `&]_[* Cerr]()&]

View file

@ -704,37 +704,6 @@ as 0 is considered as NULL pointer too...&]
[s7; [%-*C@3 count]-|Repeat count.&]
[s3; &]
[s4;%- &]
[s5;:Stream`:`:PutW`(const wchar`*`,int`):%- [@(0.0.255) void]_[* PutW]([@(0.0.255) const]_
[_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:wchar`:`:typedef^ wchar
]_`*[*@3 s], [@(0.0.255) int]_[*@3 count])&]
[s2; Writes a specified number of wchars (16`-bit character values)
to the stream in platform specific format (little`-endian or
big`-endian).&]
[s7; [%-*C@3 s]-|String to write.&]
[s7; [%-*C@3 count]-|Length of string.&]
[s3; &]
[s4;%- &]
[s5;:Stream`:`:GetW`(wchar`*`,int`):%- [_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:dword`:`:typedef^ d
word]_[* GetW]([_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:wchar`:`:typedef^ w
char]_`*[*@3 s], [@(0.0.255) int]_[*@3 count])&]
[s2; Reads a specified number of wchars (16`-bit character values)
from the stream in platform specific format.&]
[s7; [%-*C@3 s]-|Pointer to buffer to receive wchars.&]
[s7; [%-*C@3 count]-|Number of wchars.&]
[s7; [*/ Return value]-|Number of wchars actually read.&]
[s3; &]
[s4;%- &]
[s5;:Stream`:`:GetAllW`(wchar`*`,int`):%- [@(0.0.255) bool]_[* GetAllW]([_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:wchar`:`:typedef^ w
char]_`*[*@3 s], [@(0.0.255) int]_[*@3 count])&]
[s2; Reads a specified number of wchars (16`-bit character values)
from the stream in platform specific format. If there is not
enough data in the stream, LoadError is invoked (that in turn
might throw an exception).&]
[s7; [%-*C@3 s]-|&]
[s7; [%-*C@3 count]-|&]
[s7; [*/ Return value]-|&]
[s3; &]
[s4;%- &]
[s5;:Stream`:`:PutCrLf`(`):%- [@(0.0.255) void]_[* PutCrLf]()&]
[s2; Writes CR`-LF pair to the stream. &]
[s3; &]

View file

@ -109,7 +109,8 @@ td`::string][@(0.0.255) `&]_[*@3 s])&]
st]&]
[s2; Returns a number of characters contained in String. This is
equal GetCount() if default charset is not UTF`-8, but different
for UTF`-8. It is faster equivalent of ToWString().GetCount().&]
for UTF`-8 where it returns a number of unicode codepoints. It
is faster equivalent of ToWString().GetCount().&]
[s3;%- &]
[s4;%- &]
[s5;:String`:`:ToWString`(`)const:%- [_^WString^ WString]_[* ToWString]()_[@(0.0.255) const

View file

@ -411,12 +411,17 @@ void InvalidateFileTimeCache(const String& path)
Time GetFileTimeCached(const String& p)
{
LTIMING("GetFileTimeCached");
Mutex::Lock __(s_PathFileTimeMutex);
int q = s_PathFileTime.Find(p);
if(q >= 0)
return s_PathFileTime[q];
{
Mutex::Lock __(s_PathFileTimeMutex);
int q = s_PathFileTime.Find(p);
if(q >= 0)
return s_PathFileTime[q];
}
Time m = FileGetTime(p);
s_PathFileTime.Put(p, m);
{
Mutex::Lock __(s_PathFileTimeMutex);
s_PathFileTime.Put(p, m);
}
return m;
}

View file

@ -479,12 +479,7 @@ Image MakeDragImage(const Image& arrow, Image sample);
Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample)
{
#ifdef PLATFORM_WIN32
if(IsWin2K())
return MakeDragImage(arrow, sample);
else
#endif
return arrow98;
return MakeDragImage(arrow, sample);
}
};

View file

@ -12,12 +12,7 @@ Image MakeDragImage(const Image& arrow, Image sample);
Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample)
{
#ifdef PLATFORM_WIN32
if(IsWin2K())
return MakeDragImage(arrow, sample);
else
#endif
return arrow98;
return MakeDragImage(arrow, sample);
}
END_UPP_NAMESPACE

View file

@ -1,5 +1,7 @@
#include "CocoMM.h"
#include <dlfcn.h>
#ifdef GUI_COCOA
#define LLOG(x)
@ -15,9 +17,13 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon
Set(ink);
bool synth;
CFRef<CGFontRef> cgFont = CTFontCopyGraphicsFont(CT_Font(font, synth), NULL);
CGContextSetFont(cgHandle, cgFont);
CTFontRef ct_font = CT_Font(font, synth);
static void (*CTFontDrawGlyphs)(CTFontRef, const CGGlyph[], const CGPoint[], size_t, CGContextRef);
ONCELOCK {
*reinterpret_cast<void**>(&CTFontDrawGlyphs) = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs");
}
Point off = GetOffset();
CGAffineTransform tm = CGAffineTransformMakeTranslation(x + off.x, y + off.y);
@ -52,7 +58,16 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon
}
CGContextSetFontSize(cgHandle, font.GetHeight());
CGContextShowGlyphsAtPositions(cgHandle, g, p, nn); }
if(CTFontDrawGlyphs)
CTFontDrawGlyphs(ct_font, g, p, nn, cgHandle);
else {
CFRef<CGFontRef> cgFont = CTFontCopyGraphicsFont(ct_font, NULL);
CGContextSetFont(cgHandle, cgFont);
CGContextShowGlyphsAtPositions(cgHandle, g, p, nn);
}
};
}
#endif

View file

@ -83,27 +83,28 @@ void SetSurface(Draw& w, const Rect& dest, const RGBA *pixels, Size srcsz, Point
void SetSurface(Draw& w, int x, int y, int cx, int cy, const RGBA *pixels);
enum {
K_DELTA = 0x010000,
K_DELTA = 0x200000,
K_CHAR_LIM = 0x200000, // lower that this, key in Key is Unicode codepoint
K_ALT = 0x080000,
K_SHIFT = 0x040000,
K_CTRL = 0x020000,
K_ALT = 0x1000000,
K_SHIFT = 0x800000,
K_CTRL = 0x400000,
#ifdef PLATFORM_COCOA
K_OPTION = 0x2000000,
#endif
K_KEYUP = 0x100000,
K_KEYUP = 0x4000000,
K_MOUSEMIDDLE = 0x200000,
K_MOUSERIGHT = 0x400000,
K_MOUSELEFT = 0x800000,
K_MOUSEDOUBLE = 0x1000000,
K_MOUSETRIPLE = 0x2000000,
K_MOUSEMIDDLE = 0x2,
K_MOUSERIGHT = 0x4,
K_MOUSELEFT = 0x8,
K_MOUSEDOUBLE = 0x10,
K_MOUSETRIPLE = 0x20,
K_SHIFT_CTRL = K_SHIFT|K_CTRL,
#ifdef PLATFORM_COCOA
K_OPTION = 0x4000000,
#endif
K_PEN = 0x8000000,
K_PEN = 0x80,
IK_DBL_CLICK = 0x40000001, // this is just to get the info that the entry is equal to dbl-click to the menu

View file

@ -68,7 +68,7 @@ bool Ctrl::DispatchKey(dword keycode, int count)
String kl;
dword k = keycode;
const char *l = "";
if(k < 65536) {
if(k < K_CHAR_LIM) {
kl << "CHAR \'" << ToUtf8((wchar)keycode) << "\' (" << keycode << ')';
l = " ";
}

View file

@ -6,13 +6,24 @@ namespace Upp {
static StaticMutex sGLock;
// #define DELAY_WATCH 1000 _DBG_
static thread_local int sGLockLevel = 0;
void EnterGuiMutex()
{
LLOG(">EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread());
if(sGLockLevel++ == 0)
if(sGLockLevel++ == 0) {
#if DELAY_WATCH
for(int i = 0; i < DELAY_WATCH; i++) {
if(sGLock.TryEnter()) return;
Sleep(1);
}
Panic("Long timer procedure detected!");
#else
sGLock.Enter();
#endif
}
LLOG("EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread());
}

View file

@ -4,6 +4,7 @@ namespace Upp {
// #define LOG_QUEUE
#define LLOG(x) // LOG(x)
// #define DELAY_WATCH 1000 _DBG_
int MemoryProbeInt;
@ -120,7 +121,14 @@ void Ctrl::TimerProc(dword time)
else
delete todo;
sTimerLock.Leave();
#if DELAY_WATCH
int tm = msecs();
#endif
cb();
#if DELAY_WATCH
if(msecs() - tm > DELAY_WATCH)
Panic("Long timer procedure detected!");
#endif
sTimerLock.Enter();
}
time = msecs();

View file

@ -21,14 +21,15 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon
Mutex::Lock ___(sFontLock); // need this because of GetWin32Font
HGDIOBJ orgfont = ::SelectObject(handle, GetWin32Font(font, angle));
int ascent = font.Info().GetAscent();
Vector<char16> text16 = ToUtf16(text, n);
if(angle) {
double sina, cosa;
Draw::SinCos(angle, sina, cosa);
Size offset;
::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, (const WCHAR *)text, n, dx);
::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, text16.begin(), text16.GetCount(), dx);
}
else
::ExtTextOutW(handle, x, y + ascent, 0, NULL, (const WCHAR *)text, n, dx);
::ExtTextOutW(handle, x, y + ascent, 0, NULL, text16.begin(), text16.GetCount(), dx);
::SelectObject(handle, orgfont);
}

View file

@ -135,7 +135,7 @@ GlyphInfo XftGetGlyphInfoSys(Font font, int chr)
{
wchar h = chr;
XGlyphInfo info;
XftTextExtents16(Xdisplay, GetXftMetricFont(font, 0), &h, 1, &info);
XftTextExtents32(Xdisplay, GetXftMetricFont(font, 0), &h, 1, &info);
GlyphInfo gi;
gi.width = info.xOff;
gi.lspc = -info.x;

View file

@ -464,12 +464,12 @@ PrintDraw::PrintDraw(HDC hdc, const char *docname)
: SystemDraw(hdc)
{
GuiLock __;
DOCINFO di;
DOCINFOW di;
memset(&di, 0, sizeof(di));
di.cbSize = sizeof(di);
String sys_docname = ToSystemCharset(docname);
di.lpszDocName = ~sys_docname;
if(::StartDoc(hdc, &di) <= 0)
Vector<char16> sys_docname = ToSystemCharsetW(docname);
di.lpszDocName = sys_docname;
if(::StartDocW(hdc, &di) <= 0)
aborted = true;
else
InitPrinter();

View file

@ -223,8 +223,14 @@ void RTFEncoder::Command(const char *cmd, int param)
void RTFEncoder::PutText(const wchar *text)
{
for(; *text; text++)
if((uint16)*text >= 128)
stream.Put(Format("\\u%d?", (int16)*text));
if(*text >= 128) {
if(*text >= 65536) {
Vector<char16> h = ToUtf16(*text);
stream << "\\uc0 \\u" << (unsigned)h[0] << "\\uc1 \\u" << (unsigned)h[1];
}
else
stream.Put(Format("\\u%d?", (int16)*text));
}
else {
if(*text == '{' || *text == '}' || *text == '\\')
stream.Put('\\');

View file

@ -240,7 +240,7 @@ WString GetWString(PasteClip& clip)
{
GuiLock __;
if(clip.IsAvailable("text"))
return FromUtf8(clip.Get("text"));
return ToUtf32(clip.Get("text"));
return Null;
}
@ -286,7 +286,7 @@ String ReadClipboardText()
WString ReadClipboardUnicodeText()
{
return FromUtf8(Ctrl::gclipboard().Get("text"));
return ToUtf32(Ctrl::gclipboard().Get("text"));
}
bool IsClipboardAvailable(const char *id)

View file

@ -325,7 +325,7 @@ void Ctrl::AddEvent(gpointer user_data, int type, const Value& value, GdkEvent *
void Ctrl::IMCommit(GtkIMContext *context, gchar *str, gpointer user_data)
{
GuiLock __;
AddEvent(user_data, EVENT_TEXT, FromUtf8(str), NULL);
AddEvent(user_data, EVENT_TEXT, ToUtf32(str), NULL);
}
bool Ctrl::ProcessInvalids()
@ -525,7 +525,7 @@ void Ctrl::Proc()
case GDK_KEY_RELEASE:
kv = CurrentEvent.value[0];
hw = CurrentEvent.value[1];
if(kv >= 0 && kv < 65536) {
if(kv >= 0 && kv < K_CHAR_LIM) {
LLOG("keyval " << FormatIntHex(kv) << ' ' << (char)kv);
if(kv >= 'a' && kv <= 'z')
kv = kv - 'a' + 'A';

View file

@ -329,7 +329,7 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, const Rect& src,
sz = Ctrl::GetVirtualScreenArea().GetSize();
m.img = IsPrinter() && GetDeviceCaps(GetHandle(), NUMCOLORS) == 2 ? Dither(img, 360) : img; // If printer does not support color, dither
cache.Get(m).Paint(*this, x, y, src, color);
cache.Shrink(4 * sz.cx * sz.cy, IsWinNT() ? 1000 : 100);
cache.Shrink(4 * sz.cx * sz.cy, 1000);
}
void ImageDraw::Section::Init(int cx, int cy)
@ -567,12 +567,9 @@ HICON SystemDraw::IconWin32(const Image& img, bool cursor)
Point p = img.GetHotSpot();
iconinfo.xHotspot = p.x;
iconinfo.yHotspot = p.y;
static Size cursor_size(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
Size tsz = sz;
if(!IsWin2K() && cursor)
tsz = cursor_size;
Size csz = Size(min(tsz.cx, sz.cx), min(tsz.cy, sz.cy));
if(IsWinXP() && !ImageFallBack) {
if(!ImageFallBack) {
RGBA *pixels;
BitmapInfo32__ bi(tsz.cx, tsz.cy);
HDC dcMem = ::CreateCompatibleDC(NULL);

View file

@ -500,8 +500,19 @@ RTFParser::TOKEN RTFParser::Fetch()
break;
}
}
if(c && !skip)
if(c && !skip) {
text.Cat(c);
if(text.GetCount() >= 2) {
char16 h[2];
h[0] = text[text.GetCount() - 2];
h[1] = text[text.GetCount() - 1];
wchar c = ReadSurrogatePair(h, h + 2);
if(c) {
text.TrimLast(2);
text.Cat(c);
}
}
}
skip = nskip;
}
@ -1080,7 +1091,7 @@ String RTFParser::ReadBinHex(char& odd) const
byte v = ctoi(odd);
String out;
for(const wchar *s = text.Begin(); *s; s++) {
byte w = (*s >= '0' && *s <= '9' ? *s - '0'
byte w = (byte)(*s >= '0' && *s <= '9' ? *s - '0'
: *s >= 'A' && *s <= 'F' ? *s - 'A' + 10
: *s >= 'a' && *s <= 'f' ? *s - 'a' + 10
: 255);

View file

@ -75,12 +75,8 @@ void TopWindow::SyncTitle()
GuiLock __;
LLOG("TopWindow::SyncTitle0 " << UPP::Name(this));
HWND hwnd = GetHWND();
if(hwnd) {
if(IsWindowUnicode(hwnd))
::SetWindowTextW(hwnd, (const WCHAR*)~title);
else
::SetWindowText(hwnd, ToSystemCharset(title.ToString()));
}
if(hwnd)
::SetWindowTextW(hwnd, ToSystemCharsetW(title));
}
void TopWindow::DeleteIco()
@ -250,7 +246,7 @@ void TopWindow::Open(HWND hwnd)
if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1))
DistributeAccessKeys();
USRLOG(" OPEN " << Desc(this));
LLOG("TopWindow::Open, owner HWND = " << FormatIntHex((int)hwnd, 8) << ", Active = " << FormatIntHex((int)::GetActiveWindow(), 8));
LLOG("TopWindow::Open, owner HWND = " << hwnd << ", Active = " << hwnd);
IgnoreMouseUp();
SyncCaption();
LLOG("WindowStyles: " << WindowStyleAsString(style, exstyle));

View file

@ -232,7 +232,8 @@ void AppendClipboardText(const String& s)
void AppendClipboardUnicodeText(const WString& s)
{
AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength());
Vector<char16> ws = ToUtf16(s);
AppendClipboard("wtext", (const byte *)ws.begin(), 2 * ws.GetCount());
}
const char *ClipFmtsText()
@ -245,7 +246,7 @@ String GetString(PasteClip& clip)
GuiLock __;
if(clip.Accept("wtext")) {
String s = ~clip;
return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString();
return ToUtf8((const char16 *)~s, strlen16((const char16 *)~s));
}
if(clip.Accept("text"))
return ~clip;
@ -257,7 +258,7 @@ WString GetWString(PasteClip& clip)
GuiLock __;
if(clip.Accept("wtext")) {
String s = ~clip;
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
return ToUtf32((const char16 *)~s, strlen16((const char16 *)~s));
}
if(clip.Accept("text"))
return (~clip).ToWString();
@ -326,7 +327,7 @@ String ReadClipboardText()
WString ReadClipboardUnicodeText()
{
String s = ReadClipboard((const char *)CF_UNICODETEXT);
return WString((const wchar *)~s, wstrlen((const wchar *)~s));
return ToUtf32((const char16 *)~s, strlen16((const char16 *)~s));
}
bool IsClipboardAvailable(const char *id)
@ -475,7 +476,7 @@ Vector<String> GetClipFiles(const String& data)
const sDROPFILES *df = (const sDROPFILES *)~data;
const char *s = ((const char *)df + df->offset);
if(df->unicode) {
const wchar *ws = (wchar *)s;
const char16 *ws = (char16 *)s;
while(*ws) {
WString fn;
while(*ws)

View file

@ -484,10 +484,7 @@ Image MakeDragImage(const Image& arrow, Image sample);
Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample)
{
if(IsWin2K())
return MakeDragImage(arrow, sample);
else
return arrow98;
return MakeDragImage(arrow, sample);
}
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,

View file

@ -142,7 +142,7 @@ public:
SystemDraw(HDC hdc);
virtual ~SystemDraw();
bool CanSetSurface() { return Pixels() && IsWinNT(); }
bool CanSetSurface() { return Pixels(); }
};
#ifndef PLATFORM_WINCE

View file

@ -366,8 +366,23 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
keycode = KEYtoK((dword)wParam) | K_KEYUP;
else
if(message == WM_CHAR && wParam != 127 && wParam > 32 || wParam == 32 && KEYtoK(VK_SPACE) == K_SPACE) {
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX Unicode patch
if(IsWindowUnicode(hwnd)) { // TRC 04/10/17: ActiveX Unicode patch
static WCHAR surr[2];
keycode = (dword)wParam;
if((keycode & 0XFC00) == 0xD800) { // covert UTF16 surrogate pair to UTF32 codepoint
surr[0] = (WCHAR)keycode;
return 0L;
}
if((keycode & 0xFC00) == 0xDC00) {
surr[1] = (WCHAR)keycode;
keycode = ReadSurrogatePair(surr, surr + 2);
surr[0] = 0;
if(!keycode)
return 0L;
}
else
surr[0] = 0;
}
else {
char b[20];
::GetLocaleInfo(MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT),

View file

@ -5,7 +5,7 @@
namespace Upp {
#define LLOG(x) // DLOG(x)
#define LOGTIMING 0
// #define LOGTIMING 1 _DBG_
#ifdef _DEBUG
#define LOGMESSAGES 0
@ -23,8 +23,7 @@ hash_t GetHashValue(const HWND& h)
bool Ctrl::GetMsg(MSG& msg)
{
if(!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) return false;
return IsWindowUnicode(msg.hwnd) ? PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)
: PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
return PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE);
}
static bool sFinished;
@ -114,7 +113,7 @@ LRESULT CALLBACK Ctrl::OverwatchWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
}
}
if(ShutdownBlockReasonCreate)
ShutdownBlockReasonCreate(hwnd, ~WString(t_("waiting for user response")));
ShutdownBlockReasonCreate(hwnd, ToSystemCharsetW(t_("waiting for user response")));
EndSession();
ELOGW("WM_QUERYENDSESSION 1");
OverwatchEndSession.Wait();
@ -153,10 +152,7 @@ DWORD WINAPI Ctrl::Win32OverwatchThread(LPVOID)
MSG Msg;
while(GetMessage(&Msg, NULL, 0, 0) > 0) {
TranslateMessage(&Msg);
if(IsWindowUnicode(Msg.hwnd))
DispatchMessageW(&Msg);
else
DispatchMessage(&Msg);
DispatchMessageW(&Msg);
}
ELOGW("OverWatch 3");
return 0;
@ -239,18 +235,15 @@ void Ctrl::InitWin32(HINSTANCE hInstance)
sMainThreadId = GetCurrentThreadId();
#define ILOG(x) // RLOG(x)
Ctrl::hInstance = hInstance;
ILOG("RegisterClassW");
#ifndef PLATFORM_WINCE
if(IsWinNT())
#endif
{
ILOG("RegisterClassW");
WNDCLASSW wc;
Zero(wc);
wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)Ctrl::WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = IsWinVista() ? (HBRUSH)(COLOR_WINDOW+1) : (HBRUSH)NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = L"UPP-CLASS-W";
RegisterClassW(&wc);
wc.style = 0x20000|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
@ -263,35 +256,37 @@ void Ctrl::InitWin32(HINSTANCE hInstance)
wc.lpszClassName = L"UPP-CLASS-SB-DS-W";
RegisterClassW(&wc);
}
ILOG("RegisterClassA");
WNDCLASS wc;
Zero(wc);
wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)Ctrl::WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = IsWinVista() ? (HBRUSH)(COLOR_WINDOW+1) : (HBRUSH)NULL;
wc.lpszClassName = L_("UPP-CLASS-A");
RegisterClass(&wc);
if(IsWinXP()) {
{
ILOG("RegisterClassA");
WNDCLASS wc;
Zero(wc);
wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)Ctrl::WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = IsWinVista() ? (HBRUSH)(COLOR_WINDOW+1) : (HBRUSH)NULL;
wc.lpszClassName = L_("UPP-CLASS-A");
RegisterClass(&wc);
wc.style = 0x20000|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wc.lpszClassName = L_("UPP-CLASS-DS-A");
RegisterClass(&wc);
}
wc.style = CS_SAVEBITS|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wc.lpszClassName = L_("UPP-CLASS-SB-A");
RegisterClass(&wc);
if(IsWinXP()) {
wc.style = CS_SAVEBITS|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
wc.lpszClassName = L_("UPP-CLASS-SB-A");
RegisterClass(&wc);
wc.style = 0x20000|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS;
wc.lpszClassName = L_("UPP-CLASS-SB-DS-A");
RegisterClass(&wc);
}
wc.style = 0;
wc.lpszClassName = L_("UPP-TIMER");
wc.hCursor = NULL;
wc.lpfnWndProc = &Ctrl::UtilityProc;
RegisterClass(&wc);
WNDCLASS wca;
Zero(wca);
wca.hInstance = hInstance;
wca.hbrBackground = (HBRUSH)NULL;
wca.style = 0;
wca.lpszClassName = L_("UPP-TIMER");
wca.hCursor = NULL;
wca.lpfnWndProc = &Ctrl::UtilityProc;
RegisterClass(&wca);
ILOG("InitTimer");
InitTimer();
@ -307,19 +302,10 @@ void Ctrl::InitWin32(HINSTANCE hInstance)
OleInitialize(NULL);
/* TRC 05/11/14: moved to GuiSleep to avoid thread creation in OCX DllMain
DWORD dummy;
OverwatchThread = CreateThread(NULL, 0x100000, Win32OverwatchThread, NULL, 0, &dummy);
ExitLoopEvent().Wait();
*/
// TRC 05/11/18: pSetLayeredWindowAttributes moved to GLOBAL_VAR (see below) to make OCX initialization simpler
Csizeinit();
#undef ILOG
if(IsWin7())
GlobalBackPaint();
GlobalBackPaint();
EnterGuiMutex();
}
@ -487,20 +473,12 @@ void Ctrl::Create(HWND parent, DWORD style, DWORD exstyle, bool savebits, int sh
top = new Top;
ASSERT(!parent || IsWindow(parent));
style &= ~WS_VISIBLE;
if(!IsWinXP())
dropshadow = false;
if(IsWinNT() && (!parent || IsWindowUnicode(parent)))
top->hwnd = CreateWindowExW(exstyle,
savebits ? dropshadow ? L"UPP-CLASS-SB-DS-W" : L"UPP-CLASS-SB-W"
: dropshadow ? L"UPP-CLASS-DS-W" : L"UPP-CLASS-W",
L"", style, 0, 0, 0, 0,
parent, NULL, hInstance, this);
else
top->hwnd = CreateWindowEx(exstyle,
savebits ? dropshadow ? "UPP-CLASS-SB-DS-A" : "UPP-CLASS-SB-A"
: dropshadow ? "UPP-CLASS-DS-A" : "UPP-CLASS-A",
"", style, 0, 0, 0, 0,
parent, NULL, hInstance, this);
dropshadow = false;
top->hwnd = CreateWindowEx(exstyle,
savebits ? dropshadow ? "UPP-CLASS-SB-DS-W" : "UPP-CLASS-SB-W"
: dropshadow ? "UPP-CLASS-DS-W" : "UPP-CLASS-W",
"", style, 0, 0, 0, 0,
parent, NULL, hInstance, this);
inloop = false;
@ -636,9 +614,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
#if LOGMESSAGES
bool logblk = false;
if(message != WM_SETCURSOR && message != WM_CTLCOLORBTN && message != WM_TIMER &&
#ifndef PLATFORM_WINCE
message != WM_NCHITTEST && message != WM_ENTERIDLE &&
#endif
message != WM_CTLCOLORDLG && message != WM_CTLCOLOREDIT && message != WM_CTLCOLORLISTBOX &&
message != WM_CTLCOLORMSGBOX && message != WM_CTLCOLORSCROLLBAR &&
message != WM_CTLCOLORSTATIC && message != WM_CANCELMODE &&
@ -655,7 +631,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
#endif
LRESULT l = 0;
if(w && (w->GetHWND() || w->isdhctrl)) {
#if defined(_DEBUG) && LOGTIMING
#if LOGTIMING
int ticks = msecs();
String wname = w->Name();
#endif
@ -663,7 +639,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
l = w->WindowProc(message, wParam, lParam);
if(pw)
pw->SyncMoves();
#if defined(_DEBUG) && LOGTIMING
#if LOGTIMING
String msgname;
for(WinMsg *m = sWinMsg; m->ID; m++)
if(m->ID == message) {
@ -672,7 +648,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP
}
if(IsNull(msgname))
msgname = NFormat("0x%04x", (int)message);
LLOG(NFormat("T+%d %s 0x%08x 0x%08x -> %s", msecs(ticks), msgname, (int)wParam, (int)lParam, wname));
RLOG(NFormat("T+%d %s 0x%08x 0x%08x -> %s", msecs(ticks), msgname, (int)wParam, (int)lParam, wname));
#endif
}
else
@ -755,10 +731,7 @@ void Ctrl::sProcessMSG(MSG& msg)
DDUMP(cls);
#endif
if(IsWindowUnicode(msg.hwnd))
DispatchMessageW(&msg);
else
DispatchMessage(&msg);
DispatchMessageW(&msg);
}
bool Ctrl::IsWaitingEvent()
@ -1271,7 +1244,7 @@ Rect Ctrl::GetScreenClient(HWND hwnd)
}
Rect Ctrl::GetDefaultWindowRect() {
HWND hwnd = ::CreateWindow("UPP-CLASS-A", "", WS_OVERLAPPED,
HWND hwnd = ::CreateWindow("UPP-CLASS-W", "", WS_OVERLAPPED,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, NULL, NULL);
Rect sr;

View file

@ -71,7 +71,7 @@ struct KeyCtrl : Ctrl {
virtual bool Key(dword _key, int) {
if(_key == K_ENTER || _key == K_ESCAPE)
return false;
if((_key & K_KEYUP) || _key < 65536 || _key == K_SHIFT_KEY || _key == K_ALT_KEY || _key == K_CTRL_KEY)
if((_key & K_KEYUP) || _key < K_CHAR_LIM || _key == K_SHIFT_KEY || _key == K_ALT_KEY || _key == K_CTRL_KEY)
return true;
if(_key == K_SPACE || _key == K_DELETE || _key == K_BACKSPACE)
key = 0;

View file

@ -72,7 +72,7 @@ HANDLE XpWidget(int widget)
{
if(xp_widget_handle[widget] == NULL && XpTheme())
xp_widget_handle[widget] = XpTheme().OpenThemeData(NULL,
(WCHAR *)(const wchar *)WString(xp_widget_name[widget]));
ToSystemCharsetW(xp_widget_name[widget]));
return xp_widget_handle[widget];
}
@ -308,11 +308,11 @@ void Win32Look(Value& ch, int widget, int part, int state = 1, bool contentm = f
String XpThemeInfo(LPCWSTR pszPropertyName)
{
wchar theme[512], colors[512], size[512];
WCHAR theme[512], colors[512], size[512];
XpTheme().GetCurrentThemeName(theme, 512, colors, 512, size, 512);
wchar h[1024];
WCHAR h[1024];
XpTheme().GetThemeDocumentationProperty(theme, pszPropertyName, h, 1000);
return FromUnicode(h);
return ToUtf8(h);
}
struct sysColor {
@ -394,8 +394,7 @@ void ChHostSkin()
ChBaseSkin();
GUI_GlobalStyle_Write(IsWinXP() && !ScreenInPaletteMode() && IsSysFlag(0x1022 /*SPI_GETFLATMENU*/)
? GUISTYLE_XP : GUISTYLE_CLASSIC);
GUI_GlobalStyle_Write(GUISTYLE_XP);
#ifndef PLATFORM_WINCE
GUI_DragFullWindow_Write(IsSysFlag(SPI_GETDRAGFULLWINDOWS));
#endif

View file

@ -210,40 +210,13 @@ public:
#endif
#ifdef GUI_WIN
#ifndef PLATFORM_WINCE
class TrayIcon : private Ctrl {
struct NotifyIconOld {
dword sz;
HWND hwnd;
dword id;
dword flags;
dword message;
HICON icon;
char tip[64];
};
struct NotifyIconNew {
dword sz;
HWND hwnd;
dword id;
dword flags;
dword message;
HICON icon;
char tip[128];
dword state;
dword statemask;
char info[256];
dword timeout;
char title[64];
dword infoflags;
};
Image icon;
bool visible;
String tip;
NotifyIconNew nid;
HWND hwnd;
Image icon;
bool visible;
String tip;
NOTIFYICONDATAW nid;
HWND hwnd;
void Notify(dword msg);
void DoMenu(Bar& bar);
@ -348,7 +321,6 @@ public:
typedef FileSelNative FileSelector;
#endif
#endif
#ifdef GUI_X11

View file

@ -438,10 +438,10 @@ bool DocEdit::Key(dword key, int cnt)
default:
if(filter && key >= 32 && key < 65535)
key = (*filter)(key);
if(key >= ' ' && key < 65536 || key == '\n' || key == '\t' || key == K_SHIFT_SPACE) {
if(key >= ' ' && key < K_CHAR_LIM || key == '\n' || key == '\t' || key == K_SHIFT_SPACE) {
if(key == K_TAB && !processtab)
return false;
if(key >= 128 && key < 65536 && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM)
if(key >= 128 && key < K_CHAR_LIM && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM)
&& FromUnicode((wchar)key, charset) == DEFAULTCHAR)
return true;
RemoveSelection();

View file

@ -54,7 +54,7 @@ bool DropList::Key(dword k, int) {
Change(-1);
break;
default:
if(k >= 32 && k < 65536) {
if(k >= 32 && k < K_CHAR_LIM) {
bool b = list.Key(k, 1);
if(list.GetCursor() >= 0 && list.GetCursor() < key.GetCount() && key[list.GetCursor()] != value)
Select();

View file

@ -944,7 +944,7 @@ bool EditField::Key(dword key, int rep)
}
return false;
default:
if(key >= ' ' && key < 65536 || key == K_SHIFT_SPACE) {
if(key >= ' ' && key < K_CHAR_LIM || key == K_SHIFT_SPACE) {
if(!RemoveSelection()) SaveUndo();
while(rep--)
Insert(key == K_SHIFT_SPACE ? ' ' : key);

View file

@ -345,7 +345,7 @@ String FileList::GetCurrentName() const
int FileList::Find(const char *s) {
for(int i = 0; i < GetCount(); i++)
if(strcmp(Get(i).name, s) == 0) return i;
if(Get(i).name == s) return i;
return -1;
}

View file

@ -44,11 +44,11 @@ struct FileIconMaker : ImageMaker {
}
virtual Image Make() const {
SHFILEINFO info;
SHFILEINFOW info;
AvoidPaintingCheck__();
SHGetFileInfo(ToSystemCharset(file), dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL,
&info, sizeof(info),
SHGFI_ICON|(large ? SHGFI_LARGEICON : SHGFI_SMALLICON)|(exe ? 0 : SHGFI_USEFILEATTRIBUTES));
SHGetFileInfoW(ToSystemCharsetW(file), dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL,
&info, sizeof(info),
SHGFI_ICON|(large ? SHGFI_LARGEICON : SHGFI_SMALLICON)|(exe ? 0 : SHGFI_USEFILEATTRIBUTES));
return ProcessSHIcon(info.hIcon);
}
};
@ -587,14 +587,14 @@ bool Load(FileList& list, const String& dir, const char *patterns, bool dirs,
#ifdef GUI_WIN
static Mutex sExeMutex;
static wchar sExePath[1025];
static WCHAR sExePath[1025];
static bool sExeRunning;
static SHFILEINFOW sExeInfo;
static auxthread_t auxthread__ sExeIconThread(void *)
{
SHFILEINFOW info;
wchar path[1025];
WCHAR path[1025];
CoInitialize(NULL);
sExeMutex.Enter();
wcscpy(path, sExePath);
@ -649,7 +649,7 @@ void LazyExeFileIcons::Do()
sExeMutex.Enter();
bool running = sExeRunning;
if(!running) {
done = path == sExePath;
done = path == ToUtf32(sExePath);
memcpy(&info, &sExeInfo, sizeof(info));
*sExePath = '\0';
memset(&sExeInfo, 0, sizeof(sExeInfo));
@ -2389,7 +2389,9 @@ FileSel::FileSel()
places.NoWantFocus();
#ifdef PLATFORM_WIN32
list.IconWidth(GetFileIcon(GetHomeDirectory(), true, false, false).GetSize().cx);
int icx = GetFileIcon(GetHomeDirectory(), true, false, false).GetSize().cx;
if(icx)
list.IconWidth(icx);
#endif
AddStandardPlaces();

View file

@ -24,7 +24,7 @@ bool HelpWindow::GoTo0(const String& link)
topic = t.link;
if(~tree != topic)
tree.FindSetCursor(topic);
Title(FromUtf8(t.title));
Title(ToUtf32(t.title));
RichText txt = ParseQTF(t.text);
FinishText(txt);
view.Pick(pick(txt), zoom);

View file

@ -11,6 +11,7 @@ LineEdit::LineEdit() {
showtabs = false;
tabsize = 4;
font = CourierZ(12);
SyncFont();
SetFrame(ViewFrame());
sb.NoBox();
AddFrame(sb);
@ -70,10 +71,20 @@ LineEdit& LineEdit::SetFont(Font f) {
return *this;
}
void LineEdit::SyncFont()
{
fsz = GetFontSize();
}
Size LineEdit::GetFontSize() const {
return Size(font.GetMonoWidth(), font.GetCy());
}
bool LineEdit::IsDoubleChar(int ch) const
{
return ch >= 2048 && (IsDoubleWidth(ch) || font.GetWidth(ch) > fsz.cx);
}
void LineEdit::SetRectSelection(int64 anchor, int64 cursor)
{
dorectsel = true;
@ -396,7 +407,6 @@ void LineEdit::Paint0(Draw& w) {
if(rectsel)
rect = GetRectSelection();
Size sz = GetSize();
Size fsz = GetFontSize();
Point sc = sb;
int ll = min(GetLineCount(), sz.cy / fsz.cy + sc.y + 1);
int y = 0;
@ -480,7 +490,7 @@ void LineEdit::Paint0(Draw& w) {
x = fsz.cx * gp;
}
else
if(IsDoubleWidth(chr)) {
if(IsDoubleChar(chr)) {
x += 2 * fsz.cx;
gp += 2;
}
@ -508,7 +518,7 @@ void LineEdit::Paint0(Draw& w) {
h.ink = color[INK_SELECTED];
}
int x = gp * fsz.cx - scx;
bool cjk = IsDoubleWidth(h.chr);
bool cjk = IsDoubleChar(h.chr);
int xx = x + (gp + 1 + cjk) * fsz.cx;
if(h.chr == '\t') {
int ngp = (gp + tabsize) / tabsize * tabsize;
@ -649,6 +659,7 @@ void LineEdit::RefreshChars(bool (*chars)(int c))
}
void LineEdit::Layout() {
SyncFont();
Size sz = sb.GetReducedViewSize();
if(nohbar || isdrag)
sz.cy = GetSize().cy;
@ -671,7 +682,7 @@ int64 LineEdit::GetGPos(int ln, int cl) const {
if((byte)*s < 128)
gl++;
else {
WString txt = FromUtf8(s, int(e - s));
WString txt = ToUtf32(s, int(e - s));
const wchar *b = txt;
const wchar *e = txt.End();
const wchar *s = b;
@ -679,7 +690,7 @@ int64 LineEdit::GetGPos(int ln, int cl) const {
if(*s == '\t')
gl = (gl + tabsize) / tabsize * tabsize;
else
gl += 1 + IsDoubleWidth(*s);
gl += 1 + IsDoubleChar(*s);
if(cl < gl) break;
s++;
}
@ -704,7 +715,7 @@ Point LineEdit::GetColumnLine(int64 pos) const {
if(*s == '\t')
p.x = (p.x + tabsize) / tabsize * tabsize;
else
p.x += 1 + IsDoubleWidth(*s);
p.x += 1 + IsDoubleChar(*s);
s++;
}
return p;
@ -1007,11 +1018,11 @@ void LineEdit::MoveTextEnd(bool sel) {
bool LineEdit::InsertChar(dword key, int count, bool canow) {
if(key == K_TAB && !processtab)
return false;
if(filter && key >= 32 && key < 65535)
if(filter && key >= 32 && key < K_CHAR_LIM)
key = (*filter)(key);
if(!IsReadOnly() && (key >= 32 && key < 65536 || key == '\t' || key == '\n' ||
if(!IsReadOnly() && (key >= 32 && key < K_CHAR_LIM || key == '\t' || key == '\n' ||
key == K_ENTER && processenter || key == K_SHIFT_SPACE)) {
if(key >= 128 && key < 65536 && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM)
if(key >= 128 && key < K_CHAR_LIM && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM)
&& FromUnicode((wchar)key, charset) == DEFAULTCHAR)
return true;
if(!RemoveSelection() && overwrite && key != '\n' && key != K_ENTER && canow) {
@ -1113,7 +1124,7 @@ void LineEdit::SetHBar()
if(*s == '\t')
pos = (pos + tabsize) / tabsize * tabsize;
else
pos += 1 + IsDoubleWidth(*s);
pos += 1 + IsDoubleChar(*s);
s++;
}
mpos = max(mpos, pos);

View file

@ -68,6 +68,7 @@ bool PopUpTable::Key(dword key, int n) {
}
void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) {
TimeStop tm;
if(inpopup)
return;
inpopup++;

View file

@ -89,7 +89,7 @@ bool SuggestCtrl::Key(dword key, int count)
if(cc)
key = cc;
if(EditString::Key(key, count)) {
if(key >= 32 && key < 65536 || key == K_BACKSPACE || key == K_CTRL_SPACE) {
if(key >= 32 && key < K_CHAR_LIM || key == K_BACKSPACE || key == K_CTRL_SPACE) {
int h;
WString x = CF(ReadLast(h));
list.Clear();

Some files were not shown because too many files have changed in this diff Show more