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).