8b9b85e7f5
Former-commit-id: 172c8e3c300b39d5785c7a3e8dfb08ebdbc1a99b
207 lines
6.2 KiB
C#
207 lines
6.2 KiB
C#
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
// Copyright (c) 2007 Novell, Inc. (http://www.novell.com)
|
|
//
|
|
// Authors:
|
|
// Chris Toshok (toshok@ximian.com)
|
|
//
|
|
|
|
using System;
|
|
|
|
namespace System.IO.Packaging {
|
|
|
|
public static class PackUriHelper
|
|
{
|
|
public static readonly string UriSchemePack = "pack";
|
|
static readonly Uri PackSchemeUri = new Uri("pack://", UriKind.Absolute);
|
|
static readonly char[] _escapedChars = new char[] { '%', ',', '?', '@' };
|
|
|
|
|
|
static PackUriHelper ()
|
|
{
|
|
if (!UriParser.IsKnownScheme (UriSchemePack))
|
|
UriParser.Register (new PackUriParser (), UriSchemePack, -1);
|
|
}
|
|
|
|
public static int ComparePackUri (Uri firstPackUri, Uri secondPackUri)
|
|
{
|
|
if (firstPackUri == null)
|
|
return secondPackUri == null ? 0 : -1;
|
|
if (secondPackUri == null)
|
|
return 1;
|
|
|
|
Check.PackUriIsValid (firstPackUri);
|
|
Check.PackUriIsValid (secondPackUri);
|
|
|
|
// FIXME: What exactly is compared. Lets assume originalstring
|
|
return firstPackUri.OriginalString.CompareTo (secondPackUri.OriginalString);
|
|
}
|
|
|
|
public static int ComparePartUri (Uri firstPartUri, Uri secondPartUri)
|
|
{
|
|
if (firstPartUri == null)
|
|
return secondPartUri == null ? 0 : -1;
|
|
if (secondPartUri == null)
|
|
return 1;
|
|
|
|
Check.PartUriIsValid (firstPartUri);
|
|
Check.PartUriIsValid (secondPartUri);
|
|
|
|
return firstPartUri.OriginalString.CompareTo (secondPartUri.OriginalString);
|
|
}
|
|
|
|
public static Uri Create (Uri packageUri)
|
|
{
|
|
return Create (packageUri, null, null);
|
|
}
|
|
|
|
public static Uri Create (Uri packageUri, Uri partUri)
|
|
{
|
|
return Create (packageUri, partUri, null);
|
|
}
|
|
|
|
public static Uri Create (Uri packageUri, Uri partUri, string fragment)
|
|
{
|
|
Check.PackageUri (packageUri);
|
|
Check.PackageUriIsValid (packageUri);
|
|
|
|
if (partUri != null)
|
|
Check.PartUriIsValid (partUri);
|
|
|
|
if (fragment != null && (fragment.Length == 0 || fragment[0] != '#'))
|
|
throw new ArgumentException ("Fragment", "Fragment must not be empty and must start with '#'");
|
|
|
|
// FIXME: Validate that partUri is a valid one? Must be relative, must start with '/'
|
|
|
|
// First replace the slashes, then escape the special characters
|
|
//string orig = packageUri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
|
|
string orig = packageUri.OriginalString;
|
|
|
|
foreach (var ch in _escapedChars)
|
|
{
|
|
orig = !orig.Contains(ch.ToString()) ? orig : orig.Replace(ch.ToString(), Uri.HexEscape(ch));
|
|
}
|
|
|
|
orig = orig.Replace('/', ',');
|
|
|
|
if (partUri != null)
|
|
orig += partUri.OriginalString;
|
|
|
|
if ((fragment == null && partUri == null)&& orig[orig.Length - 1] != '/')
|
|
orig += '/';
|
|
|
|
if (fragment != null)
|
|
orig += fragment;
|
|
|
|
return new Uri ("pack://" + orig);
|
|
}
|
|
|
|
public static Uri CreatePartUri (Uri partUri)
|
|
{
|
|
Check.PartUri (partUri);
|
|
|
|
if (partUri.OriginalString[0] != '/')
|
|
partUri = new Uri("/" + partUri.ToString (), UriKind.Relative);
|
|
return partUri;
|
|
}
|
|
|
|
public static Uri GetNormalizedPartUri (Uri partUri)
|
|
{
|
|
Check.PartUri (partUri);
|
|
return new Uri (partUri.ToString ().ToUpperInvariant (), UriKind.Relative);
|
|
}
|
|
|
|
public static Uri GetPackageUri (Uri packUri)
|
|
{
|
|
Check.PackUri (packUri);
|
|
Check.PackUriIsValid (packUri);
|
|
|
|
string s = packUri.Host.Replace(',', '/');
|
|
return new Uri (Uri.UnescapeDataString(s), UriKind.RelativeOrAbsolute);
|
|
}
|
|
|
|
public static Uri GetPartUri (Uri packUri)
|
|
{
|
|
Check.PackUri(packUri);
|
|
Check.PackUriIsValid(packUri);
|
|
|
|
if (string.IsNullOrEmpty(packUri.AbsolutePath) || packUri.AbsolutePath == "/")
|
|
return null;
|
|
|
|
return new Uri(packUri.AbsolutePath, UriKind.Relative);
|
|
}
|
|
|
|
public static Uri GetRelationshipPartUri (Uri partUri)
|
|
{
|
|
Check.PartUri (partUri);
|
|
Check.PartUriIsValid (partUri);
|
|
|
|
int index = partUri.OriginalString.LastIndexOf ("/");
|
|
string s = partUri.OriginalString.Substring (0, index);
|
|
s += "/_rels" + partUri.OriginalString.Substring (index) + ".rels";
|
|
return new Uri (s, UriKind.Relative);
|
|
}
|
|
|
|
public static Uri GetRelativeUri (Uri sourcePartUri, Uri targetPartUri)
|
|
{
|
|
Check.SourcePartUri (sourcePartUri);
|
|
Check.TargetPartUri (targetPartUri);
|
|
|
|
Uri uri = new Uri ("http://fake.com");
|
|
Uri a = new Uri (uri, sourcePartUri.OriginalString);
|
|
Uri b = new Uri (uri, targetPartUri.OriginalString);
|
|
|
|
return a.MakeRelativeUri(b);
|
|
}
|
|
|
|
public static Uri GetSourcePartUriFromRelationshipPartUri (Uri relationshipPartUri)
|
|
{
|
|
//Check.RelationshipPartUri (relationshipPartUri);
|
|
if (!IsRelationshipPartUri (relationshipPartUri))
|
|
throw new Exception ("is not a relationship part!?");
|
|
return null;
|
|
}
|
|
|
|
public static bool IsRelationshipPartUri (Uri partUri)
|
|
{
|
|
Check.PartUri (partUri);
|
|
return partUri.OriginalString.StartsWith ("/_rels") && partUri.OriginalString.EndsWith (".rels");
|
|
}
|
|
|
|
public static Uri ResolvePartUri (Uri sourcePartUri, Uri targetUri)
|
|
{
|
|
Check.SourcePartUri (sourcePartUri);
|
|
Check.TargetUri (targetUri);
|
|
|
|
Check.PartUriIsValid (sourcePartUri);
|
|
if (targetUri.IsAbsoluteUri)
|
|
throw new ArgumentException ("targetUri", "Absolute URIs are not supported");
|
|
|
|
Uri uri = new Uri ("http://fake.com");
|
|
uri = new Uri (uri, sourcePartUri);
|
|
uri = new Uri (uri, targetUri);
|
|
|
|
// Trim out 'http://fake.com'
|
|
return new Uri (uri.OriginalString.Substring (15), UriKind.Relative);
|
|
}
|
|
}
|
|
|
|
}
|