1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.handler.codec;
18
19
20 import java.util.Map.Entry;
21
22 import io.netty.buffer.ByteBuf;
23 import io.netty.buffer.ByteBufUtil;
24 import io.netty.util.AsciiString;
25 import io.netty.util.CharsetUtil;
26 import io.netty.util.internal.ObjectUtil;
27
28 public final class AsciiHeadersEncoder {
29
30
31
32
33 public enum SeparatorType {
34
35
36
37 COLON,
38
39
40
41 COLON_SPACE,
42 }
43
44
45
46
47 public enum NewlineType {
48
49
50
51 LF,
52
53
54
55 CRLF
56 }
57
58 private final ByteBuf buf;
59 private final SeparatorType separatorType;
60 private final NewlineType newlineType;
61
62 public AsciiHeadersEncoder(ByteBuf buf) {
63 this(buf, SeparatorType.COLON_SPACE, NewlineType.CRLF);
64 }
65
66 public AsciiHeadersEncoder(ByteBuf buf, SeparatorType separatorType, NewlineType newlineType) {
67 this.buf = ObjectUtil.checkNotNull(buf, "buf");
68 this.separatorType = ObjectUtil.checkNotNull(separatorType, "separatorType");
69 this.newlineType = ObjectUtil.checkNotNull(newlineType, "newlineType");
70 }
71
72 public void encode(Entry<CharSequence, CharSequence> entry) {
73 final CharSequence name = entry.getKey();
74 final CharSequence value = entry.getValue();
75 final ByteBuf buf = this.buf;
76 final int nameLen = name.length();
77 final int valueLen = value.length();
78 final int entryLen = nameLen + valueLen + 4;
79 int offset = buf.writerIndex();
80 buf.ensureWritable(entryLen);
81 writeAscii(buf, offset, name);
82 offset += nameLen;
83
84 switch (separatorType) {
85 case COLON:
86 buf.setByte(offset ++, ':');
87 break;
88 case COLON_SPACE:
89 buf.setByte(offset ++, ':');
90 buf.setByte(offset ++, ' ');
91 break;
92 default:
93 throw new Error();
94 }
95
96 writeAscii(buf, offset, value);
97 offset += valueLen;
98
99 switch (newlineType) {
100 case LF:
101 buf.setByte(offset ++, '\n');
102 break;
103 case CRLF:
104 buf.setByte(offset ++, '\r');
105 buf.setByte(offset ++, '\n');
106 break;
107 default:
108 throw new Error();
109 }
110
111 buf.writerIndex(offset);
112 }
113
114 private static void writeAscii(ByteBuf buf, int offset, CharSequence value) {
115 if (value instanceof AsciiString) {
116 ByteBufUtil.copy((AsciiString) value, 0, buf, offset, value.length());
117 } else {
118 buf.setCharSequence(offset, value, CharsetUtil.US_ASCII);
119 }
120 }
121 }