public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Re-implement ArrayBytes et.al. using templates, lots of templates.
@ 2008-05-25 17:48 cagney
  0 siblings, 0 replies; only message in thread
From: cagney @ 2008-05-25 17:48 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  3e3394b67b6c1dcb5bce4216bedc5f363d287263 (commit)
      from  377ab0df202e7d02f4687a312abf76b0a16ee1e9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 3e3394b67b6c1dcb5bce4216bedc5f363d287263
Author: Andrew Cagney <cagney@redhat.com>
Date:   Sun May 25 13:47:12 2008 -0400

    Re-implement ArrayBytes et.al. using templates, lots of templates.
    
    frysk-sys/jnixx/ChangeLog
    2008-05-25  Andrew Cagney  <cagney@redhat.com>
    
    	* JniBindings.java: Generate GetArrayElements and
    	ReleaesArrayElements as aliases for Get<primitive>ArrayElements
    	et.al.
    	* elements.hxx (Elements<type>): Re-implement Bytes using a
    	template; typedef Bytes as Elements<jbyte>
    	(FileElements<type>): Ditto for FileBytes.
    	(ArrayElements<type,types>): Ditto for ArrayBytes.
    	(slurp): New.
    	* elements.cxx: Update.

-----------------------------------------------------------------------

Summary of changes:
 frysk-sys/frysk/sys/jni/FileDescriptor.cxx |    4 +-
 frysk-sys/jnixx/ChangeLog                  |   12 ++
 frysk-sys/jnixx/JniBindings.java           |   21 +++
 frysk-sys/jnixx/elements.cxx               |   90 +++----------
 frysk-sys/jnixx/elements.hxx               |  203 ++++++++++++++++++++--------
 5 files changed, 199 insertions(+), 131 deletions(-)

First 500 lines of diff:
diff --git a/frysk-sys/frysk/sys/jni/FileDescriptor.cxx b/frysk-sys/frysk/sys/jni/FileDescriptor.cxx
index 4340d36..0c33fd4 100644
--- a/frysk-sys/frysk/sys/jni/FileDescriptor.cxx
+++ b/frysk-sys/frysk/sys/jni/FileDescriptor.cxx
@@ -153,7 +153,9 @@ FileDescriptor::read(jnixx::env env, jint fd,
 		     jint off, jint len) {
   verifyBounds(env, bytes, off, len);
   ArrayBytes b = ArrayBytes(env, bytes);
-  return doRead(env, fd, b.elements() + off, len);
+  jint ok = doRead(env, fd, b.elements() + off, len);
+  b.release();
+  return ok;
 }
 
 jint
diff --git a/frysk-sys/jnixx/ChangeLog b/frysk-sys/jnixx/ChangeLog
index f4ccd89..d59e3b2 100644
--- a/frysk-sys/jnixx/ChangeLog
+++ b/frysk-sys/jnixx/ChangeLog
@@ -1,3 +1,15 @@
+2008-05-25  Andrew Cagney  <cagney@redhat.com>
+
+	* JniBindings.java: Generate GetArrayElements and
+	ReleaesArrayElements as aliases for Get<primitive>ArrayElements
+	et.al.
+	* elements.hxx (Elements<type>): Re-implement Bytes using a
+	template; typedef Bytes as Elements<jbyte>
+	(FileElements<type>): Ditto for FileBytes.
+	(ArrayElements<type,types>): Ditto for ArrayBytes.
+	(slurp): New.
+	* elements.cxx: Update.
+	
 2008-05-24  Andrew Cagney  <cagney@redhat.com>
 
 	* jnixx.hxx: Fully qualify all JNI types.
diff --git a/frysk-sys/jnixx/JniBindings.java b/frysk-sys/jnixx/JniBindings.java
index 3d15f36..3b517d6 100644
--- a/frysk-sys/jnixx/JniBindings.java
+++ b/frysk-sys/jnixx/JniBindings.java
@@ -412,6 +412,16 @@ class JniBindings {
 			 "return env.Get" + Type + "ArrayElements((::" + type + "Array) _object, isCopy);"
 		     })
 		.put(types[i], Binding.DYNAMIC,
+		     type + "*", "GetArrayElements",
+		     new String[] {
+			 "::jnixx::env", "env",
+			 "jboolean*", "isCopy",
+		     },
+		     null,
+		     new Object[] {
+			 "return Get" + Type + "ArrayElements(env, isCopy);",
+		     })
+		.put(types[i], Binding.DYNAMIC,
 		     null, "Release" + Type +"ArrayElements",
 		     new String[] {
 			 "::jnixx::env", "env",
@@ -423,6 +433,17 @@ class JniBindings {
 			 "env.Release" + Type + "ArrayElements((::" + type + "Array)_object, elements, mode);",
 		     })
 		.put(types[i], Binding.DYNAMIC,
+		     null, "ReleaseArrayElements",
+		     new String[] {
+			 "::jnixx::env", "env",
+			 type + "*", "elements",
+			 "jint", "mode"
+		     },
+		     null,
+		     new Object[] {
+			 "Release" + Type + "ArrayElements(env, elements, mode);",
+		     })
+		.put(types[i], Binding.DYNAMIC,
 		     "void", "Get" + Type + "ArrayRegion",
 		     new String[] {
 			 "::jnixx::env", "env",
diff --git a/frysk-sys/jnixx/elements.cxx b/frysk-sys/jnixx/elements.cxx
index dd15213..53ff5d6 100644
--- a/frysk-sys/jnixx/elements.cxx
+++ b/frysk-sys/jnixx/elements.cxx
@@ -103,47 +103,7 @@ chars2strings(::jnixx::env env, char** argv) {
 }
 
 void
-FileBytes::operator=(const FileBytes& src) {
-  release();
-  ::strcpy(this->file, src.file);
-  this->env = src.env;
-  // Don't copy the pointer.
-}
-
-FileBytes::FileBytes(jnixx::env env, const char* fmt, ...) {
-  va_list ap;
-  va_start(ap, fmt);
-  if (::vsnprintf(file, sizeof file, fmt, ap)
-      >= (int) sizeof file) {
-    errnoException(env, errno, "vsnprintf");
-  }
-  va_end(ap);
-  this->env = env;
-}
-
-FileBytes::FileBytes(jnixx::env env, int pid, const char* name) {
-  // Convert the string into a file.
-  if (::snprintf(file, sizeof file, "/proc/%d/%s", pid, name)
-      >= (int) sizeof file) {
-    errnoException(env, errno, "snprintf");
-  }
-  this->env = env;
-}
-
-FileBytes::FileBytes(jnixx::env env, int pid, int tid, const char* name) {
-  // Convert the string into a file.
-  if (::snprintf(file, sizeof file, "/proc/%d/task/%d/%s", pid, tid, name)
-      >= (int) sizeof file) {
-    errnoException(env, errno, "snprintf");
-  }
-  this->env = env;
-}
-
-jsize
-FileBytes::length() {
-  if (l >= 0)
-    return l;
-
+slurp(jnixx::env env, const char file[], jbyte*& buf, jsize& len) {
   // Attempt to open the file.
   int fd = ::open(file, O_RDONLY);
   if (fd < 0) {
@@ -157,63 +117,49 @@ FileBytes::length() {
   // reads are needed to confirm EOF.  Allocating 2&BUFSIZE ensures
   // that there's always space for at least two reads.  Ref SW #3370
   jsize allocated = BUFSIZ * 2 + 1;
-  p = (jbyte*) ::malloc(allocated);
-  if (p == NULL) {
+  buf = (jbyte*) ::malloc(allocated);
+  if (buf == NULL) {
     errnoException(env, errno, "malloc");
   }
 
-  l = 0;
+  len = 0;
   while (true) {
     // Attempt to fill the remaining buffer; less space for a
     // terminating NUL character.
-    int size = ::read(fd, p + l, allocated - l - 1);
+    int size = ::read(fd, buf + len, allocated - len - 1);
     if (size < 0) {
       ::close(fd);
-      release();
+      ::free(buf);
       // Abandon the read with elements == NULL.
-      p = NULL;
-      l = 0;
-      return 0;
+      buf = NULL;
+      len = 0;
+      return;
     } else if (size == 0) {
       break;
     }
-    l += size;
+    len += size;
 
-    if (l + BUFSIZ >= allocated) {
+    if (len + BUFSIZ >= allocated) {
       // Not enough space for the next ~BUFSIZ'd read; expand the
       // buffer.  Don't trust realloc with the pointer; will need to
       // free the old buffer if something goes wrong.
       allocated += BUFSIZ;
-      jbyte *tmp = (jbyte*)::realloc(p, allocated);
+      jbyte *tmp = (jbyte*)::realloc(buf, allocated);
       if (tmp == NULL) {
 	int err = errno;
 	::close(fd);
-	release();
+	::free(buf);
+	buf = NULL;
+	len = 0;
 	errnoException(env, err, "realloc");
       }
-      p = tmp;
+      buf = tmp;
     }
   }
 
   ::close(fd);
 
   // Null terminate the buffer.
-  p[l] = '\0';
-  l++; // count the trailing NUL
-  return l;
-}
-
-jbyte*
-FileBytes::elements() {
-  length();
-  return p;
-}
-
-void
-FileBytes::release() {
-  if (p != NULL) {
-    ::free(p);
-    p = NULL;
-  }
-  l = -1;
+  buf[len] = '\0';
+  len++; // count the trailing NUL
 }
diff --git a/frysk-sys/jnixx/elements.hxx b/frysk-sys/jnixx/elements.hxx
index 5bcae8d..bafbb51 100644
--- a/frysk-sys/jnixx/elements.hxx
+++ b/frysk-sys/jnixx/elements.hxx
@@ -37,9 +37,19 @@
 // version and license this file solely under the GPL without
 // exception.
 
-extern char** strings2chars(::jnixx::env, ::jnixx::array<java::lang::String>);
+#ifndef elements_hxx
+#define elements_hxx
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <jnixx/exceptions.hxx>
 
+extern char** strings2chars(::jnixx::env, ::jnixx::array<java::lang::String>);
 extern ::jnixx::array<java::lang::String> chars2strings(::jnixx::env, char**);
+extern void slurp(::jnixx::env, const char[], jbyte* (&), jsize&);
 
 class StringChars {
 private:
@@ -126,85 +136,162 @@ public:
   }
 };
 
-class Bytes {
-protected:
+/**
+ * A buffer of primitive types that is automatically re-claimed when
+ * the function returns, or an exception is thrown.
+ */
+template <typename type> class Elements {
+private:
   jnixx::env env;
-  jbyte* p;
-  jsize l;
-  Bytes() {
-    p = NULL;
-    l = -1;
+  type* buf;
+  jsize len;
+protected:
+  Elements() {
+    buf = NULL;
+    // Use len<0 as a marker to indicate that the buffer hasn't been
+    // read / extracted / converted.
+    len = -1;
+  }
+  Elements(jnixx::env env) {
+    this->env = env;
+    this->len = -1;
+    this->buf = NULL;
+  }
+  void copy(const Elements& old) {
+    release();
+    this->env = old.env;
+    this->len = -1;
+    this->buf = NULL;
+  }
+  virtual ~Elements() {
   }
-  virtual ~Bytes() {
+  virtual void slurp(jnixx::env& env, type* (&buf), jsize &len) = 0;
+  virtual void free(jnixx::env& env, type* buf, int mode) {
   }
 public:
-  virtual jbyte* elements() = 0;
-  virtual jsize length() = 0;
+  type* elements() {
+    if (len < 0) {
+      slurp(env, buf, len);
+    }
+    return buf;
+  };
+  jsize length() {
+    if (len < 0) {
+      slurp(env, buf, len);
+    }
+    return len;
+  };
+  void release(int mode) {
+    if (len >= 0) {
+      if (buf != NULL) {
+	free(env, buf, mode);
+	buf = NULL;
+      }
+      len = -1;
+    }
+  }
+  void release() {
+    release(0);
+  }
 };
+typedef Elements<jbyte> Bytes;
 
-class FileBytes : public Bytes {
+/**
+ * A scratch buffer containing the file's entire contents; the buffer
+ * is recovered once this goes out of scope.
+ */
+template <typename type> class FileElements : public Elements<type> {
 private:
   char file[FILENAME_MAX];
 public:
-  void operator=(const FileBytes& src);
-  FileBytes(const FileBytes& old) {
-    this->operator=(old);
+  void operator=(const FileElements& src) {
+    copy(src);
+    ::strcpy(this->file, src.file);
+    // Don't copy the pointer.
   }
-  FileBytes(jnixx::env env, const char* fmt, ...)
-  __attribute__((format(printf, 3, 4)));
-  FileBytes(jnixx::env env, int pid, const char* name);
-  FileBytes(jnixx::env env, int pid, int tid, const char* name);
-  jbyte* elements();
-  jsize length();
-  void release();
-  ~FileBytes() {
-    release();
+  FileElements(const FileElements& src) {
+    this->operator=(src);
+  }
+  FileElements(jnixx::env env, const char* fmt, ...)
+  __attribute__((format(printf, 3, 4))) : Elements<type>(env) {
+    va_list ap;
+    va_start(ap, fmt);
+    if (::vsnprintf(file, sizeof file, fmt, ap)
+	>= (int) sizeof file) {
+      errnoException(env, errno, "vsnprintf");
+    }
+    va_end(ap);
+  }
+  FileElements(jnixx::env env, int pid, const char* name)
+    : Elements<type>(env) {
+    // Convert the string into a file.
+    if (::snprintf(file, sizeof file, "/proc/%d/%s", pid, name)
+	>= (int) sizeof file) {
+      errnoException(env, errno, "snprintf");
+    }
+  }
+  FileElements(jnixx::env env, int pid, int tid, const char* name)
+    : Elements<type>(env) {
+    // Convert the string into a file.
+    if (::snprintf(file, sizeof file, "/proc/%d/task/%d/%s", pid, tid, name)
+	>= (int) sizeof file) {
+      errnoException(env, errno, "snprintf");
+    }
+  }
+  ~FileElements() {
+    this->release();
+  }
+protected:
+  void slurp(jnixx::env& env, type* (&buf), jsize &len) {
+    jbyte* buffer;
+    jsize length;
+    ::slurp(env, file, buffer, length);
+    buf = (type*)buffer;
+    len = length / sizeof(type);
+  }
+  void free(jnixx::env& env, type* buf, int mode) {
+    delete buf;
   }
 };
+typedef FileElements<jbyte> FileBytes;
 
-class ArrayBytes : public Bytes {
+/**
+ * Provide access to a java primitive type array's elements.
+ */
+template <typename type, typename typeArray> class ArrayElements
+  : public Elements<type> {
 private:
-  ::jnixx::jbyteArray bytes;
+  typeArray types;
 public:
-  void operator=(const ArrayBytes& src) {
-    release();
-    this->env = src.env;
-    this->bytes = src.bytes;
-    // don't copy the pointer.
+  void operator=(const ArrayElements& src) {
+    this->copy(src);
+    this->types = src.types;
   }
-  ArrayBytes() {
+  ArrayElements() {
   }
-  ArrayBytes(const ArrayBytes& old) {
+  ArrayElements(const ArrayElements& old) {
     this->operator=(old);
   }
-  ArrayBytes(::jnixx::env env, ::jnixx::jbyteArray bytes) {
-    this->bytes = bytes;
-    this->env = env;
+  ArrayElements(::jnixx::env env, typeArray types) : Elements<type>(env) {
+    this->types = types;
   }
-  jbyte* elements() {
-    length();
-    return p;
-  }
-  jsize length() {
-    if (l < 0) {
-      if (bytes != NULL) {
-	this->l = bytes.GetArrayLength(env);
-	this->p = bytes.GetByteArrayElements(env, NULL);
-      } else {
-	this->l = 0;
-	this->p = NULL;
-      }
-    }
-    return l;
+  ~ArrayElements() {
+    this->release();
   }
-  void release() {
-    if (p != NULL) {
-      bytes.ReleaseByteArrayElements(env, p, 0);
-      p = NULL;
+protected:
+  void slurp(jnixx::env& env, type* (&buf), jsize &len) {
+    if (types != NULL) {
+      len = types.GetArrayLength(env);
+      buf = types.GetArrayElements(env, NULL);
+    } else {
+      len = 0;
+      buf = NULL;
     }
-    l = -1;
   }
-  ~ArrayBytes() {
-    release();
+  void free(jnixx::env& env, type* buf, int mode) {
+    types.ReleaseArrayElements(env, buf, mode);
   }
 };
+typedef ArrayElements<jbyte,::jnixx::jbyteArray> ArrayBytes;
+
+#endif


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-25 17:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-25 17:48 [SCM] master: Re-implement ArrayBytes et.al. using templates, lots of templates cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).