Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add iterator to FlagValue #1769

Merged
merged 1 commit into from
Jan 9, 2019
Merged

Conversation

polybassa
Copy link
Contributor

This PR adds the iterator functionality to the FlagValue class. This might be useful. At least I want to use it for some OBD related applications.

@codecov-io
Copy link

codecov-io commented Jan 6, 2019

Codecov Report

Merging #1769 into master will increase coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #1769      +/-   ##
==========================================
+ Coverage   85.57%   85.58%   +<.01%     
==========================================
  Files         181      181              
  Lines       42187    42200      +13     
==========================================
+ Hits        36103    36117      +14     
+ Misses       6084     6083       -1
Impacted Files Coverage Δ
scapy/fields.py 91.43% <100%> (+0.08%) ⬆️
scapy/autorun.py 78.44% <0%> (-4.32%) ⬇️
scapy/automaton.py 81.84% <0%> (-0.42%) ⬇️
scapy/layers/tls/record.py 92.1% <0%> (-0.3%) ⬇️
scapy/layers/inet6.py 88.26% <0%> (+0.17%) ⬆️
scapy/asn1/ber.py 82.38% <0%> (+0.28%) ⬆️
scapy/layers/tls/basefields.py 80.53% <0%> (+0.67%) ⬆️
scapy/layers/tls/handshake_sslv2.py 92.77% <0%> (+0.76%) ⬆️
scapy/layers/tls/record_sslv2.py 88.7% <0%> (+1.69%) ⬆️

Copy link
Member

@p-l- p-l- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain the purpose of this? Maybe with a concrete example?

scapy/fields.py Outdated
@@ -1814,6 +1814,22 @@ def __str__(self):
x >>= 1
return ("+" if self.multi else "").join(r)

def __iter__(self):
self.iter = 0
return self
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think __iter__() should return a FlagValueIter object which would have two attributes: the FlagValue instance and a cursor value (which is I think a more meaningful name than iter by the way).

This would make it possible to have several iterators based on the same object with different cursor values at the same time.

Copy link
Contributor Author

@polybassa polybassa Jan 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please explain the implementation of the FlagValueIter object more in detail. I would like to implement it to full-fill your remarks. Or can you point me to an example, how this iterator should be implemented.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like that:

class FlagValueIter(object):

    slots = ["value", "cursor"]

    def __init__(self, flagvalue):
        self.value = int(flagvalue)
        self.cursor = 0

    def __iter__(self):
        return self

    def __next__(self):
        x = self.value
        x >>= self.cursor
        while x:
            self.cursor += 1
            if x & 1:
                return self.names[self.cursor - 1]
            x >>= 1
        raise StopIteration

    next = __next__


class FlagValue(object):

    __slots__ = ["value", "names", "multi"]

    [...]

    def __iter__(self):
        return FlagValueIter(self)

Would that be OK for you? It's better to keep the iterator's cursor out of the object, so that you can have multiple simultaneous iterations based on the same object.

test/fields.uts Outdated
a = FlagsTest(b"\xf0")
flags = list()
for f in a.flags:
flags.append(f)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be written as: flags = list(a.flags)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will change that. Thanks.

@polybassa
Copy link
Contributor Author

I have such an use case in mind:

resp = sock.sr1(OBD()/OBD_S01(pid=0))
for pid in resp.data_records[0].supportedPIDs:
    req = eval('OBD()/OBD_S01()/OBD_%s()' % pid)
    sock.sr1(req)
    ...

This would allow me to easy generate further request packets based on the FlagsField supportedPIDs.

@polybassa
Copy link
Contributor Author

@p-l- Is this PR fine, now?

@p-l- p-l- merged commit 2c5bd65 into secdev:master Jan 9, 2019
@p-l-
Copy link
Member

p-l- commented Jan 9, 2019

@polybassa yep! Thank you!

@polybassa polybassa deleted the IterableFlagsField branch February 11, 2019 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants