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