blob: dc4aeebdd3590c3966996250b1401e22fa5c90a5 [file] [log] [blame]
Mark Slee7eb0d632007-03-01 00:00:27 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
Mark Slee83c52a82006-06-07 06:51:18 +00007package com.facebook.thrift.protocol;
8
Mark Slee83c52a82006-06-07 06:51:18 +00009import com.facebook.thrift.TException;
Mark Slee83c52a82006-06-07 06:51:18 +000010
11/**
12 * Utility class with static methods for interacting with protocol data
13 * streams.
14 *
15 * @author Mark Slee <mcslee@facebook.com>
16 */
17public class TProtocolUtil {
David Reissd92ca7d2008-03-18 19:32:00 +000018
19 /**
20 * The maximum recursive depth the skip() function will traverse before
21 * throwing a TException.
22 */
23 private static int maxSkipDepth = Integer.MAX_VALUE;
24
25 /**
26 * Specifies the maximum recursive depth that the skip function will
27 * traverse before throwing a TException. This is a global setting, so
28 * any call to skip in this JVM will enforce this value.
29 *
30 * @param depth the maximum recursive depth. A value of 2 would allow
31 * the skip function to skip a structure or collection with basic children,
32 * but it would not permit skipping a struct that had a field containing
33 * a child struct. A value of 1 would only allow skipping of simple
34 * types and empty structs/collections.
35 */
36 public static void setMaxSkipDepth(int depth) {
37 maxSkipDepth = depth;
38 }
39
40 /**
41 * Skips over the next data element from the provided input TProtocol object.
42 *
43 * @param prot the protocol object to read from
44 * @param type the next value will be intepreted as this TType value.
45 */
Mark Slee456b7a82006-10-25 20:53:37 +000046 public static void skip(TProtocol prot, byte type)
Mark Slee83c52a82006-06-07 06:51:18 +000047 throws TException {
David Reissd92ca7d2008-03-18 19:32:00 +000048 skip(prot, type, maxSkipDepth);
49 }
Mark Slee83c52a82006-06-07 06:51:18 +000050
David Reissd92ca7d2008-03-18 19:32:00 +000051 /**
52 * Skips over the next data element from the provided input TProtocol object.
53 *
54 * @param prot the protocol object to read from
55 * @param type the next value will be intepreted as this TType value.
56 * @param maxDepth this function will only skip complex objects to this
57 * recursive depth, to prevent Java stack overflow.
58 */
59 public static void skip(TProtocol prot, byte type, int maxDepth)
60 throws TException {
61 if (maxDepth <= 0) {
62 throw new TException("Maximum skip depth exceeded");
63 }
Mark Slee83c52a82006-06-07 06:51:18 +000064 switch (type) {
Mark Slee78f58e22006-09-02 04:17:07 +000065 case TType.BOOL:
66 {
Mark Slee456b7a82006-10-25 20:53:37 +000067 prot.readBool();
Mark Slee780e4ec2007-10-02 04:43:31 +000068 break;
Mark Slee78f58e22006-09-02 04:17:07 +000069 }
Mark Slee530fd662006-08-09 00:05:18 +000070 case TType.BYTE:
Mark Slee83c52a82006-06-07 06:51:18 +000071 {
Mark Slee456b7a82006-10-25 20:53:37 +000072 prot.readByte();
Mark Slee780e4ec2007-10-02 04:43:31 +000073 break;
Mark Slee83c52a82006-06-07 06:51:18 +000074 }
Mark Slee78f58e22006-09-02 04:17:07 +000075 case TType.I16:
76 {
Mark Slee456b7a82006-10-25 20:53:37 +000077 prot.readI16();
Mark Slee780e4ec2007-10-02 04:43:31 +000078 break;
Mark Slee78f58e22006-09-02 04:17:07 +000079 }
Mark Slee530fd662006-08-09 00:05:18 +000080 case TType.I32:
Mark Slee83c52a82006-06-07 06:51:18 +000081 {
Mark Slee456b7a82006-10-25 20:53:37 +000082 prot.readI32();
Mark Slee780e4ec2007-10-02 04:43:31 +000083 break;
Mark Slee83c52a82006-06-07 06:51:18 +000084 }
Mark Slee530fd662006-08-09 00:05:18 +000085 case TType.I64:
Mark Slee83c52a82006-06-07 06:51:18 +000086 {
Mark Slee456b7a82006-10-25 20:53:37 +000087 prot.readI64();
Mark Slee780e4ec2007-10-02 04:43:31 +000088 break;
Mark Slee83c52a82006-06-07 06:51:18 +000089 }
Mark Sleec98d0502006-09-06 02:42:25 +000090 case TType.DOUBLE:
91 {
Mark Slee456b7a82006-10-25 20:53:37 +000092 prot.readDouble();
Mark Slee780e4ec2007-10-02 04:43:31 +000093 break;
Mark Sleec98d0502006-09-06 02:42:25 +000094 }
Mark Slee530fd662006-08-09 00:05:18 +000095 case TType.STRING:
Mark Slee83c52a82006-06-07 06:51:18 +000096 {
David Reissc005b1b2008-02-15 01:38:18 +000097 prot.readBinary();
Mark Slee780e4ec2007-10-02 04:43:31 +000098 break;
Mark Slee83c52a82006-06-07 06:51:18 +000099 }
Mark Slee530fd662006-08-09 00:05:18 +0000100 case TType.STRUCT:
Mark Slee83c52a82006-06-07 06:51:18 +0000101 {
Mark Slee456b7a82006-10-25 20:53:37 +0000102 prot.readStructBegin();
Mark Slee83c52a82006-06-07 06:51:18 +0000103 while (true) {
Mark Slee456b7a82006-10-25 20:53:37 +0000104 TField field = prot.readFieldBegin();
Mark Slee530fd662006-08-09 00:05:18 +0000105 if (field.type == TType.STOP) {
Mark Slee83c52a82006-06-07 06:51:18 +0000106 break;
107 }
David Reissd92ca7d2008-03-18 19:32:00 +0000108 skip(prot, field.type, maxDepth - 1);
Mark Slee456b7a82006-10-25 20:53:37 +0000109 prot.readFieldEnd();
Mark Slee83c52a82006-06-07 06:51:18 +0000110 }
Mark Slee456b7a82006-10-25 20:53:37 +0000111 prot.readStructEnd();
Mark Slee780e4ec2007-10-02 04:43:31 +0000112 break;
Mark Slee83c52a82006-06-07 06:51:18 +0000113 }
Mark Slee530fd662006-08-09 00:05:18 +0000114 case TType.MAP:
Mark Slee83c52a82006-06-07 06:51:18 +0000115 {
Mark Slee456b7a82006-10-25 20:53:37 +0000116 TMap map = prot.readMapBegin();
Mark Slee530fd662006-08-09 00:05:18 +0000117 for (int i = 0; i < map.size; i++) {
David Reissd92ca7d2008-03-18 19:32:00 +0000118 skip(prot, map.keyType, maxDepth - 1);
119 skip(prot, map.valueType, maxDepth - 1);
Mark Slee83c52a82006-06-07 06:51:18 +0000120 }
Mark Slee456b7a82006-10-25 20:53:37 +0000121 prot.readMapEnd();
Mark Slee780e4ec2007-10-02 04:43:31 +0000122 break;
Mark Slee83c52a82006-06-07 06:51:18 +0000123 }
Mark Slee530fd662006-08-09 00:05:18 +0000124 case TType.SET:
David Reiss0c90f6f2008-02-06 22:18:40 +0000125 {
Mark Slee456b7a82006-10-25 20:53:37 +0000126 TSet set = prot.readSetBegin();
Mark Slee530fd662006-08-09 00:05:18 +0000127 for (int i = 0; i < set.size; i++) {
David Reissd92ca7d2008-03-18 19:32:00 +0000128 skip(prot, set.elemType, maxDepth - 1);
Mark Slee83c52a82006-06-07 06:51:18 +0000129 }
Mark Slee456b7a82006-10-25 20:53:37 +0000130 prot.readSetEnd();
Mark Slee780e4ec2007-10-02 04:43:31 +0000131 break;
Mark Slee83c52a82006-06-07 06:51:18 +0000132 }
Mark Slee530fd662006-08-09 00:05:18 +0000133 case TType.LIST:
Mark Slee83c52a82006-06-07 06:51:18 +0000134 {
Mark Slee456b7a82006-10-25 20:53:37 +0000135 TList list = prot.readListBegin();
Mark Slee530fd662006-08-09 00:05:18 +0000136 for (int i = 0; i < list.size; i++) {
David Reissd92ca7d2008-03-18 19:32:00 +0000137 skip(prot, list.elemType, maxDepth - 1);
Mark Slee83c52a82006-06-07 06:51:18 +0000138 }
Mark Slee456b7a82006-10-25 20:53:37 +0000139 prot.readListEnd();
Mark Slee780e4ec2007-10-02 04:43:31 +0000140 break;
Mark Slee83c52a82006-06-07 06:51:18 +0000141 }
142 default:
Mark Slee780e4ec2007-10-02 04:43:31 +0000143 break;
Mark Slee83c52a82006-06-07 06:51:18 +0000144 }
145 }
146}