Describes the components of a nugget.
Formatted nuggets: The msgid for a formatted nugget: Enter between %0 and %1 characters|||100|||6 while the original string in the code for this may have been: [[[Enter between %0 and %1 characters|||{1}|||{2}]]] The canonical msgid part is that between the opening [[[ and the first ||| or ///: Enter between %0 and %1 characters
示例#1
0
        // Operations

        /// <summary>
        /// Parses a string entity for nuggets, forwarding the nugget to a caller-provided
        /// delegate, with support for replacement of nugget strings in the entity.
        /// </summary>
        /// <param name="entity">
        /// String containing nuggets to be parsed. E.g. source code file, HTTP response entity.
        /// </param>
        /// <param name="ProcessNugget">
        /// Delegate callback to be called for each nugget encountered in entity:
        ///     delegate(string nuggetString, int pos, Nugget nugget1, string entity1).
        /// Returns a string with which to replace the nugget string in the source entity.
        /// If no change, then may return null.
        /// </param>
        /// <returns>
        /// Entity string reflecting any nugget strings replacements.
        /// </returns>
        public string ParseString(
            string entity,
            Func <string, int, Nugget, string, string> ProcessNugget)
        {
            if (entity == null)
            {
                return("");
            }
            // Note that this method has two-levels of delegates:
            //   Outer delegate is the delegate which is called by regex as it matches each nugget
            //   Inner delegate is the client callback delegate (ProcessNugget) which we call from the outer delegate.
            //
            // Lookup any/all nuggets in the entity and call the client delegate (ProcessNugget) for each.
            return(m_regexNuggetBreakdown.Replace(entity, delegate(Match match)
            {
                Nugget nugget = NuggetFromRegexMatch(match);
                //
                string modifiedNuggetString = ProcessNugget(
                    match.Groups[0].Value, // entire nugget string
                    match.Groups[0].Index, // zero-based pos of the first char of entire nugget string
                    nugget,                // broken-down nugget
                    entity);               // source entity string
                // Returns either modified nugget string, or original nugget string (i.e. for no replacement).
                return modifiedNuggetString ?? match.Groups[0].Value;
            }));
        }
示例#2
0
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }
            if (this.GetType() != obj.GetType())
            {
                return(false);
            }
            Nugget other = (Nugget)obj;

            // Compare non-array members.
            if (MsgId != other.MsgId || // NB: the operator==() on string objects handles null value on either side just fine.
                Comment != other.Comment)
            {
                return(false);
            }
            // Compare arrays.
            if ((FormatItems == null) != (other.FormatItems == null) ||
                (FormatItems != null && !FormatItems.SequenceEqual(other.FormatItems)))
            {
                return(false);
            }
            return(true);
        }
示例#3
0
 private void ParseAndComp(string nuggetString, Nugget rhs, bool equal = true)
 {
    // Arrange.
     NuggetTokens nuggetTokens = new NuggetTokens("[[[", "]]]", "|||", "///");
     NuggetParser nuggetParser = new NuggetParser(nuggetTokens, NuggetParser.Context.SourceProcessing);
    // Act.
     Nugget nugget = nuggetParser.BreakdownNugget(nuggetString);
    // Assert.
     if (equal) {
         Assert.AreEqual(nugget, rhs); }
     else {
         Assert.AreNotEqual(nugget, rhs); }
 }
示例#4
0
 private void CompareNugget(Nugget n1, Nugget n2, bool equal)
 {
    // Test equality.
     if (equal) {
         Assert.AreEqual(n1, n2);
     }
     else {
         Assert.AreNotEqual(n1, n2);
     }
    // Test hash code.
     int h1 = n1.GetHashCode();
     int h2 = n2.GetHashCode();
    // · If two objects are equal then they must have the same hash code.
     if (n1.Equals(n2)) {
         Assert.AreEqual(h1, h2);
     }
    // · If two objects have different hash codes then they must be unequal.
     if (h1 != h2) {
         Assert.AreNotEqual(n1, n2);
     }
 }
示例#5
0
        /// <summary>
        /// Returns a nugget instance loaded from a regex match, or null if error.
        /// </summary>
        private Nugget NuggetFromRegexMatch(Match match)
        {
            if (!match.Success ||
                match.Groups.Count != 4)
            {
                return(null);
            }
            Nugget n = new Nugget();

            // Extract msgid from 2nd capture group.
            n.MsgId = match.Groups[1].Value;
            // Extract format items from 3rd capture group.
            var formatItems = match.Groups[2].Captures;

            if (formatItems.Count != 0)
            {
                n.FormatItems = new string[formatItems.Count];
                int i = 0;
                foreach (Capture capture in formatItems)
                {
                    if (m_context == Context.SourceProcessing &&
                        !capture.Value.IsSet())
                    {
                        return(null);
                    }                  // bad format
                    n.FormatItems[i++] = capture.Value;
                }
            }
            // Extract comment from 4th capture group.
            if (match.Groups[3].Value.IsSet())
            {
                n.Comment = match.Groups[3].Value;
            }
            // Success.
            return(n);
        }
示例#6
0
		private void AddNewTemplateItem(
            string filePath, 
            int lineNumber, 
            Nugget nugget, 
            ConcurrentDictionary<string, TemplateItem> templateItems)
		{
			string reference = filePath + ":" + lineNumber.ToString();
            string msgid = nugget.MsgId.Replace("\r\n", "\n").Replace("\r", "\\n");
                // NB: In memory msgids are normalized so that LFs are converted to "\n" char sequence.
            string key = TemplateItem.KeyFromMsgidAndComment(msgid, nugget.Comment, _settings.MessageContextEnabledFromComment);
			List<string> tmpList;
           //
            templateItems.AddOrUpdate(
                key,
                // Add routine.
                k => {
			        TemplateItem item = new TemplateItem();
                    item.MsgKey = key;
			        item.MsgId = msgid;

			        tmpList = new List<string>();
			        tmpList.Add(reference);
			        item.References = tmpList;

			        if (nugget.Comment.IsSet()) {
                        tmpList = new List<string>();
                        tmpList.Add(nugget.Comment);
                        item.Comments = tmpList;
                    }

			        return item;
                },
                // Update routine.
                (k, v) => {

					tmpList = v.References.ToList();
					tmpList.Add(reference);
					v.References = tmpList;

			        if (nugget.Comment.IsSet()) {
					    tmpList = v.Comments != null ? v.Comments.ToList() : new List<string>();
					    tmpList.Add(nugget.Comment);
					    v.Comments = tmpList;
                    }

                    return v;
                });
		}
示例#7
0
            /// <summary>
            /// Process nugget.
            /// </summary>
            /// <param name="position">Position right after begin token.</param>
            /// <returns>Parse result.</returns>
            private ParseAndProccessResult ParseAndProcessNugget(int position, bool isNested)
            {
                // Position of the comment block starting from token
                int?commentStartPosition   = null;
                int?parameterStartPosition = null;

                bool wasNestedNugget = false;

                var nugget      = new Nugget();
                var formatItems = new List <string>();

                int nextPosition = position + m_owner.m_nuggetTokens.BeginToken.Length;

                for (;;)
                {
                    var match = m_owner.m_tokensRegex.Match(m_entity, nextPosition);
                    if (!match.Success)
                    {
                        return(new ParseAndProccessResult
                        {
                            Replacement = m_entity.Substring(position),
                            NextPosition = m_entity.Length
                        });
                    }

                    // Ignoring unexpected start of nugget.
                    if (match.Value == m_owner.m_nuggetTokens.BeginToken)
                    {
                        nextPosition = match.Index + match.Length;
                        continue;
                    }

                    // Processing unexected parameter end - )))
                    if (match.Value == m_owner.m_parameterEndBeforeDelimiterToken ||
                        match.Value == m_owner.m_parameterEndBeforeEndToken)
                    {
                        if (isNested)
                        {
                            return(new ParseAndProccessResult
                            {
                                Replacement =
                                    m_entity.Substring(
                                        position,
                                        match.Index - position),
                                NextPosition = match.Index,
                                ContainNuggets = true
                            });
                        }

                        nextPosition = match.Index + m_owner.m_nuggetTokens.ParameterEndToken.Length;
                        continue;
                    }

                    // Skipping all tokens except NuggetEnd after comment was found.
                    if (commentStartPosition != null && match.Value != m_owner.m_nuggetTokens.EndToken)
                    {
                        nextPosition = match.Index + match.Length;
                        continue;
                    }

                    // Saving msgid and comment once parameter or end of nugget found.
                    if (nugget.MsgId == null)
                    {
                        nugget.MsgId = m_entity.Substring(
                            position + m_owner.m_nuggetTokens.BeginToken.Length,
                            match.Index - position - m_owner.m_nuggetTokens.BeginToken.Length);
                    }

                    // Saving parameter start position
                    if (parameterStartPosition != null)
                    {
                        var formatItemString =
                            m_entity.Substring(
                                parameterStartPosition.Value + m_owner.m_nuggetTokens.DelimiterToken.Length,
                                match.Index - parameterStartPosition.Value
                                - m_owner.m_nuggetTokens.DelimiterToken.Length);
                        formatItems.Add(formatItemString);
                    }

                    // Processing parameter with nesting - |||(((
                    if (match.Value == m_owner.m_delimiterWithParameterBeginToken)
                    {
                        wasNestedNugget = true;
                        var result = ParseAndProcessNuggetZone(match.Index + match.Length, true);
                        nextPosition = result.NextPosition;
                        formatItems.Add(result.Replacement);
                        parameterStartPosition = null;
                        continue;
                    }

                    // Processing simple parameter
                    if (match.Value == m_owner.m_nuggetTokens.DelimiterToken)
                    {
                        parameterStartPosition = match.Index;
                        nextPosition           = match.Index + match.Length;
                        continue;
                    }

                    // Saving comment start position
                    if (match.Value == m_owner.m_nuggetTokens.CommentToken)
                    {
                        if (commentStartPosition == null)
                        {
                            commentStartPosition = match.Index;
                        }

                        nextPosition = match.Index + match.Length;
                        continue;
                    }

                    if (match.Value == m_owner.m_nuggetTokens.EndToken)
                    {
                        if (commentStartPosition != null)
                        {
                            var commentTextStartPos = commentStartPosition.Value + m_owner.m_nuggetTokens.CommentToken.Length;
                            nugget.Comment = m_entity.Substring(commentTextStartPos, match.Index - commentTextStartPos);
                        }

                        if (nugget.MsgId != string.Empty)
                        {
                            var result = new ParseAndProccessResult {
                                ContainNuggets = true, NextPosition = match.Index + match.Length
                            };

                            if (formatItems.Any() && m_owner.m_context == NuggetParser.Context.ResponseProcessing)
                            {
                                nugget.FormatItems = formatItems.ToArray();
                            }

                            if (wasNestedNugget)
                            {
                                // Virtualization required
                                var virtualEntity = new StringBuilder();
                                virtualEntity.Append(m_owner.m_nuggetTokens.BeginToken);
                                virtualEntity.Append(nugget.MsgId);
                                if (nugget.Comment != null)
                                {
                                    virtualEntity.Append(m_owner.m_nuggetTokens.CommentToken);
                                    virtualEntity.Append(nugget.Comment);
                                }

                                foreach (var formatItem in formatItems)
                                {
                                    virtualEntity.Append(m_owner.m_nuggetTokens.DelimiterToken);
                                    virtualEntity.Append(formatItem);
                                }

                                virtualEntity.Append(m_owner.m_nuggetTokens.EndToken);
                                var virtualEntityString = virtualEntity.ToString();

                                // Processing nugget
                                var originalMsgId = nugget.MsgId;
                                nugget.MsgId = PreProccessMsgId(nugget.MsgId);
                                var replaceString = m_processNugget(virtualEntityString, 0, nugget, virtualEntityString);
                                result.Replacement = replaceString ?? originalMsgId;
                            }
                            else
                            {
                                // Processing nugget
                                var originalMsgId = nugget.MsgId;
                                nugget.MsgId = PreProccessMsgId(nugget.MsgId);

                                var replaceString =
                                    m_processNugget(
                                        m_entity.Substring(
                                            position,
                                            match.Index + match.Length - position),
                                        // entire nugget string
                                        position,  // zero-based pos of the first char of entire nugget string
                                        nugget,    // broken-down nugget
                                        m_entity); // source entity string

                                result.Replacement = replaceString ?? originalMsgId;
                            }

                            return(result);
                        }

                        return(new ParseAndProccessResult
                        {
                            Replacement = string.Empty,
                            ContainNuggets = true,
                            NextPosition = match.Index + match.Length
                        });
                    }
                }
            }
示例#8
0
            private ParseAndProccessResult ParseAndProcessNuggetZone(int position, bool isNested)
            {
                bool containsNuggets = false;

                StringBuilder processedZone = new StringBuilder();

                int nextPosition = position;

                for (;;)
                {
                    var match = m_owner.m_tokensRegex.Match(m_entity, nextPosition);
                    if (!match.Success)
                    {
                        processedZone.Append(
                            m_entity.Substring(nextPosition));
                        return(new ParseAndProccessResult {
                            Replacement = processedZone.ToString()
                        });
                    }

                    if (match.Value == m_owner.m_nuggetTokens.BeginToken)
                    {
                        processedZone.Append(m_entity.Substring(nextPosition, match.Index - nextPosition));

                        var processedNugget = ParseAndProcessNugget(match.Index, isNested);

                        processedZone.Append(processedNugget.Replacement);
                        nextPosition    = processedNugget.NextPosition;
                        containsNuggets = true;
                        continue;
                    }

                    if (isNested)
                    {
                        if (IsParameterEnd(match.Value))
                        {
                            if (!containsNuggets)
                            {
                                // This is original behavior of ((())).
                                var stringToProccess = m_entity.Substring(nextPosition, match.Index - nextPosition);

                                var nugget = new Nugget
                                {
                                    MsgId =
                                        stringToProccess
                                };
                                string modifiedNuggetString = null;

                                if (m_owner.m_context == NuggetParser.Context.SourceProcessing)
                                {
                                    string fakeNuggetString = string.Format(
                                        "{0}{1}{2}",
                                        m_owner.m_nuggetTokens.BeginToken,
                                        stringToProccess,
                                        m_owner.m_nuggetTokens.EndToken);
                                    nugget.MsgId = PreProccessMsgId(nugget.MsgId);

                                    modifiedNuggetString = m_processNugget(
                                        fakeNuggetString,                         // entire nugget string
                                        m_owner.m_nuggetTokens.BeginToken.Length, // zero-based pos of the first char of entire nugget string
                                        nugget,                                   // broken-down nugget
                                        fakeNuggetString);                        // source entity string
                                                                                  // Returns either modified nugget string, or original nugget string (i.e. for no replacement).
                                }

                                return(new ParseAndProccessResult
                                {
                                    Replacement = modifiedNuggetString ?? stringToProccess,
                                    NextPosition = match.Index + m_owner.m_nuggetTokens.ParameterEndToken.Length,
                                    ContainNuggets = containsNuggets
                                });
                            }

                            processedZone.Append(m_entity.Substring(nextPosition, match.Index - nextPosition));

                            return(new ParseAndProccessResult
                            {
                                Replacement = processedZone.ToString(),
                                NextPosition = match.Index + m_owner.m_nuggetTokens.ParameterEndToken.Length,
                                ContainNuggets = containsNuggets
                            });
                        }
                    }

                    processedZone.Append(m_entity.Substring(nextPosition, match.Index + match.Length - nextPosition));
                    nextPosition = match.Index + match.Length;
                }
            }
示例#9
0
 /// <summary>
 /// Returns a nugget instance loaded from a regex match, or null if error.
 /// </summary>
 private Nugget NuggetFromRegexMatch(Match match)
 {
     if (!match.Success
         || match.Groups.Count != 4) {
         return null; }
     Nugget n = new Nugget();
    // Extract msgid from 2nd capture group.
     n.MsgId = match.Groups[1].Value;
    // Extract format items from 3rd capture group.
     var formatItems = match.Groups[2].Captures;
     if (formatItems.Count != 0) {
         n.FormatItems = new string[formatItems.Count];
         int i = 0;
         foreach (Capture capture in formatItems) {
             if (m_context == Context.SourceProcessing
                 && !capture.Value.IsSet()) {
                 return null; } // bad format
             n.FormatItems[i++] = capture.Value;
         }
     }
    // Extract comment from 4th capture group.
     if (match.Groups[3].Value.IsSet()) {
         n.Comment = match.Groups[3].Value; }
    // Success.
     return n;
 }
示例#10
0
        public void Nugget_EqualsAndHashCode()
        {
            Nugget nugget01 = new Nugget { MsgId = "msgid" };
            Nugget nugget02 = new Nugget { MsgId = "msgid", FormatItems = new string[] { "fi1", "fi2" } };
            Nugget nugget03 = new Nugget { MsgId = "msgid", Comment = "comment" };
            Nugget nugget04 = new Nugget { MsgId = "msgid", FormatItems = new string[] { "fi1", "fi2" }, Comment = "comment" };
            Nugget nugget05 = new Nugget { MsgId = "msgid", FormatItems = new string[] { "fi1" } };
            Nugget nugget06 = new Nugget { MsgId = "msgid", FormatItems = new string[] {}, Comment = "comment" };

            Nugget nugget11 = new Nugget { MsgId = "msgid" };
            Nugget nugget12 = new Nugget { MsgId = "msgid", FormatItems = new string[] { "fi1", "fi2" } };
            Nugget nugget13 = new Nugget { MsgId = "msgid", Comment = "comment" };
            Nugget nugget14 = new Nugget { MsgId = "msgid", FormatItems = new string[] { "fi1", "fi2" }, Comment = "comment" };
            Nugget nugget15 = new Nugget { MsgId = "msgid", FormatItems = new string[] { "fi1" } };
            Nugget nugget16 = new Nugget { MsgId = "msgid", FormatItems = new string[] {}, Comment = "comment" };

            CompareNugget(nugget01, nugget01, true);
            CompareNugget(nugget02, nugget02, true);
            CompareNugget(nugget03, nugget03, true);
            CompareNugget(nugget04, nugget04, true);
            CompareNugget(nugget05, nugget05, true);
            CompareNugget(nugget06, nugget06, true);

            CompareNugget(nugget01, nugget11, true);
            CompareNugget(nugget02, nugget12, true);
            CompareNugget(nugget03, nugget13, true);
            CompareNugget(nugget04, nugget14, true);
            CompareNugget(nugget05, nugget15, true);
            CompareNugget(nugget06, nugget16, true);

            CompareNugget(nugget01, nugget11, true);
            CompareNugget(nugget02, nugget11, false);
            CompareNugget(nugget03, nugget11, false);
            CompareNugget(nugget04, nugget11, false);
            CompareNugget(nugget05, nugget11, false);
            CompareNugget(nugget06, nugget11, false);

            CompareNugget(nugget01, nugget12, false);
            CompareNugget(nugget02, nugget12, true);
            CompareNugget(nugget03, nugget12, false);
            CompareNugget(nugget04, nugget12, false);
            CompareNugget(nugget05, nugget12, false);
            CompareNugget(nugget06, nugget12, false);

            CompareNugget(nugget01, nugget13, false);
            CompareNugget(nugget02, nugget13, false);
            CompareNugget(nugget03, nugget13, true);
            CompareNugget(nugget04, nugget13, false);
            CompareNugget(nugget05, nugget13, false);
            CompareNugget(nugget06, nugget13, false);

            CompareNugget(nugget01, nugget14, false);
            CompareNugget(nugget02, nugget14, false);
            CompareNugget(nugget03, nugget14, false);
            CompareNugget(nugget04, nugget14, true);
            CompareNugget(nugget05, nugget14, false);
            CompareNugget(nugget06, nugget14, false);

            CompareNugget(nugget01, nugget15, false);
            CompareNugget(nugget02, nugget15, false);
            CompareNugget(nugget03, nugget15, false);
            CompareNugget(nugget04, nugget15, false);
            CompareNugget(nugget05, nugget15, true);
            CompareNugget(nugget06, nugget15, false);

            CompareNugget(nugget01, nugget16, false);
            CompareNugget(nugget02, nugget16, false);
            CompareNugget(nugget03, nugget16, false);
            CompareNugget(nugget04, nugget16, false);
            CompareNugget(nugget05, nugget16, false);
            CompareNugget(nugget06, nugget16, true);
        }
示例#11
0
        private void AddNewTemplateItem(
            string fileName,
            ReferenceContext referenceContext,
            Nugget nugget, 
            ConcurrentDictionary<string, TemplateItem> templateItems)
        {
            string msgid = nugget.MsgId.Replace("\r\n", "\n").Replace("\r", "\\n");
                // NB: In memory msgids are normalized so that LFs are converted to "\n" char sequence.
            string key = TemplateItem.KeyFromMsgidAndComment(msgid, nugget.Comment, _settings.MessageContextEnabledFromComment);
            List<string> tmpList;
               //
            templateItems.AddOrUpdate(
                key,
                // Add routine.
                k => {
                    TemplateItem item = new TemplateItem();
                    item.MsgKey = key;
                    item.MsgId = msgid;
                    item.FileName = fileName;

                    item.References = new List<ReferenceContext> {referenceContext};

                    if (nugget.Comment.IsSet()) {
                        tmpList = new List<string>();
                        tmpList.Add(nugget.Comment);
                        item.Comments = tmpList;
                    }

                    return item;
                },
                // Update routine.
                (k, v) =>
                {
                    if (!_settings.DisableReferences)
                    {
                        var newReferences = new List<ReferenceContext>(v.References.ToList());
                        newReferences.Add(referenceContext);
                        v.References = newReferences;
                    }

                    if (nugget.Comment.IsSet()) {
                        tmpList = v.Comments != null ? v.Comments.ToList() : new List<string>();
                        if (!_settings.DisableReferences || !tmpList.Contains(nugget.Comment))
                            tmpList.Add(nugget.Comment);
                        v.Comments = tmpList;
                    }

                    return v;
                });
        }