1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ******************************************************************************* 5 * Copyright (C) 2001-2010, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ******************************************************************************* 8 */ 9 10 package com.ibm.icu.dev.test.bidi; 11 12 import java.util.Arrays; 13 14 import org.junit.Test; 15 16 import com.ibm.icu.text.Bidi; 17 18 /** 19 * Regression test for variants to the UBA. 20 * 21 * @author Lina Kemmel, Matitiahu Allouche 22 */ 23 24 public class TestReorderingMode extends BidiFmwk { 25 26 static final String[] textIn = { 27 /* (0) 123 */ 28 "123", 29 /* (1) .123->4.5 */ 30 ".123->4.5", 31 /* (2) 678 */ 32 "678", 33 /* (3) .678->8.9 */ 34 ".678->8.9", 35 /* (4) JIH1.2,3MLK */ 36 "JIH1.2,3MLK", 37 /* (5) FE.>12-> */ 38 "FE.>12->", 39 /* (6) JIH.>12->a */ 40 "JIH.>12->a", 41 /* (7) CBA.>67->89=a */ 42 "CBA.>67->89=a", 43 /* (8) CBA.123->xyz */ 44 "CBA.123->xyz", 45 /* (9) .>12->xyz */ 46 ".>12->xyz", 47 /* (10) a.>67->xyz */ 48 "a.>67->xyz", 49 /* (11) 123JIH */ 50 "123JIH", 51 /* (12) 123 JIH */ 52 "123 JIH" 53 }; 54 55 static final String[] textOut = { 56 /* TC 0: 123 */ 57 "123", /* (0) */ 58 /* TC 1: .123->4.5 */ 59 ".123->4.5", /* (1) */ 60 "4.5<-123.", /* (2) */ 61 /* TC 2: 678 */ 62 "678", /* (3) */ 63 /* TC 3: .678->8.9 */ 64 ".8.9<-678", /* (4) */ 65 "8.9<-678.", /* (5) */ 66 ".678->8.9", /* (6) */ 67 /* TC 4: MLK1.2,3JIH */ 68 "KLM1.2,3HIJ", /* (7) */ 69 /* TC 5: FE.>12-> */ 70 "12<.EF->", /* (8) */ 71 "<-12<.EF", /* (9) */ 72 "EF.>@12->", /* (10) */ 73 /* TC 6: JIH.>12->a */ 74 "12<.HIJ->a", /* (11) */ 75 "a<-12<.HIJ", /* (12) */ 76 "HIJ.>@12->a", /* (13) */ 77 "a&<-12<.HIJ", /* (14) */ 78 /* TC 7: CBA.>67->89=a */ 79 "ABC.>@67->89=a", /* (15) */ 80 "a=89<-67<.ABC", /* (16) */ 81 "a&=89<-67<.ABC", /* (17) */ 82 "89<-67<.ABC=a", /* (18) */ 83 /* TC 8: CBA.123->xyz */ 84 "123.ABC->xyz", /* (19) */ 85 "xyz<-123.ABC", /* (20) */ 86 "ABC.@123->xyz", /* (21) */ 87 "xyz&<-123.ABC", /* (22) */ 88 /* TC 9: .>12->xyz */ 89 ".>12->xyz", /* (23) */ 90 "xyz<-12<.", /* (24) */ 91 "xyz&<-12<.", /* (25) */ 92 /* TC 10: a.>67->xyz */ 93 "a.>67->xyz", /* (26) */ 94 "a.>@67@->xyz", /* (27) */ 95 "xyz<-67<.a", /* (28) */ 96 /* TC 11: 123JIH */ 97 "123HIJ", /* (29) */ 98 "HIJ123", /* (30) */ 99 /* TC 12: 123 JIH */ 100 "123 HIJ", /* (31) */ 101 "HIJ 123", /* (32) */ 102 }; 103 104 static final int[][][][] outIndices = { 105 { /* TC 0: 123 */ 106 {{ 0, 0}, { 0, 0}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 107 {{ 0, 0}, { 0, 0}}, /* REORDER_INVERSE_LIKE_DIRECT */ 108 {{ 0, 0}, { 0, 0}}, /* REORDER_NUMBERS_SPECIAL */ 109 {{ 0, 0}, { 0, 0}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 110 }, 111 { /* TC 1: .123->4.5 */ 112 {{ 1, 2}, { 1, 2}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 113 {{ 1, 2}, { 1, 2}}, /* REORDER_INVERSE_LIKE_DIRECT */ 114 {{ 1, 2}, { 1, 2}}, /* REORDER_NUMBERS_SPECIAL */ 115 {{ 1, 2}, { 1, 2}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 116 }, 117 { /* TC 2: 678 */ 118 {{ 3, 3}, { 3, 3}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 119 {{ 3, 3}, { 3, 3}}, /* REORDER_INVERSE_LIKE_DIRECT */ 120 {{ 3, 3}, { 3, 3}}, /* REORDER_NUMBERS_SPECIAL */ 121 {{ 3, 3}, { 3, 3}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 122 }, 123 { /* TC 3: .678->8.9 */ 124 {{ 6, 5}, { 6, 5}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 125 {{ 4, 5}, { 4, 5}}, /* REORDER_INVERSE_LIKE_DIRECT */ 126 {{ 6, 5}, { 6, 5}}, /* REORDER_NUMBERS_SPECIAL */ 127 {{ 6, 5}, { 6, 5}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 128 }, 129 { /* TC 4: MLK1.2,3JIH */ 130 {{ 7, 7}, { 7, 7}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 131 {{ 7, 7}, { 7, 7}}, /* REORDER_INVERSE_LIKE_DIRECT */ 132 {{ 7, 7}, { 7, 7}}, /* REORDER_NUMBERS_SPECIAL */ 133 {{ 7, 7}, { 7, 7}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 134 }, 135 { /* TC 5: FE.>12-> */ 136 {{ 8, 9}, { 8, 9}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 137 {{10, 9}, { 8, 9}}, /* REORDER_INVERSE_LIKE_DIRECT */ 138 {{ 8, 9}, { 8, 9}}, /* REORDER_NUMBERS_SPECIAL */ 139 {{10, 9}, { 8, 9}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 140 }, 141 { /* TC 6: JIH.>12->a */ 142 {{11, 12}, {11, 12}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 143 {{13, 14}, {11, 12}}, /* REORDER_INVERSE_LIKE_DIRECT */ 144 {{11, 12}, {11, 12}}, /* REORDER_NUMBERS_SPECIAL */ 145 {{13, 14}, {11, 12}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 146 }, 147 { /* TC 7: CBA.>67->89=a */ 148 {{18, 16}, {18, 16}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 149 {{18, 17}, {18, 16}}, /* REORDER_INVERSE_LIKE_DIRECT */ 150 {{18, 16}, {18, 16}}, /* REORDER_NUMBERS_SPECIAL */ 151 {{15, 17}, {18, 16}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 152 }, 153 { /* TC 8: CBA.>124->xyz */ 154 {{19, 20}, {19, 20}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 155 {{21, 22}, {19, 20}}, /* REORDER_INVERSE_LIKE_DIRECT */ 156 {{19, 20}, {19, 20}}, /* REORDER_NUMBERS_SPECIAL */ 157 {{21, 22}, {19, 20}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 158 }, 159 { /* TC 9: .>12->xyz */ 160 {{23, 24}, {23, 24}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 161 {{23, 25}, {23, 24}}, /* REORDER_INVERSE_LIKE_DIRECT */ 162 {{23, 24}, {23, 24}}, /* REORDER_NUMBERS_SPECIAL */ 163 {{23, 25}, {23, 24}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 164 }, 165 { /* TC 10: a.>67->xyz */ 166 {{26, 26}, {26, 26}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 167 {{26, 27}, {26, 28}}, /* REORDER_INVERSE_LIKE_DIRECT */ 168 {{26, 28}, {26, 28}}, /* REORDER_NUMBERS_SPECIAL */ 169 {{26, 27}, {26, 28}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 170 }, 171 { /* TC 11: 124JIH */ 172 {{30, 30}, {30, 30}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 173 {{29, 30}, {29, 30}}, /* REORDER_INVERSE_LIKE_DIRECT */ 174 {{30, 30}, {30, 30}}, /* REORDER_NUMBERS_SPECIAL */ 175 {{30, 30}, {30, 30}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 176 }, 177 { /* TC 12: 124 JIH */ 178 {{32, 32}, {32, 32}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 179 {{31, 32}, {31, 32}}, /* REORDER_INVERSE_LIKE_DIRECT */ 180 {{31, 32}, {31, 32}}, /* REORDER_NUMBERS_SPECIAL */ 181 {{31, 32}, {31, 32}} /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 182 } 183 }; 184 185 static final short[] modes = { 186 Bidi.REORDER_GROUP_NUMBERS_WITH_R, 187 Bidi.REORDER_INVERSE_LIKE_DIRECT, 188 Bidi.REORDER_NUMBERS_SPECIAL, 189 Bidi.REORDER_INVERSE_FOR_NUMBERS_SPECIAL, 190 Bidi.REORDER_INVERSE_NUMBERS_AS_L 191 }; 192 193 static final int[] options = { Bidi.OPTION_INSERT_MARKS, 0 }; 194 195 static final byte[] paraLevels = { Bidi.LTR, Bidi.RTL }; 196 197 static final int TC_COUNT = textIn.length; 198 static final int MODES_COUNT = modes.length; 199 static final int OPTIONS_COUNT = options.length; 200 static final int LEVELS_COUNT = paraLevels.length; 201 202 @Test 203 public void testReorderingMode() { 204 205 String src, dest; 206 Bidi bidi = new Bidi(); 207 Bidi bidi2 = new Bidi(); 208 Bidi bidi3 = new Bidi(); 209 int tc, mode, option, level; 210 int modeValue, modeBack; 211 int optionValue, optionBack; 212 int index; 213 String expected; 214 boolean testOK = true; 215 216 logln("\nEntering TestReorderingMode\n"); 217 218 bidi2.setInverse(true); 219 220 for (tc = 0; tc < TC_COUNT; tc++) { 221 src = textIn[tc]; 222 223 for (mode = 0; mode < MODES_COUNT; mode++) { 224 modeValue = modes[mode]; 225 bidi.setReorderingMode(modeValue); 226 modeBack = bidi.getReorderingMode(); 227 if (modeValue != modeBack) { 228 errln("Error while setting reordering mode to " + 229 modeValue + ", returned " + modeBack); 230 } 231 232 for (option = 0; option < OPTIONS_COUNT; option++) { 233 optionValue = options[option]; 234 bidi.setReorderingOptions(optionValue); 235 optionBack = bidi.getReorderingOptions(); 236 if (optionValue != optionBack) { 237 errln("Error while setting reordering options to " + 238 modeValue + ", returned " + modeBack); 239 } 240 241 for (level = 0; level < LEVELS_COUNT; level++) { 242 logln("starting test " + tc + " mode=" + modeValue + 243 " option=" + optionValue + " level=" + level); 244 bidi.setPara(pseudoToU16(src), paraLevels[level], null); 245 246 dest = bidi.writeReordered(Bidi.DO_MIRRORING); 247 dest = u16ToPseudo(dest); 248 if (!((modeValue == Bidi.REORDER_INVERSE_NUMBERS_AS_L) && 249 (optionValue == Bidi.OPTION_INSERT_MARKS))) { 250 checkWhatYouCan(bidi, src, dest); 251 } 252 String modeDesc = modeToString(modeValue); 253 String optDesc = spOptionsToString(optionValue); 254 255 if (modeValue == Bidi.REORDER_INVERSE_NUMBERS_AS_L) { 256 index = -1; 257 expected = inverseBasic(bidi2, src, optionValue, 258 paraLevels[level]); 259 } 260 else { 261 index = outIndices[tc][mode][option][level]; 262 expected = textOut[index]; 263 } 264 if (!assertEquals("Actual and expected output mismatch", 265 expected, dest, src, modeDesc, optDesc, 266 String.valueOf(level))) { 267 testOK = false; 268 continue; 269 } 270 if ((optionValue == Bidi.OPTION_INSERT_MARKS) && 271 !assertRoundTrip(bidi3, tc, index, src, dest, 272 mode, option, 273 paraLevels[level])) { 274 testOK = false; 275 continue; 276 } 277 if (!checkResultLength(bidi, src, dest, modeDesc, optDesc, 278 paraLevels[level])) { 279 testOK = false; 280 continue; 281 } 282 if ((index > -1) && 283 !checkMaps(bidi, index, src, dest, modeDesc, optDesc, 284 paraLevels[level], true)) { 285 testOK = false; 286 } 287 } 288 } 289 } 290 } 291 if (testOK) { 292 logln("Reordering mode test OK"); 293 } 294 295 logln("\nExiting TestReorderingMode\n"); 296 } 297 298 String inverseBasic(Bidi bidi, String src, int option, byte level) { 299 String dest2; 300 301 if (bidi == null || src == null) { 302 return null; 303 } 304 bidi.setReorderingOptions(option); 305 bidi.setPara(pseudoToU16(src), level, null); 306 dest2 = u16ToPseudo(bidi.writeReordered(Bidi.DO_MIRRORING)); 307 if (!(option == Bidi.OPTION_INSERT_MARKS)) { 308 checkWhatYouCan(bidi, src, dest2); 309 } 310 return dest2; 311 } 312 313 static final byte roundtrip[][][][] = 314 { 315 { /* TC 0: 123 */ 316 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 317 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 318 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 319 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 320 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 321 }, 322 { /* TC 1: .123->4.5 */ 323 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 324 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 325 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 326 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 327 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 328 }, 329 { /* TC 2: 678 */ 330 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 331 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 332 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 333 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 334 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 335 }, 336 { /* TC 3: .678->8.9 */ 337 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 338 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 339 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 340 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 341 {{ 0, 0}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 342 }, 343 { /* TC 4: MLK1.2,3JIH */ 344 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 345 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 346 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 347 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 348 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 349 }, 350 { /* TC 5: FE.>12-> */ 351 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 352 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 353 {{ 0, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 354 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 355 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 356 }, 357 { /* TC 6: JIH.>12->a */ 358 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 359 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 360 {{ 0, 0}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 361 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 362 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 363 }, 364 { /* TC 7: CBA.>67->89=a */ 365 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 366 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 367 {{ 0, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 368 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 369 {{ 0, 0}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 370 }, 371 { /* TC 8: CBA.>123->xyz */ 372 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 373 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 374 {{ 0, 0}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 375 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 376 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 377 }, 378 { /* TC 9: .>12->xyz */ 379 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 380 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 381 {{ 1, 0}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 382 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 383 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 384 }, 385 { /* TC 10: a.>67->xyz */ 386 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 387 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 388 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 389 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 390 {{ 1, 0}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 391 }, 392 { /* TC 11: 123JIH */ 393 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 394 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 395 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 396 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 397 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 398 }, 399 { /* TC 12: 123 JIH */ 400 {{ 1, 1}, { 1, 1}}, /* REORDER_GROUP_NUMBERS_WITH_R */ 401 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_LIKE_DIRECT */ 402 {{ 1, 1}, { 1, 1}}, /* REORDER_NUMBERS_SPECIAL */ 403 {{ 1, 1}, { 1, 1}}, /* REORDER_INVERSE_FOR_NUMBERS_SPECIAL */ 404 {{ 1, 1}, { 1, 1}} /* REORDER_INVERSE_NUMBERS_AS_L */ 405 } 406 }; 407 408 private boolean assertRoundTrip(Bidi bidi, int tc, int outIndex, 409 String src, String dest, 410 int mode, int option, byte level) { 411 String descMode, descOption; 412 String dest2; 413 414 switch (modes[mode]) { 415 case Bidi.REORDER_NUMBERS_SPECIAL: 416 bidi.setReorderingMode(Bidi.REORDER_INVERSE_FOR_NUMBERS_SPECIAL); 417 break; 418 case Bidi.REORDER_GROUP_NUMBERS_WITH_R: 419 bidi.setReorderingMode(Bidi.REORDER_GROUP_NUMBERS_WITH_R); 420 break; 421 case Bidi.REORDER_RUNS_ONLY: 422 bidi.setReorderingMode(Bidi.REORDER_RUNS_ONLY); 423 break; 424 case Bidi.REORDER_INVERSE_NUMBERS_AS_L: 425 bidi.setReorderingMode(Bidi.REORDER_DEFAULT); 426 break; 427 case Bidi.REORDER_INVERSE_LIKE_DIRECT: 428 bidi.setReorderingMode(Bidi.REORDER_DEFAULT); 429 break; 430 case Bidi.REORDER_INVERSE_FOR_NUMBERS_SPECIAL: 431 bidi.setReorderingMode(Bidi.REORDER_NUMBERS_SPECIAL); 432 break; 433 default: 434 bidi.setReorderingMode(Bidi.REORDER_INVERSE_LIKE_DIRECT); 435 break; 436 } 437 bidi.setReorderingOptions(Bidi.OPTION_REMOVE_CONTROLS); 438 439 bidi.setPara(pseudoToU16(dest), level, null); 440 dest2 = bidi.writeReordered(Bidi.DO_MIRRORING); 441 442 dest2 = u16ToPseudo(dest2); 443 checkWhatYouCan(bidi, dest, dest2); 444 descMode = modeToString(modes[mode]); 445 descOption = spOptionsToString(options[option]); 446 if (!src.equals(dest2)) { 447 if (roundtrip[tc][mode][option][level] == 1) { 448 errln("\nRound trip failed for case=" + tc + 449 " mode=" + mode + " option=" + option + 450 "\nOriginal text: " + src + 451 "\nRound-tripped text: " + dest2 + 452 "\nIntermediate text: " + dest + 453 "\nReordering mode: " + descMode + 454 "\nReordering option: " + descOption + 455 "\nParagraph level: " + level); 456 } else { 457 logln("\nExpected round trip failure for case=" + tc + 458 " mode=" + mode + " option=" + option + 459 "\nOriginal text: " + src + 460 "\nRound-tripped text: " + dest2 + 461 "\nIntermediate text: " + dest + 462 "\nReordering mode: " + descMode + 463 "\nReordering option: " + descOption + 464 "\nParagraph level: " + level); 465 } 466 return false; 467 } 468 if (!checkResultLength(bidi, dest, dest2, descMode, 469 "OPTION_REMOVE_CONTROLS", level)) { 470 return false; 471 } 472 if ((outIndex > -1) && 473 !checkMaps(bidi, outIndex, src, dest, descMode, 474 "OPTION_REMOVE_CONTROLS", level, false)) { 475 return false; 476 } 477 return true; 478 } 479 480 private boolean checkResultLength(Bidi bidi, String src, String dest, 481 String mode, String option, byte level) { 482 int actualLen; 483 if (mode.equals("REORDER_INVERSE_NUMBERS_AS_L")) 484 actualLen = dest.length(); 485 else 486 actualLen = bidi.getResultLength(); 487 if (actualLen != dest.length()) { 488 errln("\nBidi.getResultLength failed." + 489 "\nExpected: " + dest.length() + 490 "\nActual: " + actualLen + 491 "\nInput: " + src + 492 "\nOutput: " + dest + 493 "\nReordering mode: " + mode + 494 "\nReordering option: " + option + 495 "\nParagraph level: " + level); 496 return false; 497 } 498 return true; 499 } 500 501 static String formatMap(int[] map) 502 { 503 char[] buffer = new char[map.length]; 504 int i, k; 505 char c; 506 for (i = 0; i < map.length; i++) { 507 k = map[i]; 508 if (k < 0) 509 c = '-'; 510 else if (k >= columns.length) 511 c = '+'; 512 else 513 c = columns[k]; 514 buffer[i] = c; 515 } 516 return new String(buffer); 517 } 518 519 static final int NO = Bidi.MAP_NOWHERE; 520 521 static final int forwardMap[][] = { 522 /* TC 0: 123 */ 523 { 0, 1, 2 }, /* (0) */ 524 /* TC 1: .123->4.5 */ 525 { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (1) */ 526 { 8, 5, 6, 7, 4, 3, 0, 1, 2 }, /* (2) */ 527 /* TC 2: 678 */ 528 { 0, 1, 2 }, /* (3) */ 529 /* TC 3: .678->8.9 */ 530 { 0, 6, 7, 8, 5, 4, 1, 2, 3 }, /* (4) */ 531 { 8, 5, 6, 7, 4, 3, 0, 1, 2 }, /* (5) */ 532 { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (6) */ 533 /* TC 4: MLK1.2,3JIH */ 534 { 10, 9, 8, 3, 4, 5, 6, 7, 2, 1, 0 }, /* (7) */ 535 /* TC 5: FE.>12-> */ 536 { 5, 4, 3, 2, 0, 1, 6, 7 }, /* (8) */ 537 { 7, 6, 5, 4, 2, 3, 1, 0 }, /* (9) */ 538 { 1, 0, 2, 3, 5, 6, 7, 8 }, /* (10) */ 539 /* TC 6: JIH.>12->a */ 540 { 6, 5, 4, 3, 2, 0, 1, 7, 8, 9 }, /* (11) */ 541 { 9, 8, 7, 6, 5, 3, 4, 2, 1, 0 }, /* (12) */ 542 { 2, 1, 0, 3, 4, 6, 7, 8, 9, 10 }, /* (13) */ 543 { 10, 9, 8, 7, 6, 4, 5, 3, 2, 0 }, /* (14) */ 544 /* TC 7: CBA.>67->89=a */ 545 { 2, 1, 0, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13 }, /* (15) */ 546 { 12, 11, 10, 9, 8, 6, 7, 5, 4, 2, 3, 1, 0 }, /* (16) */ 547 { 13, 12, 11, 10, 9, 7, 8, 6, 5, 3, 4, 2, 0 }, /* (17) */ 548 { 10, 9, 8, 7, 6, 4, 5, 3, 2, 0, 1, 11, 12 }, /* (18) */ 549 /* TC 8: CBA.123->xyz */ 550 { 6, 5, 4, 3, 0, 1, 2, 7, 8, 9, 10, 11 }, /* (19) */ 551 { 11, 10, 9, 8, 5, 6, 7, 4, 3, 0, 1, 2 }, /* (20) */ 552 { 2, 1, 0, 3, 5, 6, 7, 8, 9, 10, 11, 12 }, /* (21) */ 553 { 12, 11, 10, 9, 6, 7, 8, 5, 4, 0, 1, 2 }, /* (22) */ 554 /* TC 9: .>12->xyz */ 555 { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (23) */ 556 { 8, 7, 5, 6, 4, 3, 0, 1, 2 }, /* (24) */ 557 { 9, 8, 6, 7, 5, 4, 0, 1, 2 }, /* (25) */ 558 /* TC 10: a.>67->xyz */ 559 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, /* (26) */ 560 { 0, 1, 2, 4, 5, 7, 8, 9, 10, 11 }, /* (27) */ 561 { 9, 8, 7, 5, 6, 4, 3, 0, 1, 2 }, /* (28) */ 562 /* TC 11: 123JIH */ 563 { 0, 1, 2, 5, 4, 3 }, /* (29) */ 564 { 3, 4, 5, 2, 1, 0 }, /* (30) */ 565 /* TC 12: 123 JIH */ 566 { 0, 1, 2, 3, 6, 5, 4 }, /* (31) */ 567 { 4, 5, 6, 3, 2, 1, 0 }, /* (32) */ 568 }; 569 static final int inverseMap[][] = { 570 /* TC 0: 123 */ 571 { 0, 1, 2 }, /* (0) */ 572 /* TC 1: .123->4.5 */ 573 { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (1) */ 574 { 6, 7, 8, 5, 4, 1, 2, 3, 0 }, /* (2) */ 575 /* TC 2: 678 */ 576 { 0, 1, 2 }, /* (3) */ 577 /* TC 3: .678->8.9 */ 578 { 0, 6, 7, 8, 5, 4, 1, 2, 3 }, /* (4) */ 579 { 6, 7, 8, 5, 4, 1, 2, 3, 0 }, /* (5) */ 580 { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (6) */ 581 /* TC 4: MLK1.2,3JIH */ 582 { 10, 9, 8, 3, 4, 5, 6, 7, 2, 1, 0 }, /* (7) */ 583 /* TC 5: FE.>12-> */ 584 { 4, 5, 3, 2, 1, 0, 6, 7 }, /* (8) */ 585 { 7, 6, 4, 5, 3, 2, 1, 0 }, /* (9) */ 586 { 1, 0, 2, 3, NO, 4, 5, 6, 7 }, /* (10) */ 587 /* TC 6: JIH.>12->a */ 588 { 5, 6, 4, 3, 2, 1, 0, 7, 8, 9 }, /* (11) */ 589 { 9, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (12) */ 590 { 2, 1, 0, 3, 4, NO, 5, 6, 7, 8, 9 }, /* (13) */ 591 { 9, NO, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (14) */ 592 /* TC 7: CBA.>67->89=a */ 593 { 2, 1, 0, 3, 4, NO, 5, 6, 7, 8, 9, 10, 11, 12 }, /* (15) */ 594 { 12, 11, 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (16) */ 595 { 12, NO, 11, 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0 }, /* (17) */ 596 { 9, 10, 8, 7, 5, 6, 4, 3, 2, 1, 0, 11, 12 }, /* (18) */ 597 /* TC 8: CBA.123->xyz */ 598 { 4, 5, 6, 3, 2, 1, 0, 7, 8, 9, 10, 11 }, /* (19) */ 599 { 9, 10, 11, 8, 7, 4, 5, 6, 3, 2, 1, 0 }, /* (20) */ 600 { 2, 1, 0, 3, NO, 4, 5, 6, 7, 8, 9, 10, 11 }, /* (21) */ 601 { 9, 10, 11, NO, 8, 7, 4, 5, 6, 3, 2, 1, 0 }, /* (22) */ 602 /* TC 9: .>12->xyz */ 603 { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, /* (23) */ 604 { 6, 7, 8, 5, 4, 2, 3, 1, 0 }, /* (24) */ 605 { 6, 7, 8, NO, 5, 4, 2, 3, 1, 0 }, /* (25) */ 606 /* TC 10: a.>67->xyz */ 607 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, /* (26) */ 608 { 0, 1, 2, NO, 3, 4, NO, 5, 6, 7, 8, 9 }, /* (27) */ 609 { 7, 8, 9, 6, 5, 3, 4, 2, 1, 0 }, /* (28) */ 610 /* TC 11: 123JIH */ 611 { 0, 1, 2, 5, 4, 3 }, /* (29) */ 612 { 5, 4, 3, 0, 1, 2 }, /* (30) */ 613 /* TC 12: 123 JIH */ 614 { 0, 1, 2, 3, 6, 5, 4 }, /* (31) */ 615 { 6, 5, 4, 3, 0, 1, 2 }, /* (32) */ 616 }; 617 618 private boolean checkMaps(Bidi bidi, int stringIndex, String src, String dest, 619 String mode, String option, byte level, boolean forward) { 620 621 int[] actualLogicalMap; 622 int[] actualVisualMap; 623 int[] getIndexMap; 624 int i, srcLen, resLen, index; 625 int[] expectedLogicalMap, expectedVisualMap; 626 boolean testOK = true; 627 628 if (forward) { 629 expectedLogicalMap = forwardMap[stringIndex]; 630 expectedVisualMap = inverseMap[stringIndex]; 631 } else { 632 expectedLogicalMap = inverseMap[stringIndex]; 633 expectedVisualMap = forwardMap[stringIndex]; 634 } 635 actualLogicalMap = bidi.getLogicalMap(); 636 srcLen = bidi.getProcessedLength(); 637 if (!Arrays.equals(expectedLogicalMap, actualLogicalMap)) { 638 err("Bidi.getLogicalMap returned unexpected map for output " + 639 "string index " + stringIndex + "\n" + 640 "source: " + src + "\n" + 641 "dest : " + dest + "\n" + 642 "Scale : " + columnString + "\n" + 643 "ExpMap: " + formatMap(expectedLogicalMap) + "\n" + 644 "Actual: " + formatMap(actualLogicalMap) + "\n" + 645 "Paragraph level : " + level + " == " + bidi.getParaLevel() + "\n" + 646 "Reordering mode : " + mode + " == " + bidi.getReorderingMode() + "\n" + 647 "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" + 648 "Forward flag : " + forward + "\n"); 649 testOK = false; 650 } 651 resLen = bidi.getResultLength(); 652 actualVisualMap = bidi.getVisualMap(); 653 if (!Arrays.equals(expectedVisualMap, actualVisualMap)) { 654 err("Bidi.getVisualMap returned unexpected map for output " + 655 "string index " + stringIndex + "\n" + 656 "source: " + src + "\n" + 657 "dest : " + dest + "\n" + 658 "Scale : " + columnString + "\n" + 659 "ExpMap: " + formatMap(expectedVisualMap) + "\n" + 660 "Actual: " + formatMap(actualVisualMap) + "\n" + 661 "Paragraph level : " + level + " == " + bidi.getParaLevel() + "\n" + 662 "Reordering mode : " + mode + " == " + bidi.getReorderingMode() + "\n" + 663 "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" + 664 "Forward flag : " + forward + "\n"); 665 testOK = false; 666 } 667 getIndexMap = new int[srcLen]; 668 for (i = 0; i < srcLen; i++) { 669 index = bidi.getVisualIndex(i); 670 getIndexMap[i] = index; 671 } 672 if (!Arrays.equals(actualLogicalMap, getIndexMap)) { 673 err("Mismatch between getLogicalMap and getVisualIndex for output " + 674 "string index " + stringIndex + "\n" + 675 "source: " + src + "\n" + 676 "dest : " + dest + "\n" + 677 "Scale : " + columnString + "\n" + 678 "ActMap: " + formatMap(actualLogicalMap) + "\n" + 679 "IdxMap: " + formatMap(getIndexMap) + "\n" + 680 "Paragraph level : " + level + " == " + bidi.getParaLevel() + "\n" + 681 "Reordering mode : " + mode + " == " + bidi.getReorderingMode() + "\n" + 682 "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" + 683 "Forward flag : " + forward + "\n"); 684 testOK = false; 685 } 686 getIndexMap = new int[resLen]; 687 for (i = 0; i < resLen; i++) { 688 index = bidi.getLogicalIndex(i); 689 getIndexMap[i] = index; 690 } 691 if (!Arrays.equals(actualVisualMap, getIndexMap)) { 692 err("Mismatch between getVisualMap and getLogicalIndex for output " + 693 "string index " + stringIndex + "\n" + 694 "source: " + src + "\n" + 695 "dest : " + dest + "\n" + 696 "Scale : " + columnString + "\n" + 697 "ActMap: " + formatMap(actualVisualMap) + "\n" + 698 "IdxMap: " + formatMap(getIndexMap) + "\n" + 699 "Paragraph level : " + level + " == " + bidi.getParaLevel() + "\n" + 700 "Reordering mode : " + mode + " == " + bidi.getReorderingMode() + "\n" + 701 "Reordering option: " + option + " == " + bidi.getReorderingOptions() + "\n" + 702 "Forward flag : " + forward + "\n"); 703 testOK = false; 704 } 705 return testOK; 706 } 707 } 708