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/transport/THTTPClient.h b/lib/cocoa/src/transport/THTTPClient.h
new file mode 100644
index 0000000..86f3f05
--- /dev/null
+++ b/lib/cocoa/src/transport/THTTPClient.h
@@ -0,0 +1,42 @@
+/*
+ * 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"
+
+@interface THTTPClient : NSObject <TTransport> {
+  NSURL * mURL;
+  NSMutableURLRequest * mRequest;
+  NSMutableData * mRequestData;
+  NSData * mResponseData;
+  int mResponseDataOffset;
+  NSString * mUserAgent;
+  int mTimeout;
+}
+
+- (id) initWithURL: (NSURL *) aURL;
+
+- (id) initWithURL: (NSURL *) aURL
+         userAgent: (NSString *) userAgent
+           timeout: (int) timeout;
+
+- (void) setURL: (NSURL *) aURL;
+
+@end
+
diff --git a/lib/cocoa/src/transport/THTTPClient.m b/lib/cocoa/src/transport/THTTPClient.m
new file mode 100644
index 0000000..6391bea
--- /dev/null
+++ b/lib/cocoa/src/transport/THTTPClient.m
@@ -0,0 +1,159 @@
+/*
+ * 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 "THTTPClient.h"
+#import "TTransportException.h"
+
+@implementation THTTPClient
+
+
+- (void) setupRequest
+{
+  if (mRequest != nil) {
+    [mRequest release];
+  }
+
+  // set up our request object that we'll use for each request
+  mRequest = [[NSMutableURLRequest alloc] initWithURL: mURL];
+  [mRequest setHTTPMethod: @"POST"];
+  [mRequest setValue: @"application/x-thrift" forHTTPHeaderField: @"Content-Type"];
+  [mRequest setValue: @"application/x-thrift" forHTTPHeaderField: @"Accept"];
+
+  NSString * userAgent = mUserAgent;
+  if (!userAgent) {
+    userAgent = @"Cocoa/THTTPClient";
+  }
+  [mRequest setValue: userAgent forHTTPHeaderField: @"User-Agent"];
+
+  [mRequest setCachePolicy: NSURLRequestReloadIgnoringCacheData];
+  if (mTimeout) {
+    [mRequest setTimeoutInterval: mTimeout];
+  }
+}
+
+
+- (id) initWithURL: (NSURL *) aURL
+{
+  return [self initWithURL: aURL
+                 userAgent: nil
+                   timeout: 0];
+}
+
+
+- (id) initWithURL: (NSURL *) aURL
+         userAgent: (NSString *) userAgent
+           timeout: (int) timeout
+{
+  self = [super init];
+  if (!self) {
+    return nil;
+  }
+
+  mTimeout = timeout;
+  if (userAgent) {
+    mUserAgent = [userAgent retain];
+  }
+  mURL = [aURL retain];
+
+  [self setupRequest];
+
+  // create our request data buffer
+  mRequestData = [[NSMutableData alloc] initWithCapacity: 1024];
+
+  return self;
+}
+
+
+- (void) setURL: (NSURL *) aURL
+{
+  [aURL retain];
+  [mURL release];
+  mURL = aURL;
+
+  [self setupRequest];
+}
+
+
+- (void) dealloc
+{
+  [mURL release];
+  [mUserAgent release];
+  [mRequest release];
+  [mRequestData release];
+  [mResponseData release];
+  [super dealloc];
+}
+
+
+- (int) readAll: (uint8_t *) buf offset: (int) off length: (int) len
+{
+  NSRange r;
+  r.location = mResponseDataOffset;
+  r.length = len;
+
+  [mResponseData getBytes: buf+off range: r];
+  mResponseDataOffset += len;
+
+  return len;
+}
+
+
+- (void) write: (const uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
+{
+  [mRequestData appendBytes: data+offset length: length];
+}
+
+
+- (void) flush
+{
+  [mRequest setHTTPBody: mRequestData]; // not sure if it copies the data
+
+  // make the HTTP request
+  NSURLResponse * response;
+  NSError * error;
+  NSData * responseData =
+    [NSURLConnection sendSynchronousRequest: mRequest returningResponse: &response error: &error];
+
+  [mRequestData setLength: 0];
+
+  if (responseData == nil) {
+    @throw [TTransportException exceptionWithName: @"TTransportException"
+                                reason: @"Could not make HTTP request"
+                                error: error];
+  }
+  if (![response isKindOfClass: [NSHTTPURLResponse class]]) {
+    @throw [TTransportException exceptionWithName: @"TTransportException"
+                                           reason: @"Unexpected NSURLResponse type"];
+  }
+
+  NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
+  if ([httpResponse statusCode] != 200) {
+    @throw [TTransportException exceptionWithName: @"TTransportException"
+                                           reason: [NSString stringWithFormat: @"Bad response from HTTP server: %d",
+                                                    [httpResponse statusCode]]];
+  }
+
+  // phew!
+  [mResponseData release];
+  mResponseData = [responseData retain];
+  mResponseDataOffset = 0;
+}
+
+
+@end
diff --git a/lib/cocoa/src/transport/TNSFileHandleTransport.h b/lib/cocoa/src/transport/TNSFileHandleTransport.h
new file mode 100644
index 0000000..64a6af3
--- /dev/null
+++ b/lib/cocoa/src/transport/TNSFileHandleTransport.h
@@ -0,0 +1,35 @@
+/*
+ * 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"
+
+@interface TNSFileHandleTransport : NSObject <TTransport> {
+  NSFileHandle * mInputFileHandle;
+  NSFileHandle * mOutputFileHandle;
+}
+
+- (id) initWithFileHandle: (NSFileHandle *) fileHandle;
+
+- (id) initWithInputFileHandle: (NSFileHandle *) inputFileHandle
+              outputFileHandle: (NSFileHandle *) outputFileHandle;
+
+
+@end
diff --git a/lib/cocoa/src/transport/TNSFileHandleTransport.m b/lib/cocoa/src/transport/TNSFileHandleTransport.m
new file mode 100644
index 0000000..1533934
--- /dev/null
+++ b/lib/cocoa/src/transport/TNSFileHandleTransport.m
@@ -0,0 +1,87 @@
+/*
+ * 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 "TNSFileHandleTransport.h"
+#import "TTransportException.h"
+
+
+@implementation TNSFileHandleTransport
+
+- (id) initWithFileHandle: (NSFileHandle *) fileHandle
+{
+  return [self initWithInputFileHandle: fileHandle
+                      outputFileHandle: fileHandle];
+}
+
+
+- (id) initWithInputFileHandle: (NSFileHandle *) inputFileHandle
+              outputFileHandle: (NSFileHandle *) outputFileHandle
+{
+  self = [super init];
+
+  mInputFileHandle = [inputFileHandle retain];
+  mOutputFileHandle = [outputFileHandle retain];
+
+  return self;
+}
+
+
+- (void) dealloc {
+  [mInputFileHandle release];
+  [mOutputFileHandle release];
+  [super dealloc];
+}
+
+
+- (int) readAll: (uint8_t *) buf offset: (int) off length: (int) len
+{
+  int got = 0;
+  while (got < len) {
+    NSData * d = [mInputFileHandle readDataOfLength: len-got];
+    if ([d length] == 0) {
+      @throw [TTransportException exceptionWithName: @"TTransportException"
+                                  reason: @"Cannot read. No more data."];
+    }
+    [d getBytes: buf+got];
+    got += [d length];
+  }
+  return got;
+}
+
+
+- (void) write: (uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
+{
+  NSData * dataObject = [[NSData alloc] initWithBytesNoCopy: data+offset
+                                                     length: length
+                                               freeWhenDone: NO];
+
+  [mOutputFileHandle writeData: dataObject];
+
+
+  [dataObject release];
+}
+
+
+- (void) flush
+{
+
+}
+
+@end
diff --git a/lib/cocoa/src/transport/TNSStreamTransport.h b/lib/cocoa/src/transport/TNSStreamTransport.h
new file mode 100644
index 0000000..295a185
--- /dev/null
+++ b/lib/cocoa/src/transport/TNSStreamTransport.h
@@ -0,0 +1,38 @@
+/*
+ * 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"
+
+@interface TNSStreamTransport : NSObject <TTransport> {
+  NSInputStream * mInput;
+  NSOutputStream * mOutput;
+}
+
+- (id) initWithInputStream: (NSInputStream *) input
+              outputStream: (NSOutputStream *) output;
+
+- (id) initWithInputStream: (NSInputStream *) input;
+
+- (id) initWithOutputStream: (NSOutputStream *) output;
+
+@end
+
+
+
diff --git a/lib/cocoa/src/transport/TNSStreamTransport.m b/lib/cocoa/src/transport/TNSStreamTransport.m
new file mode 100644
index 0000000..52a02e2
--- /dev/null
+++ b/lib/cocoa/src/transport/TNSStreamTransport.m
@@ -0,0 +1,87 @@
+/*
+ * 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 "TNSStreamTransport.h"
+#import "TTransportException.h"
+
+
+@implementation TNSStreamTransport
+
+- (id) initWithInputStream: (NSInputStream *) input
+              outputStream: (NSOutputStream *) output
+{
+  [super init];
+  mInput = [input retain];
+  mOutput = [output retain];
+  return self;
+}
+
+- (id) initWithInputStream: (NSInputStream *) input
+{
+  return [self initWithInputStream: input outputStream: nil];
+}
+
+- (id) initWithOutputStream: (NSOutputStream *) output
+{
+  return [self initWithInputStream: nil outputStream: output];
+}
+
+- (void) dealloc
+{
+  [mInput release];
+  [mOutput release];
+  [super dealloc];
+}
+
+
+- (int) readAll: (uint8_t *) buf offset: (int) off length: (int) len
+{
+  int got = 0;
+  int ret = 0;
+  while (got < len) {
+    ret = [mInput read: buf+off+got maxLength: len-got];
+    if (ret <= 0) {
+      @throw [TTransportException exceptionWithReason: @"Cannot read. Remote side has closed."];
+    }
+    got += ret;
+  }
+  return got;
+}
+
+
+// FIXME:geech:20071019 - make this write all
+- (void) write: (uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length
+{
+  int result = [mOutput write: data+offset maxLength: length];
+  if (result == -1) {
+    @throw [TTransportException exceptionWithReason: @"Error writing to transport output stream."
+                                              error: [mOutput streamError]];
+  } else if (result == 0) {
+    @throw [TTransportException exceptionWithReason: @"End of output stream."];
+  } else if (result != length) {
+    @throw [TTransportException exceptionWithReason: @"Output stream did not write all of our data."];
+  }
+}
+
+- (void) flush
+{
+  // no flush for you!
+}
+
+@end
diff --git a/lib/cocoa/src/transport/TSocketClient.h b/lib/cocoa/src/transport/TSocketClient.h
new file mode 100644
index 0000000..a883acb
--- /dev/null
+++ b/lib/cocoa/src/transport/TSocketClient.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "TNSStreamTransport.h"
+
+@interface TSocketClient : TNSStreamTransport {
+}
+
+- (id) initWithHostname: (NSString *) hostname
+                   port: (int) port;
+
+@end
+
+
+
diff --git a/lib/cocoa/src/transport/TSocketClient.m b/lib/cocoa/src/transport/TSocketClient.m
new file mode 100644
index 0000000..7c07c56
--- /dev/null
+++ b/lib/cocoa/src/transport/TSocketClient.m
@@ -0,0 +1,47 @@
+/*
+ * 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 "TSocketClient.h"
+
+@implementation TSocketClient
+
+- (id) initWithHostname: (NSString *) hostname
+                   port: (int) port
+{
+  NSInputStream * input = nil;
+  NSOutputStream * output = nil;
+
+  [NSStream getStreamsToHost: [NSHost hostWithName: hostname]
+            port: port
+            inputStream: &input
+            outputStream: &output];
+
+  self = [super initWithInputStream: input outputStream: output];
+  [input open];
+  [output open];
+
+  return self;
+}
+
+
+@end
+
+
+
diff --git a/lib/cocoa/src/transport/TTransport.h b/lib/cocoa/src/transport/TTransport.h
new file mode 100644
index 0000000..61ebbd2
--- /dev/null
+++ b/lib/cocoa/src/transport/TTransport.h
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+@protocol TTransport <NSObject>
+
+  /**
+   * Guarantees that all of len bytes are read
+   *
+   * @param buf Buffer to read into
+   * @param off Index in buffer to start storing bytes at
+   * @param len Maximum number of bytes to read
+   * @return The number of bytes actually read, which must be equal to len
+   * @throws TTransportException if there was an error reading data
+   */
+- (int) readAll: (uint8_t *) buf offset: (int) off length: (int) len;
+
+- (void) write: (const uint8_t *) data offset: (unsigned int) offset length: (unsigned int) length;
+
+- (void) flush;
+@end
diff --git a/lib/cocoa/src/transport/TTransportException.h b/lib/cocoa/src/transport/TTransportException.h
new file mode 100644
index 0000000..6749fe2
--- /dev/null
+++ b/lib/cocoa/src/transport/TTransportException.h
@@ -0,0 +1,30 @@
+/*
+ * 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 TTransportException : TException {
+}
+
++ (id) exceptionWithReason: (NSString *) reason
+                     error: (NSError *) error;
+
++ (id) exceptionWithReason: (NSString *) reason;
+
+@end
diff --git a/lib/cocoa/src/transport/TTransportException.m b/lib/cocoa/src/transport/TTransportException.m
new file mode 100644
index 0000000..aa67149
--- /dev/null
+++ b/lib/cocoa/src/transport/TTransportException.m
@@ -0,0 +1,43 @@
+/*
+ * 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 "TTransportException.h"
+
+@implementation TTransportException
+
++ (id) exceptionWithReason: (NSString *) reason
+                     error: (NSError *) error
+{
+  NSDictionary * userInfo = nil;
+  if (error != nil) {
+    userInfo = [NSDictionary dictionaryWithObject: error forKey: @"error"];
+  }
+
+  return [super exceptionWithName: @"TTransportException"
+                           reason: reason
+                         userInfo: userInfo];
+}
+
+
++ (id) exceptionWithReason: (NSString *) reason
+{
+  return [self exceptionWithReason: reason error: nil];
+}
+
+@end