{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/32822772","id":32822772,"diff_hunk":"@@ -0,0 +1,744 @@\n+// Copyright (c) Microsoft. All rights reserved.\n+// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n+\n+//-----------------------------------------------------------------------------\n+//\n+// Description:\n+//  ContentType class parses and validates the content-type string.\n+//  It provides functionality to compare the type/subtype values.\n+//\n+// Details:\n+// Grammar which this class follows - \n+//\n+// Content-type grammar MUST conform to media-type grammar as per \n+// RFC 2616 (ABNF notation):\n+// \n+// media-type     = type \"/\" subtype *( \";\" parameter )\n+// type           = token\n+// subtype        = token\n+// parameter      = attribute \"=\" value\n+// attribute      = token\n+// value          = token | quoted-string\n+// quoted-string  = ( <\"> *(qdtext | quoted-pair ) <\"> )\n+// qdtext         = <any TEXT except <\">>\n+// quoted-pair    = \"\\\" CHAR\n+// token          = 1*<any CHAR except CTLs or separators>\n+// separators     = \"(\" | \")\" | \"<\" | \">\" | \"@\"\n+//                  | \",\" | \";\" | \":\" | \"\\\" | <\">\n+//                  | \"/\" | \"[\" | \"]\" | \"?\" | \"=\"\n+//                  | \"{\" | \"}\" | SP | HT\n+// TEXT           = <any OCTET except CTLs, but including LWS>\n+// OCTET          = <any 8-bit sequence of data>\n+// CHAR           = <any US-ASCII character (octets 0 - 127)>\n+// CTL            = <any US-ASCII control character(octets 0 - 31)and DEL(127)>\n+// CR             = <US-ASCII CR, carriage return (13)>\n+// LF             = <US-ASCII LF, linefeed (10)>\n+// SP             = <US-ASCII SP, space (32)>\n+// HT             = <US-ASCII HT, horizontal-tab (9)>\n+// <\">            = <US-ASCII double-quote mark (34)>\n+// LWS            = [CRLF] 1*( SP | HT )\n+// CRLF           = CR LF\n+// Linear white space (LWS) MUST NOT be used between the type and subtype, nor \n+// between an attribute and its value. Leading and trailing LWS are prohibited.\n+// \n+//-----------------------------------------------------------------------------\n+\n+using System;\n+using System.Collections.Generic;   // For Dictionary<string, string>\n+using System.Text;                  // For StringBuilder\n+using System.Diagnostics;           // For Debug.Assert\n+\n+namespace System.IO.Packaging\n+{\n+    /// <summary>\n+    /// Content Type class\n+    /// </summary>\n+    internal sealed class ContentType\n+    {\n+        //------------------------------------------------------\n+        //\n+        //  Internal Constructors\n+        //\n+        //------------------------------------------------------\n+\n+        #region Internal Constructors\n+\n+        /// <summary>\n+        /// This constructor creates a ContentType object that represents \n+        /// the content-type string. At construction time we validate the \n+        /// string as per the grammar specified in RFC 2616.\n+        /// Note: We allow empty strings as valid input. Empty string should\n+        /// we used more as an indication of an absent/unknown ContentType. \n+        /// </summary>\n+        /// <param name=\"contentType\">content-type</param>\n+        /// <exception cref=\"ArgumentNullException\">If the contentType parameter is null</exception>\n+        /// <exception cref=\"ArgumentException\">If the contentType string has leading or \n+        /// trailing Linear White Spaces(LWS) characters</exception>\n+        /// <exception cref=\"ArgumentException\">If the contentType string invalid CR-LF characters</exception>\n+        internal ContentType(string contentType)\n+        {\n+            if (contentType == null)\n+                throw new ArgumentNullException(\"contentType\");\n+\n+            if (String.CompareOrdinal(contentType, String.Empty) == 0)\n+            {\n+                _contentType = String.Empty;\n+            }\n+            else\n+            {\n+                if (IsLinearWhiteSpaceChar(contentType[0]) || IsLinearWhiteSpaceChar(contentType[contentType.Length - 1]))\n+                    throw new ArgumentException(SR.Get(SRID.ContentTypeCannotHaveLeadingTrailingLWS));\n+\n+                //Carriage return can be expressed as '\\r\\n' or '\\n\\r'\n+                //We need to make sure that a \\r is accompanied by \\n\n+                ValidateCarriageReturns(contentType);\n+\n+                //Begin Parsing                \n+                int semiColonIndex = contentType.IndexOf(_semicolonSeparator);\n+\n+                if (semiColonIndex == -1)\n+                {\n+                    // Parse content type similar to - type/subtype\n+                    ParseTypeAndSubType(contentType);\n+                }\n+                else\n+                {\n+                    // Parse content type similar to - type/subtype ; param1=value1 ; param2=value2 ; param3=\"value3\"\n+                    ParseTypeAndSubType(contentType.Substring(0, semiColonIndex));\n+                    ParseParameterAndValue(contentType.Substring(semiColonIndex));\n+                }\n+            }\n+\n+            // keep this untouched for return from OriginalString property\n+            _originalString = contentType;\n+\n+            //This variable is used to print out the correct content type string representation\n+            //using the ToString method. This is mainly important while debugging and seeing the\n+            //value of the content type object in the debugger.\n+            _isInitialized = true;\n+        }\n+\n+        #endregion Internal Constructors\n+\n+        //------------------------------------------------------\n+        //\n+        //  Internal Methods\n+        //\n+        //------------------------------------------------------\n+\n+        #region Internal Properties\n+\n+        /// <summary>\n+        /// TypeComponent of the Content Type\n+        /// If the content type is \"text/xml\". This property will return \"text\"\n+        /// </summary>\n+        internal string TypeComponent\n+        {\n+            get\n+            {\n+                return _type;\n+            }\n+        }\n+\n+        /// <summary>\n+        /// SubType component\n+        /// If the content type is \"text/xml\". This property will return \"xml\"\n+        /// </summary>\n+        internal string SubTypeComponent\n+        {\n+            get\n+            {\n+                return _subType;\n+            }\n+        }\n+\n+        /// <summary>\n+        /// Enumerator which iterates over the Parameter and Value pairs which are stored \n+        /// in a dictionary. We hand out just the enumerator in order to make this property\n+        /// ReadOnly\n+        /// Consider following Content type - \n+        /// type/subtype ; param1=value1 ; param2=value2 ; param3=\"value3\"\n+        /// This will return a enumerator over a dictionary of the parameter/value pairs. \n+        /// </summary>\n+        internal Dictionary<string, string>.Enumerator ParameterValuePairs\n+        {\n+            get\n+            {\n+                EnsureParameterDictionary();\n+                return _parameterDictionary.GetEnumerator();\n+            }\n+        }\n+\n+\n+        /// <summary>\n+        /// Static property that represents a content type that is empty \"\"\n+        /// This is not a valid content type as per the grammar and should be used\n+        /// in places where the content type is missing or not available. \n+        /// </summary>\n+        internal static ContentType Empty\n+        {\n+            get\n+            {\n+                return s_emptyContentType;\n+            }\n+        }\n+\n+        /// <summary>\n+        /// Original string provided to constructor\n+        /// </summary>\n+        internal string OriginalString\n+        {\n+            get\n+            {\n+                return _originalString;\n+            }\n+        }\n+        #endregion Internal Properties\n+\n+        //------------------------------------------------------\n+        //\n+        //  Internal Methods\n+        //\n+        //------------------------------------------------------\n+\n+        #region Internal Methods\n+\n+        /// <summary>\n+        /// This method does a strong comparison of the content types, as parameters are not allowed. \n+        /// We only compare the type and subType values in an ASCII case-insensitive manner.\n+        /// Parameters are not allowed to be present on any of the content type operands.\n+        /// </summary>\n+        /// <param name=\"contentType\">Content type to be compared with</param>\n+        /// <returns></returns>\n+        internal bool AreTypeAndSubTypeEqual(ContentType contentType)\n+        {\n+            return AreTypeAndSubTypeEqual(contentType, false);\n+        }\n+\n+        /// <summary>\n+        /// This method does a weak comparison of the content types. We only compare the\n+        /// type and subType values in an ASCII case-insensitive manner.\n+        /// Parameter and value pairs are not used for the comparison. \n+        /// If you wish to compare the paramters too, then you must get the ParameterValuePairs from\n+        /// both the ContentType objects and compare each parameter entry.\n+        /// The allowParameterValuePairs parameter is used to indicate whether the \n+        /// comparison is tolerant to parameters being present or no.\n+        /// </summary>\n+        /// <param name=\"contentType\">Content type to be compared with</param>\n+        /// <param name=\"allowParameterValuePairs\">If true, allows the presence of parameter value pairs. \n+        /// If false, parameter/value pairs cannot be present in the content type string.\n+        /// In either case, the parameter value pair is not used for the comparison.</param>\n+        /// <returns></returns>\n+        internal bool AreTypeAndSubTypeEqual(ContentType contentType, bool allowParameterValuePairs)\n+        {\n+            bool result = false;\n+\n+            if (contentType != null)\n+            {\n+                if (!allowParameterValuePairs)\n+                {\n+                    //Return false if this content type object has parameters\n+                    if (_parameterDictionary != null && _parameterDictionary.Count > 0)\n+                        return false;\n+\n+                    //Return false if the content type object passed in has parameters\n+                    Dictionary<string, string>.Enumerator contentTypeEnumerator;\n+                    contentTypeEnumerator = contentType.ParameterValuePairs;\n+                    contentTypeEnumerator.MoveNext();\n+                    if (contentTypeEnumerator.Current.Key != null)\n+                        return false;\n+                }\n+\n+                // Perform a case-insensitive comparison on the type/subtype strings.  This is a\n+                // safe comparison because the _type and _subType strings have been restricted to\n+                // ASCII characters, digits, and a small set of symbols.  This is not a safe comparison\n+                // for the broader set of strings that have not been restricted in the same way.\n+                result = (String.Compare(_type, contentType.TypeComponent, StringComparison.OrdinalIgnoreCase) == 0 &&\n+                          String.Compare(_subType, contentType.SubTypeComponent, StringComparison.OrdinalIgnoreCase) == 0);\n+            }\n+            return result;\n+        }\n+\n+        /// <summary>\n+        /// ToString - outputs a normalized form of the content type string\n+        /// </summary>\n+        /// <returns></returns>\n+        public override string ToString()\n+        {\n+            if (_contentType == null)\n+            {\n+                //This is needed so that while debugging we get the correct \n+                //string\n+                if (!_isInitialized)\n+                    return String.Empty;\n+\n+                Debug.Assert(String.CompareOrdinal(_type, String.Empty) != 0\n+                   || String.CompareOrdinal(_subType, String.Empty) != 0);\n+\n+                StringBuilder stringBuilder = new StringBuilder(_type);\n+                stringBuilder.Append(s_forwardSlashSeparator[0]);\n+                stringBuilder.Append(_subType);\n+\n+                if (_parameterDictionary != null && _parameterDictionary.Count > 0)\n+                {\n+                    foreach (string paramterKey in _parameterDictionary.Keys)\n+                    {\n+                        stringBuilder.Append(s_linearWhiteSpaceChars[0]);\n+                        stringBuilder.Append(_semicolonSeparator);\n+                        stringBuilder.Append(s_linearWhiteSpaceChars[0]);\n+                        stringBuilder.Append(paramterKey);\n+                        stringBuilder.Append(_equalSeparator);\n+                        stringBuilder.Append(_parameterDictionary[paramterKey]);\n+                    }\n+                }\n+\n+                _contentType = stringBuilder.ToString();\n+            }\n+\n+            return _contentType;\n+        }\n+\n+        #endregion Internal Methods\n+\n+        //------------------------------------------------------\n+        //\n+        //  Nested Classes\n+        //\n+        //------------------------------------------------------\n+\n+        #region Nested Classes\n+\n+        /// <summary>\n+        /// Comparer class makes it easier to put ContentType objects in collections.\n+        /// Only compares type and subtype components of the ContentType.  Could be\n+        /// expanded to optionally compare parameters as well.\n+        /// </summary>\n+        internal class StrongComparer : IEqualityComparer<ContentType>\n+        {\n+            /// <summary>\n+            /// This method does a strong comparison of the content types.\n+            /// Only compares the ContentTypes' type and subtype components.\n+            /// </summary>\n+            public bool Equals(ContentType x, ContentType y)\n+            {\n+                if (x == null)\n+                {\n+                    return (y == null);\n+                }\n+                else\n+                {\n+                    return x.AreTypeAndSubTypeEqual(y);\n+                }\n+            }\n+\n+            /// <summary>\n+            /// We lower case the results of ToString() because it returns the original\n+            /// casing passed into the constructor.  ContentTypes that are equal (which\n+            /// ignores casing) must have the same hash code.\n+            /// </summary>\n+            public int GetHashCode(ContentType obj)\n+            {\n+                return obj.ToString().ToUpperInvariant().GetHashCode();\n+            }\n+        }\n+\n+        internal class WeakComparer : IEqualityComparer<ContentType>\n+        {\n+            /// <summary>            \n+            /// This method does a weak comparison of the content types. \n+            /// Parameter and value pairs are not used for the comparison. \n+            /// </summary>\n+            public bool Equals(ContentType x, ContentType y)\n+            {\n+                if (x == null)\n+                {\n+                    return (y == null);\n+                }\n+                else\n+                {\n+                    return x.AreTypeAndSubTypeEqual(y, true);\n+                }\n+            }\n+\n+            /// <summary>\n+            /// We lower case the results of ToString() because it returns the original\n+            /// casing passed into the constructor.  ContentTypes that are equal (which\n+            /// ignores casing) must have the same hash code.\n+            /// </summary>\n+            public int GetHashCode(ContentType obj)\n+            {\n+                return obj._type.ToUpperInvariant().GetHashCode() ^ obj._subType.ToUpperInvariant().GetHashCode();\n+            }\n+        }\n+        #endregion Nested Classes\n+\n+        //------------------------------------------------------\n+        //\n+        //  Private Methods\n+        //\n+        //------------------------------------------------------\n+\n+        #region Private Methods\n+\n+\n+        /// <summary>\n+        /// This method validates if the content type string has\n+        /// valid CR-LF characters. Specifically we test if '\\r' is \n+        /// accompanied by a '\\n' in the string, else its an error.\n+        /// </summary>\n+        /// <param name=\"contentType\"></param>\n+        private static void ValidateCarriageReturns(string contentType)\n+        {\n+            Debug.Assert(!IsLinearWhiteSpaceChar(contentType[0]) && !IsLinearWhiteSpaceChar(contentType[contentType.Length - 1]));\n+\n+            //Prior to calling this method we have already checked that first and last\n+            //character of the content type are not Linear White Spaces. So its safe to\n+            //assume that the index will be greater than 0 and less that length-2.\n+\n+            int index = contentType.IndexOf(s_linearWhiteSpaceChars[2]);\n+\n+            while (index != -1)\n+            {\n+                if (contentType[index - 1] == s_linearWhiteSpaceChars[1] || contentType[index + 1] == s_linearWhiteSpaceChars[1])\n+                {\n+                    index = contentType.IndexOf(s_linearWhiteSpaceChars[2], ++index);\n+                }\n+                else\n+                    throw new ArgumentException(SR.Get(SRID.InvalidLinearWhiteSpaceCharacter));\n+            }\n+        }\n+\n+        /// <summary>\n+        /// Parses the type ans subType tokens from the string. \n+        /// Also verifies if the Tokens are valid as per the grammar.\n+        /// </summary>\n+        /// <param name=\"typeAndSubType\">substring that has the type and subType of the content type</param>\n+        /// <exception cref=\"ArgumentException\">If the typeAndSubType parameter does not have the \"/\" character</exception>\n+        private void ParseTypeAndSubType(string typeAndSubType)\n+        {\n+            //okay to trim at this point the end of the string as Linear White Spaces(LWS) chars are allowed here.\n+            typeAndSubType = typeAndSubType.TrimEnd(s_linearWhiteSpaceChars);\n+\n+            string[] splitBasedOnForwardSlash = typeAndSubType.Split(s_forwardSlashSeparator);\n+\n+            if (splitBasedOnForwardSlash.Length != 2)\n+                throw new ArgumentException(SR.Get(SRID.InvalidTypeSubType));\n+\n+            _type = ValidateToken(splitBasedOnForwardSlash[0]);\n+            _subType = ValidateToken(splitBasedOnForwardSlash[1]);\n+        }\n+\n+        /// <summary>\n+        /// Parse the individual parameter=value strings\n+        /// </summary>\n+        /// <param name=\"parameterAndValue\">This string has the parameter and value pair of the form\n+        /// parameter=value</param>\n+        /// <exception cref=\"ArgumentException\">If the string does not have the required \"=\"</exception>\n+        private void ParseParameterAndValue(string parameterAndValue)\n+        {\n+            while (String.CompareOrdinal(parameterAndValue, String.Empty) != 0)\n+            {\n+                //At this point the first character MUST be a semi-colon\n+                //First time through this test is serving more as an assert.\n+                if (parameterAndValue[0] != _semicolonSeparator)\n+                    throw new ArgumentException(SR.Get(SRID.ExpectingSemicolon));\n+\n+                //At this point if we have just one semicolon, then its an error.\n+                //Also, there can be no trailing LWS characters, as we already checked for that\n+                //in the constructor.\n+                if (parameterAndValue.Length == 1)\n+                    throw new ArgumentException(SR.Get(SRID.ExpectingParameterValuePairs));\n+\n+                //Removing the leading ; from the string\n+                parameterAndValue = parameterAndValue.Substring(1);\n+\n+                //okay to trim start as there can be spaces before the begining\n+                //of the parameter name.\n+                parameterAndValue = parameterAndValue.TrimStart(s_linearWhiteSpaceChars);\n+\n+                int equalSignIndex = parameterAndValue.IndexOf(_equalSeparator);\n+\n+                if (equalSignIndex <= 0 || equalSignIndex == (parameterAndValue.Length - 1))\n+                    throw new ArgumentException(SR.Get(SRID.InvalidParameterValuePair));\n+\n+                int parameterStartIndex = equalSignIndex + 1;\n+\n+                //Get length of the parameter value\n+                int parameterValueLength = GetLengthOfParameterValue(parameterAndValue, parameterStartIndex);\n+\n+                EnsureParameterDictionary();\n+\n+                _parameterDictionary.Add(\n+                    ValidateToken(parameterAndValue.Substring(0, equalSignIndex)),\n+                    ValidateQuotedStringOrToken(parameterAndValue.Substring(parameterStartIndex, parameterValueLength)));\n+\n+                parameterAndValue = parameterAndValue.Substring(parameterStartIndex + parameterValueLength).TrimStart(s_linearWhiteSpaceChars);\n+            }\n+        }\n+\n+        /// <summary>\n+        /// This method returns the length of the first parameter value in the input string.\n+        /// </summary>\n+        /// <param name=\"s\"></param>\n+        /// <param name=\"startIndex\">Starting index for parsing</param>\n+        /// <returns></returns>\n+        private static int GetLengthOfParameterValue(string s, int startIndex)\n+        {\n+            Debug.Assert(s != null);\n+\n+            int length = 0;\n+\n+            //if the parameter value does not start with a '\"' then,\n+            //we expect a valid token. So we look for Linear White Spaces or\n+            //a ';' as the terminator for the token value.\n+            if (s[startIndex] != '\"')\n+            {\n+                int semicolonIndex = s.IndexOf(_semicolonSeparator, startIndex);\n+\n+                if (semicolonIndex != -1)\n+                {\n+                    int lwsIndex = s.IndexOfAny(s_linearWhiteSpaceChars, startIndex);\n+                    if (lwsIndex != -1 && lwsIndex < semicolonIndex)\n+                        length = lwsIndex;\n+                    else\n+                        length = semicolonIndex;\n+                }\n+                else\n+                    length = semicolonIndex;\n+\n+                //If there is no linear white space found we treat the entire remaining string as \n+                //parameter value.\n+                if (length == -1)\n+                    length = s.Length;\n+            }\n+            else\n+            {\n+                //if the parameter value starts with a '\"' then, we need to look for the\n+                //pairing '\"' that is not preceded by a \"\\\" [\"\\\" is used to escape the '\"']\n+                bool found = false;\n+                length = startIndex;\n+\n+                while (!found)\n+                {\n+                    length = s.IndexOf('\"', ++length);\n+\n+                    if (length == -1)\n+                        throw new ArgumentException(SR.Get(SRID.InvalidParameterValue));\n+\n+                    if (s[length - 1] != '\\\\')\n+                    {\n+                        found = true;\n+                        length++;\n+                    }\n+                }\n+            }\n+            return length - startIndex;\n+        }\n+\n+        /// <summary>\n+        /// Validating the given token\n+        /// The following checks are being made - \n+        /// 1. If all the characters in the token are either ASCII letter or digit.\n+        /// 2. If all the characters in the token are either from the remaining allowed cha----ter set.\n+        /// </summary>\n+        /// <param name=\"token\">string token</param>\n+        /// <returns>validated string token</returns>\n+        /// <exception cref=\"ArgumentException\">If the token is Empty</exception>\n+        private static string ValidateToken(string token)\n+        {\n+            if (String.CompareOrdinal(token, String.Empty) == 0)\n+                throw new ArgumentException(SR.Get(SRID.InvalidToken));\n+\n+            for (int i = 0; i < token.Length; i++)\n+            {\n+                if (IsAsciiLetterOrDigit(token[i]))\n+                    continue;\n+                else\n+                    if (IsAllowedCharacter(token[i]))","path":"src/System.IO.Packaging/src/System/IO/Packaging/ContentType.cs","position":557,"original_position":557,"commit_id":"a53796bab08ca37ebcedc97be5d7788b341f3427","original_commit_id":"8b927da87f6aae6981bed44a9a87bc6e08a30661","user":{"login":"EricWhiteDev","id":1280392,"avatar_url":"https://avatars.githubusercontent.com/u/1280392?v=3","gravatar_id":"","url":"https://api.github.com/users/EricWhiteDev","html_url":"https://github.com/EricWhiteDev","followers_url":"https://api.github.com/users/EricWhiteDev/followers","following_url":"https://api.github.com/users/EricWhiteDev/following{/other_user}","gists_url":"https://api.github.com/users/EricWhiteDev/gists{/gist_id}","starred_url":"https://api.github.com/users/EricWhiteDev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/EricWhiteDev/subscriptions","organizations_url":"https://api.github.com/users/EricWhiteDev/orgs","repos_url":"https://api.github.com/users/EricWhiteDev/repos","events_url":"https://api.github.com/users/EricWhiteDev/events{/privacy}","received_events_url":"https://api.github.com/users/EricWhiteDev/received_events","type":"User","site_admin":false},"body":"Fixed.","created_at":"2015-06-19T12:04:36Z","updated_at":"2015-06-19T12:04:36Z","html_url":"https://github.com/dotnet/corefx/pull/1818#discussion_r32822772","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/1818","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/32822772"},"html":{"href":"https://github.com/dotnet/corefx/pull/1818#discussion_r32822772"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/1818"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/1818","id":35974881,"html_url":"https://github.com/dotnet/corefx/pull/1818","diff_url":"https://github.com/dotnet/corefx/pull/1818.diff","patch_url":"https://github.com/dotnet/corefx/pull/1818.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/1818","number":1818,"state":"open","locked":false,"title":"Initial commit of System.IO.Packaging","user":{"login":"EricWhiteDev","id":1280392,"avatar_url":"https://avatars.githubusercontent.com/u/1280392?v=3","gravatar_id":"","url":"https://api.github.com/users/EricWhiteDev","html_url":"https://github.com/EricWhiteDev","followers_url":"https://api.github.com/users/EricWhiteDev/followers","following_url":"https://api.github.com/users/EricWhiteDev/following{/other_user}","gists_url":"https://api.github.com/users/EricWhiteDev/gists{/gist_id}","starred_url":"https://api.github.com/users/EricWhiteDev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/EricWhiteDev/subscriptions","organizations_url":"https://api.github.com/users/EricWhiteDev/orgs","repos_url":"https://api.github.com/users/EricWhiteDev/repos","events_url":"https://api.github.com/users/EricWhiteDev/events{/privacy}","received_events_url":"https://api.github.com/users/EricWhiteDev/received_events","type":"User","site_admin":false},"body":"New version of System.IO.Packaging, rewritten to use System.IO.Compression.  This assembly is used by the Open XML SDK.  The code was written to work with both .NET 4.5.* and COREFX/CORECLR.  I will be adding additional tests in the near future.  In addition, I have a massive amount of tests that will go into \"outer-loop\" testing after some cleanup.","created_at":"2015-05-21T20:37:49Z","updated_at":"2015-06-19T12:04:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"036a2ed382be54b5ab49751a9fc5af58d0b267c3","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/1818/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/1818/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/1818/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/a53796bab08ca37ebcedc97be5d7788b341f3427","head":{"label":"EricWhiteDev:systemiopackaging","ref":"systemiopackaging","sha":"a53796bab08ca37ebcedc97be5d7788b341f3427","user":{"login":"EricWhiteDev","id":1280392,"avatar_url":"https://avatars.githubusercontent.com/u/1280392?v=3","gravatar_id":"","url":"https://api.github.com/users/EricWhiteDev","html_url":"https://github.com/EricWhiteDev","followers_url":"https://api.github.com/users/EricWhiteDev/followers","following_url":"https://api.github.com/users/EricWhiteDev/following{/other_user}","gists_url":"https://api.github.com/users/EricWhiteDev/gists{/gist_id}","starred_url":"https://api.github.com/users/EricWhiteDev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/EricWhiteDev/subscriptions","organizations_url":"https://api.github.com/users/EricWhiteDev/orgs","repos_url":"https://api.github.com/users/EricWhiteDev/repos","events_url":"https://api.github.com/users/EricWhiteDev/events{/privacy}","received_events_url":"https://api.github.com/users/EricWhiteDev/received_events","type":"User","site_admin":false},"repo":{"id":34161309,"name":"corefx","full_name":"EricWhiteDev/corefx","owner":{"login":"EricWhiteDev","id":1280392,"avatar_url":"https://avatars.githubusercontent.com/u/1280392?v=3","gravatar_id":"","url":"https://api.github.com/users/EricWhiteDev","html_url":"https://github.com/EricWhiteDev","followers_url":"https://api.github.com/users/EricWhiteDev/followers","following_url":"https://api.github.com/users/EricWhiteDev/following{/other_user}","gists_url":"https://api.github.com/users/EricWhiteDev/gists{/gist_id}","starred_url":"https://api.github.com/users/EricWhiteDev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/EricWhiteDev/subscriptions","organizations_url":"https://api.github.com/users/EricWhiteDev/orgs","repos_url":"https://api.github.com/users/EricWhiteDev/repos","events_url":"https://api.github.com/users/EricWhiteDev/events{/privacy}","received_events_url":"https://api.github.com/users/EricWhiteDev/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/EricWhiteDev/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":true,"url":"https://api.github.com/repos/EricWhiteDev/corefx","forks_url":"https://api.github.com/repos/EricWhiteDev/corefx/forks","keys_url":"https://api.github.com/repos/EricWhiteDev/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/EricWhiteDev/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/EricWhiteDev/corefx/teams","hooks_url":"https://api.github.com/repos/EricWhiteDev/corefx/hooks","issue_events_url":"https://api.github.com/repos/EricWhiteDev/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/EricWhiteDev/corefx/events","assignees_url":"https://api.github.com/repos/EricWhiteDev/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/EricWhiteDev/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/EricWhiteDev/corefx/tags","blobs_url":"https://api.github.com/repos/EricWhiteDev/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/EricWhiteDev/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/EricWhiteDev/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/EricWhiteDev/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/EricWhiteDev/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/EricWhiteDev/corefx/languages","stargazers_url":"https://api.github.com/repos/EricWhiteDev/corefx/stargazers","contributors_url":"https://api.github.com/repos/EricWhiteDev/corefx/contributors","subscribers_url":"https://api.github.com/repos/EricWhiteDev/corefx/subscribers","subscription_url":"https://api.github.com/repos/EricWhiteDev/corefx/subscription","commits_url":"https://api.github.com/repos/EricWhiteDev/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/EricWhiteDev/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/EricWhiteDev/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/EricWhiteDev/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/EricWhiteDev/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/EricWhiteDev/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/EricWhiteDev/corefx/merges","archive_url":"https://api.github.com/repos/EricWhiteDev/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/EricWhiteDev/corefx/downloads","issues_url":"https://api.github.com/repos/EricWhiteDev/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/EricWhiteDev/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/EricWhiteDev/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/EricWhiteDev/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/EricWhiteDev/corefx/labels{/name}","releases_url":"https://api.github.com/repos/EricWhiteDev/corefx/releases{/id}","created_at":"2015-04-18T10:12:07Z","updated_at":"2015-04-18T10:12:22Z","pushed_at":"2015-06-19T07:51:44Z","git_url":"git://github.com/EricWhiteDev/corefx.git","ssh_url":"git@github.com:EricWhiteDev/corefx.git","clone_url":"https://github.com/EricWhiteDev/corefx.git","svn_url":"https://github.com/EricWhiteDev/corefx","homepage":"","size":19697,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"b558a7f9c872ff81a6b4c980b77e6c463afc603a","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","created_at":"2014-11-06T23:42:48Z","updated_at":"2015-06-19T09:59:28Z","pushed_at":"2015-06-19T10:43:43Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/core/","size":47995,"stargazers_count":7941,"watchers_count":7941,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1621,"mirror_url":null,"open_issues_count":433,"forks":1621,"open_issues":433,"watchers":7941,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/1818"},"html":{"href":"https://github.com/dotnet/corefx/pull/1818"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/1818"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/1818/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/1818/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/1818/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/a53796bab08ca37ebcedc97be5d7788b341f3427"}}}}