The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl.Xslt \ ScopeReord

  1. //------------------------------------------------------------------------------
  2. // <copyright file="OutputScopeManager.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. using System;
  16. using System.Diagnostics;
  17. using System.Xml;
  18. using System.Collections;
  19. namespace System.Xml.Xsl.Xslt
  20. {
  21.     internal class OutputScopeManager
  22.     {
  23.         public struct ScopeReord
  24.         {
  25.             public int scopeCount;
  26.             public string prefix;
  27.             public string nsUri;
  28.         }
  29.         ScopeReord[] records = new ScopeReord[32];
  30.         int lastRecord = 0;
  31.         int lastScopes = 0;
  32.         // This is cash of records[lastRecord].scopeCount field;
  33.         // most often we will have PushScope()/PopScope pare over the same record.
  34.         // It has sence to avoid adresing this field through array access.
  35.         public OutputScopeManager()
  36.         {
  37.             Reset();
  38.         }
  39.        
  40.         public void Reset()
  41.         {
  42.             // AddNamespace(null, null); -- lookup barier
  43.             records[0].prefix = null;
  44.             records[0].nsUri = null;
  45.             PushScope();
  46.         }
  47.        
  48.         public void PushScope()
  49.         {
  50.             lastScopes++;
  51.         }
  52.        
  53.         public void PopScope()
  54.         {
  55.             if (0 < lastScopes) {
  56.                 lastScopes--;
  57.             }
  58.             else {
  59.                 while (records[--lastRecord].scopeCount == 0)
  60.                     ;
  61.                 lastScopes = records[lastRecord].scopeCount;
  62.                 lastScopes--;
  63.             }
  64.         }
  65.        
  66.         // This can be ns declaration or ns exclussion. Las one when prefix == null;
  67.         public void AddNamespace(string prefix, string uri)
  68.         {
  69.             Debug.Assert(prefix != null);
  70.             Debug.Assert(uri != null);
  71.             // uri = nameTable.Add(uri);
  72.             AddRecord(prefix, uri);
  73.         }
  74.        
  75.         private void AddRecord(string prefix, string uri)
  76.         {
  77.             records[lastRecord].scopeCount = lastScopes;
  78.             lastRecord++;
  79.             if (lastRecord == records.Length) {
  80.                 ScopeReord[] newRecords = new ScopeReord[lastRecord * 2];
  81.                 Array.Copy(records, 0, newRecords, 0, lastRecord);
  82.                 records = newRecords;
  83.             }
  84.             lastScopes = 0;
  85.             records[lastRecord].prefix = prefix;
  86.             records[lastRecord].nsUri = uri;
  87.         }
  88.        
  89.         //
  90.        
  91.        
  92.         public void InvalidateAllPrefixes()
  93.         {
  94.             if (records[lastRecord].prefix == null) {
  95.                 return;
  96.                 // Averything was invalidated already. Nothing to do.
  97.             }
  98.             AddRecord(null, null);
  99.         }
  100.        
  101.         public void InvalidateNonDefaultPrefixes()
  102.         {
  103.             string defaultNs = LookupNamespace(string.Empty);
  104.             if (defaultNs == null) {
  105.                 // We don't know default NS anyway.
  106.                 InvalidateAllPrefixes();
  107.             }
  108.             else {
  109.                 if (records[lastRecord].prefix.Length == 0 && records[lastRecord - 1].prefix == null) {
  110.                     return;
  111.                     // Averything was already done
  112.                 }
  113.                 AddRecord(null, null);
  114.                 AddRecord(string.Empty, defaultNs);
  115.             }
  116.         }
  117.        
  118.         public string LookupNamespace(string prefix)
  119.         {
  120.             Debug.Assert(prefix != null);
  121.             // from last record
  122.             // till lookup barrier
  123.             // in reverce direction
  124.             for (int record = lastRecord; records[record].prefix != null; --record) {
  125.                 Debug.Assert(0 < record, "first record is lookup bariaer, so we don't need to check this condition runtime");
  126.                 if (records[record].prefix == prefix) {
  127.                     return records[record].nsUri;
  128.                 }
  129.             }
  130.             return null;
  131.         }
  132.     }
  133. }

Developer Fusion