Thrift now a TLP - INFRA-3116

git-svn-id: https://svn.apache.org/repos/asf/thrift/branches/0.1.x@1028168 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cocoa/src/protocol/TBinaryProtocol.h b/lib/cocoa/src/protocol/TBinaryProtocol.h
new file mode 100644
index 0000000..52cf266
--- /dev/null
+++ b/lib/cocoa/src/protocol/TBinaryProtocol.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "TProtocol.h"
+#import "TTransport.h"
+#import "TProtocolFactory.h"
+
+
+@interface TBinaryProtocol : NSObject <TProtocol> {
+  id <TTransport> mTransport;
+  BOOL mStrictRead;
+  BOOL mStrictWrite;
+  int32_t mMessageSizeLimit;
+}
+
+- (id) initWithTransport: (id <TTransport>) transport;
+
+- (id) initWithTransport: (id <TTransport>) transport
+              strictRead: (BOOL) strictRead
+             strictWrite: (BOOL) strictWrite;
+
+- (int32_t) messageSizeLimit;
+- (void) setMessageSizeLimit: (int32_t) sizeLimit;
+
+@end;
+
+
+@interface TBinaryProtocolFactory : NSObject <TProtocolFactory> {
+}
+
++ (TBinaryProtocolFactory *) sharedFactory;
+
+- (TBinaryProtocol *) newProtocolOnTransport: (id <TTransport>) transport;
+
+@end
diff --git a/lib/cocoa/src/protocol/TBinaryProtocol.m b/lib/cocoa/src/protocol/TBinaryProtocol.m
new file mode 100644
index 0000000..ba7f462
--- /dev/null
+++ b/lib/cocoa/src/protocol/TBinaryProtocol.m
@@ -0,0 +1,469 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "TBinaryProtocol.h"
+#import "TProtocolException.h"
+
+int32_t VERSION_1 = 0x80010000;
+int32_t VERSION_MASK = 0xffff0000;
+
+
+static TBinaryProtocolFactory * gSharedFactory = nil;
+
+@implementation TBinaryProtocolFactory
+
++ (TBinaryProtocolFactory *) sharedFactory {
+  if (gSharedFactory == nil) {
+    gSharedFactory = [[TBinaryProtocolFactory alloc] init];
+  }
+
+  return gSharedFactory;
+}
+
+- (TBinaryProtocol *) newProtocolOnTransport: (id <TTransport>) transport {
+  return [[[TBinaryProtocol alloc] initWithTransport: transport] autorelease];
+}
+
+@end
+
+
+
+@implementation TBinaryProtocol
+
+- (id) initWithTransport: (id <TTransport>) transport
+{
+  return [self initWithTransport: transport strictRead: NO strictWrite: NO];
+}
+
+- (id) initWithTransport: (id <TTransport>) transport
+              strictRead: (BOOL) strictRead
+             strictWrite: (BOOL) strictWrite
+{
+  self = [super init];
+  mTransport = [transport retain];
+  mStrictRead = strictRead;
+  mStrictWrite = strictWrite;
+  return self;
+}
+
+
+- (int32_t) messageSizeLimit
+{
+  return mMessageSizeLimit;
+}
+
+
+- (void) setMessageSizeLimit: (int32_t) sizeLimit
+{
+  mMessageSizeLimit = sizeLimit;
+}
+
+
+- (void) dealloc
+{
+  [mTransport release];
+  [super dealloc];
+}
+
+
+- (id <TTransport>) transport
+{
+  return mTransport;
+}
+
+
+- (NSString *) readStringBody: (int) size
+{
+  char buff[size+1];
+  [mTransport readAll: (uint8_t *) buff offset: 0 length: size];
+  buff[size] = 0;
+  return [NSString stringWithUTF8String: buff];
+}
+
+
+- (void) readMessageBeginReturningName: (NSString **) name
+                                  type: (int *) type
+                            sequenceID: (int *) sequenceID
+{
+  int32_t size = [self readI32];
+  if (size < 0) {
+    int version = size & VERSION_MASK;
+    if (version != VERSION_1) {
+      @throw [TProtocolException exceptionWithName: @"TProtocolException"
+                                 reason: @"Bad version in readMessageBegin"];
+    }
+    if (type != NULL) {
+      *type = version & 0x00FF;
+    }
+    NSString * messageName = [self readString];
+    if (name != NULL) {
+      *name = messageName;
+    }
+    int seqID = [self readI32];
+    if (sequenceID != NULL) {
+      *sequenceID = seqID;
+    }
+  } else {
+    if (mStrictRead) {
+      @throw [TProtocolException exceptionWithName: @"TProtocolException"
+                                 reason: @"Missing version in readMessageBegin, old client?"];
+    }
+    if ([self messageSizeLimit] > 0 && size > [self messageSizeLimit]) {
+      @throw [TProtocolException exceptionWithName: @"TProtocolException"
+                                            reason: [NSString stringWithFormat: @"Message too big.  Size limit is: %d Message size is: %d",
+                                                     mMessageSizeLimit,
+                                                     size]];
+    }
+    NSString * messageName = [self readStringBody: size];
+    if (name != NULL) {
+      *name = messageName;
+    }
+    int messageType = [self readByte];
+    if (type != NULL) {
+      *type = messageType;
+    }
+    int seqID = [self readI32];
+    if (sequenceID != NULL) {
+      *sequenceID = seqID;
+    }
+  }
+}
+
+
+- (void) readMessageEnd {}
+
+
+- (void) readStructBeginReturningName: (NSString **) name
+{
+  if (name != NULL) {
+    *name = nil;
+  }
+}
+
+
+- (void) readStructEnd {}
+
+
+- (void) readFieldBeginReturningName: (NSString **) name
+                                type: (int *) fieldType
+                             fieldID: (int *) fieldID
+{
+  if (name != NULL) {
+    *name = nil;
+  }
+  int ft = [self readByte];
+  if (fieldType != NULL) {
+    *fieldType = ft;
+  }
+  if (ft != TType_STOP) {
+    int fid = [self readI16];
+    if (fieldID != NULL) {
+      *fieldID = fid;
+    }
+  }
+}
+
+
+- (void) readFieldEnd {}
+
+
+- (int32_t) readI32
+{
+  uint8_t i32rd[4];
+  [mTransport readAll: i32rd offset: 0 length: 4];
+  return
+    ((i32rd[0] & 0xff) << 24) |
+    ((i32rd[1] & 0xff) << 16) |
+    ((i32rd[2] & 0xff) <<  8) |
+    ((i32rd[3] & 0xff));
+}
+
+
+- (NSString *) readString
+{
+  int size = [self readI32];
+  return [self readStringBody: size];
+}
+
+
+- (BOOL) readBool
+{
+  return [self readByte] == 1;
+}
+
+- (uint8_t) readByte
+{
+  uint8_t myByte;
+  [mTransport readAll: &myByte offset: 0 length: 1];
+  return myByte;
+}
+
+- (short) readI16
+{
+  uint8_t buff[2];
+  [mTransport readAll: buff offset: 0 length: 2];
+  return (short)
+    (((buff[0] & 0xff) << 8) |
+     ((buff[1] & 0xff)));
+  return 0;
+}
+
+- (int64_t) readI64;
+{
+  uint8_t i64rd[8];
+  [mTransport readAll: i64rd offset: 0 length: 8];
+  return
+    ((int64_t)(i64rd[0] & 0xff) << 56) |
+    ((int64_t)(i64rd[1] & 0xff) << 48) |
+    ((int64_t)(i64rd[2] & 0xff) << 40) |
+    ((int64_t)(i64rd[3] & 0xff) << 32) |
+    ((int64_t)(i64rd[4] & 0xff) << 24) |
+    ((int64_t)(i64rd[5] & 0xff) << 16) |
+    ((int64_t)(i64rd[6] & 0xff) <<  8) |
+    ((int64_t)(i64rd[7] & 0xff));
+}
+
+- (double) readDouble;
+{
+  // FIXME - will this get us into trouble on PowerPC?
+  int64_t ieee754 = [self readI64];
+  return *((double *) &ieee754);
+}
+
+
+- (NSData *) readBinary
+{
+  int32_t size = [self readI32];
+  uint8_t * buff = malloc(size);
+  if (buff == NULL) {
+    @throw [TProtocolException
+             exceptionWithName: @"TProtocolException"
+             reason: [NSString stringWithFormat: @"Out of memory.  Unable to allocate %d bytes trying to read binary data.",
+                               size]];
+  }
+  [mTransport readAll: buff offset: 0 length: size];
+  return [NSData dataWithBytesNoCopy: buff length: size];
+}
+
+
+- (void) readMapBeginReturningKeyType: (int *) keyType
+                            valueType: (int *) valueType
+                                 size: (int *) size
+{
+  int kt = [self readByte];
+  int vt = [self readByte];
+  int s = [self readI32];
+  if (keyType != NULL) {
+    *keyType = kt;
+  }
+  if (valueType != NULL) {
+    *valueType = vt;
+  }
+  if (size != NULL) {
+    *size = s;
+  }
+}
+
+- (void) readMapEnd {}
+
+
+- (void) readSetBeginReturningElementType: (int *) elementType
+                                     size: (int *) size
+{
+  int et = [self readByte];
+  int s = [self readI32];
+  if (elementType != NULL) {
+    *elementType = et;
+  }
+  if (size != NULL) {
+    *size = s;
+  }
+}
+
+
+- (void) readSetEnd {}
+
+
+- (void) readListBeginReturningElementType: (int *) elementType
+                                      size: (int *) size
+{
+  int et = [self readByte];
+  int s = [self readI32];
+  if (elementType != NULL) {
+    *elementType = et;
+  }
+  if (size != NULL) {
+    *size = s;
+  }
+}
+
+
+- (void) readListEnd {}
+
+
+- (void) writeByte: (uint8_t) value
+{
+  [mTransport write: &value offset: 0 length: 1];
+}
+
+
+- (void) writeMessageBeginWithName: (NSString *) name
+                              type: (int) messageType
+                        sequenceID: (int) sequenceID
+{
+  if (mStrictWrite) {
+    int version = VERSION_1 | messageType;
+    [self writeI32: version];
+    [self writeString: name];
+    [self writeI32: sequenceID];
+  } else {
+    [self writeString: name];
+    [self writeByte: messageType];
+    [self writeI32: sequenceID];
+  }
+}
+
+
+- (void) writeMessageEnd {}
+
+
+- (void) writeStructBeginWithName: (NSString *) name {}
+
+
+- (void) writeStructEnd {}
+
+
+- (void) writeFieldBeginWithName: (NSString *) name
+                            type: (int) fieldType
+                         fieldID: (int) fieldID
+{
+  [self writeByte: fieldType];
+  [self writeI16: fieldID];
+}
+
+
+- (void) writeI32: (int32_t) value
+{
+  uint8_t buff[4];
+  buff[0] = 0xFF & (value >> 24);
+  buff[1] = 0xFF & (value >> 16);
+  buff[2] = 0xFF & (value >> 8);
+  buff[3] = 0xFF & value;
+  [mTransport write: buff offset: 0 length: 4];
+}
+
+- (void) writeI16: (short) value
+{
+  uint8_t buff[2];
+  buff[0] = 0xff & (value >> 8);
+  buff[1] = 0xff & value;
+  [mTransport write: buff offset: 0 length: 2];
+}
+
+
+- (void) writeI64: (int64_t) value
+{
+  uint8_t buff[8];
+  buff[0] = 0xFF & (value >> 56);
+  buff[1] = 0xFF & (value >> 48);
+  buff[2] = 0xFF & (value >> 40);
+  buff[3] = 0xFF & (value >> 32);
+  buff[4] = 0xFF & (value >> 24);
+  buff[5] = 0xFF & (value >> 16);
+  buff[6] = 0xFF & (value >> 8);
+  buff[7] = 0xFF & value;
+  [mTransport write: buff offset: 0 length: 8];
+}
+
+- (void) writeDouble: (double) value
+{
+  // spit out IEEE 754 bits - FIXME - will this get us in trouble on
+  // PowerPC?
+  [self writeI64: *((int64_t *) &value)];
+}
+
+
+- (void) writeString: (NSString *) value
+{
+  if (value != nil) {
+    const char * utf8Bytes = [value UTF8String];
+    size_t length = strlen(utf8Bytes);
+    [self writeI32: length];
+    [mTransport write: (uint8_t *) utf8Bytes offset: 0 length: length];
+  } else {
+    // instead of crashing when we get null, let's write out a zero
+    // length string
+    [self writeI32: 0];
+  }
+}
+
+
+- (void) writeBinary: (NSData *) data
+{
+  [self writeI32: [data length]];
+  [mTransport write: [data bytes] offset: 0 length: [data length]];
+}
+
+- (void) writeFieldStop
+{
+  [self writeByte: TType_STOP];
+}
+
+
+- (void) writeFieldEnd {}
+
+
+- (void) writeMapBeginWithKeyType: (int) keyType
+                        valueType: (int) valueType
+                             size: (int) size
+{
+  [self writeByte: keyType];
+  [self writeByte: valueType];
+  [self writeI32: size];
+}
+
+- (void) writeMapEnd {}
+
+
+- (void) writeSetBeginWithElementType: (int) elementType
+                                 size: (int) size
+{
+  [self writeByte: elementType];
+  [self writeI32: size];
+}
+
+- (void) writeSetEnd {}
+
+
+- (void) writeListBeginWithElementType: (int) elementType
+                                  size: (int) size
+{
+  [self writeByte: elementType];
+  [self writeI32: size];
+}
+
+- (void) writeListEnd {}
+
+
+- (void) writeBool: (BOOL) value
+{
+  [self writeByte: (value ? 1 : 0)];
+}
+
+@end
diff --git a/lib/cocoa/src/protocol/TProtocol.h b/lib/cocoa/src/protocol/TProtocol.h
new file mode 100644
index 0000000..cc8cdb4
--- /dev/null
+++ b/lib/cocoa/src/protocol/TProtocol.h
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+#import "TTransport.h"
+
+
+enum {
+  TMessageType_CALL = 1,
+  TMessageType_REPLY = 2,
+  TMessageType_EXCEPTION = 3,
+  TMessageType_ONEWAY = 4
+};
+
+enum {
+  TType_STOP   = 0,
+  TType_VOID   = 1,
+  TType_BOOL   = 2,
+  TType_BYTE   = 3,
+  TType_DOUBLE = 4,
+  TType_I16    = 6,
+  TType_I32    = 8,
+  TType_I64    = 10,
+  TType_STRING = 11,
+  TType_STRUCT = 12,
+  TType_MAP    = 13,
+  TType_SET    = 14,
+  TType_LIST   = 15
+};
+
+
+@protocol TProtocol <NSObject>
+
+- (id <TTransport>) transport;
+
+- (void) readMessageBeginReturningName: (NSString **) name
+                                  type: (int *) type
+                            sequenceID: (int *) sequenceID;
+- (void) readMessageEnd;
+
+- (void) readStructBeginReturningName: (NSString **) name;
+- (void) readStructEnd;
+
+- (void) readFieldBeginReturningName: (NSString **) name
+                                type: (int *) fieldType
+                             fieldID: (int *) fieldID;
+- (void) readFieldEnd;
+
+- (NSString *) readString;
+
+- (BOOL) readBool;
+
+- (unsigned char) readByte;
+
+- (short) readI16;
+
+- (int32_t) readI32;
+
+- (int64_t) readI64;
+
+- (double) readDouble;
+
+- (NSData *) readBinary;
+
+- (void) readMapBeginReturningKeyType: (int *) keyType
+                            valueType: (int *) valueType
+                                 size: (int *) size;
+- (void) readMapEnd;
+
+
+- (void) readSetBeginReturningElementType: (int *) elementType
+                                     size: (int *) size;
+- (void) readSetEnd;
+
+
+- (void) readListBeginReturningElementType: (int *) elementType
+                                      size: (int *) size;
+- (void) readListEnd;
+
+
+- (void) writeMessageBeginWithName: (NSString *) name
+                              type: (int) messageType
+                        sequenceID: (int) sequenceID;
+- (void) writeMessageEnd;
+
+- (void) writeStructBeginWithName: (NSString *) name;
+- (void) writeStructEnd;
+
+- (void) writeFieldBeginWithName: (NSString *) name
+                            type: (int) fieldType
+                         fieldID: (int) fieldID;
+
+- (void) writeI32: (int32_t) value;
+
+- (void) writeI64: (int64_t) value;
+
+- (void) writeI16: (short) value;
+
+- (void) writeByte: (uint8_t) value;
+
+- (void) writeString: (NSString *) value;
+
+- (void) writeDouble: (double) value;
+
+- (void) writeBool: (BOOL) value;
+
+- (void) writeBinary: (NSData *) data;
+
+- (void) writeFieldStop;
+
+- (void) writeFieldEnd;
+
+- (void) writeMapBeginWithKeyType: (int) keyType
+                        valueType: (int) valueType
+                             size: (int) size;
+- (void) writeMapEnd;
+
+
+- (void) writeSetBeginWithElementType: (int) elementType
+                                 size: (int) size;
+- (void) writeSetEnd;
+
+
+- (void) writeListBeginWithElementType: (int) elementType
+                                  size: (int) size;
+
+- (void) writeListEnd;
+
+
+@end
+
diff --git a/lib/cocoa/src/protocol/TProtocolException.h b/lib/cocoa/src/protocol/TProtocolException.h
new file mode 100644
index 0000000..ad354fc
--- /dev/null
+++ b/lib/cocoa/src/protocol/TProtocolException.h
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "TException.h"
+
+@interface TProtocolException : TException {
+}
+
+@end
diff --git a/lib/cocoa/src/protocol/TProtocolException.m b/lib/cocoa/src/protocol/TProtocolException.m
new file mode 100644
index 0000000..681487a
--- /dev/null
+++ b/lib/cocoa/src/protocol/TProtocolException.m
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "TProtocolException.h"
+
+@implementation TProtocolException
+@end
diff --git a/lib/cocoa/src/protocol/TProtocolFactory.h b/lib/cocoa/src/protocol/TProtocolFactory.h
new file mode 100644
index 0000000..2d125e9
--- /dev/null
+++ b/lib/cocoa/src/protocol/TProtocolFactory.h
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "TProtocol.h"
+#import "TTransport.h"
+
+
+@protocol TProtocolFactory <NSObject>
+
+- (id <TProtocol>) newProtocolOnTransport: (id <TTransport>) transport;
+
+@end
diff --git a/lib/cocoa/src/protocol/TProtocolUtil.h b/lib/cocoa/src/protocol/TProtocolUtil.h
new file mode 100644
index 0000000..c2d2521
--- /dev/null
+++ b/lib/cocoa/src/protocol/TProtocolUtil.h
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "TProtocol.h"
+#import "TTransport.h"
+
+@interface TProtocolUtil : NSObject {
+
+}
+
++ (void) skipType: (int) type onProtocol: (id <TProtocol>) protocol;
+
+@end;
diff --git a/lib/cocoa/src/protocol/TProtocolUtil.m b/lib/cocoa/src/protocol/TProtocolUtil.m
new file mode 100644
index 0000000..13d7095
--- /dev/null
+++ b/lib/cocoa/src/protocol/TProtocolUtil.m
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import "TProtocolUtil.h"
+
+@implementation TProtocolUtil
+
++ (void) skipType: (int) type onProtocol: (id <TProtocol>) protocol
+{
+  switch (type) {
+  case TType_BOOL:
+    [protocol readBool];
+    break;
+  case TType_BYTE:
+    [protocol readByte];
+    break;
+  case TType_I16:
+    [protocol readI16];
+    break;
+  case TType_I32:
+    [protocol readI32];
+    break;
+  case TType_I64:
+    [protocol readI64];
+    break;
+  case TType_DOUBLE:
+    [protocol readDouble];
+    break;
+  case TType_STRING:
+    [protocol readString];
+    break;
+  case TType_STRUCT:
+    [protocol readStructBeginReturningName: NULL];
+    while (true) {
+      int fieldType;
+      [protocol readFieldBeginReturningName: nil type: &fieldType fieldID: nil];
+      if (fieldType == TType_STOP) {
+        break;
+      }
+      [TProtocolUtil skipType: fieldType onProtocol: protocol];
+      [protocol readFieldEnd];
+    }
+    [protocol readStructEnd];
+    break;
+  case TType_MAP:
+  {
+    int keyType;
+    int valueType;
+    int size;
+    [protocol readMapBeginReturningKeyType: &keyType valueType: &valueType size: &size];
+    int i;
+    for (i = 0; i < size; i++) {
+      [TProtocolUtil skipType: keyType onProtocol: protocol];
+      [TProtocolUtil skipType: valueType onProtocol: protocol];
+    }
+    [protocol readMapEnd];
+  }
+    break;
+    case TType_SET:
+    {
+      int elemType;
+      int size;
+      [protocol readSetBeginReturningElementType: &elemType size: &size];
+      int i;
+      for (i = 0; i < size; i++) {
+        [TProtocolUtil skipType: elemType onProtocol: protocol];
+      }
+      [protocol readSetEnd];
+    }
+      break;
+    case TType_LIST:
+    {
+      int elemType;
+      int size;
+      [protocol readListBeginReturningElementType: &elemType size: &size];
+      int i;
+      for (i = 0; i < size; i++) {
+        [TProtocolUtil skipType: elemType onProtocol: protocol];
+      }
+      [protocol readListEnd];
+    }
+      break;
+    default:
+      return;
+  }
+}
+
+@end