1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections; 7 using System.Collections.Generic; 8 using System.Diagnostics; 9 10 namespace System.IO.Packaging 11 { 12 /// <summary> 13 /// Collection of all the relationships corresponding to a given source PackagePart. 14 /// This class is part of the MMCF Packaging Layer. It handles serialization to/from 15 /// relationship parts, creation of those parts and offers methods to create, delete 16 /// and enumerate relationships. 17 /// </summary> 18 public class PackageRelationshipCollection : IEnumerable<PackageRelationship> 19 { 20 #region IEnumerable 21 22 /// <summary> 23 /// Returns an enumerator for all the relationships for a PackagePart 24 /// </summary> 25 /// <returns></returns> IEnumerable.GetEnumerator()26 IEnumerator IEnumerable.GetEnumerator() 27 { 28 return GetEnumerator(); 29 } 30 31 32 /// <summary> 33 /// Returns an enumerator over all the relationships for a PackagePart 34 /// </summary> 35 /// <returns></returns> GetEnumerator()36 public IEnumerator<PackageRelationship> GetEnumerator() 37 { 38 List<PackageRelationship>.Enumerator relationshipsEnumerator = _relationships.GetEnumerator(); 39 40 if (_filter == null) 41 return relationshipsEnumerator; 42 else 43 return new FilteredEnumerator(relationshipsEnumerator, _filter); 44 } 45 #endregion 46 47 #region Internal Members 48 /// <summary> 49 /// Constructor 50 /// </summary> 51 /// <remarks>For use by PackagePart</remarks> PackageRelationshipCollection(InternalRelationshipCollection relationships, string filter)52 internal PackageRelationshipCollection(InternalRelationshipCollection relationships, string filter) 53 { 54 Debug.Assert(relationships != null, "relationships parameter cannot be null"); 55 56 _relationships = relationships; 57 _filter = filter; 58 } 59 60 #endregion 61 62 #region Private Members 63 64 private InternalRelationshipCollection _relationships; 65 private string _filter; 66 67 #endregion 68 69 #region Private Class 70 71 #region FilteredEnumerator Class 72 73 /// <summary> 74 /// Internal class for the FilteredEnumerator 75 /// </summary> 76 private sealed class FilteredEnumerator : IEnumerator<PackageRelationship> 77 { 78 #region Constructor 79 80 /// <summary> 81 /// Constructs a FilteredEnumerator 82 /// </summary> 83 /// <param name="enumerator"></param> 84 /// <param name="filter"></param> FilteredEnumerator(IEnumerator<PackageRelationship> enumerator, string filter)85 internal FilteredEnumerator(IEnumerator<PackageRelationship> enumerator, string filter) 86 { 87 Debug.Assert((enumerator != null), "Enumerator cannot be null"); 88 Debug.Assert(filter != null, "PackageRelationship filter string cannot be null"); 89 90 // Look for empty string or string with just spaces 91 Debug.Assert(filter.Trim() != String.Empty, 92 "RelationshipType filter cannot be empty string or a string with just spaces"); 93 94 _enumerator = enumerator; 95 _filter = filter; 96 } 97 98 #endregion Constructor 99 100 #region IEnumerator Methods 101 102 /// <summary> 103 /// This method keeps moving the enumerator the next position till 104 /// a relationship is found with the matching Name 105 /// </summary> 106 /// <returns>Bool indicating if the enumerator successfully moved to the next position</returns> IEnumerator.MoveNext()107 bool IEnumerator.MoveNext() 108 { 109 while (_enumerator.MoveNext()) 110 { 111 if (RelationshipTypeMatches()) 112 return true; 113 } 114 115 return false; 116 } 117 118 /// <summary> 119 /// Gets the current object in the enumerator 120 /// </summary> 121 /// <value></value> 122 Object IEnumerator.Current 123 { 124 get 125 { 126 return _enumerator.Current; 127 } 128 } 129 130 /// <summary> 131 /// Resets the enumerator to the beginning 132 /// </summary> IEnumerator.Reset()133 void IEnumerator.Reset() 134 { 135 _enumerator.Reset(); 136 } 137 138 #endregion IEnumerator Methods 139 140 #region IEnumerator<PackageRelationship> Members 141 142 143 /// <summary> 144 /// Gets the current object in the enumerator 145 /// </summary> 146 /// <value></value> 147 public PackageRelationship Current 148 { 149 get 150 { 151 return _enumerator.Current; 152 } 153 } 154 155 #endregion IEnumerator<PackageRelationship> Members 156 157 #region IDisposable Members 158 Dispose()159 public void Dispose() 160 { 161 //Most enumerators have dispose as a no-op, we follow the same pattern. 162 _enumerator.Dispose(); 163 } 164 165 #endregion IDisposable Members 166 167 #region Private Methods 168 RelationshipTypeMatches()169 private bool RelationshipTypeMatches() 170 { 171 PackageRelationship r = _enumerator.Current; 172 173 //Case-sensitive comparison 174 if (String.CompareOrdinal(r.RelationshipType, _filter) == 0) 175 return true; 176 else 177 return false; 178 } 179 180 #endregion Private Methods 181 182 #region Private Members 183 184 private IEnumerator<PackageRelationship> _enumerator; 185 private string _filter; 186 187 #endregion Private Members 188 } 189 190 #endregion FilteredEnumerator Class 191 192 #endregion Private Class 193 } 194 } 195