1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements.  See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22package com.sun.org.apache.xerces.internal.util;
23
24import com.sun.org.apache.xerces.internal.xni.XMLString;
25
26/**
27 * XMLString is a structure used to pass character arrays. However,
28 * XMLStringBuffer is a buffer in which characters can be appended
29 * and extends XMLString so that it can be passed to methods
30 * expecting an XMLString object. This is a safe operation because
31 * it is assumed that any callee will <strong>not</strong> modify
32 * the contents of the XMLString structure.
33 * <p>
34 * The contents of the string are managed by the string buffer. As
35 * characters are appended, the string buffer will grow as needed.
36 * <p>
37 * <strong>Note:</strong> Never set the <code>ch</code>,
38 * <code>offset</code>, and <code>length</code> fields directly.
39 * These fields are managed by the string buffer. In order to reset
40 * the buffer, call <code>clear()</code>.
41 *
42 * @author Andy Clark, IBM
43 * @author Eric Ye, IBM
44 *
45 */
46public class XMLStringBuffer
47extends XMLString {
48
49    //
50    // Constants
51    //
52
53
54    /** Default buffer size (32). */
55    public static final int DEFAULT_SIZE = 32;
56
57    //
58    // Data
59    //
60
61    //
62    // Constructors
63    //
64
65    /**
66     *
67     */
68    public XMLStringBuffer() {
69        this(DEFAULT_SIZE);
70    } // <init>()
71
72    /**
73     *
74     *
75     * @param size
76     */
77    public XMLStringBuffer(int size) {
78        ch = new char[size];
79    } // <init>(int)
80
81    /** Constructs a string buffer from a char. */
82    public XMLStringBuffer(char c) {
83        this(1);
84        append(c);
85    } // <init>(char)
86
87    /** Constructs a string buffer from a String. */
88    public XMLStringBuffer(String s) {
89        this(s.length());
90        append(s);
91    } // <init>(String)
92
93    /** Constructs a string buffer from the specified character array. */
94    public XMLStringBuffer(char[] ch, int offset, int length) {
95        this(length);
96        append(ch, offset, length);
97    } // <init>(char[],int,int)
98
99    /** Constructs a string buffer from the specified XMLString. */
100    public XMLStringBuffer(XMLString s) {
101        this(s.length);
102        append(s);
103    } // <init>(XMLString)
104
105    //
106    // Public methods
107    //
108
109    /** Clears the string buffer. */
110    public void clear() {
111        offset = 0;
112        length = 0;
113    }
114
115    /**
116     * append
117     *
118     * @param c
119     */
120    public void append(char c) {
121        if(this.length + 1 > this.ch.length){
122            int newLength = this.ch.length * 2 ;
123            if(newLength < this.ch.length + DEFAULT_SIZE){
124                newLength = this.ch.length + DEFAULT_SIZE;
125            }
126            char [] tmp = new char[newLength];
127            System.arraycopy(this.ch, 0, tmp, 0, this.length);
128            this.ch = tmp;
129        }
130        this.ch[this.length] = c ;
131        this.length++;
132    } // append(char)
133
134    /**
135     * append
136     *
137     * @param s
138     */
139    public void append(String s) {
140        int length = s.length();
141        if (this.length + length > this.ch.length) {
142            int newLength = this.ch.length * 2 ;
143            if(newLength < this.ch.length + length + DEFAULT_SIZE){
144                newLength = this.ch.length + length+ DEFAULT_SIZE;
145            }
146
147            char[] newch = new char[newLength];
148            System.arraycopy(this.ch, 0, newch, 0, this.length);
149            this.ch = newch;
150        }
151        s.getChars(0, length, this.ch, this.length);
152        this.length += length;
153    } // append(String)
154
155    /**
156     * append
157     *
158     * @param ch
159     * @param offset
160     * @param length
161     */
162    public void append(char[] ch, int offset, int length) {
163        if (this.length + length > this.ch.length) {
164            int newLength = this.ch.length * 2 ;
165            if(newLength < this.ch.length + length + DEFAULT_SIZE){
166                newLength = this.ch.length + length + DEFAULT_SIZE;
167            }
168            char[] newch = new char[newLength];
169            System.arraycopy(this.ch, 0, newch, 0, this.length);
170            this.ch = newch;
171        }
172        //making the code more robust as it would handle null or 0 length data,
173        //add the data only when it contains some thing
174        if(ch != null && length > 0){
175            System.arraycopy(ch, offset, this.ch, this.length, length);
176            this.length += length;
177        }
178    } // append(char[],int,int)
179
180    /**
181     * append
182     *
183     * @param s
184     */
185    public void append(XMLString s) {
186        append(s.ch, s.offset, s.length);
187    } // append(XMLString)
188
189
190} // class XMLStringBuffer
191