1: public class UnicodeInfoCompact2: {3:4: private UnicodeInfoCompact()
5: {6: }7:8: public static boolean IsLetter(char value)9: {10: return GetLetter(value) != 0L;
11: }12:13: public static char ToUpper(char value)14: {15: long info = GetLetter(value);
16: return
17: info == 018: ? value19: : (char) ((info >> 16) & 0xFFFF);
20: }21:22: public static char ToLower(char value)23: {24: long info = GetLetter(value);
25: return
26: info == 027: ? value28: : (char) (info & 0xFFFF);
29: }30:31:32: private static long GetLetter(char value)33: {34: int v = (int) value;35: int lb = _blocks.length;
36: for(int i=lb-1; i>=0; i--)37: {38: int bv = _blocks[i];
39: int firstUpper = (bv >> 16) & 0xFFFF;
40: int translation = (int) (byte) (bv & 0xFF);41: int delta = ((bv & 0x100) == 0) ? 1 : 2;
42: int length = (bv >> 9) & 0x7F;
43: int firstLower = firstUpper + translation;
44: // is upper case
45: if (v >= firstUpper && v <= firstUpper + (length - 1) * delta)
46: {47: if (((v-firstUpper) % delta) == 0)
48: {49: long ret = (v << 16) | (firstLower + (v-firstUpper));
50: return ret;
51: }52: }53:54: // is lower case
55: if (v >= firstLower && v <= firstLower + (length - 1) * delta)
56: {57: if (((v - firstLower) % delta) == 0)
58: {59: long ret = ((firstUpper + (v - firstLower)) << 16) | v;
60: return ret;
61: }62: }63: }64:65: // outside of blocks
66: int lc = _chars.length;
67: for(int i=0; i<lc; i++)68: {69: int lower = _chars[i] & 0xFFFF;
70: int upper = _chars[i] >> 16;
71: if (v == lower || v == upper)
72: {73: long ret = (upper << 16) | lower;
74: return ret;
75: }76: }77:78: return 0L;
79: }80:81: private static final int _blocks[] = new int[] {82: 0x00413420, // Block: 0041 ( 26*1) U=L 32
83: 0x00C02E20, // Block: 00C0 ( 23*1) U=L 32
84: 0x00D80E20, // Block: 00D8 ( 7*1) U=L 32
85: 0x01003101, // Block: 0100 ( 24*2) U=L 1
86: 0x01320701, // Block: 0132 ( 3*2) U=L 1
87: 0x01391101, // Block: 0139 ( 8*2) U=L 1
88: 0x014A2F01, // Block: 014A ( 23*2) U=L 1
89: 0x01790701, // Block: 0179 ( 3*2) U=L 1
90: 0x01A00701, // Block: 01A0 ( 3*2) U=L 1
91: 0x01CD1101, // Block: 01CD ( 8*2) U=L 1
92: 0x01DE1301, // Block: 01DE ( 9*2) U=L 1
93: 0x01FC1D01, // Block: 01FC ( 14*2) U=L 1
94: 0x03880625, // Block: 0388 ( 3*1) U=L 37
95: 0x03912220, // Block: 0391 ( 17*1) U=L 32
96: 0x03A31220, // Block: 03A3 ( 9*1) U=L 32
97: 0x03E20F01, // Block: 03E2 ( 7*2) U=L 1
98: 0x04011850, // Block: 0401 ( 12*1) U=L 80
99: 0x04104020, // Block: 0410 ( 32*1) U=L 32
100: 0x04602301, // Block: 0460 ( 17*2) U=L 1
101: 0x04903101, // Block: 0490 ( 24*2) U=L 1
102: 0x04D01D01, // Block: 04D0 ( 14*2) U=L 1
103: 0x04EE0901, // Block: 04EE ( 4*2) U=L 1
104: 0x05314C30, // Block: 0531 ( 38*1) U=L 48
105: 0x10A04C30, // Block: 10A0 ( 38*1) U=L 48
106: 0x1E009701, // Block: 1E00 ( 75*2) U=L 1
107: 0x1EA05B01, // Block: 1EA0 ( 45*2) U=L 1
108: 0x1F0810F8, // Block: 1F08 ( 8*1) U=L -8
109: 0x1F180CF8, // Block: 1F18 ( 6*1) U=L -8
110: 0x1F2810F8, // Block: 1F28 ( 8*1) U=L -8
111: 0x1F3810F8, // Block: 1F38 ( 8*1) U=L -8
112: 0x1F480CF8, // Block: 1F48 ( 6*1) U=L -8
113: 0x1F5909F8, // Block: 1F59 ( 4*2) U=L -8
114: 0x1F6810F8, // Block: 1F68 ( 8*1) U=L -8
115: 0x1FC808AA, // Block: 1FC8 ( 4*1) U=L -86
116: 0xFF213420 // Block: FF21 ( 26*1) U=L 32
117:118: };119: private static final int _chars[] = new int[] {120: 0x017800FF,121: 0x01810253,122: 0x01820183,123: 0x01840185,124: 0x01860254,125: 0x01870188,126: 0x01890256,127: 0x018A0257,128: 0x018B018C,129: 0x018E01DD,130: 0x018F0259,131: 0x0190025B,132: 0x01910192,133: 0x01930260,134: 0x01940263,135: 0x01960269,136: 0x01970268,137: 0x01980199,138: 0x019C026F,139: 0x019D0272,140: 0x019F0275,141: 0x01A701A8,142: 0x01A90283,143: 0x01AC01AD,144: 0x01AE0288,145: 0x01AF01B0,146: 0x01B1028A,147: 0x01B2028B,148: 0x01B301B4,149: 0x01B501B6,150: 0x01B70292,151: 0x01B801B9,152: 0x01BC01BD,153: 0x01C401C6,154: 0x01C701C9,155: 0x01CA01CC,156: 0x01F101F3,157: 0x01F401F5,158: 0x01FA01FB,159: 0x038603AC,160: 0x038C03CC,161: 0x038E03CD,162: 0x038F03CE,163: 0x040E045E,164: 0x040F045F,165: 0x04C104C2,166: 0x04C304C4,167: 0x04C704C8,168: 0x04CB04CC,169: 0x04F804F9,170: 0x1FBA1F70,171: 0x1FBB1F71,172: 0x1FDA1F76,173: 0x1FDB1F77,174: 0x1FF81F78,175: 0x1FF91F79,176: 0x1FEA1F7A,177: 0x1FEB1F7B,178: 0x1FFA1F7C,179: 0x1FFB1F7D,180: 0x1FB81FB0,181: 0x1FB91FB1,182: 0x1FD81FD0,183: 0x1FD91FD1,184: 0x1FE81FE0,185: 0x1FE91FE1,186: 0x1FEC1FE5187:188: };189:190:191: }192:
the mine universe
вторник, 21 октября 2008 г.
Обработка строк без учета регистра
Казалось бы космические карабли бороздят просторы нашей вселенной и сообщество devелопмента активно сопротивляется сдвигам парадигмы и коментариями забрасывают новое. А мне почему-то в первом посте хочется вернуться в историю и вспомнить что сегодня все еще существуют и активно продаются устройства с очень... Хотя нет, с драматически урезанными платформами. Урезанными еще мягко сказано. Вот представте себе что в базовом наборе библиотек нет математики вещественных чисел. Или сортировки, или встроенной поддержки форматирования дат и чисел хотя бы для европы и америки. И тем неменее некоторые реализации урезанных платформ представляются не только юзабельными но и эстетически привлекательными в базовой поставке. И что? А вот что нашел в своих архивах - преобразование символов к нужному регистру и сравнение строк без учета регистра, без которой та самая сортировка строк оказывается неприемлемой. Еще попробую претендовать на самый компактный код - после обсфукации получается бинарник размером менее 2K.
Поддерживаются всякие разные языки. Какие напишу позже. Продолжение следует.