536cd135cc
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
347 lines
12 KiB
C#
347 lines
12 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="XmlSchemaObjectTable.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
// <owner current="true" primary="true">Microsoft</owner>
|
|
//------------------------------------------------------------------------------
|
|
|
|
namespace System.Xml.Schema {
|
|
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
|
|
/// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable"]/*' />
|
|
public class XmlSchemaObjectTable {
|
|
Dictionary<XmlQualifiedName, XmlSchemaObject> table = new Dictionary<XmlQualifiedName,XmlSchemaObject>();
|
|
List<XmlSchemaObjectEntry> entries = new List<XmlSchemaObjectEntry>();
|
|
|
|
internal XmlSchemaObjectTable() {
|
|
}
|
|
|
|
internal void Add(XmlQualifiedName name, XmlSchemaObject value) {
|
|
Debug.Assert(!table.ContainsKey(name), "XmlSchemaObjectTable.Add: entry already exists");
|
|
table.Add(name, value);
|
|
entries.Add(new XmlSchemaObjectEntry(name, value));
|
|
}
|
|
|
|
internal void Insert(XmlQualifiedName name, XmlSchemaObject value) {
|
|
XmlSchemaObject oldValue = null;
|
|
if (table.TryGetValue(name, out oldValue)) {
|
|
table[name] = value; //set new value
|
|
Debug.Assert(oldValue != null);
|
|
int matchedIndex = FindIndexByValue(oldValue);
|
|
Debug.Assert(matchedIndex >= 0);
|
|
//set new entry
|
|
Debug.Assert(entries[matchedIndex].qname == name);
|
|
entries[matchedIndex] = new XmlSchemaObjectEntry(name, value);
|
|
}
|
|
else {
|
|
Add(name, value);
|
|
}
|
|
|
|
}
|
|
|
|
internal void Replace(XmlQualifiedName name, XmlSchemaObject value) {
|
|
XmlSchemaObject oldValue;
|
|
if (table.TryGetValue(name, out oldValue)) {
|
|
table[name] = value; //set new value
|
|
Debug.Assert(oldValue != null);
|
|
int matchedIndex = FindIndexByValue(oldValue);
|
|
Debug.Assert(entries[matchedIndex].qname == name);
|
|
entries[matchedIndex] = new XmlSchemaObjectEntry(name, value);
|
|
}
|
|
}
|
|
|
|
internal void Clear() {
|
|
table.Clear();
|
|
entries.Clear();
|
|
}
|
|
|
|
internal void Remove(XmlQualifiedName name) {
|
|
XmlSchemaObject value;
|
|
if (table.TryGetValue(name, out value)) {
|
|
table.Remove(name);
|
|
int matchedIndex = FindIndexByValue(value);
|
|
Debug.Assert(matchedIndex >= 0);
|
|
Debug.Assert(entries[matchedIndex].qname == name);
|
|
entries.RemoveAt(matchedIndex);
|
|
}
|
|
}
|
|
|
|
private int FindIndexByValue(XmlSchemaObject xso) {
|
|
int index;
|
|
for(index = 0; index < entries.Count; index++) {
|
|
if((object)entries[index].xso == (object)xso) {
|
|
return index;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
/// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Count"]/*' />
|
|
public int Count {
|
|
get {
|
|
Debug.Assert(table.Count == entries.Count);
|
|
return table.Count;
|
|
}
|
|
}
|
|
|
|
/// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Contains"]/*' />
|
|
public bool Contains(XmlQualifiedName name) {
|
|
return table.ContainsKey(name);
|
|
}
|
|
|
|
/// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.this"]/*' />
|
|
public XmlSchemaObject this[XmlQualifiedName name] {
|
|
get {
|
|
XmlSchemaObject value;
|
|
if (table.TryGetValue(name, out value)) {
|
|
return value;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Names"]/*' />
|
|
public ICollection Names {
|
|
get {
|
|
return new NamesCollection(entries, table.Count);
|
|
}
|
|
}
|
|
|
|
/// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.Values"]/*' />
|
|
public ICollection Values {
|
|
get {
|
|
return new ValuesCollection(entries, table.Count);
|
|
}
|
|
}
|
|
|
|
/// <include file='doc\XmlSchemaObjectTable.uex' path='docs/doc[@for="XmlSchemaObjectTable.GetEnumerator"]/*' />
|
|
public IDictionaryEnumerator GetEnumerator() {
|
|
return new XSODictionaryEnumerator(this.entries, table.Count, EnumeratorType.DictionaryEntry);
|
|
}
|
|
|
|
internal enum EnumeratorType {
|
|
Keys,
|
|
Values,
|
|
DictionaryEntry,
|
|
}
|
|
|
|
internal struct XmlSchemaObjectEntry {
|
|
internal XmlQualifiedName qname;
|
|
internal XmlSchemaObject xso;
|
|
|
|
public XmlSchemaObjectEntry(XmlQualifiedName name, XmlSchemaObject value) {
|
|
qname = name;
|
|
xso = value;
|
|
}
|
|
|
|
public XmlSchemaObject IsMatch(string localName, string ns) {
|
|
if (localName == qname.Name && ns == qname.Namespace) {
|
|
return xso;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void Reset() {
|
|
qname = null;
|
|
xso = null;
|
|
}
|
|
}
|
|
|
|
internal class NamesCollection : ICollection {
|
|
private List<XmlSchemaObjectEntry> entries;
|
|
int size;
|
|
|
|
internal NamesCollection(List<XmlSchemaObjectEntry> entries, int size) {
|
|
this.entries = entries;
|
|
this.size = size;
|
|
}
|
|
|
|
public int Count {
|
|
get { return size; }
|
|
}
|
|
|
|
public Object SyncRoot {
|
|
get {
|
|
return ((ICollection)entries).SyncRoot;
|
|
}
|
|
}
|
|
|
|
public bool IsSynchronized {
|
|
get {
|
|
return ((ICollection)entries).IsSynchronized;
|
|
}
|
|
}
|
|
|
|
public void CopyTo(Array array, int arrayIndex) {
|
|
if (array == null)
|
|
throw new ArgumentNullException("array");
|
|
|
|
if (arrayIndex < 0)
|
|
throw new ArgumentOutOfRangeException("arrayIndex");
|
|
|
|
Debug.Assert(array.Length >= size, "array is not big enough to hold all the items in the ICollection");
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
array.SetValue(entries[i].qname, arrayIndex++);
|
|
}
|
|
}
|
|
|
|
public IEnumerator GetEnumerator() {
|
|
return new XSOEnumerator(this.entries, this.size, EnumeratorType.Keys);
|
|
}
|
|
}
|
|
|
|
//ICollection for Values
|
|
internal class ValuesCollection : ICollection {
|
|
private List<XmlSchemaObjectEntry> entries;
|
|
int size;
|
|
|
|
internal ValuesCollection(List<XmlSchemaObjectEntry> entries, int size) {
|
|
this.entries = entries;
|
|
this.size = size;
|
|
}
|
|
|
|
public int Count {
|
|
get { return size; }
|
|
}
|
|
|
|
public Object SyncRoot {
|
|
get {
|
|
return ((ICollection)entries).SyncRoot;
|
|
}
|
|
}
|
|
|
|
public bool IsSynchronized {
|
|
get {
|
|
return ((ICollection)entries).IsSynchronized;
|
|
}
|
|
}
|
|
|
|
public void CopyTo(Array array, int arrayIndex) {
|
|
if (array == null)
|
|
throw new ArgumentNullException("array");
|
|
|
|
if (arrayIndex < 0)
|
|
throw new ArgumentOutOfRangeException("arrayIndex");
|
|
|
|
Debug.Assert(array.Length >= size, "array is not big enough to hold all the items in the ICollection");
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
array.SetValue(entries[i].xso, arrayIndex++);
|
|
}
|
|
}
|
|
|
|
public IEnumerator GetEnumerator() {
|
|
return new XSOEnumerator(this.entries, this.size, EnumeratorType.Values);
|
|
}
|
|
}
|
|
|
|
internal class XSOEnumerator : IEnumerator {
|
|
private List<XmlSchemaObjectEntry> entries;
|
|
private EnumeratorType enumType;
|
|
|
|
protected int currentIndex;
|
|
protected int size;
|
|
protected XmlQualifiedName currentKey;
|
|
protected XmlSchemaObject currentValue;
|
|
|
|
|
|
internal XSOEnumerator(List<XmlSchemaObjectEntry> entries, int size, EnumeratorType enumType) {
|
|
this.entries = entries;
|
|
this.size = size;
|
|
this.enumType = enumType;
|
|
currentIndex = -1;
|
|
}
|
|
|
|
public Object Current {
|
|
get {
|
|
if (currentIndex == -1) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
|
|
}
|
|
if (currentIndex >= size) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
|
|
}
|
|
switch(enumType) {
|
|
case EnumeratorType.Keys:
|
|
return currentKey;
|
|
|
|
case EnumeratorType.Values:
|
|
return currentValue;
|
|
|
|
case EnumeratorType.DictionaryEntry:
|
|
return new DictionaryEntry(currentKey, currentValue);
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public bool MoveNext() {
|
|
if (currentIndex >= size - 1) {
|
|
currentValue = null;
|
|
currentKey = null;
|
|
return false;
|
|
}
|
|
currentIndex++;
|
|
currentValue = entries[currentIndex].xso;
|
|
currentKey = entries[currentIndex].qname;
|
|
return true;
|
|
}
|
|
|
|
public void Reset() {
|
|
currentIndex = -1;
|
|
currentValue = null;
|
|
currentKey = null;
|
|
}
|
|
}
|
|
|
|
internal class XSODictionaryEnumerator : XSOEnumerator, IDictionaryEnumerator {
|
|
|
|
internal XSODictionaryEnumerator(List<XmlSchemaObjectEntry> entries, int size, EnumeratorType enumType) : base(entries, size, enumType) {
|
|
}
|
|
|
|
//IDictionaryEnumerator members
|
|
public DictionaryEntry Entry {
|
|
get {
|
|
if (currentIndex == -1) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
|
|
}
|
|
if (currentIndex >= size) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
|
|
}
|
|
return new DictionaryEntry(currentKey, currentValue);
|
|
}
|
|
}
|
|
|
|
public object Key {
|
|
get {
|
|
if (currentIndex == -1) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
|
|
}
|
|
if (currentIndex >= size) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
|
|
}
|
|
return currentKey;
|
|
}
|
|
}
|
|
|
|
public object Value {
|
|
get {
|
|
if (currentIndex == -1) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumNotStarted, string.Empty));
|
|
}
|
|
if (currentIndex >= size) {
|
|
throw new InvalidOperationException(Res.GetString(Res.Sch_EnumFinished, string.Empty));
|
|
}
|
|
return currentValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|