public static object Append (object ws, XmlReader reader)
		{
			if (reader.NodeType == XmlNodeType.Comment) {
				var newWs = new MSBuildWhitespace {
					isComment = true,
					content = reader.Value
				};
				if (ws == null)
					return newWs;
				else if (ws is string || ws is StringBuilder) {
					return new MSBuildWhitespace {
						content = ws.ToString (),
						next = newWs
					};
				} else {
					var last = ((MSBuildWhitespace)ws).GetLast ();
					last.next = newWs;
					return ws;
				}
			} else if (ws is MSBuildWhitespace) {
				var last = ((MSBuildWhitespace)ws).GetLast ();
				if (last.isComment) {
					last.next = new MSBuildWhitespace {
						content = reader.Value
					};
				} else if (last.content is StringBuilder)
					((StringBuilder)last.content).Append (reader.Value);
				else {
					var val = reader.Value;
					var sb = new StringBuilder ((string)last.content, ((string)last.content).Length + val.Length);
					sb.Append (val);
					last.content = sb;
				}
				return ws;
			} else {
				if (ws == null)
					return reader.Value;
				if (ws is StringBuilder) {
					((StringBuilder)ws).Append (reader.Value);
					return ws;
				}
				else {
					var val = reader.Value;
					var sb = new StringBuilder ((string)ws, ((string)ws).Length + val.Length);
					sb.Append (val);
					return sb;
				}
			}
		}
 internal override void Write(XmlWriter writer, WriteContext context)
 {
     MSBuildWhitespace.Write(StartWhitespace, writer);
     writer.WriteComment(Value);
     MSBuildWhitespace.Write(EndWhitespace, writer);
 }
		public static object ConsumeUntilNewLine (ref object ws)
		{
			if (ws == null)
				return null;

			var s = ws as string;
			if (s != null) {
				for (int n = s.Length - 1; n >= 0; n--) {
					var c = s [n];
					if (c == '\r' || c == '\n') {
						if (n == s.Length - 1)
							break; // Default case, consume the whole string
						var res = s.Substring (0, n + 1);
						ws = s.Substring (n + 1);
						return res;
					}
				}
				var result = ws;
				ws = null;
				return result;
			}
			var sb = ws as StringBuilder;
			if (sb != null) {
				for (int n = sb.Length - 1; n >= 0; n--) {
					var c = sb [n];
					if (c == '\r' || c == '\n') {
						if (n == sb.Length - 1)
							break; // Default case, consume the whole string
						var res = sb.ToString (0, n + 1);
						sb.Remove (0, n + 1);
						return res;
					}
				}
				var result = ws.ToString ();
				ws = null;
				return result;
			}

			// It's a MSBuildWhitespace

			var mw = (MSBuildWhitespace)ws;
			mw.GenerateStrings ();

			var toSplit = mw.FindLastWithNewLine ();
			if (toSplit == null) {
				var result = ws;
				ws = null;
				return result;
			} else {
				var remaining = toSplit.content;
				var result = ConsumeUntilNewLine (ref remaining);

				// Set the remaining value

				if (toSplit.next == null) {
					// New line found in last node. The remaining is just the split string
					ws = remaining;
				} else {
					if (remaining == null)
						return toSplit.next; // Consumed the whole string of this node. The remaining is the next node
					
					// New line found in the middle of the chain. A new node with the remaining has to be created
					ws = new MSBuildWhitespace {
						content = remaining,
						next = toSplit.next
					};
				}

				// Generate the consumed value

				if (toSplit != mw) {
					// New line found in the middle of the chain. Update the node content and split the chain.
					toSplit.content = result;
					toSplit.next = null;
					return mw;
				} else {
					// New line found in first node. The result is just the consumed string. Nothing else to do.
					return result;
				}
			}
		}
 public static object Append(object ws, XmlReader reader)
 {
     if (reader.NodeType == XmlNodeType.Comment)
     {
         var newWs = new MSBuildWhitespace {
             isComment = true,
             content   = reader.Value
         };
         if (ws == null)
         {
             return(newWs);
         }
         else if (ws is string || ws is StringBuilder)
         {
             return(new MSBuildWhitespace {
                 content = ws.ToString(),
                 next = newWs
             });
         }
         else
         {
             var last = ((MSBuildWhitespace)ws).GetLast();
             last.next = newWs;
             return(ws);
         }
     }
     else if (ws is MSBuildWhitespace)
     {
         var last = ((MSBuildWhitespace)ws).GetLast();
         if (last.isComment)
         {
             last.next = new MSBuildWhitespace {
                 content = reader.Value
             };
         }
         else if (last.content is StringBuilder)
         {
             ((StringBuilder)last.content).Append(reader.Value);
         }
         else
         {
             var val = reader.Value;
             var sb  = new StringBuilder((string)last.content, ((string)last.content).Length + val.Length);
             sb.Append(val);
             last.content = sb;
         }
         return(ws);
     }
     else
     {
         if (ws == null)
         {
             return(reader.Value);
         }
         if (ws is StringBuilder)
         {
             ((StringBuilder)ws).Append(reader.Value);
             return(ws);
         }
         else
         {
             var val = reader.Value;
             var sb  = new StringBuilder((string)ws, ((string)ws).Length + val.Length);
             sb.Append(val);
             return(sb);
         }
     }
 }
        public static object ConsumeUntilNewLine(ref object ws)
        {
            if (ws == null)
            {
                return(null);
            }

            var s = ws as string;

            if (s != null)
            {
                for (int n = s.Length - 1; n >= 0; n--)
                {
                    var c = s [n];
                    if (c == '\r' || c == '\n')
                    {
                        if (n == s.Length - 1)
                        {
                            break;                             // Default case, consume the whole string
                        }
                        var res = s.Substring(0, n + 1);
                        ws = s.Substring(n + 1);
                        return(res);
                    }
                }
                var result = ws;
                ws = null;
                return(result);
            }
            var sb = ws as StringBuilder;

            if (sb != null)
            {
                for (int n = sb.Length - 1; n >= 0; n--)
                {
                    var c = sb [n];
                    if (c == '\r' || c == '\n')
                    {
                        if (n == sb.Length - 1)
                        {
                            break;                             // Default case, consume the whole string
                        }
                        var res = sb.ToString(0, n + 1);
                        sb.Remove(0, n + 1);
                        return(res);
                    }
                }
                var result = ws.ToString();
                ws = null;
                return(result);
            }

            // It's a MSBuildWhitespace

            var mw = (MSBuildWhitespace)ws;

            mw.GenerateStrings();

            var toSplit = mw.FindLastWithNewLine();

            if (toSplit == null)
            {
                var result = ws;
                ws = null;
                return(result);
            }
            else
            {
                var remaining = toSplit.content;
                var result    = ConsumeUntilNewLine(ref remaining);

                // Set the remaining value

                if (toSplit.next == null)
                {
                    // New line found in last node. The remaining is just the split string
                    ws = remaining;
                }
                else
                {
                    if (remaining == null)
                    {
                        return(toSplit.next);                        // Consumed the whole string of this node. The remaining is the next node
                    }
                    // New line found in the middle of the chain. A new node with the remaining has to be created
                    ws = new MSBuildWhitespace {
                        content = remaining,
                        next    = toSplit.next
                    };
                }

                // Generate the consumed value

                if (toSplit != mw)
                {
                    // New line found in the middle of the chain. Update the node content and split the chain.
                    toSplit.content = result;
                    toSplit.next    = null;
                    return(mw);
                }
                else
                {
                    // New line found in first node. The result is just the consumed string. Nothing else to do.
                    return(result);
                }
            }
        }
 public void ReadAndStoreWhitespace()
 {
     currentWhitespace = MSBuildWhitespace.Append(currentWhitespace, XmlReader);
     Read();
 }
 public object ConsumeWhitespaceUntilNewLine()
 {
     return(MSBuildWhitespace.ConsumeUntilNewLine(ref currentWhitespace));
 }
Exemple #8
0
        internal override void Write(XmlWriter writer, WriteContext context)
        {
            MSBuildWhitespace.Write(StartWhitespace, writer);

            writer.WriteStartElement(NamespacePrefix, GetElementName(), Namespace);

            var props = metadata.PropertiesAttributeOrder;

            if (props.Count > 0)
            {
                int    propIndex  = 0;
                int    knownIndex = 0;
                var    knownAtts  = attributeOrder ?? GetKnownAttributes();
                string lastAttr   = null;
                do
                {
                    if (propIndex < props.Count && (lastAttr == props [propIndex].AfterAttribute || props [propIndex].AfterAttribute == null))
                    {
                        var prop = props [propIndex++];
                        writer.WriteAttributeString(prop.Name, prop.Value);
                        lastAttr = prop.Name;
                    }
                    else if (knownIndex < knownAtts.Length)
                    {
                        var aname = knownAtts [knownIndex++];
                        lastAttr = aname;
                        var val = WriteAttribute(aname);
                        if (val != null)
                        {
                            writer.WriteAttributeString(aname, val);
                        }
                    }
                    else
                    {
                        lastAttr = null;
                    }
                } while (propIndex < props.Count || knownIndex < knownAtts.Length);
            }
            else
            {
                var knownAtts = attributeOrder ?? GetKnownAttributes();
                for (int i = 0; i < knownAtts.Length; i++)
                {
                    var aname = knownAtts [i];
                    var val   = WriteAttribute(aname);
                    if (val != null)
                    {
                        writer.WriteAttributeString(aname, val);
                    }
                }
            }

            WriteContent(writer, context);

            writer.WriteEndElement();

            MSBuildWhitespace.Write(EndWhitespace, writer);
            if (context.Evaluating)
            {
                string id = context.ItemMap.Count.ToString();
                context.ItemMap [id] = this;
            }
        }