Thu, 12 Oct 2017 19:44:07 +0800
merge
1 /*
2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
28 package com.sun.xml.internal.fastinfoset.util;
30 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
31 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
34 public class DuplicateAttributeVerifier {
35 public static final int MAP_SIZE = 256;
37 public int _currentIteration;
39 public static class Entry {
40 private int iteration;
41 private int value;
43 private Entry hashNext;
45 private Entry poolNext;
46 }
48 private Entry[] _map;
50 public final Entry _poolHead;
51 public Entry _poolCurrent;
52 private Entry _poolTail;
55 public DuplicateAttributeVerifier() {
56 _poolTail = _poolHead = new Entry();
57 }
59 public final void clear() {
60 _currentIteration = 0;
62 Entry e = _poolHead;
63 while (e != null) {
64 e.iteration = 0;
65 e = e.poolNext;
66 }
68 reset();
69 }
71 public final void reset() {
72 _poolCurrent = _poolHead;
73 if (_map == null) {
74 _map = new Entry[MAP_SIZE];
75 }
76 }
78 private final void increasePool(int capacity) {
79 if (_map == null) {
80 _map = new Entry[MAP_SIZE];
81 _poolCurrent = _poolHead;
82 } else {
83 final Entry tail = _poolTail;
84 for (int i = 0; i < capacity; i++) {
85 final Entry e = new Entry();
86 _poolTail.poolNext = e;
87 _poolTail = e;
88 }
90 _poolCurrent = tail.poolNext;
91 }
92 }
94 public final void checkForDuplicateAttribute(int hash, int value) throws FastInfosetException {
95 if (_poolCurrent == null) {
96 increasePool(16);
97 }
99 // Get next free entry
100 final Entry newEntry = _poolCurrent;
101 _poolCurrent = _poolCurrent.poolNext;
103 final Entry head = _map[hash];
104 if (head == null || head.iteration < _currentIteration) {
105 newEntry.hashNext = null;
106 _map[hash] = newEntry;
107 newEntry.iteration = _currentIteration;
108 newEntry.value = value;
109 } else {
110 Entry e = head;
111 do {
112 if (e.value == value) {
113 reset();
114 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.duplicateAttribute"));
115 }
116 } while ((e = e.hashNext) != null);
118 newEntry.hashNext = head;
119 _map[hash] = newEntry;
120 newEntry.iteration = _currentIteration;
121 newEntry.value = value;
122 }
123 }
124 }