changeset 146:c4f841ccb208

Allow the completeness checker to report failure (invalid message) as well as incompleteness
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 19 Jan 2017 09:57:58 +0000
parents 228a66adfb30
children 96488e9e9096
files vamp-client/CapnpRRClient.h vamp-client/ProcessQtTransport.h vamp-client/SynchronousTransport.h
diffstat 3 files changed, 32 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/vamp-client/CapnpRRClient.h	Wed Jan 18 14:53:07 2017 +0000
+++ b/vamp-client/CapnpRRClient.h	Thu Jan 19 09:57:58 2017 +0000
@@ -75,19 +75,38 @@
 
     class CompletenessChecker : public MessageCompletenessChecker {
     public:
-        bool isComplete(const std::vector<char> &message) const override {
+        State check(const std::vector<char> &message) const override {
+
             auto karr = toKJArray(message);
             size_t words = karr.size();
             size_t expected = capnp::expectedSizeInWordsFromPrefix(karr);
+
+            // Lacking a way to definitively check whether a message
+            // is valid or not, we would still like to trap obvious
+            // cases where a programming mistake results in garbage
+            // being returned from the server. We impose a limit on
+            // message size and, if a prefix is projected to exceed
+            // that limit, call it invalid. If an extractor wants to
+            // return a feature set greater than a gigaword in size,
+            // it'll just have to do it across multiple process calls.
+            size_t limit = size_t(1) << 30;
+            
 //            cerr << "CompletenessChecker: message.size() = " << message.size()
-//                 << ", words = " << words << ", expected = " << expected << endl;
+//                 << ", words = " << words << ", limit = " << limit << ", expected = " << expected << endl;
+
             if (words > expected) {
                 std::cerr << "WARNING: obtained more data than expected ("
                           << words << " " << sizeof(capnp::word)
                           << "-byte words, expected "
                           << expected << ")" << std::endl;
+                return Complete;
+            } else if (words == expected) {
+                return Complete;
+            } else if (expected > limit) {
+                return Invalid;
+            } else {
+                return Incomplete;
             }
-            return words >= expected;
         }
     };
     
--- a/vamp-client/ProcessQtTransport.h	Wed Jan 18 14:53:07 2017 +0000
+++ b/vamp-client/ProcessQtTransport.h	Thu Jan 19 09:57:58 2017 +0000
@@ -187,7 +187,13 @@
                 size_t formerSize = buffer.size();
                 buffer.resize(formerSize + byteCount);
                 m_process->read(buffer.data() + formerSize, byteCount);
-                complete = m_completenessChecker->isComplete(buffer);
+                switch (m_completenessChecker->check(buffer)) {
+                case MessageCompletenessChecker::Complete: complete = true; break;
+                case MessageCompletenessChecker::Incomplete: break;
+                case MessageCompletenessChecker::Invalid:
+                    throw std::runtime_error
+                        ("Invalid message received: corrupt stream from server?");
+                }
             }
         }
 
--- a/vamp-client/SynchronousTransport.h	Wed Jan 18 14:53:07 2017 +0000
+++ b/vamp-client/SynchronousTransport.h	Thu Jan 19 09:57:58 2017 +0000
@@ -46,8 +46,10 @@
 class MessageCompletenessChecker // interface
 {
 public:
+    enum State { Complete, Incomplete, Invalid };
+
     virtual ~MessageCompletenessChecker() = default;
-    virtual bool isComplete(const std::vector<char> &message) const = 0;
+    virtual State check(const std::vector<char> &message) const = 0;
 };
 
 class ServerCrashed : public std::runtime_error