Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

PackUriHelper.cs 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace System.IO.Packaging
  7. {
  8. public static class PackUriHelper
  9. {
  10. public static readonly string UriSchemePack = "pack";
  11. static readonly Uri PackSchemeUri = new Uri("pack://", UriKind.Absolute);
  12. static readonly char[] _escapedChars = new char[] { '%', ',', '?', '@' };
  13. static PackUriHelper()
  14. {
  15. if (!UriParser.IsKnownScheme(UriSchemePack))
  16. UriParser.Register(new PackUriParser(), UriSchemePack, -1);
  17. }
  18. public static int ComparePackUri(Uri firstPackUri, Uri secondPackUri)
  19. {
  20. if (firstPackUri == null)
  21. return secondPackUri == null ? 0 : -1;
  22. if (secondPackUri == null)
  23. return 1;
  24. Check.PackUriIsValid(firstPackUri);
  25. Check.PackUriIsValid(secondPackUri);
  26. // FIXME: What exactly is compared. Lets assume originalstring
  27. return firstPackUri.OriginalString.CompareTo(secondPackUri.OriginalString);
  28. }
  29. public static int ComparePartUri(Uri firstPartUri, Uri secondPartUri)
  30. {
  31. if (firstPartUri == null)
  32. return secondPartUri == null ? 0 : -1;
  33. if (secondPartUri == null)
  34. return 1;
  35. Check.PartUriIsValid(firstPartUri);
  36. Check.PartUriIsValid(secondPartUri);
  37. return firstPartUri.OriginalString.CompareTo(secondPartUri.OriginalString);
  38. }
  39. public static Uri Create(Uri packageUri)
  40. {
  41. return Create(packageUri, null, null);
  42. }
  43. public static Uri Create(Uri packageUri, Uri partUri)
  44. {
  45. return Create(packageUri, partUri, null);
  46. }
  47. public static Uri Create(Uri packageUri, Uri partUri, string fragment)
  48. {
  49. Check.PackageUri(packageUri);
  50. Check.PackageUriIsValid(packageUri);
  51. if (partUri != null)
  52. Check.PartUriIsValid(partUri);
  53. if (fragment != null && (fragment.Length == 0 || fragment[0] != '#'))
  54. throw new ArgumentException("Fragment", "Fragment must not be empty and must start with '#'");
  55. // FIXME: Validate that partUri is a valid one? Must be relative, must start with '/'
  56. // First replace the slashes, then escape the special characters
  57. //string orig = packageUri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
  58. string orig = packageUri.OriginalString;
  59. foreach (var ch in _escapedChars)
  60. {
  61. orig = !orig.Contains(ch.ToString()) ? orig : orig.Replace(ch.ToString(), Uri.HexEscape(ch));
  62. }
  63. orig = orig.Replace('/', ',');
  64. if (partUri != null)
  65. orig += partUri.OriginalString;
  66. if ((fragment == null && partUri == null) && orig[orig.Length - 1] != '/')
  67. orig += '/';
  68. if (fragment != null)
  69. orig += fragment;
  70. return new Uri("pack://" + orig);
  71. }
  72. public static Uri CreatePartUri(Uri partUri)
  73. {
  74. Check.PartUri(partUri);
  75. if (partUri.OriginalString[0] != '/')
  76. partUri = new Uri("/" + partUri.ToString(), UriKind.Relative);
  77. return partUri;
  78. }
  79. public static Uri GetNormalizedPartUri(Uri partUri)
  80. {
  81. Check.PartUri(partUri);
  82. return new Uri(partUri.ToString().ToUpperInvariant(), UriKind.Relative);
  83. }
  84. public static Uri GetPackageUri(Uri packUri)
  85. {
  86. Check.PackUri(packUri);
  87. Check.PackUriIsValid(packUri);
  88. string s = packUri.Host.Replace(',', '/');
  89. return new Uri(Uri.UnescapeDataString(s), UriKind.RelativeOrAbsolute);
  90. }
  91. public static Uri GetPartUri(Uri packUri)
  92. {
  93. Check.PackUri(packUri);
  94. Check.PackUriIsValid(packUri);
  95. if (string.IsNullOrEmpty(packUri.AbsolutePath) || packUri.AbsolutePath == "/")
  96. return null;
  97. return new Uri(packUri.AbsolutePath, UriKind.Relative);
  98. }
  99. public static Uri GetRelationshipPartUri(Uri partUri)
  100. {
  101. Check.PartUri(partUri);
  102. Check.PartUriIsValid(partUri);
  103. int index = partUri.OriginalString.LastIndexOf("/");
  104. string s = partUri.OriginalString.Substring(0, index);
  105. s += "/_rels" + partUri.OriginalString.Substring(index) + ".rels";
  106. return new Uri(s, UriKind.Relative);
  107. }
  108. public static Uri GetRelativeUri(Uri sourcePartUri, Uri targetPartUri)
  109. {
  110. Check.SourcePartUri(sourcePartUri);
  111. Check.TargetPartUri(targetPartUri);
  112. Uri uri = new Uri("http://fake.com");
  113. Uri a = new Uri(uri, sourcePartUri.OriginalString);
  114. Uri b = new Uri(uri, targetPartUri.OriginalString);
  115. return a.MakeRelativeUri(b);
  116. }
  117. public static Uri GetSourcePartUriFromRelationshipPartUri(Uri relationshipPartUri)
  118. {
  119. //Check.RelationshipPartUri (relationshipPartUri);
  120. if (!IsRelationshipPartUri(relationshipPartUri))
  121. throw new Exception("is not a relationship part!?");
  122. return null;
  123. }
  124. public static bool IsRelationshipPartUri(Uri partUri)
  125. {
  126. Check.PartUri(partUri);
  127. return partUri.OriginalString.StartsWith("/_rels") && partUri.OriginalString.EndsWith(".rels");
  128. }
  129. public static Uri ResolvePartUri(Uri sourcePartUri, Uri targetUri)
  130. {
  131. Check.SourcePartUri(sourcePartUri);
  132. Check.TargetUri(targetUri);
  133. Check.PartUriIsValid(sourcePartUri);
  134. // commented out because on Android they are absolute file:///
  135. // if (targetUri.IsAbsoluteUri)
  136. // throw new ArgumentException("targetUri", "Absolute URIs are not supported");
  137. Uri uri = new Uri("http://fake.com");
  138. uri = new Uri(uri, sourcePartUri);
  139. uri = new Uri(uri, targetUri);
  140. // Trim out 'http://fake.com'
  141. return new Uri(uri.OriginalString.Substring(15), UriKind.Relative);
  142. }
  143. }
  144. }