View Javadoc

1   package org.eclipse.jetty.util;
2   
3   import java.io.IOException;
4   
5   public abstract class Utf8Appendable
6   {
7       protected final Appendable _appendable;
8       protected int _more;
9       protected int _bits;
10  
11      public Utf8Appendable(Appendable appendable)
12      {
13          _appendable=appendable;
14      }
15  
16      public abstract int length();
17      
18      public void append(byte b)
19      {
20          try
21          {
22              appendByte(b);
23          }
24          catch(IOException e)
25          {
26              throw new RuntimeException(e);
27          }
28      }
29      
30      public void append(byte[] b,int offset, int length)
31      {
32          try
33          {
34              int end=offset+length;
35              for (int i=offset; i<end;i++)
36                  appendByte(b[i]);
37          }
38          catch(IOException e)
39          {
40              throw new RuntimeException(e);
41          }
42      }
43  
44      public boolean append(byte[] b,int offset, int length, int maxChars)
45      {
46          try
47          {
48              int end=offset+length;
49              for (int i=offset; i<end;i++)
50              {
51                  if (length()>maxChars)
52                      return false;
53                  appendByte(b[i]);
54              }
55              return true;
56          }
57          catch(IOException e)
58          {
59              throw new RuntimeException(e);
60          }
61      }
62      
63      protected void appendByte(byte b) throws IOException
64      {
65          if (b>=0)
66          {
67              if (_more>0)
68              {
69                  _appendable.append('?');
70                  _more=0;
71                  _bits=0;
72              }
73              else
74                  _appendable.append((char)(0x7f&b));
75          }
76          else if (_more==0)
77          {
78              if ((b&0xc0)!=0xc0)
79              {
80                  // 10xxxxxx
81                  _appendable.append('?');
82                  _more=0;
83                  _bits=0;
84              }
85              else
86              { 
87                  if ((b & 0xe0) == 0xc0)
88                  {
89                      //110xxxxx
90                      _more=1;
91                      _bits=b&0x1f;
92                  }
93                  else if ((b & 0xf0) == 0xe0)
94                  {
95                      //1110xxxx
96                      _more=2;
97                      _bits=b&0x0f;
98                  }
99                  else if ((b & 0xf8) == 0xf0)
100                 {
101                     //11110xxx
102                     _more=3;
103                     _bits=b&0x07;
104                 }
105                 else if ((b & 0xfc) == 0xf8)
106                 {
107                     //111110xx
108                     _more=4;
109                     _bits=b&0x03;
110                 }
111                 else if ((b & 0xfe) == 0xfc) 
112                 {
113                     //1111110x
114                     _more=5;
115                     _bits=b&0x01;
116                 }
117                 else
118                 {
119                     throw new IllegalArgumentException("!utf8");
120                 }
121             }
122         }
123         else
124         {
125             if ((b&0xc0)==0xc0)
126             {    // 11??????
127                 _appendable.append('?');
128                 _more=0;
129                 _bits=0;
130                 throw new IllegalArgumentException("!utf8");
131             }
132             else
133             {
134                 // 10xxxxxx
135                 _bits=(_bits<<6)|(b&0x3f);
136                 if (--_more==0)
137                     _appendable.append(new String(Character.toChars(_bits)));
138             }
139         }
140     }
141 
142 }