summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-11-15 11:53:58 -0800
committerPixel <pixel@nobis-crew.org>2011-11-15 11:53:58 -0800
commit1a5dacb93f2c3f2cfc8f4a9da6599beaebcc6845 (patch)
treef03f1502575f51c36b94d232384c42e5f2845f74
parent5154e80b61bc5678cd1ce6018fd52b023c4b9079 (diff)
Adding the forceRead/Write methods, to circumvent the potential problem that a file descriptor can do less than being asked.
-rw-r--r--includes/Handle.h6
-rw-r--r--src/Handle.cc50
2 files changed, 54 insertions, 2 deletions
diff --git a/includes/Handle.h b/includes/Handle.h
index 4ac8991..cfb004d 100644
--- a/includes/Handle.h
+++ b/includes/Handle.h
@@ -32,8 +32,8 @@ class Handle {
virtual const char * getName() = 0;
virtual ssize_t read(void * buf, size_t count) throw (GeneralException);
virtual ssize_t write(const void * buf, size_t count) throw (GeneralException);
- void writeString(const char * str, ssize_t len = -1) { if (len < 0) len = strlen(str); write(str, len); }
- void writeString(const String & str) { write(str.to_charp(), str.strlen()); }
+ void writeString(const char * str, ssize_t len = -1) { if (len < 0) len = strlen(str); forceWrite(str, len); }
+ void writeString(const String & str) { forceWrite(str.to_charp(), str.strlen()); }
void seek(off_t offset, int whence = SEEK_SET) { rseek(offset, whence); }
virtual void rseek(off_t offset, int whence = SEEK_SET) throw (GeneralException);
virtual void wseek(off_t offset, int whence = SEEK_SET) throw (GeneralException);
@@ -42,6 +42,8 @@ class Handle {
virtual off_t wtell() throw (GeneralException);
virtual off_t getSize();
virtual time_t getMTime();
+ ssize_t forceRead(void * buf, size_t count) throw (GeneralException);
+ ssize_t forceWrite(const void * buf, size_t count) throw (GeneralException);
protected:
Handle() : m_refCount(0) { }
private:
diff --git a/src/Handle.cc b/src/Handle.cc
index 0ec39be..8fa0417 100644
--- a/src/Handle.cc
+++ b/src/Handle.cc
@@ -83,6 +83,56 @@ ssize_t Balau::Handle::write(const void * buf, size_t count) throw (GeneralExcep
return -1;
}
+ssize_t Balau::Handle::forceRead(void * _buf, size_t count) throw (GeneralException) {
+ ssize_t total;
+ uint8_t * buf = (uint8_t *) _buf;
+ if (!canRead())
+ throw GeneralException("Handle can't read");
+
+ while (count && !isClosed()) {
+ ssize_t r;
+ try {
+ r = read(buf, count);
+ }
+ catch (EAgain e) {
+ Task::yield(e.getEvent());
+ continue;
+ }
+ if (r < 0)
+ return r;
+ total += r;
+ count -= r;
+ buf += r;
+ }
+
+ return total;
+}
+
+ssize_t Balau::Handle::forceWrite(const void * _buf, size_t count) throw (GeneralException) {
+ ssize_t total;
+ const uint8_t * buf = (const uint8_t *) _buf;
+ if (!canWrite())
+ throw GeneralException("Handle can't write");
+
+ while (count && !isClosed()) {
+ ssize_t r;
+ try {
+ r = write(buf, count);
+ }
+ catch (EAgain e) {
+ Task::yield(e.getEvent());
+ continue;
+ }
+ if (r < 0)
+ return r;
+ total += r;
+ count -= r;
+ buf += r;
+ }
+
+ return total;
+}
+
void Balau::Handle::rseek(off_t offset, int whence) throw (GeneralException) {
if (canSeek())
throw GeneralException(String("Handle ") + getName() + " can seek, but rseek() not implemented (missing in class " + ClassName(this).c_str() + ")");