5
5
* you may not use this file except in compliance with the License.
6
6
* You may obtain a copy of the License at
7
7
*
8
- * http://www.apache.org/licenses/LICENSE-2.0
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
9
*
10
10
* Unless required by applicable law or agreed to in writing, software
11
11
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -56,13 +56,12 @@ public class StompDecoder {
56
56
57
57
/**
58
58
* Decodes one or more STOMP frames from the given {@code ByteBuffer} into a
59
- * list of {@link Message}s. If the input buffer contains any incplcontains partial STOMP frame content, or additional
60
- * content with a partial STOMP frame, the buffer is reset and {@code null} is
61
- * returned.
62
- *
63
- * @param buffer The buffer to decode the STOMP frame from
64
- *
65
- * @return the decoded messages or an empty list
59
+ * list of {@link Message}s. If the input buffer contains partial STOMP frame
60
+ * content, or additional content with a partial STOMP frame, the buffer is
61
+ * reset and {@code null} is returned.
62
+ * @param buffer the buffer to decode the STOMP frame from
63
+ * @return the decoded messages, or an empty list if none
64
+ * @throws StompConversionException raised in case of decoding issues
66
65
*/
67
66
public List <Message <byte []>> decode (ByteBuffer buffer ) {
68
67
return decode (buffer , new LinkedMultiValueMap <String , String >());
@@ -71,35 +70,29 @@ public List<Message<byte[]>> decode(ByteBuffer buffer) {
71
70
/**
72
71
* Decodes one or more STOMP frames from the given {@code buffer} and returns
73
72
* a list of {@link Message}s.
74
- *
75
73
* <p>If the given ByteBuffer contains only partial STOMP frame content and no
76
74
* complete STOMP frames, an empty list is returned, and the buffer is reset to
77
75
* to where it was.
78
- *
79
76
* <p>If the buffer contains one ore more STOMP frames, those are returned and
80
77
* the buffer reset to point to the beginning of the unused partial content.
81
- *
82
78
* <p>The input headers map is used to store successfully parsed headers and
83
79
* is cleared after ever successfully read message. So when partial content is
84
80
* read the caller can check if a "content-length" header was read, which helps
85
81
* to determine how much more content is needed before the next STOMP frame
86
82
* can be decoded.
87
- *
88
- * @param buffer The buffer to decode the STOMP frame from
83
+ * @param buffer the buffer to decode the STOMP frame from
89
84
* @param headers an empty map that will contain successfully parsed headers
90
85
* in cases where the partial buffer ended with a partial STOMP frame
91
- *
92
- * @return decoded messages or an empty list
86
+ * @return the decoded messages, or an empty list if none
93
87
* @throws StompConversionException raised in case of decoding issues
94
88
*/
95
89
public List <Message <byte []>> decode (ByteBuffer buffer , MultiValueMap <String , String > headers ) {
96
90
Assert .notNull (headers , "headers is required" );
97
91
List <Message <byte []>> messages = new ArrayList <Message <byte []>>();
98
92
while (buffer .hasRemaining ()) {
99
- Message <byte []> m = decodeMessage (buffer , headers );
100
- if (m != null ) {
101
- messages .add (m );
102
- headers .clear ();
93
+ Message <byte []> message = decodeMessage (buffer , headers );
94
+ if (message != null ) {
95
+ messages .add (message );
103
96
}
104
97
else {
105
98
break ;
@@ -112,20 +105,17 @@ public List<Message<byte[]>> decode(ByteBuffer buffer, MultiValueMap<String, Str
112
105
* Decode a single STOMP frame from the given {@code buffer} into a {@link Message}.
113
106
*/
114
107
private Message <byte []> decodeMessage (ByteBuffer buffer , MultiValueMap <String , String > headers ) {
115
-
116
108
Message <byte []> decodedMessage = null ;
117
109
skipLeadingEol (buffer );
118
110
buffer .mark ();
119
111
120
112
String command = readCommand (buffer );
121
113
if (command .length () > 0 ) {
122
-
123
114
readHeaders (buffer , headers );
124
115
byte [] payload = readPayload (buffer , headers );
125
-
126
116
if (payload != null ) {
127
117
StompCommand stompCommand = StompCommand .valueOf (command );
128
- if (( payload .length > 0 ) && ( !stompCommand .isBodyAllowed () )) {
118
+ if (payload .length > 0 && !stompCommand .isBodyAllowed ()) {
129
119
throw new StompConversionException (stompCommand + " shouldn't have but " +
130
120
"has a payload with length=" + payload .length + ", headers=" + headers );
131
121
}
@@ -137,7 +127,7 @@ private Message<byte[]> decodeMessage(ByteBuffer buffer, MultiValueMap<String, S
137
127
}
138
128
else {
139
129
if (logger .isTraceEnabled ()) {
140
- logger .trace ("Received incomplete frame. Resetting buffer." );
130
+ logger .trace ("Incomplete frame, resetting input buffer.. ." );
141
131
}
142
132
buffer .reset ();
143
133
}
@@ -182,10 +172,10 @@ private void readHeaders(ByteBuffer buffer, MultiValueMap<String, String> header
182
172
if (headerStream .size () > 0 ) {
183
173
String header = new String (headerStream .toByteArray (), UTF8_CHARSET );
184
174
int colonIndex = header .indexOf (':' );
185
- if (( colonIndex <= 0 ) || ( colonIndex == header .length () - 1 ) ) {
175
+ if (colonIndex <= 0 || colonIndex == header .length () - 1 ) {
186
176
if (buffer .remaining () > 0 ) {
187
- throw new StompConversionException (
188
- "Illegal header: '" + header + "' . A header must be of the form <name>:<value>" );
177
+ throw new StompConversionException ("Illegal header: '" + header +
178
+ "' . A header must be of the form <name>:<value>. " );
189
179
}
190
180
}
191
181
else {
@@ -205,13 +195,15 @@ private void readHeaders(ByteBuffer buffer, MultiValueMap<String, String> header
205
195
* <a href="http://stomp.github.io/stomp-specification-1.2.html#Value_Encoding">"Value Encoding"</a>.
206
196
*/
207
197
private String unescape (String inString ) {
208
-
209
- StringBuilder sb = new StringBuilder ();
210
- int pos = 0 ; // position in the old string
198
+ StringBuilder sb = new StringBuilder (inString .length ());
199
+ int pos = 0 ; // position in the old string
211
200
int index = inString .indexOf ("\\ " );
212
201
213
202
while (index >= 0 ) {
214
203
sb .append (inString .substring (pos , index ));
204
+ if (index + 1 >= inString .length ()) {
205
+ throw new StompConversionException ("Illegal escape sequence at index " + index + ": " + inString );
206
+ }
215
207
Character c = inString .charAt (index + 1 );
216
208
if (c == 'r' ) {
217
209
sb .append ('\r' );
@@ -282,7 +274,6 @@ protected Integer getContentLength(MultiValueMap<String, String> headers) {
282
274
283
275
/**
284
276
* Try to read an EOL incrementing the buffer position if successful.
285
- *
286
277
* @return whether an EOL was consumed
287
278
*/
288
279
private boolean tryConsumeEndOfLine (ByteBuffer buffer ) {
0 commit comments