Adds a modified copy of talk/base to webrtc/base. It is the first step in migrating talk/base to webrtc/base.

BUG=N/A
R=andrew@webrtc.org, wu@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/12199004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@6107 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/base/sec_buffer.h b/webrtc/base/sec_buffer.h
new file mode 100644
index 0000000..d4cda00
--- /dev/null
+++ b/webrtc/base/sec_buffer.h
@@ -0,0 +1,156 @@
+/*
+ *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+// @file Contains utility classes that make it easier to use SecBuffers
+
+#ifndef WEBRTC_BASE_SEC_BUFFER_H__
+#define WEBRTC_BASE_SEC_BUFFER_H__
+
+namespace rtc {
+
+// A base class for CSecBuffer<T>. Contains
+// all implementation that does not require
+// template arguments.
+class CSecBufferBase : public SecBuffer {
+ public:
+  CSecBufferBase() {
+    Clear();
+  }
+
+  // Uses the SSPI to free a pointer, must be
+  // used for buffers returned from SSPI APIs.
+  static void FreeSSPI(void *ptr) {
+    if ( ptr ) {
+      SECURITY_STATUS status;
+      status = ::FreeContextBuffer(ptr);
+      ASSERT(SEC_E_OK == status); // "Freeing context buffer"
+    }
+  }
+
+  // Deletes a buffer with operator delete
+  static void FreeDelete(void *ptr) {
+    delete [] reinterpret_cast<char*>(ptr);
+  }
+
+  // A noop delete, for buffers over other
+  // people's memory
+  static void FreeNone(void *ptr) {
+  }
+
+ protected:
+  // Clears the buffer to EMPTY & NULL
+  void Clear() {
+    this->BufferType = SECBUFFER_EMPTY;
+    this->cbBuffer = 0;
+    this->pvBuffer = NULL;
+  }
+};
+
+// Wrapper class for SecBuffer to take care
+// of initialization and destruction.
+template <void (*pfnFreeBuffer)(void *ptr)>
+class CSecBuffer: public CSecBufferBase {
+ public:
+  // Initializes buffer to empty & NULL
+  CSecBuffer() {
+  }
+
+  // Frees any allocated memory
+  ~CSecBuffer() {
+    Release();
+  }
+
+  // Frees the buffer appropriately, and re-nulls
+  void Release() {
+    pfnFreeBuffer(this->pvBuffer);
+    Clear();
+  }
+
+ private:
+  // A placeholder function for compile-time asserts on the class
+  void CompileAsserts() {
+    // never invoked...
+    assert(false); // _T("Notreached")
+
+    // This class must not extend the size of SecBuffer, since
+    // we use arrays of CSecBuffer in CSecBufferBundle below
+    cassert(sizeof(CSecBuffer<SSPIFree> == sizeof(SecBuffer)));
+  }
+};
+
+// Contains all generic implementation for the
+// SecBufferBundle class
+class SecBufferBundleBase {
+ public:
+};
+
+// A template class that bundles a SecBufferDesc with
+// one or more SecBuffers for convenience. Can take
+// care of deallocating buffers appropriately, as indicated
+// by pfnFreeBuffer function.
+// By default does no deallocation.
+template <int num_buffers,
+          void (*pfnFreeBuffer)(void *ptr) = CSecBufferBase::FreeNone>
+class CSecBufferBundle : public SecBufferBundleBase {
+ public:
+  // Constructs a security buffer bundle with num_buffers
+  // buffers, all of which are empty and nulled.
+  CSecBufferBundle() {
+    desc_.ulVersion = SECBUFFER_VERSION;
+    desc_.cBuffers = num_buffers;
+    desc_.pBuffers = buffers_;
+  }
+
+  // Frees all currently used buffers.
+  ~CSecBufferBundle() {
+    Release();
+  }
+
+  // Accessor for the descriptor
+  PSecBufferDesc desc() {
+    return &desc_;
+  }
+
+  // Accessor for the descriptor
+  const PSecBufferDesc desc() const {
+    return &desc_;
+  }
+
+  // returns the i-th security buffer
+  SecBuffer &operator[] (size_t num) {
+    ASSERT(num < num_buffers); // "Buffer index out of bounds"
+    return buffers_[num];
+  }
+
+  // returns the i-th security buffer
+  const SecBuffer &operator[] (size_t num) const {
+    ASSERT(num < num_buffers); // "Buffer index out of bounds"
+    return buffers_[num];
+  }
+
+  // Frees all non-NULL security buffers,
+  // using the deallocation function
+  void Release() {
+    for ( size_t i = 0; i < num_buffers; ++i ) {
+      buffers_[i].Release();
+    }
+  }
+
+ private:
+  // Our descriptor
+  SecBufferDesc               desc_;
+  // Our bundled buffers, each takes care of its own
+  // initialization and destruction
+  CSecBuffer<pfnFreeBuffer>   buffers_[num_buffers];
+};
+
+} // namespace rtc
+
+#endif  // WEBRTC_BASE_SEC_BUFFER_H__