| /* |
| * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| * |
| * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC. |
| */ |
| |
| package com.sun.xml.internal.fastinfoset.util; |
| |
| import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException; |
| import com.sun.xml.internal.fastinfoset.CommonResourceBundle; |
| |
| |
| public class DuplicateAttributeVerifier { |
| public static final int MAP_SIZE = 256; |
| |
| public int _currentIteration; |
| |
| public static class Entry { |
| private int iteration; |
| private int value; |
| |
| private Entry hashNext; |
| |
| private Entry poolNext; |
| } |
| |
| private Entry[] _map; |
| |
| public final Entry _poolHead; |
| public Entry _poolCurrent; |
| private Entry _poolTail; |
| |
| |
| public DuplicateAttributeVerifier() { |
| _poolTail = _poolHead = new Entry(); |
| } |
| |
| public final void clear() { |
| _currentIteration = 0; |
| |
| Entry e = _poolHead; |
| while (e != null) { |
| e.iteration = 0; |
| e = e.poolNext; |
| } |
| |
| reset(); |
| } |
| |
| public final void reset() { |
| _poolCurrent = _poolHead; |
| if (_map == null) { |
| _map = new Entry[MAP_SIZE]; |
| } |
| } |
| |
| private final void increasePool(int capacity) { |
| if (_map == null) { |
| _map = new Entry[MAP_SIZE]; |
| _poolCurrent = _poolHead; |
| } else { |
| final Entry tail = _poolTail; |
| for (int i = 0; i < capacity; i++) { |
| final Entry e = new Entry(); |
| _poolTail.poolNext = e; |
| _poolTail = e; |
| } |
| |
| _poolCurrent = tail.poolNext; |
| } |
| } |
| |
| public final void checkForDuplicateAttribute(int hash, int value) throws FastInfosetException { |
| if (_poolCurrent == null) { |
| increasePool(16); |
| } |
| |
| // Get next free entry |
| final Entry newEntry = _poolCurrent; |
| _poolCurrent = _poolCurrent.poolNext; |
| |
| final Entry head = _map[hash]; |
| if (head == null || head.iteration < _currentIteration) { |
| newEntry.hashNext = null; |
| _map[hash] = newEntry; |
| newEntry.iteration = _currentIteration; |
| newEntry.value = value; |
| } else { |
| Entry e = head; |
| do { |
| if (e.value == value) { |
| reset(); |
| throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.duplicateAttribute")); |
| } |
| } while ((e = e.hashNext) != null); |
| |
| newEntry.hashNext = head; |
| _map[hash] = newEntry; |
| newEntry.iteration = _currentIteration; |
| newEntry.value = value; |
| } |
| } |
| } |