public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
From: cagney@sourceware.org
To: frysk-cvs@sourceware.org
Subject: [SCM]  master: Re-implement ArrayBytes et.al. using templates, lots of templates.
Date: Sun, 25 May 2008 17:48:00 -0000	[thread overview]
Message-ID: <20080525174813.16353.qmail@sourceware.org> (raw)

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


                 reply	other threads:[~2008-05-25 17:48 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080525174813.16353.qmail@sourceware.org \
    --to=cagney@sourceware.org \
    --cc=frysk-cvs@sourceware.org \
    --cc=frysk@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).