1 /*------------------------------------------------------------------------------
  2 Name:      XmlBuffer.java
  3 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  4 ------------------------------------------------------------------------------*/
  5 
  6 using System.Text;
  7 
  8 namespace org.xmlBlaster.util
  9 {
 10 
 11 
 12    /**
 13     * Same as StringBuffer but has the additional method AppendEscaped() which
 14     * escapes predefined XML identities.
 15     * @author mr@marcelruff.info
 16     */
 17    public class XmlBuffer
 18    {
 19       private StringBuilder buf;
 20       public XmlBuffer(int len)
 21       {
 22          this.buf = new StringBuilder(len);
 23       }
 24 
 25       /**
 26        * Escape predefined xml entities (&, <, >, ', ").
 27        * Additionally the '\0' is escaped.
 28        * @param text
 29        * @return The escaped text is appended to the StringBuffer.
 30        */
 31       public XmlBuffer AppendEscaped(string text)
 32       {
 33          Append(this.buf, text);
 34          return this;
 35       }
 36 
 37       /**
 38        * Escape predefined xml entities (', ", \r) for attributes.
 39        * Additionally the '\0' is escaped.
 40        * @param text
 41        * @return The escaped text is Appended to the StringBuffer.
 42        */
 43       public XmlBuffer AppendAttributeEscaped(string text)
 44       {
 45          AppendAttr(this.buf, text);
 46          return this;
 47       }
 48 
 49       /**
 50        * Appends a tag name (e.g. "bla" of a tag called <bla>).
 51        * Currently is a normal Append()
 52        * @param tagName Could in future escape invalid tokens  '<' and '&' in a tag name.
 53        * @return
 54        */
 55       public XmlBuffer AppendTag(string tagName)
 56       {
 57          this.buf.Append(tagName);
 58          return this;
 59       }
 60 
 61       /**
 62        * Aquivalent to a StringBuffer.Append().
 63        */
 64       public XmlBuffer Append(string str)
 65       {
 66          this.buf.Append(str);
 67          return this;
 68       }
 69 
 70       /**
 71        * Aquivalent to a StringBuffer.Append().
 72        */
 73       public XmlBuffer Append(long ln)
 74       {
 75          this.buf.Append(ln);
 76          return this;
 77       }
 78 
 79       /**
 80        * Aquivalent to a StringBuffer.Append().
 81        */
 82       public XmlBuffer Append(float ln)
 83       {
 84          this.buf.Append(ln);
 85          return this;
 86       }
 87 
 88       /**
 89        * Aquivalent to a StringBuffer.Append().
 90        */
 91       public XmlBuffer Append(double ln)
 92       {
 93          this.buf.Append(ln);
 94          return this;
 95       }
 96 
 97       /**
 98        * Aquivalent to a StringBuffer.Append().
 99        */
100       public XmlBuffer Append(bool b)
101       {
102          this.buf.Append(b);
103          return this;
104       }
105 
106       public StringBuilder getRawBuffer()
107       {
108          return this.buf;
109       }
110 
111       public int Length()
112       {
113          return this.buf.Length;
114       }
115 
116       /**
117        * Removes all buffer entries.
118        * Calling Append fills new data to the beginning of the buffer. 
119        */
120       public void Reset()
121       {
122          this.buf.Remove(0, this.buf.Length);
123       }
124 
125       override public string ToString()
126       {
127          return this.buf.ToString();
128       }
129 
130       // 5 predefined XML entities plus some extra escapers

131       private static readonly string S_AMP = "&amp;";
132       private static readonly string S_LT = "&lt;";
133       private static readonly string S_GT = "&gt;";
134       private static readonly string S_QUOT = "&quot;";
135       private static readonly string S_APOS = "&apos;";
136 
137       private static readonly string S_SLASH_R = "&#x0D;";
138       private static readonly string S_NULL = "&#x0;";
139 
140       private static readonly char[] AMP = S_AMP.ToCharArray();
141       private static readonly char[] LT = S_LT.ToCharArray();
142       private static readonly char[] GT = S_GT.ToCharArray();
143       private static readonly char[] QUOT = S_QUOT.ToCharArray();
144       private static readonly char[] APOS = S_APOS.ToCharArray();
145 
146       private static readonly char[] SLASH_R = S_SLASH_R.ToCharArray();
147       private static readonly char[] NULL = S_NULL.ToCharArray();
148 
149       /**
150        * Escape predefined xml entities (&, <, >, ', ").
151        * Additionally the '\0' is escaped.
152        * @param text e.g. "Hello < and &"
153        * @return "Hello &lt; and &amp;"
154        */
155       public static string escape(string text)
156       {
157          if (text == null || text.Length < 1)
158             return text;
159          StringBuilder buf = new StringBuilder((int)(text.Length * 1.2));
160          Append(buf, text);
161          return buf.ToString();
162       }
163 
164       /**
165        * Escape predefined xml entities (&, <, >, ', ").
166        * Additionally the '\0' is escaped.
167        * @param text
168        * @return The escaped text is Appended to the given StringBuffer.
169        */
170       public static void Append(StringBuilder buf, string text)
171       {
172          if (text == null) return;
173          int length = text.Length;
174          for (int i = 0; i < length; i++)
175          {
176             char c = text[i];
177             switch (c)
178             {
179                case '\0':
180                   buf.Append(NULL);
181                   break;
182                case '&':
183                   buf.Append(AMP);
184                   break;
185                case '<':
186                   buf.Append(LT);
187                   break;
188                case '>':
189                   buf.Append(GT);
190                   break;
191                case '"':
192                   buf.Append(QUOT);
193                   break;
194                case '\'':
195                   buf.Append(APOS);
196                   break;
197                case '\r':
198                   buf.Append(SLASH_R);
199                   break;
200                default:
201                   buf.Append(c);
202                   break;
203             }
204          }
205       }
206       /**
207        * Escape predefined xml entities (\0, ', ", \r). for attribute notation
208        * Additionally the '\0' is escaped.
209        * @param text
210        * @return The escaped text is appended to the given StringBuffer.
211        */
212       public static void AppendAttr(StringBuilder buf, string text)
213       {
214          if (text == null) return;
215          int length = text.Length;
216          for (int i = 0; i < length; i++)
217          {
218             char c = text[i];
219             switch (c)
220             {
221                case '\0':
222                   buf.Append(NULL);
223                   break;
224                case '&':
225                        buf.Append(AMP);
226                    break;
227                case '<':
228                        buf.Append(LT);
229                    break;
230                /*
231                case '>':
232                        buf.Append(GT);
233                    break;
234                */
235                case '"':
236                   buf.Append(QUOT);
237                   break;
238                case '\'':
239                   buf.Append(APOS);
240                   break;
241                case '\r':
242                   buf.Append(SLASH_R);
243                   break;
244                default:
245                   buf.Append(c);
246                   break;
247             }
248          }
249       }
250 
251       public static string UnEscape(string text)
252       {
253          if (text == null) return "";
254          int length = text.Length;
255          StringBuilder buf = new StringBuilder(length);
256          for (int i = 0; i < length; i++)
257          {
258             if (text[i] == '&')
259             {
260                int len = 0;
261                string sub = text.Substring(i);
262                if (sub.StartsWith(S_NULL))
263                {
264                   buf.Append('\0');
265                   len = S_NULL.Length;
266                }
267                else if (sub.StartsWith(S_AMP))
268                {
269                   buf.Append('&');
270                   len = S_AMP.Length;
271                }
272                else if (sub.StartsWith(S_LT))
273                {
274                   buf.Append('<');
275                   len = S_LT.Length;
276                }
277                else if (sub.StartsWith(S_GT))
278                {
279                   buf.Append('>');
280                   len = S_GT.Length;
281                }
282                else if (sub.StartsWith(S_QUOT))
283                {
284                   buf.Append('"');
285                   len = S_QUOT.Length;
286                }
287                else if (sub.StartsWith(S_APOS))
288                {
289                   buf.Append('\'');
290                   len = S_APOS.Length;
291                }
292                else if (sub.StartsWith(S_SLASH_R))
293                {
294                   buf.Append('\r');
295                   len = S_SLASH_R.Length;
296                }
297 
298                if (len > 0)
299                {
300                   i += (len - 1);
301                   continue;
302                }
303             }
304             buf.Append(text[i]);
305          }
306          return buf.ToString();
307       }
308 
309    } // class

310 } // namespace


syntax highlighted by Code2HTML, v. 0.9.1