checkin for GSS import name
[gssweb.git] / json_gssapi / src / datamodel / GSSBuffer.cpp
diff --git a/json_gssapi/src/datamodel/GSSBuffer.cpp b/json_gssapi/src/datamodel/GSSBuffer.cpp
new file mode 100644 (file)
index 0000000..e00c650
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2014 <copyright holder> <email>
+ * 
+ * For license details, see the LICENSE file in the root of this project.
+ * 
+ */
+
+#include <stdexcept>
+#include <cstring>
+#include "GSSBuffer.h"
+#include "../GSSException.h"
+
+
+/* Constructor pattern:
+ * 1) Set gssInternal to false, so that setting values is permitted.
+ * 2) Allocate memory for a new gss_buffer_desc
+ * 3) Set the buffer length to 0, so that setting values doesn't try
+ *    to free memory.
+ * 4) Set the value of the buffer.
+ * 5) Set the value of gssInternal correctly
+ */
+GSSBuffer::GSSBuffer ( const GSSBuffer &other )
+{
+  gss_buffer_t otherBuf = other.buf;
+  initEmpty();
+  setValue( (char *)(otherBuf->value), otherBuf->length);
+  this->gssInternal = false;
+}
+
+GSSBuffer::GSSBuffer(std::string str, bool gssInternal)
+{
+  initEmpty();
+  setValue(str);
+  this->gssInternal = gssInternal;
+}
+
+GSSBuffer::GSSBuffer(char *str, bool gssInternal)
+{
+  initEmpty();
+  setValue(str);
+  this->gssInternal = gssInternal;
+}
+
+GSSBuffer::GSSBuffer(char *str, int len, bool gssInternal)
+{
+  initEmpty();
+  setValue(str, len);
+  this->gssInternal = gssInternal;
+}
+
+GSSBuffer::GSSBuffer(gss_buffer_t gssbuf, bool gssInternal)
+{
+  initEmpty();
+  setValue(gssbuf);
+  this->gssInternal = gssInternal;
+}
+
+GSSBuffer::~GSSBuffer(void)
+{
+  OM_uint32 major, minor;
+
+  if (this->gssInternal) 
+  {
+    major = gss_release_buffer(&minor, buf);
+    if (GSS_ERROR(major))
+    {
+      throw GSSException("Error in releasing a buffer allocated by GSS", major, minor);
+    }
+  } else {
+    freeBufValue();
+  }
+}
+
+
+void GSSBuffer::initEmpty()
+{
+  this->gssInternal = false;
+  this->buf = new gss_buffer_desc;
+  this->buf->length = 0;
+  this->buf->value = NULL;
+}
+
+void GSSBuffer::freeBufValue()
+{
+  if (this->buf->length == 0 && this->buf->value != NULL)
+    delete[] ( (char *)(this->buf->value) );
+  this->buf->length = 0;
+  this->buf->value = NULL;
+}
+
+
+/* setValue pattern:
+ * 1) Throw an exception when attempting to mutate a buffer supplied by 
+ *    GSS itself. 
+ * 2) Free the GSS buffer value, if needed.
+ * 3) Set the buffer value as needed.
+ */
+void GSSBuffer::setValue(std::string str)
+{
+  setValue((char *)str.c_str(), str.size());
+}
+
+void GSSBuffer::setValue(char *str)
+{
+  setValue(str, std::strlen(str));
+}
+
+void GSSBuffer::setValue(char *str, int len)
+{
+  /* Variables */
+  /* Error checking */
+  if (this->gssInternal)
+    throw std::logic_error("Attempting to modify an immutable GSSBuffer");
+  
+  /* Setup */
+  freeBufValue();
+  
+  /* Main */
+  this->buf->value = new char[len];
+  std::memcpy( (void *)(this->buf->value), (void *)str, len);
+  this->buf->length = len;
+  
+  /* Cleanup */
+  /* Return */
+}
+
+void GSSBuffer::setValue(gss_buffer_t gssbuf)
+{
+  if (this->gssInternal)
+    throw std::logic_error("Attempting to modify an immutable GSSBuffer");
+  freeBufValue();
+  delete buf;
+  this->buf = gssbuf;
+}