Repository: d0c-s4vage/pfp (python)

Issue:
Feature Request: dom child iteration via __iter__
## Is your feature request related to a problem? Please describe
Not really a "problem". More that I find it not terribly intuitive to write dom._pfp__children.

## Describe the solution you'd like
My natural response to iterating through a list of object is to use something like "for item in dom". In this case, my proposed solution would be to implement `__iter__` as simply `return self._pfp__children.__iter__()`.

## Describe alternatives you've considered
Currently I just reference ._pfp__children when I want to see the listing.

## Additional context
N/A

Pull request:
Added children and array item iteration
fixes #119 

Patch:
diff --git a/pfp/fields.py b/pfp/fields.py
index 78dd419..537439d 100644
--- a/pfp/fields.py
+++ b/pfp/fields.py
@@ -1029,6 +1029,11 @@ class Struct(Field):
             )
         res.append("{}}}".format("    " * level))
         return "\n".join(res)
+    
+    def __iter__(self):
+        """Iterate over this struct's children
+        """
+        return self._pfp__children.__iter__()
 
 
 @inherit_hash
@@ -2324,6 +2329,11 @@ class Array(Field):
         else:
             return len(self.items)
 
+    def __iter__(self):
+        """Iterate over all items in this array
+        """
+        return self.items.__iter__()
+
 
 # http://www.sweetscape.com/010editor/manual/ArraysStrings.htm
 @inherit_hash


Test patch:
diff --git a/tests/test_arrays.py b/tests/test_arrays.py
index f98a224..3da3263 100644
--- a/tests/test_arrays.py
+++ b/tests/test_arrays.py
@@ -292,6 +292,32 @@ class TestArrays(utils.PfpTestCase):
         struct.array = [0xFFFF]
         self.assertEqual(struct.array[0], 0xFFFF)
 
+    def test_array_iter(self):
+        """Test array item iteration.
+        """
+        dom = self._test_parse_build(
+            "ABCDEFGHI",
+            """
+                typedef struct {
+                    char first;
+                    char second;
+                    char third;
+                } three_bytes;
+
+                three_bytes three_three_bytes[3];
+            """,
+        )
+        items = [x for x in dom.three_three_bytes]
+        self.assertEqual(items[0].first, 0x41)
+        self.assertEqual(items[0].second, 0x42)
+        self.assertEqual(items[0].third, 0x43)
+        self.assertEqual(items[1].first, 0x44)
+        self.assertEqual(items[1].second, 0x45)
+        self.assertEqual(items[1].third, 0x46)
+        self.assertEqual(items[2].first, 0x47)
+        self.assertEqual(items[2].second, 0x48)
+        self.assertEqual(items[2].third, 0x49)
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tests/test_struct_union.py b/tests/test_struct_union.py
index d0197e6..b65265b 100644
--- a/tests/test_struct_union.py
+++ b/tests/test_struct_union.py
@@ -443,6 +443,26 @@ class TestStructUnion(utils.PfpTestCase):
             stdout="3",
         )
 
+    def test_struct_iter(self):
+        """Test struct children iteration.
+        """
+        dom = self._test_parse_build(
+            "ABC",
+            """
+                typedef struct {
+                    char first;
+                    char second;
+                    char third;
+                } three_bytes;
+
+                three_bytes bytes;
+            """,
+        )
+        chars = [x for x in dom.bytes]
+        self.assertEquals(chars[0], 0x41)
+        self.assertEquals(chars[1], 0x42)
+        self.assertEquals(chars[2], 0x43)
+
 
 if __name__ == "__main__":
     unittest.main()