Skip to content

Commit 03bca5f

Browse files
committed
Merge bug21929 into default
2 parents bad5a41 + 893c02c commit 03bca5f

File tree

4 files changed

+252
-168
lines changed

4 files changed

+252
-168
lines changed

src/com/rabbitmq/client/impl/Frame.java

Lines changed: 69 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.util.Date;
4444
import java.util.HashMap;
4545
import java.util.Map;
46+
import java.util.List;
4647

4748
import com.rabbitmq.client.AMQP;
4849
import com.rabbitmq.client.MalformedFrameException;
@@ -260,64 +261,85 @@ public static Map<String, Object> buildTable(Object[] keysValues) {
260261
return result;
261262
}
262263

263-
/** Computes the AMQP wire-protocol length of a protocol-encoded table. */
264+
/** Computes the AMQP wire-protocol length of protocol-encoded table entries.
265+
*/
264266
public static long tableSize(Map<String, Object> table)
265267
throws UnsupportedEncodingException
266268
{
267269
long acc = 0;
268270
for(Map.Entry<String, Object> entry: table.entrySet()) {
269271
acc += shortStrSize(entry.getKey());
270-
acc += 1;
271-
Object value = entry.getValue();
272-
if(value instanceof String) {
273-
acc += longStrSize((String)entry.getValue());
274-
}
275-
else if(value instanceof LongString) {
276-
acc += 4 + ((LongString)value).length();
277-
}
278-
else if(value instanceof Integer) {
279-
acc += 4;
280-
}
281-
else if(value instanceof BigDecimal) {
282-
acc += 5;
283-
}
284-
else if(value instanceof Date || value instanceof Timestamp) {
285-
acc += 8;
286-
}
287-
else if(value instanceof Map) {
288-
acc += 4 + tableSize((Map<String, Object>) value);
289-
}
290-
else if (value instanceof Byte) {
291-
acc += 1;
292-
}
293-
else if(value instanceof Double) {
294-
acc += 8;
295-
}
296-
else if(value instanceof Float) {
297-
acc += 4;
298-
}
299-
else if(value instanceof Long) {
300-
acc += 8;
301-
}
302-
else if(value instanceof Short) {
303-
acc += 2;
304-
}
305-
else if(value instanceof Boolean) {
306-
acc += 1;
307-
}
308-
else if(value instanceof byte[]) {
309-
acc += 4 + ((byte[])value).length;
310-
}
311-
else if(value == null) {
312-
}
313-
else {
314-
throw new IllegalArgumentException("invalid value in table");
315-
}
272+
acc += fieldValueSize(entry.getValue());
316273
}
274+
return acc;
275+
}
317276

277+
/** Computes the AMQP wire-protocol length of a protocol-encoded field-value. */
278+
public static long fieldValueSize(Object value)
279+
throws UnsupportedEncodingException
280+
{
281+
long acc = 1; // for the type tag
282+
if(value instanceof String) {
283+
acc += longStrSize((String)value);
284+
}
285+
else if(value instanceof LongString) {
286+
acc += 4 + ((LongString)value).length();
287+
}
288+
else if(value instanceof Integer) {
289+
acc += 4;
290+
}
291+
else if(value instanceof BigDecimal) {
292+
acc += 5;
293+
}
294+
else if(value instanceof Date || value instanceof Timestamp) {
295+
acc += 8;
296+
}
297+
else if(value instanceof Map) {
298+
acc += 4 + tableSize((Map<String, Object>) value);
299+
}
300+
else if (value instanceof Byte) {
301+
acc += 1;
302+
}
303+
else if(value instanceof Double) {
304+
acc += 8;
305+
}
306+
else if(value instanceof Float) {
307+
acc += 4;
308+
}
309+
else if(value instanceof Long) {
310+
acc += 8;
311+
}
312+
else if(value instanceof Short) {
313+
acc += 2;
314+
}
315+
else if(value instanceof Boolean) {
316+
acc += 1;
317+
}
318+
else if(value instanceof byte[]) {
319+
acc += 4 + ((byte[])value).length;
320+
}
321+
else if(value instanceof List) {
322+
acc += 4 + arraySize((List)value);
323+
}
324+
else if(value == null) {
325+
}
326+
else {
327+
throw new IllegalArgumentException("invalid value in table");
328+
}
318329
return acc;
319330
}
320331

332+
/** Computes the AMQP wire-protocol length of an encoded field-array */
333+
public static long arraySize(List values)
334+
throws UnsupportedEncodingException
335+
{
336+
long acc = 0;
337+
for (Object value : values) {
338+
acc += fieldValueSize(value);
339+
}
340+
return acc;
341+
}
342+
321343
/** Computes the AMQP wire-protocol length of a protocol-encoded long string. */
322344
public static int longStrSize(String str)
323345
throws UnsupportedEncodingException

src/com/rabbitmq/client/impl/ValueReader.java

Lines changed: 74 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import java.util.Date;
3939
import java.util.HashMap;
4040
import java.util.Map;
41+
import java.util.List;
42+
import java.util.ArrayList;
4143

4244
import com.rabbitmq.client.MalformedFrameException;
4345

@@ -162,64 +164,86 @@ public static final Map<String, Object> readTable(DataInputStream in)
162164

163165
DataInputStream tableIn = new DataInputStream
164166
(new TruncatedInputStream(in, tableLength));
165-
Object value = null;
166167
while(tableIn.available() > 0) {
167168
String name = readShortstr(tableIn);
168-
switch(tableIn.readUnsignedByte()) {
169-
case 'S':
170-
value = readLongstr(tableIn);
171-
break;
172-
case 'I':
173-
value = tableIn.readInt();
174-
break;
175-
case 'D':
176-
int scale = tableIn.readUnsignedByte();
177-
byte [] unscaled = new byte[4];
178-
tableIn.readFully(unscaled);
179-
value = new BigDecimal(new BigInteger(unscaled), scale);
180-
break;
181-
case 'T':
182-
value = readTimestamp(tableIn);
183-
break;
184-
case 'F':
185-
value = readTable(tableIn);
186-
break;
187-
case 'b':
188-
value = tableIn.readByte();
189-
break;
190-
case 'd':
191-
value = tableIn.readDouble();
192-
break;
193-
case 'f':
194-
value = tableIn.readFloat();
195-
break;
196-
case 'l':
197-
value = tableIn.readLong();
198-
break;
199-
case 's':
200-
value = tableIn.readShort();
201-
break;
202-
case 't':
203-
value = tableIn.readBoolean();
204-
break;
205-
case 'x':
206-
value = readBytes(tableIn);
207-
break;
208-
case 'V':
209-
value = null;
210-
break;
211-
default:
212-
throw new MalformedFrameException
213-
("Unrecognised type in table");
214-
}
215-
169+
Object value = readFieldValue(tableIn);
216170
if(!table.containsKey(name))
217171
table.put(name, value);
218172
}
219-
220173
return table;
221174
}
222175

176+
public static final Object readFieldValue(DataInputStream in)
177+
throws IOException {
178+
Object value = null;
179+
switch(in.readUnsignedByte()) {
180+
case 'S':
181+
value = readLongstr(in);
182+
break;
183+
case 'I':
184+
value = in.readInt();
185+
break;
186+
case 'D':
187+
int scale = in.readUnsignedByte();
188+
byte [] unscaled = new byte[4];
189+
in.readFully(unscaled);
190+
value = new BigDecimal(new BigInteger(unscaled), scale);
191+
break;
192+
case 'T':
193+
value = readTimestamp(in);
194+
break;
195+
case 'F':
196+
value = readTable(in);
197+
break;
198+
case 'A':
199+
value = readArray(in);
200+
break;
201+
case 'b':
202+
value = in.readByte();
203+
break;
204+
case 'd':
205+
value = in.readDouble();
206+
break;
207+
case 'f':
208+
value = in.readFloat();
209+
break;
210+
case 'l':
211+
value = in.readLong();
212+
break;
213+
case 's':
214+
value = in.readShort();
215+
break;
216+
case 't':
217+
value = in.readBoolean();
218+
break;
219+
case 'x':
220+
value = readBytes(in);
221+
break;
222+
case 'V':
223+
value = null;
224+
break;
225+
default:
226+
throw new MalformedFrameException
227+
("Unrecognised type in table");
228+
}
229+
return value;
230+
}
231+
232+
/** Read a field-array */
233+
public static List readArray(DataInputStream in)
234+
throws IOException
235+
{
236+
long length = unsignedExtend(in.readInt());
237+
DataInputStream arrayIn = new DataInputStream
238+
(new TruncatedInputStream(in, length));
239+
List array = new ArrayList();
240+
while(arrayIn.available() > 0) {
241+
Object value = readFieldValue(arrayIn);
242+
array.add(value);
243+
}
244+
return array;
245+
}
246+
223247
/** Public API - reads a table. */
224248
public final Map<String, Object> readTable()
225249
throws IOException

0 commit comments

Comments
 (0)