-
Notifications
You must be signed in to change notification settings - Fork 88
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
Packet switch to receivers, packet modification #92
Conversation
packet/adaptationfield.go
Outdated
|
||
// invalid returns true if the size of the slice (AdaptationField) is invalid, | ||
// or the adaptation field doesnt exist | ||
func (af AdaptationField) invalid() bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be valid
. Calling !invalid()
is awkward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or isValid
. Functions/methods that return boolean values should be name interrogatively.
packet/modify_test.go
Outdated
"000000000000000000000000000000000" | ||
) | ||
|
||
func createPacketEmptyBody(t *testing.T, header string) (p Packet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does body mean? If it means "payload" let's call it payload. Body has no specific meaning in MPEGTS.
packet/modify_test.go
Outdated
return | ||
} | ||
|
||
func assertPacket(t *testing.T, target Packet, generated Packet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This swallows all error context. How do we know what failed?
packet/adaptationfield.go
Outdated
oldValue := af.getBit(index, mask) | ||
if value != oldValue { | ||
if value { | ||
return 1 // growing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of documenting the return values in-line, write a GoDoc comment for this function that has the return value in it.
@alextarasov1 It looks like you could also remove adaptationfield/create.go and fix #82 here. |
packet/adaptationfield.go
Outdated
// transportPrivateDataLength returns the length of the transport private data, | ||
// if there is no transport private data then its length is zero. | ||
func (af AdaptationField) transportPrivateDataLength() int { | ||
if af.hasTransportPrivateData() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invert this condition to return early and reduce the mass of text to the right (Go idiom).
packet/adaptationfield.go
Outdated
// adaptationExtensionLength returns the length of the adaptation field extension, | ||
// if there is no adaptation field extension then its length is zero | ||
func (af AdaptationField) adaptationExtensionLength() int { | ||
if af.hasAdaptationFieldExtension() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
packet/adaptationfield.go
Outdated
// 0 is returned if the bit is unchanged. | ||
// this can be used to find if a field is growing or shrinking. | ||
func (af AdaptationField) bitDelta(index int, mask byte, value bool) int { | ||
if value != af.getBit(index, mask) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here.
@kortschak I won't remove adaptationfield/create.go in this PR (that way the PR is limited to new features only), but it is certainly a possibility in the future. |
It is incorrect and untested and will be replaced by methods in Comcast#92.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing all this work! I appreciate all the attention to detail, and comments. This is really close to being ready for merging, but I would like to have input from some of the other maintainers and the open source community on #98. Many of these functions provide duplicate functionality. While I like the receiver functions, there needs to be a discussion on how to treat the older functions in the packet package.
SOFTWARE. | ||
*/ | ||
|
||
package packet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see why this file was not put in packet/adapatationfield
as that would cause an import cycle, but it does bother me that now two packages have identical functionality with different functions. This definitely means we have to determine the best course of action for #98
packet/adaptationfield.go
Outdated
// index is the byte in the packet where the bit is located | ||
// mask is the bitmask that has that bit set to one and the rest of the bits set to zero | ||
// value is the value that the bit will be set to | ||
func (af AdaptationField) setBit(index int, mask byte, value bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also feels a bit redundant, but I suppose this makes sense since packet is type [188]byte
and adaptationfield is []byte
packet/adaptationfield.go
Outdated
// parseAdaptationField parses the adaptation field that is present in a packet. | ||
// this function is only used by packet functions. | ||
func parseAdaptationField(p *Packet) AdaptationField { | ||
return AdaptationField(p[:]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems superfluous as it is only used in one spot and is just a type change.
packet/adaptationfield.go
Outdated
} | ||
|
||
// RandomAccess returns the value of the random access field in the packet. | ||
func (af AdaptationField) RandomAccess() (bool, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to get some test coverage on RandomAccess and StreamPriority? Splice point and splice countdown also look like they don't get touched.
packet/adaptationfield.go
Outdated
|
||
// Length returns the length of the adaptation field | ||
func (af AdaptationField) Length() (int, error) { | ||
if len(af) != PacketSize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to make type AdaptationField [188]byte
as well? That way we ditch the error checking? Or I would recommend thinking about making the AdaptationField a slice with variable length that actually represents the length of the field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was just thinking a similar thing. If AdaptationField
is type AdaptationField Packet
, you get all the conversions for free and the type itself becomes a namespacing tool. (Though see overall comment coming soon).
// FromBytes creates a ts packet from a slice of bytes 188 in length. | ||
// If the bytes provided have errors or the slice is not 188 in length, | ||
// then an error vill be returned along with a nill slice. | ||
func FromBytes(bytes []byte) (pkt Packet, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit vague. Perhaps PacketFromBytes
or NewPacketFromBytes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will read as packet.FromBytes(b
) in user code. This is good API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point. The above comment can be ignored.
My thought, FWIW. One of them should go away, since being able to do things in two trivially similar ways leads to confusion and style wars. The question is about which and why. Apologies for the Go101, but it helps explain the reasoning. In Go methods are used for a variety of reasons:
In this case the first is not relevant, since there is only one type, the second has merit, as does the third. In many cases for Functions are used in the place of generics (when taking interface arguments), or for simple stateless mutations (or world mutations). Separation of functions into distinct packages is often overdone - here it seems that separating packet and adaptation field is one of those times. The benefits that are gained by doing it are achieved by the method namespacing. Given the number of functions being provided, ISTM that providing the functions as methods is worthwhile for 2 and 3 above and the para above. It did also seem like the "adaptationfield" name was long for a postentially commonly used package. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. Thanks for all your hard work! I'm going to try to get another approval, and if not we merge early next week anyway.
This is a big change! Thanks for the hard work. |
It is incorrect and untested and will be replaced by methods in Comcast#92.
It is incorrect and untested and will be replaced by methods in Comcast#92.
Gots has the ability to read packets, but its ability to create or modify packets is very limited. Packet creation is an essential feature for writing unit tests.
Packet type can now use receivers. These changes will not break the existing library interfaces and will remain compatible with old versions of the library. This will be more consistent with the rest of the library (EBP, PSI, PES, SCTE35 all use receivers). Packet creation and modification functionality is added. Almost all fields of the packet can now be read, modified, and created. Error checking was added that checks the packet so it is not corrupted, or in an invalid state.
Old way to create packet:
New way to create packet: