This version won't print the full payload (which could be large).
It also prints human friendly values for types and flags.
| durin42 |
| hg-reviewers |
This version won't print the full payload (which could be large).
It also prints human friendly values for types and flags.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/wireprotoframing.py (24 lines) |
| FRAME_TYPE_ERROR_RESPONSE: FLAGS_ERROR_RESPONSE, | FRAME_TYPE_ERROR_RESPONSE: FLAGS_ERROR_RESPONSE, | ||||
| FRAME_TYPE_TEXT_OUTPUT: {}, | FRAME_TYPE_TEXT_OUTPUT: {}, | ||||
| FRAME_TYPE_PROGRESS: {}, | FRAME_TYPE_PROGRESS: {}, | ||||
| FRAME_TYPE_STREAM_SETTINGS: {}, | FRAME_TYPE_STREAM_SETTINGS: {}, | ||||
| } | } | ||||
| ARGUMENT_RECORD_HEADER = struct.Struct(r'<HH') | ARGUMENT_RECORD_HEADER = struct.Struct(r'<HH') | ||||
| def humanflags(mapping, value): | |||||
| """Convert a numeric flags value to a human value, using a mapping table.""" | |||||
| flags = [] | |||||
| for val, name in sorted({v: k for k, v in mapping.iteritems()}.iteritems()): | |||||
| if value & val: | |||||
| flags.append(name) | |||||
| return b'|'.join(flags) | |||||
| @attr.s(slots=True) | @attr.s(slots=True) | ||||
| class frameheader(object): | class frameheader(object): | ||||
| """Represents the data in a frame header.""" | """Represents the data in a frame header.""" | ||||
| length = attr.ib() | length = attr.ib() | ||||
| requestid = attr.ib() | requestid = attr.ib() | ||||
| streamid = attr.ib() | streamid = attr.ib() | ||||
| streamflags = attr.ib() | streamflags = attr.ib() | ||||
| typeid = attr.ib() | typeid = attr.ib() | ||||
| flags = attr.ib() | flags = attr.ib() | ||||
| @attr.s(slots=True) | @attr.s(slots=True, repr=False) | ||||
| class frame(object): | class frame(object): | ||||
| """Represents a parsed frame.""" | """Represents a parsed frame.""" | ||||
| requestid = attr.ib() | requestid = attr.ib() | ||||
| streamid = attr.ib() | streamid = attr.ib() | ||||
| streamflags = attr.ib() | streamflags = attr.ib() | ||||
| typeid = attr.ib() | typeid = attr.ib() | ||||
| flags = attr.ib() | flags = attr.ib() | ||||
| payload = attr.ib() | payload = attr.ib() | ||||
| def __repr__(self): | |||||
| typename = '<unknown>' | |||||
| for name, value in FRAME_TYPES.iteritems(): | |||||
| if value == self.typeid: | |||||
| typename = name | |||||
| break | |||||
| return ('frame(size=%d; request=%d; stream=%d; streamflags=%s; ' | |||||
| 'type=%s; flags=%s)' % ( | |||||
| len(self.payload), self.requestid, self.streamid, | |||||
| humanflags(STREAM_FLAGS, self.streamflags), typename, | |||||
| humanflags(FRAME_TYPE_FLAGS[self.typeid], self.flags))) | |||||
| def makeframe(requestid, streamid, streamflags, typeid, flags, payload): | def makeframe(requestid, streamid, streamflags, typeid, flags, payload): | ||||
| """Assemble a frame into a byte array.""" | """Assemble a frame into a byte array.""" | ||||
| # TODO assert size of payload. | # TODO assert size of payload. | ||||
| frame = bytearray(FRAME_HEADER_SIZE + len(payload)) | frame = bytearray(FRAME_HEADER_SIZE + len(payload)) | ||||
| # 24 bits length | # 24 bits length | ||||
| # 16 bits request id | # 16 bits request id | ||||
| # 8 bits stream id | # 8 bits stream id | ||||