1 57 58 package org.enhydra.apache.xerces.framework; 59 60 import org.enhydra.apache.xerces.utils.QName; 61 import org.enhydra.apache.xerces.utils.StringPool; 62 import org.xml.sax.AttributeList ; 63 64 96 public final class XMLAttrList 97 implements AttributeList { 98 99 103 105 private static final int CHUNK_SHIFT = 5; private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT); 107 private static final int CHUNK_MASK = CHUNK_SIZE - 1; 108 private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); 110 112 private static final int ATTFLAG_SPECIFIED = 1; 113 private static final int ATTFLAG_LASTATTR = 2; 114 private static final int ATTFLAG_NEEDSEARCH = 4; 115 116 120 122 private StringPool fStringPool = null; 123 private int fCurrentHandle = -1; 124 private int fAttributeListHandle = -1; 125 private int fAttributeListLength = 0; 126 private int fAttrCount = 0; 127 private int[][] fAttPrefix = new int[INITIAL_CHUNK_COUNT][]; 128 private int[][] fAttLocalpart = new int[INITIAL_CHUNK_COUNT][]; 129 private int[][] fAttName = new int[INITIAL_CHUNK_COUNT][]; 130 private int[][] fAttURI = new int[INITIAL_CHUNK_COUNT][]; 131 private int[][] fAttValue = new int[INITIAL_CHUNK_COUNT][]; 132 private int[][] fAttType = new int[INITIAL_CHUNK_COUNT][]; 133 private byte[][] fAttFlags = new byte[INITIAL_CHUNK_COUNT][]; 134 135 137 private QName fAttributeQName = new QName(); 138 139 144 public XMLAttrList(StringPool stringPool) { 145 fStringPool = stringPool; 146 } 147 148 153 public void reset(StringPool stringPool) { 154 fStringPool = stringPool; 155 fCurrentHandle = -1; 156 fAttributeListHandle = -1; 157 fAttributeListLength = 0; 158 fAttrCount = 0; 159 } 160 161 public int addAttr(int attrName, int attValue, 162 int attType, boolean specified, boolean search) throws Exception 163 { 164 fAttributeQName.setValues(-1, attrName, attrName); 165 return addAttr(fAttributeQName, attValue, attType, specified, search); 166 } 167 179 public int addAttr(QName attribute, 180 int attValue, int attType, 181 boolean specified, boolean search) throws Exception { 182 183 int chunk; 184 int index; 185 if (search) { 186 chunk = fCurrentHandle >> CHUNK_SHIFT; 187 index = fCurrentHandle & CHUNK_MASK; 188 for (int attrIndex = fCurrentHandle; attrIndex < fAttrCount; attrIndex++) { 189 if (fStringPool.equalNames(fAttName[chunk][index], attribute.rawname)) { 192 return -1; 193 } 194 if (++index == CHUNK_SIZE) { 195 chunk++; 196 index = 0; 197 } 198 } 199 } else { 200 chunk = fAttrCount >> CHUNK_SHIFT; 201 index = fAttrCount & CHUNK_MASK; 202 } 203 204 ensureCapacity(chunk, index); 205 fAttPrefix[chunk][index] = attribute.prefix; 206 fAttLocalpart[chunk][index] = attribute.localpart; 207 fAttName[chunk][index] = attribute.rawname; 208 fAttURI[chunk][index] = attribute.uri; 209 fAttValue[chunk][index] = attValue; 210 fAttType[chunk][index] = attType; 211 fAttFlags[chunk][index] = (byte)((specified ? ATTFLAG_SPECIFIED : 0) | (search ? ATTFLAG_NEEDSEARCH : 0)); 212 return fAttrCount++; 213 214 } 216 221 public int startAttrList() { 222 fCurrentHandle = fAttrCount; 223 return fCurrentHandle; 224 } 225 226 229 public int[] endAttrList() { 230 if (fCurrentHandle == -1) 231 return null; 232 int oldHandle = fCurrentHandle; 233 234 int attrIndex = fAttrCount - 1; 235 int chunk = attrIndex >> CHUNK_SHIFT; 236 int index = attrIndex & CHUNK_MASK; 237 fAttFlags[chunk][index] |= ATTFLAG_LASTATTR; 238 fCurrentHandle = -1; 239 240 int dupCount = 0; 241 int dupNames[] = null; 242 243 int attrIndex1 = oldHandle + 1, attrIndex2; 244 int chunk1 = attrIndex1 >> CHUNK_SHIFT; 245 int index1 = attrIndex1 & CHUNK_MASK; 246 int chunk2, index2; 247 for (; attrIndex1 < fAttrCount; attrIndex1++) { 248 if ((fAttFlags[chunk1][index1] & ATTFLAG_NEEDSEARCH) == 0) 249 continue; 250 chunk2 = chunk1; 251 index2 = index1; 252 for (attrIndex2 = oldHandle; attrIndex2 < attrIndex1; attrIndex2++) { 253 if (--index2 == -1) { 254 chunk2--; 255 index2 = CHUNK_SIZE-1; 256 } 257 if (fStringPool.equalNames(fAttURI[chunk1][index1], fAttURI[chunk2][index2]) && 258 fStringPool.equalNames(fAttLocalpart[chunk1][index1], fAttLocalpart[chunk2][index2])) { 259 if (dupCount == 0) 260 dupNames = new int[fAttrCount - oldHandle]; 261 dupNames[dupCount++] = fAttName[chunk1][index1]; 262 } 263 } 264 if (++index1 == CHUNK_SIZE) { 265 chunk1++; 266 index1 = 0; 267 } 268 } 269 270 if (dupCount > 0) { 271 int[] names = new int[dupCount]; 272 System.arraycopy(dupNames, 0, names, 0, dupCount); 273 dupNames = names; 274 } 275 276 return dupNames; 277 } 278 279 282 public int getAttrPrefix(int attrIndex) { 283 if (attrIndex < 0 || attrIndex >= fAttrCount) 284 return -1; 285 int chunk = attrIndex >> CHUNK_SHIFT; 286 int index = attrIndex & CHUNK_MASK; 287 return fAttPrefix[chunk][index]; 288 } 289 290 293 public int getAttrLocalpart(int attrIndex) { 294 if (attrIndex < 0 || attrIndex >= fAttrCount) 295 return -1; 296 int chunk = attrIndex >> CHUNK_SHIFT; 297 int index = attrIndex & CHUNK_MASK; 298 return fAttLocalpart[chunk][index]; 299 } 300 301 308 public int getAttrName(int attrIndex) { 309 if (attrIndex < 0 || attrIndex >= fAttrCount) 310 return -1; 311 int chunk = attrIndex >> CHUNK_SHIFT; 312 int index = attrIndex & CHUNK_MASK; 313 return fAttName[chunk][index]; 314 } 315 316 317 public void setAttrURI(int attrIndex, int uri) { 318 if (attrIndex < 0 || attrIndex >= fAttrCount) 319 return; 320 int chunk = attrIndex >> CHUNK_SHIFT; 321 int index = attrIndex & CHUNK_MASK; 322 fAttURI[chunk][index] = uri; 323 } 324 325 326 public int getAttrURI(int attrIndex) { 327 if (attrIndex < 0 || attrIndex >= fAttrCount) 328 return -1; 329 int chunk = attrIndex >> CHUNK_SHIFT; 330 int index = attrIndex & CHUNK_MASK; 331 return fAttURI[chunk][index]; 332 } 333 334 340 public int getAttValue(int attrIndex) { 341 if (attrIndex < 0 || attrIndex >= fAttrCount) 342 return -1; 343 int chunk = attrIndex >> CHUNK_SHIFT; 344 int index = attrIndex & CHUNK_MASK; 345 return fAttValue[chunk][index]; 346 } 347 348 351 public void setAttValue(int attrIndex, int attrValue) { 352 if (attrIndex < 0 || attrIndex >= fAttrCount) 353 return; 354 int chunk = attrIndex >> CHUNK_SHIFT; 355 int index = attrIndex & CHUNK_MASK; 356 fAttValue[chunk][index] = attrValue; 357 } 358 359 360 public void setAttType(int attrIndex, int attTypeIndex) { 361 if (attrIndex < 0 || attrIndex >= fAttrCount) 362 return; 363 int chunk = attrIndex >> CHUNK_SHIFT; 364 int index = attrIndex & CHUNK_MASK; 365 fAttType[chunk][index] = attTypeIndex; 366 } 367 368 374 public int getAttType(int attrIndex) { 375 if (attrIndex < 0 || attrIndex >= fAttrCount) 376 return -1; 377 int chunk = attrIndex >> CHUNK_SHIFT; 378 int index = attrIndex & CHUNK_MASK; 379 return fAttType[chunk][index]; 380 } 381 382 389 public boolean isSpecified(int attrIndex) { 390 if (attrIndex < 0 || attrIndex >= fAttrCount) 391 return true; 392 int chunk = attrIndex >> CHUNK_SHIFT; 393 int index = attrIndex & CHUNK_MASK; 394 return (fAttFlags[chunk][index] & ATTFLAG_SPECIFIED) != 0; 395 } 396 397 402 public void releaseAttrList(int attrListHandle) { 403 if (attrListHandle == -1) 404 return; 405 int chunk = attrListHandle >> CHUNK_SHIFT; 406 int index = attrListHandle & CHUNK_MASK; 407 while (true) { 408 boolean last = (fAttFlags[chunk][index] & ATTFLAG_LASTATTR) != 0; 409 fAttPrefix[chunk][index] = -1; 410 fAttLocalpart[chunk][index] = -1; 411 fAttName[chunk][index] = -1; 412 fAttURI[chunk][index] = StringPool.EMPTY_STRING; 413 if ((fAttFlags[chunk][index] & ATTFLAG_SPECIFIED) != 0) 414 fStringPool.releaseString(fAttValue[chunk][index]); 415 fAttValue[chunk][index] = -1; 416 if (++index == CHUNK_SIZE) { 417 chunk++; 418 index = 0; 419 } 420 if (last) 421 break; 422 } 423 int lastIndex = (chunk << CHUNK_SHIFT) + index; 424 if (fAttrCount == lastIndex) 425 fAttrCount = attrListHandle; 426 } 427 428 435 public int getFirstAttr(int attrListHandle) { 436 if (attrListHandle < 0 || attrListHandle >= fAttrCount) { 437 return -1; 438 } 439 return attrListHandle; 442 } 443 444 451 public int getNextAttr(int attrIndex) { 452 if (attrIndex < 0 || attrIndex + 1 >= fAttrCount) { 453 return -1; 454 } 455 int chunk = attrIndex >> CHUNK_SHIFT; 456 int index = attrIndex & CHUNK_MASK; 457 if ((fAttFlags[chunk][index] & ATTFLAG_LASTATTR) != 0) { 458 return -1; 459 } 460 return attrIndex + 1; 464 } 465 466 467 468 473 public AttributeList getAttributeList(int attrListHandle) { 474 fAttributeListHandle = attrListHandle; 475 if (fAttributeListHandle == -1) 476 fAttributeListLength = 0; 477 else { 478 int chunk = fAttributeListHandle >> CHUNK_SHIFT; 479 int index = fAttributeListHandle & CHUNK_MASK; 480 fAttributeListLength = 1; 481 while ((fAttFlags[chunk][index] & ATTFLAG_LASTATTR) == 0) { 482 if (++index == CHUNK_SIZE) { 483 chunk++; 484 index = 0; 485 } 486 fAttributeListLength++; 487 } 488 } 489 return this; 490 } 491 492 502 public int getLength() { 503 return fAttributeListLength; 504 } 505 506 509 public String getPrefix(int i) { 510 if (i < 0 || i >= fAttributeListLength) { 511 return null; 512 } 513 int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT; 514 int index = (fAttributeListHandle + i) & CHUNK_MASK; 515 return fStringPool.toString(fAttPrefix[chunk][index]); 516 } 517 518 521 public String getLocalpart(int i) { 522 if (i < 0 || i >= fAttributeListLength) { 523 return null; 524 } 525 int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT; 526 int index = (fAttributeListHandle + i) & CHUNK_MASK; 527 return fStringPool.toString(fAttLocalpart[chunk][index]); 528 } 529 530 546 public String getName(int i) { 547 if (i < 0 || i >= fAttributeListLength) 548 return null; 549 int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT; 550 int index = (fAttributeListHandle + i) & CHUNK_MASK; 551 return fStringPool.toString(fAttName[chunk][index]); 552 } 553 554 555 public String getURI(int i) { 556 if (i < 0 || i >= fAttributeListLength) 557 return null; 558 int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT; 559 int index = (fAttributeListHandle + i) & CHUNK_MASK; 560 return fStringPool.toString(fAttURI[chunk][index]); 561 } 562 563 584 public String getType(int i) { 585 if (i < 0 || i >= fAttributeListLength) 586 return null; 587 int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT; 588 int index = (fAttributeListHandle + i) & CHUNK_MASK; 589 int attType = fAttType[chunk][index]; 590 if (attType == fStringPool.addSymbol("ENUMERATION")) 591 attType = fStringPool.addSymbol("NMTOKEN"); 592 return fStringPool.toString(attType); 593 } 594 595 608 public String getValue(int i) { 609 if (i < 0 || i >= fAttributeListLength) 610 return null; 611 int chunk = (fAttributeListHandle + i) >> CHUNK_SHIFT; 612 int index = (fAttributeListHandle + i) & CHUNK_MASK; 613 return fStringPool.toString(fAttValue[chunk][index]); 614 } 615 616 630 public String getType(String name) { 631 int nameIndex = fStringPool.addSymbol(name); 632 if (nameIndex == -1) 633 return null; 634 int chunk = fAttributeListHandle >> CHUNK_SHIFT; 635 int index = fAttributeListHandle & CHUNK_MASK; 636 for (int i = 0; i < fAttributeListLength; i++) { 637 if (fStringPool.equalNames(fAttName[chunk][index], nameIndex)) { 638 int attType = fAttType[chunk][index]; 639 if (attType == fStringPool.addSymbol("ENUMERATION")) 640 attType = fStringPool.addSymbol("NMTOKEN"); 641 return fStringPool.toString(attType); 642 } 643 if (++index == CHUNK_SIZE) { 644 chunk++; 645 index = 0; 646 } 647 } 648 return null; 649 } 650 651 665 public String getValue(String name) { 666 int nameIndex = fStringPool.addSymbol(name); 667 if (nameIndex == -1) 668 return null; 669 int chunk = fAttributeListHandle >> CHUNK_SHIFT; 670 int index = fAttributeListHandle & CHUNK_MASK; 671 for (int i = 0; i < fAttributeListLength; i++) { 672 if (fStringPool.equalNames(fAttName[chunk][index], nameIndex)) 673 return fStringPool.toString(fAttValue[chunk][index]); 674 if (++index == CHUNK_SIZE) { 675 chunk++; 676 index = 0; 677 } 678 } 679 return null; 680 } 681 682 686 687 private void ensureCapacity(int chunk, int index) { 688 if (chunk >= fAttPrefix.length) { 689 int[][] newIntArray = new int[chunk * 2][]; 690 System.arraycopy(fAttPrefix, 0, newIntArray, 0, chunk); 691 fAttPrefix = newIntArray; 692 newIntArray = new int[chunk * 2][]; 693 System.arraycopy(fAttLocalpart, 0, newIntArray, 0, chunk); 694 fAttLocalpart = newIntArray; 695 newIntArray = new int[chunk * 2][]; 696 System.arraycopy(fAttName, 0, newIntArray, 0, chunk); 697 fAttName = newIntArray; 698 newIntArray = new int[chunk * 2][]; 699 System.arraycopy(fAttURI, 0, newIntArray, 0, chunk); 700 fAttURI = newIntArray; 701 newIntArray = new int[chunk * 2][]; 702 System.arraycopy(fAttValue, 0, newIntArray, 0, chunk); 703 fAttValue = newIntArray; 704 newIntArray = new int[chunk * 2][]; 705 System.arraycopy(fAttType, 0, newIntArray, 0, chunk); 706 fAttType = newIntArray; 707 byte[][] newByteArray = new byte[chunk * 2][]; 708 System.arraycopy(fAttFlags, 0, newByteArray, 0, chunk); 709 fAttFlags = newByteArray; 710 } 711 else if (fAttPrefix[chunk] != null) { 712 return; 713 } 714 fAttPrefix[chunk] = new int[CHUNK_SIZE]; 715 fAttLocalpart[chunk] = new int[CHUNK_SIZE]; 716 fAttName[chunk] = new int[CHUNK_SIZE]; 717 fAttURI[chunk] = new int[CHUNK_SIZE]; 718 fAttValue[chunk] = new int[CHUNK_SIZE]; 719 fAttType[chunk] = new int[CHUNK_SIZE]; 720 fAttFlags[chunk] = new byte[CHUNK_SIZE]; 721 return; 722 723 } 725 } | Popular Tags |