Billy Barrow 1 год назад
Родитель
Сommit
93bf11f0d3

+ 16 - 0
src/lib/Concrete/BinaryData.vala

@@ -274,6 +274,22 @@ namespace Invercargill {
             return new BinaryData.from_enumerable(skip(start).take(end-start));
         }
 
+        public bool read_in(Bytes? data, ref size_t amount) throws Error {
+            if(data == null) {
+                return true;
+            }
+            if(data.length == 0) {
+                throw new BinaryDataReadError.EMPTY_READ("Encounterd zero-length data object");
+            }
+            if(amount > data.length) {
+                throw new BinaryDataReadError.BUFFER_OVERFLOW("Encountered more data than requested");
+            }
+
+            append_bytes(data);
+            amount -= data.length;
+            return amount != 0;
+        }
+
     }
 
 }

+ 26 - 0
src/lib/Enumerable.vala

@@ -181,6 +181,32 @@ namespace Invercargill {
             return null;
         }
 
+        public virtual T last(owned PredicateDelegate<T>? predicate = null) throws SequenceError {
+            var tracker = predicate == null ? get_tracker() : where((owned)predicate).get_tracker();
+            if(!tracker.has_next()) {
+                throw new SequenceError.NO_ELEMENTS("The sequence contains no elements");
+            }
+            while(true) {
+                T item = tracker.get_next();
+                if(!tracker.has_next()) {
+                    return item;
+                }
+            }
+        }
+
+        public virtual T? last_or_default(owned PredicateDelegate<T>? predicate = null) {
+            var tracker = predicate == null ? get_tracker() : where((owned)predicate).get_tracker();
+            if(!tracker.has_next()) {
+                return null;
+            }
+            while(true) {
+                T item = tracker.get_next();
+                if(!tracker.has_next()) {
+                    return item;
+                }
+            }
+        }
+
         public virtual T single(owned PredicateDelegate<T>? predicate = null) throws SequenceError {
             var tracker = predicate == null ? get_tracker() : where((owned)predicate).get_tracker();
             if(tracker.has_next()) {

+ 5 - 0
src/lib/SequenceError.vala → src/lib/Errors.vala

@@ -4,4 +4,9 @@ namespace Invercargill {
         MULTUPLE_ELEMENTS,
         INVALID_TYPE
     }
+
+    public errordomain BinaryDataReadError {
+        EMPTY_READ,
+        BUFFER_OVERFLOW,
+    }
 }

+ 1 - 1
src/lib/meson.build

@@ -11,7 +11,7 @@ sources += files('Enumerable.vala')
 sources += files('Delegates.vala')
 sources += files('Pair.vala')
 sources += files('Tracker.vala')
-sources += files('SequenceError.vala')
+sources += files('Errors.vala')
 sources += files('SelectionContext.vala')
 
 sources += files('Queries/Query.vala')

+ 0 - 1
src/tests/Integration/BinaryData.vala

@@ -62,5 +62,4 @@ void binary_data_tests() {
 
     });
 
-
 }

+ 37 - 0
src/tests/Integration/Firsts.vala

@@ -39,4 +39,41 @@ void first_tests() {
         }
     });
 
+    Test.add_func("/invercargill/operator/scalar/last/no-condition", () => {
+        var items = ate(new int[] { 1, 2, 3, 4, 5, 6});
+
+        try{
+            var last = items.last();
+            assert_true(last == 6);
+        }
+        catch (Error e) {
+            assert_no_error(e);
+        }
+        
+    });
+
+    Test.add_func("/invercargill/operator/scalar/last/condition", () => {
+        var items = ate(new int[] { 1, 2, 3, 4, 5, 6});
+
+        try {
+            var last = items.last(i => i < 4);
+            assert_true(last == 3);
+        }
+        catch (Error e) {
+            assert_no_error(e);
+        }
+    });
+
+    Test.add_func("/invercargill/operator/scalar/last/empty", () => {
+        var items = ate(new int[] {});
+
+        try {
+            items.last();
+            assert_not_reached();
+        }
+        catch (Error e) {
+
+        }
+    });
+
 }