001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.sql.old;
020
021import java.io.IOException;
022import java.io.InputStream;
023import java.io.InputStreamReader;
024import java.io.Reader;
025
026import lucee.commons.lang.ExceptionUtil;
027
028public final class SimpleCharStream
029{
030
031    private final void ExpandBuff(boolean flag)
032    {
033        char ac[] = new char[bufsize + 2048];
034        int ai[] = new int[bufsize + 2048];
035        int ai1[] = new int[bufsize + 2048];
036        try
037        {
038            if(flag)
039            {
040                System.arraycopy(buffer, tokenBegin, ac, 0, bufsize - tokenBegin);
041                System.arraycopy(buffer, 0, ac, bufsize - tokenBegin, bufpos);
042                buffer = ac;
043                System.arraycopy(bufline, tokenBegin, ai, 0, bufsize - tokenBegin);
044                System.arraycopy(bufline, 0, ai, bufsize - tokenBegin, bufpos);
045                bufline = ai;
046                System.arraycopy(bufcolumn, tokenBegin, ai1, 0, bufsize - tokenBegin);
047                System.arraycopy(bufcolumn, 0, ai1, bufsize - tokenBegin, bufpos);
048                bufcolumn = ai1;
049                maxNextCharInd = bufpos += bufsize - tokenBegin;
050            } else
051            {
052                System.arraycopy(buffer, tokenBegin, ac, 0, bufsize - tokenBegin);
053                buffer = ac;
054                System.arraycopy(bufline, tokenBegin, ai, 0, bufsize - tokenBegin);
055                bufline = ai;
056                System.arraycopy(bufcolumn, tokenBegin, ai1, 0, bufsize - tokenBegin);
057                bufcolumn = ai1;
058                maxNextCharInd = bufpos -= tokenBegin;
059            }
060        }
061        catch(Throwable throwable) {
062                        ExceptionUtil.rethrowIfNecessary(throwable);
063            throw new Error(throwable.getMessage());
064        }
065        bufsize += 2048;
066        available = bufsize;
067        tokenBegin = 0;
068    }
069
070    private final void FillBuff()
071        throws IOException
072    {
073        if(maxNextCharInd == available)
074            if(available == bufsize)
075            {
076                if(tokenBegin > 2048)
077                {
078                    bufpos = maxNextCharInd = 0;
079                    available = tokenBegin;
080                } else
081                if(tokenBegin < 0)
082                    bufpos = maxNextCharInd = 0;
083                else
084                    ExpandBuff(false);
085            } else
086            if(available > tokenBegin)
087                available = bufsize;
088            else
089            if(tokenBegin - available < 2048)
090                ExpandBuff(true);
091            else
092                available = tokenBegin;
093        int i;
094        try
095        {
096            if((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
097            {
098                inputStream.close();
099                throw new IOException();
100            } 
101            maxNextCharInd += i;
102            return;
103        }
104        catch(IOException ioexception)
105        {
106            bufpos--;
107            backup(0);
108            if(tokenBegin == -1)
109                tokenBegin = bufpos;
110            throw ioexception;
111        }
112    }
113
114    public final char BeginToken()
115        throws IOException
116    {
117        tokenBegin = -1;
118        char c = readChar();
119        tokenBegin = bufpos;
120        return c;
121    }
122
123    private final void UpdateLineColumn(char c)
124    {
125        column++;
126        if(prevCharIsLF)
127        {
128            prevCharIsLF = false;
129            line += column = 1;
130        } else
131        if(prevCharIsCR)
132        {
133            prevCharIsCR = false;
134            if(c == '\n')
135                prevCharIsLF = true;
136            else
137                line += column = 1;
138        }
139        switch(c)
140        {
141        case 13: // '\r'
142            prevCharIsCR = true;
143            break;
144
145        case 10: // '\n'
146            prevCharIsLF = true;
147            break;
148
149        case 9: // '\t'
150            column--;
151            column += 8 - (column & 7);
152            break;
153        }
154        bufline[bufpos] = line;
155        bufcolumn[bufpos] = column;
156    }
157
158    public final char readChar()
159        throws IOException
160    {
161        if(inBuf > 0)
162        {
163            inBuf--;
164            if(++bufpos == bufsize)
165                bufpos = 0;
166            return buffer[bufpos];
167        }
168        if(++bufpos >= maxNextCharInd)
169            FillBuff();
170        char c = buffer[bufpos];
171        UpdateLineColumn(c);
172        return c;
173    }
174
175    /**
176     * @deprecated Method getColumn is deprecated
177     */
178
179    public final int getColumn()
180    {
181        return bufcolumn[bufpos];
182    }
183
184    /**
185     * @deprecated Method getLine is deprecated
186     */
187
188    public final int getLine()
189    {
190        return bufline[bufpos];
191    }
192
193    public final int getEndColumn()
194    {
195        return bufcolumn[bufpos];
196    }
197
198    public final int getEndLine()
199    {
200        return bufline[bufpos];
201    }
202
203    public final int getBeginColumn()
204    {
205        return bufcolumn[tokenBegin];
206    }
207
208    public final int getBeginLine()
209    {
210        return bufline[tokenBegin];
211    }
212
213    public final void backup(int i)
214    {
215        inBuf += i;
216        if((bufpos -= i) < 0)
217            bufpos += bufsize;
218    }
219
220    public SimpleCharStream(Reader reader, int i, int j, int k)
221    {
222        bufpos = -1;
223        column = 0;
224        line = 1;
225        prevCharIsCR = false;
226        prevCharIsLF = false;
227        maxNextCharInd = 0;
228        inBuf = 0;
229        inputStream = reader;
230        line = i;
231        column = j - 1;
232        available = bufsize = k;
233        buffer = new char[k];
234        bufline = new int[k];
235        bufcolumn = new int[k];
236    }
237
238    public SimpleCharStream(Reader reader, int i, int j)
239    {
240        this(reader, i, j, 4096);
241    }
242
243    public SimpleCharStream(Reader reader)
244    {
245        this(reader, 1, 1, 4096);
246    }
247
248    public void ReInit(Reader reader, int i, int j, int k)
249    {
250        inputStream = reader;
251        line = i;
252        column = j - 1;
253        if(buffer == null || k != buffer.length)
254        {
255            available = bufsize = k;
256            buffer = new char[k];
257            bufline = new int[k];
258            bufcolumn = new int[k];
259        }
260        prevCharIsLF = prevCharIsCR = false;
261        tokenBegin = inBuf = maxNextCharInd = 0;
262        bufpos = -1;
263    }
264
265    public void ReInit(Reader reader, int i, int j)
266    {
267        ReInit(reader, i, j, 4096);
268    }
269
270    public void ReInit(Reader reader)
271    {
272        ReInit(reader, 1, 1, 4096);
273    }
274
275    public SimpleCharStream(InputStream inputstream, int i, int j, int k)
276    {
277        this(( (new InputStreamReader(inputstream))), i, j, 4096);
278    }
279
280    public SimpleCharStream(InputStream inputstream, int i, int j)
281    {
282        this(inputstream, i, j, 4096);
283    }
284
285    public SimpleCharStream(InputStream inputstream)
286    {
287        this(inputstream, 1, 1, 4096);
288    }
289
290    public void ReInit(InputStream inputstream, int i, int j, int k)
291    {
292        ReInit(( (new InputStreamReader(inputstream))), i, j, 4096);
293    }
294
295    public void ReInit(InputStream inputstream)
296    {
297        ReInit(inputstream, 1, 1, 4096);
298    }
299
300    public void ReInit(InputStream inputstream, int i, int j)
301    {
302        ReInit(inputstream, i, j, 4096);
303    }
304
305    public final String GetImage()
306    {
307        if(bufpos >= tokenBegin)
308            return new String(buffer, tokenBegin, (bufpos - tokenBegin) + 1);
309        return new String(buffer, tokenBegin, bufsize - tokenBegin) + new String(buffer, 0, bufpos + 1);
310    }
311
312    public final char[] GetSuffix(int i)
313    {
314        char ac[] = new char[i];
315        if(bufpos + 1 >= i)
316        {
317            System.arraycopy(buffer, (bufpos - i) + 1, ac, 0, i);
318        } else
319        {
320            System.arraycopy(buffer, bufsize - (i - bufpos - 1), ac, 0, i - bufpos - 1);
321            System.arraycopy(buffer, 0, ac, i - bufpos - 1, bufpos + 1);
322        }
323        return ac;
324    }
325
326    public void Done()
327    {
328        buffer = null;
329        bufline = null;
330        bufcolumn = null;
331    }
332
333    public void adjustBeginLineColumn(int i, int j)
334    {
335        int k = tokenBegin;
336        int l;
337        if(bufpos >= tokenBegin)
338            l = (bufpos - tokenBegin) + inBuf + 1;
339        else
340            l = (bufsize - tokenBegin) + bufpos + 1 + inBuf;
341        int i1 = 0;
342        int j1 = 0;
343        //boolean flag = false;
344        //boolean flag1 = false;
345        int i2 = 0;
346        int k1;
347        for(; i1 < l && bufline[j1 = k % bufsize] == bufline[k1 = ++k % bufsize]; i1++)
348        {
349            bufline[j1] = i;
350            int l1 = (i2 + bufcolumn[k1]) - bufcolumn[j1];
351            bufcolumn[j1] = j + i2;
352            i2 = l1;
353        }
354
355        if(i1 < l)
356        {
357            bufline[j1] = i++;
358            bufcolumn[j1] = j + i2;
359            while(i1++ < l) 
360                if(bufline[j1 = k % bufsize] != bufline[++k % bufsize])
361                    bufline[j1] = i++;
362                else
363                    bufline[j1] = i;
364        }
365        line = bufline[j1];
366        column = bufcolumn[j1];
367    }
368
369    public static final boolean staticFlag = false;
370    int bufsize;
371    int available;
372    int tokenBegin;
373    public int bufpos;
374    private int bufline[];
375    private int bufcolumn[];
376    private int column;
377    private int line;
378    private boolean prevCharIsCR;
379    private boolean prevCharIsLF;
380    private Reader inputStream;
381    private char buffer[];
382    private int maxNextCharInd;
383    private int inBuf;
384}