Bläddra i källkod

Add read functions to binary data

Billy Barrow 1 år sedan
förälder
incheckning
69a7b16873
2 ändrade filer med 224 tillägg och 1 borttagningar
  1. 153 0
      src/lib/Collections/BinaryData.vala
  2. 71 1
      src/tests/Integration/BinaryData.vala

+ 153 - 0
src/lib/Collections/BinaryData.vala

@@ -114,6 +114,27 @@ namespace Invercargill {
             append(ate(chunk));
         }
 
+        public int64? read_int64(int index) {
+            var data = skip(index).take((int)sizeof(int64)).to_array();
+            if(data.length != sizeof(int64))
+                return null;
+            int64 value = 0;
+            int64 val = 0;
+            Memory.copy(&value, data, sizeof(int64));
+            switch (endianness) {
+                case Endianness.Native:
+                    val = value;
+                    break;
+                case Endianness.BigEndian:
+                    val = value.to_big_endian();
+                    break;
+                case Endianness.LittleEndian:
+                    val = value.to_little_endian();
+                    break;
+            } 
+            return val;           
+        }
+
         public void push_all_int64(Enumerable<int64?> values) {
             values.iterate(i => push_int64(i));
         }
@@ -137,6 +158,28 @@ namespace Invercargill {
         }
 
 
+        public uint64? read_uint64(int index) {
+            var data = skip(index).take((int)sizeof(uint64)).to_array();
+            if(data.length != sizeof(uint64))
+                return null;
+            uint64 value = 0;
+            uint64 val = 0;
+            Memory.copy(&value, data, sizeof(uint64));
+            switch (endianness) {
+                case Endianness.Native:
+                    val = value;
+                    break;
+                case Endianness.BigEndian:
+                    val = value.to_big_endian();
+                    break;
+                case Endianness.LittleEndian:
+                    val = value.to_little_endian();
+                    break;
+            } 
+            return val;
+        }
+
+
         public void push_all_uint64(Enumerable<uint64?> values) {
             values.iterate(i => push_uint64(i));
         }
@@ -163,6 +206,28 @@ namespace Invercargill {
             append(ate(chunk));
         }
 
+
+        public int32? read_int32(int index) {
+            var data = skip(index).take((int)sizeof(int32)).to_array();
+            if(data.length != sizeof(int32))
+                return null;
+            int32 value = 0;
+            int32 val = 0;
+            Memory.copy(&value, data, sizeof(int32));
+            switch (endianness) {
+                case Endianness.Native:
+                    val = value;
+                    break;
+                case Endianness.BigEndian:
+                    val = value.to_big_endian();
+                    break;
+                case Endianness.LittleEndian:
+                    val = value.to_little_endian();
+                    break;
+            } 
+            return val;           
+        }
+
         public void push_all_int32(Enumerable<int32?> values) {
             values.iterate(i => push_int32(i));
         }
@@ -185,6 +250,28 @@ namespace Invercargill {
             append(ate(chunk));
         }
 
+
+        public uint32? read_uint32(int index) {
+            var data = skip(index).take((int)sizeof(uint32)).to_array();
+            if(data.length != sizeof(uint32))
+                return null;
+            uint32 value = 0;
+            uint32 val = 0;
+            Memory.copy(&value, data, sizeof(uint32));
+            switch (endianness) {
+                case Endianness.Native:
+                    val = value;
+                    break;
+                case Endianness.BigEndian:
+                    val = value.to_big_endian();
+                    break;
+                case Endianness.LittleEndian:
+                    val = value.to_little_endian();
+                    break;
+            } 
+            return val;           
+        }
+
         public void push_all_uint32(Enumerable<uint32?> values) {
             values.iterate(i => push_uint32(i));
         }
@@ -207,6 +294,28 @@ namespace Invercargill {
             append(ate(chunk));
         }
 
+
+        public int16? read_int16(int index) {
+            var data = skip(index).take((int)sizeof(int16)).to_array();
+            if(data.length != sizeof(int16))
+                return null;
+            int16 value = 0;
+            int16 val = 0;
+            Memory.copy(&value, data, sizeof(int16));
+            switch (endianness) {
+                case Endianness.Native:
+                    val = value;
+                    break;
+                case Endianness.BigEndian:
+                    val = value.to_big_endian();
+                    break;
+                case Endianness.LittleEndian:
+                    val = value.to_little_endian();
+                    break;
+            } 
+            return val;           
+        }
+
         public void push_all_int16(Enumerable<int16?> values) {
             values.iterate(i => push_int16(i));
         }
@@ -229,6 +338,27 @@ namespace Invercargill {
             append(ate(chunk));
         }
 
+        public uint16? read_uint16(int index) {
+            var data = skip(index).take((int)sizeof(uint16)).to_array();
+            if(data.length != sizeof(uint16))
+                return null;
+            uint16 value = 0;
+            uint16 val = 0;
+            Memory.copy(&value, data, sizeof(uint16));
+            switch (endianness) {
+                case Endianness.Native:
+                    val = value;
+                    break;
+                case Endianness.BigEndian:
+                    val = value.to_big_endian();
+                    break;
+                case Endianness.LittleEndian:
+                    val = value.to_little_endian();
+                    break;
+            } 
+            return val;           
+        }
+
         public void push_all_uint16(Enumerable<uint16?> values) {
             values.iterate(i => push_uint16(i));
         }
@@ -239,6 +369,16 @@ namespace Invercargill {
             append(ate(chunk));
         }
 
+
+        public int8? read_int8(int index) {
+            var data = skip(index).take((int)sizeof(int8)).to_array();
+            if(data.length != sizeof(int8))
+                return null;
+            int8 value = 0;
+            Memory.copy(&value, data, sizeof(int8));
+            return value;           
+        }
+
         public void push_all_int8(Enumerable<int8?> values) {
             values.iterate(i => push_int8(i));
         }
@@ -248,6 +388,15 @@ namespace Invercargill {
             append(ate(chunk));
         }
 
+        public uint8? read_uint8(int index) {
+            var data = skip(index).take((int)sizeof(uint8)).to_array();
+            if(data.length != sizeof(uint8))
+                return null;
+            uint8 value = 0;
+            Memory.copy(&value, data, sizeof(uint8));
+            return value;           
+        }
+
         public void push_all_uint8(Enumerable<uint8?> values) {
             values.iterate(i => push_uint8(i));
         }
@@ -281,6 +430,10 @@ namespace Invercargill {
             return new BinaryData.from_enumerable(skip(start).take(end-start));
         }
 
+        public BinaryData read(int start, int length) {
+            return new BinaryData.from_enumerable(skip(start).take(length));
+        }
+
         public bool read_in(Bytes? data, ref size_t amount) throws Error {
             if(amount <= 0) {
                 return false;

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

@@ -3,7 +3,7 @@ using Invercargill.Convert;
 
 void binary_data_tests() {
 
-    Test.add_func("/invercargill/structure/binary_data/endian_test", () => {
+    Test.add_func("/invercargill/structure/binary_data/endian_write_test", () => {
 
         uint64 u64 = 3292849078942343;
         int64 i64 = 637292174;
@@ -63,4 +63,74 @@ void binary_data_tests() {
 
     });
 
+    Test.add_func("/invercargill/structure/binary_data/little_endian_read_test", () => {
+
+        uint64 u64 = 3292849078942343;
+        int64 i64 = 637292174;
+        uint32 u32 = 43782989;
+        int32 i32 = 32898762;
+        uint16 u16 = 47839;
+        int16 i16 = 3892;
+        uint8 u8 = 253;
+        int8 i8 = 121;
+
+        var le = new BinaryData.from_byte_array(new uint8[] { 
+            0x87, 0x3A, 0xA6, 0x2B, 0xD4, 0xB2, 0x0B, 0x00, // u64
+            0x8E, 0x4E, 0xFC, 0x25, 0x00, 0x00, 0x00, 0x00, // i64
+            0x4D, 0x13, 0x9C, 0x02, // u32
+            0xCA, 0xFE, 0xF5, 0x01, // i32
+            0xDF, 0xBA, // u16
+            0x34, 0x0F, // i16
+            0xFD, // u8
+            0x79  // i8
+        });
+
+        le.endianness = BinaryData.Endianness.LittleEndian;
+
+        assert_true(le.read_uint64(0) == u64);
+        assert_true(le.read_int64(8) == i64);
+        assert_true(le.read_uint32(16) == u32);
+        assert_true(le.read_int32(20) == i32);
+        assert_true(le.read_uint16(24) == u16);
+        assert_true(le.read_int16(26) == i16);
+        assert_true(le.read_uint8(28) == u8);
+        assert_true(le.read_int8(29) == i8);
+
+    });
+
+    Test.add_func("/invercargill/structure/binary_data/big_endian_read_test", () => {
+
+        uint64 u64 = 3292849078942343;
+        int64 i64 = 637292174;
+        uint32 u32 = 43782989;
+        int32 i32 = 32898762;
+        uint16 u16 = 47839;
+        int16 i16 = 3892;
+        uint8 u8 = 253;
+        int8 i8 = 121;
+
+        var be = new BinaryData.from_byte_array(new uint8[] { 
+            0x00, 0x0B, 0xB2, 0xD4, 0x2B, 0xA6, 0x3A, 0x87, // u64
+            0x00, 0x00, 0x00, 0x00, 0x25, 0xFC, 0x4E, 0x8E, // i64
+            0x02, 0x9C, 0x13, 0x4D, // u32
+            0x01, 0xF5, 0xFE, 0xCA, // i32
+            0xBA, 0xDF, // u16
+            0x0F, 0x34, // i16
+            0xFD, // u8
+            0x79  // i8
+        });
+
+        be.endianness = BinaryData.Endianness.BigEndian;
+
+        assert_true(be.read_uint64(0) == u64);
+        assert_true(be.read_int64(8) == i64);
+        assert_true(be.read_uint32(16) == u32);
+        assert_true(be.read_int32(20) == i32);
+        assert_true(be.read_uint16(24) == u16);
+        assert_true(be.read_int16(26) == i16);
+        assert_true(be.read_uint8(28) == u8);
+        assert_true(be.read_int8(29) == i8);
+
+    });
+
 }