]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/Utf8LineParser.java
Importing upstream Jetty jetty-9.2.1.v20140609
[gigi.git] / lib / jetty / org / eclipse / jetty / util / Utf8LineParser.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.util;
20
21 import java.nio.ByteBuffer;
22
23 import org.eclipse.jetty.util.Utf8Appendable.NotUtf8Exception;
24
25 /**
26  * Stateful parser for lines of UTF8 formatted text, looking for <code>"\n"</code> as a line termination character.
27  * <p>
28  * For use with new IO framework that is based on ByteBuffer parsing.
29  */
30 public class Utf8LineParser
31 {
32     private enum State
33     {
34         START,
35         PARSE,
36         END;
37     }
38
39     private State state;
40     private Utf8StringBuilder utf;
41
42     public Utf8LineParser()
43     {
44         this.state = State.START;
45     }
46
47     /**
48      * Parse a ByteBuffer (could be a partial buffer), and return once a complete line of UTF8 parsed text has been reached.
49      *
50      * @param buf
51      *            the buffer to parse (could be an incomplete buffer)
52      * @return the line of UTF8 parsed text, or null if no line end termination has been reached within the {@link ByteBuffer#remaining() remaining} bytes of
53      *         the provided ByteBuffer. (In the case of a null, a subsequent ByteBuffer with a line end termination should be provided)
54      * @throws NotUtf8Exception
55      *             if the input buffer has bytes that do not conform to UTF8 validation (validation performed by {@link Utf8StringBuilder}
56      */
57     public String parse(ByteBuffer buf)
58     {
59         byte b;
60         while (buf.remaining() > 0)
61         {
62             b = buf.get();
63             if (parseByte(b))
64             {
65                 state = State.START;
66                 return utf.toString();
67             }
68         }
69         // have not reached end of line (yet)
70         return null;
71     }
72
73     private boolean parseByte(byte b)
74     {
75         switch (state)
76         {
77             case START:
78                 utf = new Utf8StringBuilder();
79                 state = State.PARSE;
80                 return parseByte(b);
81             case PARSE:
82                 // not waiting on more UTF sequence parts.
83                 if (utf.isUtf8SequenceComplete() && ((b == '\r') || (b == '\n')))
84                 {
85                     state = State.END;
86                     return parseByte(b);
87                 }
88                 utf.append(b);
89                 break;
90             case END:
91                 if (b == '\n')
92                 {
93                     // we've reached the end
94                     state = State.START;
95                     return true;
96                 }
97                 break;
98         }
99         return false;
100     }
101 }