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
81 _appendable.append('?');
82 _more=0;
83 _bits=0;
84 }
85 else
86 {
87 if ((b & 0xe0) == 0xc0)
88 {
89
90 _more=1;
91 _bits=b&0x1f;
92 }
93 else if ((b & 0xf0) == 0xe0)
94 {
95
96 _more=2;
97 _bits=b&0x0f;
98 }
99 else if ((b & 0xf8) == 0xf0)
100 {
101
102 _more=3;
103 _bits=b&0x07;
104 }
105 else if ((b & 0xfc) == 0xf8)
106 {
107
108 _more=4;
109 _bits=b&0x03;
110 }
111 else if ((b & 0xfe) == 0xfc)
112 {
113
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 {
127 _appendable.append('?');
128 _more=0;
129 _bits=0;
130 throw new IllegalArgumentException("!utf8");
131 }
132 else
133 {
134
135 _bits=(_bits<<6)|(b&0x3f);
136 if (--_more==0)
137 _appendable.append(new String(Character.toChars(_bits)));
138 }
139 }
140 }
141
142 }