Skip to content

Commit bf3cb12

Browse files
authored
Separate schema validation restrictions to own files (#352)
1 parent cc73f83 commit bf3cb12

37 files changed

+2503
-2186
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Diagnostics;
6+
using System.Runtime.Serialization;
7+
8+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
9+
{
10+
/// <summary>
11+
/// AnyURI (xsd:anyURI) based simple type constraint.
12+
/// </summary>
13+
/// <remarks>
14+
/// anyURI represents a Uniform Resource Identifier Reference (URI).
15+
/// An anyURI value can be absolute or relative, and may have an optional fragment identifier (i.e., it may be a URI Reference).
16+
/// This type should be used to specify the intention that the value fulfills the role of a URI as defined by [RFC 2396], as amended by [RFC 2732].
17+
/// </remarks>
18+
[DataContract]
19+
internal class AnyUriRestriction : StringRestriction
20+
{
21+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
22+
private static char[] WhitespaceChars = new char[] { ' ', '\t', '\n', '\r' };
23+
24+
/// <inheritdoc />
25+
public override XsdType XsdType => XsdType.AnyURI;
26+
27+
/// <inheritdoc />
28+
public override string ClrTypeName => typeof(Uri).Name;
29+
30+
/// <inheritdoc />
31+
public override bool ValidateValueType(OpenXmlSimpleType attributeValue)
32+
{
33+
Uri result = null;
34+
Debug.Assert(attributeValue != null);
35+
string uriString = attributeValue.InnerText;
36+
37+
// code copied from XmlConvert.TryToUri()
38+
39+
if ((uriString != null) && (uriString.Length > 0))
40+
{
41+
uriString = uriString.Trim(WhitespaceChars);
42+
if ((uriString.Length == 0) || (uriString.IndexOf("##", StringComparison.Ordinal) != -1))
43+
{
44+
return false;
45+
}
46+
}
47+
if (!Uri.TryCreate(uriString, UriHelper.RelativeOrAbsolute, out result))
48+
{
49+
return false;
50+
}
51+
52+
return true;
53+
}
54+
}
55+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using DocumentFormat.OpenXml.Validation;
5+
using System;
6+
using System.Runtime.Serialization;
7+
8+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
9+
{
10+
/// <summary>
11+
/// Base64 binary (xsd:base64Binary) based simple type constraint.
12+
/// </summary>
13+
/// <remarks>
14+
/// The lexical forms of base64Binary values are limited to the 65 characters of the Base64 Alphabet defined in [RFC 2045], i.e., a-z, A-Z, 0-9, the plus sign (+), the forward slash (/) and the equal sign (=), together with the characters defined in [XML 1.0 (Second Edition)] as white space. No other characters are allowed.
15+
/// </remarks>
16+
[DataContract]
17+
internal class Base64BinaryRestriction : StringRestriction
18+
{
19+
/// <inheritdoc />
20+
public override XsdType XsdType => XsdType.Base64Binary;
21+
22+
/// <inheritdoc />
23+
public override string ClrTypeName => ValidationResources.TypeName_base64Binary;
24+
25+
/// <inheritdoc />
26+
public override bool ValidateValueType(OpenXmlSimpleType attributeValue)
27+
{
28+
if (attributeValue.InnerText == null)
29+
{
30+
return false;
31+
}
32+
else if (attributeValue.InnerText.Length == 0)
33+
{
34+
return true;
35+
}
36+
37+
try
38+
{
39+
Convert.FromBase64String(attributeValue.InnerText);
40+
}
41+
catch (FormatException)
42+
{
43+
return false;
44+
}
45+
46+
return true;
47+
}
48+
49+
/// <inheritdoc />
50+
internal override int GetValueLength(OpenXmlSimpleType attributeValue)
51+
{
52+
// decoded the data
53+
var binaryData = Convert.FromBase64String(attributeValue.InnerText);
54+
return binaryData.Length;
55+
}
56+
}
57+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Diagnostics;
6+
using System.Runtime.Serialization;
7+
8+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
9+
{
10+
/// <summary>
11+
/// Boolean (xsd:boolean) based simple type constraint.
12+
/// </summary>
13+
[DataContract]
14+
internal class BooleanValueRestriction : SimpleTypeRestriction
15+
{
16+
// BooleanValueRestriction is the only SimpleTypeRestriction that can have
17+
// multiple values of XsdType, so we only need to serialize this instance
18+
[DataMember(Name = nameof(XsdType))]
19+
private XsdType _xsdType = XsdType.Boolean;
20+
21+
/// <inheritdoc />
22+
public override XsdType XsdType => _xsdType;
23+
24+
public void SetXsdType(XsdType value)
25+
{
26+
Debug.Assert(value == XsdType.Boolean || value == XsdType.SpecialBoolean);
27+
this._xsdType = value;
28+
}
29+
30+
/// <inheritdoc />
31+
public override string ClrTypeName => typeof(Boolean).Name;
32+
33+
#if DEBUG
34+
public override void Verify()
35+
{
36+
Debug.Assert(this.XsdType == XsdType.Boolean || this.XsdType == XsdType.SpecialBoolean);
37+
Debug.Assert(this.IsEnum == false);
38+
Debug.Assert(this.IsList == false);
39+
Debug.Assert(this.Pattern == null);
40+
}
41+
#endif
42+
}
43+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Runtime.Serialization;
6+
7+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
8+
{
9+
/// <summary>
10+
/// Byte ( xsd:unsignedByte ) based value restriction.
11+
/// </summary>
12+
[DataContract]
13+
internal class ByteValueRestriction : SimpleValueRestriction<Byte, ByteValue>
14+
{
15+
protected override Byte MinValue => Byte.MinValue;
16+
17+
protected override Byte MaxValue => Byte.MaxValue;
18+
19+
/// <inheritdoc />
20+
public override XsdType XsdType => XsdType.UnsignedByte;
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Runtime.Serialization;
6+
7+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
8+
{
9+
/// <summary>
10+
/// DateTime (xsd:dateTime) based value restriction.
11+
/// </summary>
12+
[DataContract]
13+
internal class DateTimeValueRestriction : SimpleValueRestriction<DateTime, DateTimeValue>
14+
{
15+
protected override DateTime MinValue => DateTime.MinValue;
16+
17+
protected override DateTime MaxValue => DateTime.MaxValue;
18+
19+
/// <inheritdoc />
20+
public override XsdType XsdType => XsdType.DateTime;
21+
}
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Runtime.Serialization;
6+
7+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
8+
{
9+
/// <summary>
10+
/// DateTime (xsd:date) based value restriction.
11+
/// </summary>
12+
[DataContract]
13+
internal class DateValueRestriction : SimpleValueRestriction<DateTime, DateTimeValue>
14+
{
15+
protected override DateTime MinValue => DateTime.MinValue;
16+
17+
protected override DateTime MaxValue => DateTime.MaxValue;
18+
19+
/// <inheritdoc />
20+
public override XsdType XsdType => XsdType.Date;
21+
22+
// TODO: validate date.
23+
}
24+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Runtime.Serialization;
6+
7+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
8+
{
9+
/// <summary>
10+
/// Decimal (xsd:decimal) based value restriction.
11+
/// </summary>
12+
/// <remarks>
13+
/// decimal represents a subset of the real numbers, which can be represented by decimal numerals.
14+
/// The ·value space· of decimal is the set of numbers that can be obtained by multiplying an integer by a non-positive power of ten,
15+
/// i.e., expressible as i × 10^-n where i and n are integers and n >= 0.
16+
/// Precision is not reflected in this value space; the number 2.0 is not distinct from the number 2.00.
17+
/// The ·order-relation· on decimal is the order relation on real numbers, restricted to this subset.
18+
/// </remarks>
19+
[DataContract]
20+
internal class DecimalValueRestriction : SimpleValueRestriction<Decimal, DecimalValue>
21+
{
22+
protected override Decimal MinValue => Decimal.MinValue;
23+
24+
protected override Decimal MaxValue => Decimal.MaxValue;
25+
26+
/// <inheritdoc />
27+
public override XsdType XsdType => XsdType.Decimal;
28+
}
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.Runtime.Serialization;
6+
7+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
8+
{
9+
/// <summary>
10+
/// Double (xsd:double) based value restriction.
11+
/// </summary>
12+
[DataContract]
13+
internal class DoubleValueRestriction : SimpleValueRestriction<Double, DoubleValue>
14+
{
15+
protected override Double MinValue => Double.MinValue;
16+
17+
protected override Double MaxValue => Double.MaxValue;
18+
19+
/// <inheritdoc />
20+
public override XsdType XsdType => XsdType.Double;
21+
22+
/// <inheritdoc />
23+
public override bool ValidateValueType(OpenXmlSimpleType attributeValue)
24+
{
25+
if (attributeValue.HasValue)
26+
{
27+
return true;
28+
29+
// TODO: is NaN valid?
30+
//double value = ((DoubleValue)attributeValue).Value;
31+
//return !double.IsNaN(value);
32+
}
33+
return false;
34+
}
35+
}
36+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System.Runtime.Serialization;
5+
6+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
7+
{
8+
/// <summary>
9+
/// Class for all string enum based simple types.
10+
/// </summary>
11+
/// <remarks>
12+
/// We do not save the enums in the database. Instead we reuse the generated enum class in the generated code.
13+
/// For attributes, the type of the enum is known through the code-gen'ed data.
14+
/// </remarks>
15+
[DataContract]
16+
internal class EnumValueRestriction : SimpleTypeRestriction
17+
{
18+
/// <inheritdoc />
19+
public override XsdType XsdType => XsdType.Enum;
20+
21+
/// <inheritdoc />
22+
public override bool IsEnum => true;
23+
24+
/// <inheritdoc />
25+
public override bool ValidateValueType(OpenXmlSimpleType attributeValue)
26+
{
27+
if (attributeValue.HasValue)
28+
{
29+
// Items in the enum are merged from both Office2007 and Office2010.
30+
// So, we should report error when the item is not defined in the specified version.
31+
32+
return attributeValue.IsInVersion(this.FileFormat);
33+
}
34+
return false;
35+
}
36+
}
37+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using DocumentFormat.OpenXml.Validation;
5+
using System.Runtime.Serialization;
6+
using System.Text.RegularExpressions;
7+
8+
namespace DocumentFormat.OpenXml.Internal.SchemaValidation
9+
{
10+
/// <summary>
11+
/// Hex binary (xsd:hexBinary) based simple type constraint.
12+
/// </summary>
13+
/// <remarks>
14+
/// hexBinary has a lexical representation where each binary octet is encoded as a character tuple,
15+
/// consisting of two hexadecimal digits ([0-9a-fA-F]) representing the octet code.
16+
/// For example, "0FB7" is a hex encoding for the 16-bit integer 4023 (whose binary representation is 111110110111).
17+
/// </remarks>
18+
[DataContract]
19+
internal class HexBinaryRestriction : StringRestriction
20+
{
21+
/// <inheritdoc />
22+
public override XsdType XsdType => XsdType.HexBinary;
23+
24+
/// <inheritdoc />
25+
public override string ClrTypeName => ValidationResources.TypeName_hexBinary;
26+
27+
/// <inheritdoc />
28+
public override bool ValidateValueType(OpenXmlSimpleType attributeValue)
29+
{
30+
if (attributeValue.InnerText == null)
31+
{
32+
return false;
33+
}
34+
else if (attributeValue.InnerText.Length == 0)
35+
{
36+
return true;
37+
}
38+
39+
string pattern = @"\A([0-9a-fA-F][0-9a-fA-F])+\z";
40+
41+
return Regex.IsMatch(attributeValue.InnerText, pattern, RegexOptions.CultureInvariant);
42+
}
43+
44+
/// <inheritdoc />
45+
internal override int GetValueLength(OpenXmlSimpleType attributeValue)
46+
{
47+
// so, the data length is the number of octets
48+
// then the data lenght is string lenght / 2
49+
var stringLength = attributeValue.InnerText.Length;
50+
//Debug.Assert(stringLength % 2 == 0);
51+
return (stringLength + 1) / 2;
52+
}
53+
}
54+
}

0 commit comments

Comments
 (0)