Пример #1
0
 private static void CheckIdRange(PackageXmlEnum id)
 {
     if (id <= PackageXmlEnum.NotDefined || id >= (PackageXmlEnum)27)
     {
         throw new ArgumentOutOfRangeException("id");
     }
 }
Пример #2
0
 private static void CheckIdRange(PackageXmlEnum id)
 {
     if ((id <= PackageXmlEnum.NotDefined) || (id >= (PackageXmlEnum.LastPrinted | PackageXmlEnum.XmlSchemaInstanceNamespace)))
     {
         throw new ArgumentOutOfRangeException(nameof(id));
     }
 }
Пример #3
0
 private static void CheckIdRange(PackageXmlEnum id)
 {
     if ((id <= PackageXmlEnum.NotDefined) || (id >= (PackageXmlEnum.LastPrinted | PackageXmlEnum.XmlSchemaInstanceNamespace)))
     {
         throw new ArgumentOutOfRangeException("id");
     }
 }
Пример #4
0
        // Set new property value.
        // Null value is passed for deleting a property.
        // While initializing, we are not assigning new values, and so the dirty flag should
        // stay untouched.
        private void RecordNewBinding(PackageXmlEnum propertyenum, object value, bool initializing, XmlTextReader reader)
        {
            // If we are reading values from the package, reader cannot be null
            Debug.Assert(!initializing || reader != null);

            if (!initializing)
            {
                _package.ThrowIfReadOnly();
            }

            // Case of an existing property.
            if (_propertyDictionary.ContainsKey(propertyenum))
            {
                // Parsing should detect redundant entries.
                if (initializing)
                {
                    throw new XmlException(SR.Get(SRID.DuplicateCorePropertyName, reader.Name),
                                           null, reader.LineNumber, reader.LinePosition);
                }

                // No edit of existing properties in streaming production.
                if (_package.InStreamingCreation)
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationViolatesWriteOnceSemantics));
                }

                // Nullable<DateTime> values can be checked against null
                if (value == null) // a deletion
                {
                    _propertyDictionary.Remove(propertyenum);
                }
                else // an update
                {
                    _propertyDictionary[propertyenum] = value;
                }
                // If the binding is an assignment rather than an initialization, set the dirty flag.
                _dirty = !initializing;
            }
            // Case of a null value in the absence of an existing property.
            else if (value == null)
            {
                // Even thinking about setting a property to null in streaming production is a no-no.
                if (_package.InStreamingCreation)
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationViolatesWriteOnceSemantics));
                }

                // Outside of streaming production, deleting a non-existing property is a no-op.
            }
            // Case of an initial value being set for a property.
            else
            {
                _propertyDictionary.Add(propertyenum, value);
                // If the binding is an assignment rather than an initialization, set the dirty flag.
                _dirty = !initializing;
            }
        }
        // The property store is implemented as a hash table of objects.
        // Keys are taken from the set of string constants defined in this
        // class and compared by their references rather than their values.

        private object GetPropertyValue(PackageXmlEnum propertyName)
        {
            _package.ThrowIfWriteOnly();

            if (!_propertyDictionary.ContainsKey(propertyName))
            {
                return(null);
            }
            return(_propertyDictionary[propertyName]);
        }
        // Shim function to adequately cast the result of GetPropertyValue.
        private Nullable <DateTime> GetDateTimePropertyValue(PackageXmlEnum propertyName)
        {
            object valueObject = GetPropertyValue(propertyName);

            if (valueObject == null)
            {
                return(null);
            }
            // If an object is there, it will be a DateTime (not a Nullable<DateTime>).
            return((Nullable <DateTime>)valueObject);
        }
        // Write the property elements and clear _dirty.
        private void SerializeDirtyProperties()
        {
            Debug.Assert(_xmlWriter != null);

            // Create a property element for each non-null entry.
            foreach (KeyValuePair <PackageXmlEnum, object> entry in _propertyDictionary)
            {
                Debug.Assert(entry.Value != null);

                PackageXmlEnum propertyNamespace = PackageXmlStringTable.GetXmlNamespace(entry.Key);

                _xmlWriter.WriteStartElement(PackageXmlStringTable.GetXmlString(entry.Key),
                                             PackageXmlStringTable.GetXmlString(propertyNamespace));

                if (entry.Value is Nullable <DateTime> )
                {
                    if (propertyNamespace == PackageXmlEnum.DublinCoreTermsNamespace)
                    {
                        // xsi:type=
                        _xmlWriter.WriteStartAttribute(PackageXmlStringTable.GetXmlString(PackageXmlEnum.Type),
                                                       PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));

                        // "dcterms:W3CDTF"
                        _xmlWriter.WriteQualifiedName(W3cdtf,
                                                      PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCoreTermsNamespace));

                        _xmlWriter.WriteEndAttribute();
                    }

                    // Use sortable ISO 8601 date/time pattern. Include second fractions down to the 100-nanosecond interval,
                    // which is the definition of a "tick" for the DateTime type.
                    _xmlWriter.WriteString(XmlConvert.ToString(((Nullable <DateTime>)entry.Value).Value.ToUniversalTime(), "yyyy-MM-ddTHH:mm:ss.fffffffZ"));
                }
                else
                {
                    // The following uses the fact that ToString is virtual.
                    _xmlWriter.WriteString(entry.Value.ToString());
                }

                _xmlWriter.WriteEndElement();
            }

            // Mark properties as saved.
            _dirty = false;
        }
        // Set new property value.
        // Null value is passed for deleting a property.
        // While initializing, we are not assigning new values, and so the dirty flag should
        // stay untouched.
        private void RecordNewBinding(PackageXmlEnum propertyenum, object value, bool initializing, XmlReader reader)
        {
            // If we are reading values from the package, reader cannot be null
            Debug.Assert(!initializing || reader != null);

            if (!initializing)
            {
                _package.ThrowIfReadOnly();
            }

            // Case of an existing property.
            if (_propertyDictionary.ContainsKey(propertyenum))
            {
                // Parsing should detect redundant entries.
                if (initializing)
                {
                    throw new XmlException(SR.Format(SR.DuplicateCorePropertyName, reader.Name),
                                           null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                }

                // Nullable<DateTime> values can be checked against null
                if (value == null) // a deletion
                {
                    _propertyDictionary.Remove(propertyenum);
                }
                else // an update
                {
                    _propertyDictionary[propertyenum] = value;
                }
                // If the binding is an assignment rather than an initialization, set the dirty flag.
                _dirty = !initializing;
            }
            // Case of an initial value being set for a property. If value is null, no need to do anything
            else if (value != null)
            {
                _propertyDictionary.Add(propertyenum, value);
                // If the binding is an assignment rather than an initialization, set the dirty flag.
                _dirty = !initializing;
            }
        }
Пример #9
0
 internal static PackageXmlEnum GetXmlNamespace(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return(PackageXmlStringTable._xmlstringtable[(int)id].Namespace);
 }
Пример #10
0
 internal static string GetXmlString(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return((string)PackageXmlStringTable._xmlstringtable[(int)id].Name);
 }
Пример #11
0
 internal static object GetXmlStringAsObject(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return(PackageXmlStringTable._xmlstringtable[(int)id].Name);
 }
        // Set new property value.
        // Null value is passed for deleting a property. 
        // While initializing, we are not assigning new values, and so the dirty flag should
        // stay untouched.
        private void RecordNewBinding(PackageXmlEnum propertyenum, object value, bool initializing, XmlTextReader reader)
        { 
            // If we are reading values from the package, reader cannot be null
            Debug.Assert(!initializing || reader != null); 
 
            if (!initializing)
                _package.ThrowIfReadOnly(); 

            // Case of an existing property.
            if (_propertyDictionary.ContainsKey(propertyenum))
            { 
                // Parsing should detect redundant entries.
                if (initializing) 
                { 
                    throw new XmlException(SR.Get(SRID.DuplicateCorePropertyName, reader.Name),
                        null, reader.LineNumber, reader.LinePosition); 
                }

                // No edit of existing properties in streaming production.
                if (_package.InStreamingCreation) 
                    throw new InvalidOperationException(SR.Get(SRID.OperationViolatesWriteOnceSemantics));
 
                // Nullable<DateTime> values can be checked against null 
                if (value == null) // a deletion
                { 
                    _propertyDictionary.Remove(propertyenum);
                }
                else // an update
                { 
                    _propertyDictionary[propertyenum] = value;
                } 
                // If the binding is an assignment rather than an initialization, set the dirty flag. 
                _dirty = !initializing;
            } 
            // Case of a null value in the absence of an existing property.
            else if (value == null)
            {
                // Even thinking about setting a property to null in streaming production is a no-no. 
                if (_package.InStreamingCreation)
                    throw new InvalidOperationException(SR.Get(SRID.OperationViolatesWriteOnceSemantics)); 
 
                // Outside of streaming production, deleting a non-existing property is a no-op.
            } 
            // Case of an initial value being set for a property.
            else
            {
                _propertyDictionary.Add(propertyenum, value); 
                // If the binding is an assignment rather than an initialization, set the dirty flag.
                _dirty = !initializing; 
            } 
        }
Пример #13
0
 internal XmlStringTableStruct(object nameString, PackageXmlEnum ns, string valueType)
 {
     this._nameString = nameString;
     this._namespace  = ns;
     this._valueType  = valueType;
 }
        //------------------------------------------------------
        //
        //  Internal Properties
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        // The property store is implemented as a hash table of objects.
        // Keys are taken from the set of string constants defined in this
        // class and compared by their references rather than their values.

        private object GetPropertyValue(PackageXmlEnum propertyName)
        {
            _package.ThrowIfWriteOnly();

            if (!_propertyDictionary.ContainsKey(propertyName))
                return null;
            return _propertyDictionary[propertyName];
        }
Пример #15
0
        // Write the property elements and clear _dirty.
        private void SerializeDirtyProperties()
        {
            // In streaming mode, nullify dictionary values.
            // As no property can be set to null through the API, this makes it possible to keep
            // track of all properties that have been set since the CoreProperties object was created.
            KeyValuePair <PackageXmlEnum, Object>[] entriesToNullify = null;
            int numEntriesToNullify = 0;

            if (_package.InStreamingCreation)
            {
                entriesToNullify = new KeyValuePair <PackageXmlEnum, Object> [_propertyDictionary.Count];
            }

            // Create a property element for each non-null entry.
            foreach (KeyValuePair <PackageXmlEnum, Object> entry in _propertyDictionary)
            {
                // If we are NOT in streaming mode, the property value should NOT be null
                Debug.Assert(entry.Value != null || _package.InStreamingCreation);

                if (_package.InStreamingCreation &&
                    entry.Value == null)    // already saved
                {
                    continue;
                }


                PackageXmlEnum propertyNamespace = PackageXmlStringTable.GetXmlNamespace(entry.Key);

                _xmlWriter.WriteStartElement(PackageXmlStringTable.GetXmlString(entry.Key),
                                             PackageXmlStringTable.GetXmlString(propertyNamespace));

                if (entry.Value is Nullable <DateTime> )
                {
                    if (propertyNamespace == PackageXmlEnum.DublinCoreTermsNamespace)
                    {
                        // xsi:type=
                        _xmlWriter.WriteStartAttribute(PackageXmlStringTable.GetXmlString(PackageXmlEnum.Type),
                                                       PackageXmlStringTable.GetXmlString(PackageXmlEnum.XmlSchemaInstanceNamespace));

                        // "dcterms:W3CDTF"
                        _xmlWriter.WriteQualifiedName(_w3cdtf,
                                                      PackageXmlStringTable.GetXmlString(PackageXmlEnum.DublinCoreTermsNamespace));

                        _xmlWriter.WriteEndAttribute();
                    }

                    // Use sortable ISO 8601 date/time pattern. Include second fractions down to the 100-nanosecond interval,
                    // which is the definition of a "tick" for the DateTime type.
                    _xmlWriter.WriteString(XmlConvert.ToString(((Nullable <DateTime>)entry.Value).Value.ToUniversalTime(), "yyyy-MM-ddTHH:mm:ss.fffffffZ"));
                }
                else
                {
                    // The following uses the fact that ToString is virtual.
                    _xmlWriter.WriteString(entry.Value.ToString());
                }

                _xmlWriter.WriteEndElement();

                if (_package.InStreamingCreation)
                {
                    entriesToNullify[numEntriesToNullify++] = entry;
                }
            }

            // Mark properties as saved.
            _dirty = false;

            // Detailed marking of saved properties for the streaming mode.
            if (_package.InStreamingCreation)
            {
                for (int i = 0; i < numEntriesToNullify; ++i)
                {
                    _propertyDictionary[entriesToNullify[i].Key] = null;
                }
            }
        }
Пример #16
0
 internal static string GetValueType(PackageXmlEnum id)
 {
     PackageXmlStringTable.CheckIdRange(id);
     return(PackageXmlStringTable._xmlstringtable[(int)id].ValueType);
 }
 // Set new property value.
 // Override that sets the initializing flag to false to reflect the default
 // situation: recording a binding to implement a value assignment.
 private void RecordNewBinding(PackageXmlEnum propertyenum, object value)
 {
     RecordNewBinding(propertyenum, value, false /* not invoked at construction */, null);
 }
        // Set new property value.
        // Null value is passed for deleting a property.
        // While initializing, we are not assigning new values, and so the dirty flag should
        // stay untouched.
        private void RecordNewBinding(PackageXmlEnum propertyenum, object value, bool initializing, XmlReader reader)
        {
            // If we are reading values from the package, reader cannot be null
            Debug.Assert(!initializing || reader != null);

            if (!initializing)
                _package.ThrowIfReadOnly();

            // Case of an existing property.
            if (_propertyDictionary.ContainsKey(propertyenum))
            {
                // Parsing should detect redundant entries.
                if (initializing)
                {
                    throw new XmlException(SR.Format(SR.DuplicateCorePropertyName, reader.Name),
                        null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                }

                // Nullable<DateTime> values can be checked against null
                if (value == null) // a deletion
                {
                    _propertyDictionary.Remove(propertyenum);
                }
                else // an update
                {
                    _propertyDictionary[propertyenum] = value;
                }
                // If the binding is an assignment rather than an initialization, set the dirty flag.
                _dirty = !initializing;
            }
            // Case of an initial value being set for a property.
            else
            {
                _propertyDictionary.Add(propertyenum, value);
                // If the binding is an assignment rather than an initialization, set the dirty flag.
                _dirty = !initializing;
            }
        }
Пример #19
0
 internal XmlStringTableStruct(object nameString, PackageXmlEnum ns, string valueType)
 {
     _nameString = nameString;
     _namespace = ns;
     _valueType = valueType;
 }
Пример #20
0
 internal static object GetXmlStringAsObject(PackageXmlEnum id)
 {
     CheckIdRange(id);
     return s_xmlstringtable[(int)id].Name;
 }
Пример #21
0
 internal static string GetXmlString(PackageXmlEnum id)
 {
     CheckIdRange(id);
     return (string)s_xmlstringtable[(int)id].Name;
 }
Пример #22
0
 internal static PackageXmlEnum GetXmlNamespace(PackageXmlEnum id)
 {
     CheckIdRange(id);
     return s_xmlstringtable[(int)id].Namespace;
 }
Пример #23
0
 internal static string?GetValueType(PackageXmlEnum id)
 {
     CheckIdRange(id);
     return(s_xmlstringtable[(int)id].ValueType);
 }
 // Shim function to adequately cast the result of GetPropertyValue.
 private Nullable<DateTime> GetDateTimePropertyValue(PackageXmlEnum propertyName)
 {
     object valueObject = GetPropertyValue(propertyName);
     if (valueObject == null)
         return null;
     // If an object is there, it will be a DateTime (not a Nullable<DateTime>).
     return (Nullable<DateTime>)valueObject;
 }
Пример #25
0
 // Set new property value.
 // Override that sets the initializing flag to false to reflect the default
 // situation: recording a binding to implement a value assignment.
 private void RecordNewBinding(PackageXmlEnum propertyenum, object value)
 {
     RecordNewBinding(propertyenum, value, false /* not invoked at construction */, null);
 }
Пример #26
0
 internal static string GetValueType(PackageXmlEnum id)
 {
     CheckIdRange(id);
     return s_xmlstringtable[(int)id].ValueType;
 }
Пример #27
0
        // Deserialize properties part.
        private void ParseCorePropertyPart(PackagePart part)
        {
            XmlReaderSettings xrs = new XmlReaderSettings();

            xrs.NameTable = _nameTable;
            using (Stream stream = part.GetStream(FileMode.Open, FileAccess.Read))

                // Create a reader that uses _nameTable so as to use the set of tag literals
                // in effect as a set of atomic identifiers.
                using (XmlReader reader = XmlReader.Create(stream, xrs))
                {
                    //This method expects the reader to be in ReadState.Initial.
                    //It will make the first read call.
                    PackagingUtilities.PerformInitialReadAndVerifyEncoding(reader);

                    //Note: After the previous method call the reader should be at the first tag in the markup.
                    //MoveToContent - Skips over the following - ProcessingInstruction, DocumentType, Comment, Whitespace, or SignificantWhitespace
                    //If the reader is currently at a content node then this function call is a no-op
                    if (reader.MoveToContent() != XmlNodeType.Element ||
                        (object)reader.NamespaceURI != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.PackageCorePropertiesNamespace) ||
                        (object)reader.LocalName != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.CoreProperties))
                    {
                        throw new XmlException(SR.CorePropertiesElementExpected,
                                               null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                    }

                    // The schema is closed and defines no attributes on the root element.
                    if (PackagingUtilities.GetNonXmlnsAttributeCount(reader) != 0)
                    {
                        throw new XmlException(SR.Format(SR.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                               null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                    }

                    // Iterate through property elements until EOF. Note the proper closing of all
                    // open tags is checked by the reader itself.
                    // This loop deals only with depth-1 start tags. Handling of element content
                    // is delegated to dedicated functions.
                    int attributesCount;

                    while (reader.Read() && reader.MoveToContent() != XmlNodeType.None)
                    {
                        // Ignore end-tags. We check element errors on opening tags.
                        if (reader.NodeType == XmlNodeType.EndElement)
                        {
                            continue;
                        }

                        // Any content markup that is not an element here is unexpected.
                        if (reader.NodeType != XmlNodeType.Element)
                        {
                            throw new XmlException(SR.PropertyStartTagExpected,
                                                   null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                        }

                        // Any element below the root should open at level 1 exclusively.
                        if (reader.Depth != 1)
                        {
                            throw new XmlException(SR.NoStructuredContentInsideProperties,
                                                   null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                        }

                        attributesCount = PackagingUtilities.GetNonXmlnsAttributeCount(reader);

                        // Property elements can occur in any order (xsd:all).
                        object         localName      = reader.LocalName;
                        PackageXmlEnum xmlStringIndex = PackageXmlStringTable.GetEnumOf(localName);
                        string         valueType      = PackageXmlStringTable.GetValueType(xmlStringIndex);

                        if (Array.IndexOf(s_validProperties, xmlStringIndex) == -1) // An unexpected element is an error.
                        {
                            throw new XmlException(
                                      SR.Format(SR.InvalidPropertyNameInCorePropertiesPart, reader.LocalName),
                                      null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                        }

                        // Any element not in the valid core properties namespace is unexpected.
                        // The following is an object comparison, not a string comparison.
                        if ((object)reader.NamespaceURI != PackageXmlStringTable.GetXmlStringAsObject(PackageXmlStringTable.GetXmlNamespace(xmlStringIndex)))
                        {
                            throw new XmlException(SR.UnknownNamespaceInCorePropertiesPart,
                                                   null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                        }

                        if (string.CompareOrdinal(valueType, "String") == 0)
                        {
                            // The schema is closed and defines no attributes on this type of element.
                            if (attributesCount != 0)
                            {
                                throw new XmlException(SR.Format(SR.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                                       null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                            }

                            RecordNewBinding(xmlStringIndex, GetStringData(reader), true /*initializing*/, reader);
                        }
                        else if (string.CompareOrdinal(valueType, "DateTime") == 0)
                        {
                            int allowedAttributeCount = (object)reader.NamespaceURI ==
                                                        PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.DublinCoreTermsNamespace)
                                                        ? 1 : 0;

                            // The schema is closed and defines no attributes on this type of element.
                            if (attributesCount != allowedAttributeCount)
                            {
                                throw new XmlException(SR.Format(SR.PropertyWrongNumbOfAttribsDefinedOn, reader.Name),
                                                       null, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition);
                            }

                            if (allowedAttributeCount != 0)
                            {
                                ValidateXsiType(reader,
                                                PackageXmlStringTable.GetXmlStringAsObject(PackageXmlEnum.DublinCoreTermsNamespace),
                                                W3cdtf);
                            }

                            RecordNewBinding(xmlStringIndex, GetDateData(reader), true /*initializing*/, reader);
                        }
                        else // An unexpected element is an error.
                        {
                            Debug.Fail("Unknown value type for properties");
                        }
                    }
                }
        }
Пример #28
0
 internal XmlStringTableStruct(object nameString, PackageXmlEnum ns, string?valueType)
 {
     _nameString = nameString;
     _namespace  = ns;
     _valueType  = valueType;
 }