Skip to content

Commit

Permalink
Now using bytes iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
asticode committed Aug 9, 2019
1 parent f5a59e8 commit 8d58895
Show file tree
Hide file tree
Showing 24 changed files with 1,617 additions and 626 deletions.
34 changes: 24 additions & 10 deletions data.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package astits

import (
"github.com/pkg/errors"
"github.com/asticode/go-astitools/byte"
)

// PIDs
Expand Down Expand Up @@ -38,40 +39,53 @@ func parseData(ps []*Packet, prs PacketsParser, pm programMap) (ds []*Data, err
}
}

// Reconstruct payload
// Get payload length
var l int
for _, p := range ps {
l += len(p.Payload)
}

// Append payload
var payload = make([]byte, l)
var c int
for _, p := range ps {
c += copy(payload[c:], p.Payload)
}

// Create iterator
i := astibyte.NewIterator(payload)

// Parse PID
var pid = ps[0].Header.PID
pid := ps[0].Header.PID

// Parse payload
if pid == PIDCAT {
// Information in a CAT payload is private and dependent on the CA system. Use the PacketsParser
// to parse this type of payload
} else if isPSIPayload(pid, pm) {
// Parse PSI data
var psiData *PSIData
if psiData, err = parsePSIData(payload); err != nil {
if psiData, err = parsePSIData(i); err != nil {
err = errors.Wrap(err, "astits: parsing PSI data failed")
return
}

// Append data
ds = psiData.toData(ps[0], pid)
} else if isPESPayload(payload) {
d, err := parsePESData(payload)
if err == nil {
ds = append(ds, &Data{
FirstPacket: ps[0],
PES: d,
PID: pid,
})
// Parse PES data
var pesData *PESData
if pesData, err = parsePESData(i); err != nil {
err = errors.Wrap(err, "astits: parsing PES data failed")
return
}

// Append data
ds = append(ds, &Data{
FirstPacket: ps[0],
PES: pesData,
PID: pid,
})
}
return
}
Expand Down
88 changes: 69 additions & 19 deletions data_eit.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package astits

import "time"
import (
"time"

astibyte "github.com/asticode/go-astitools/byte"
"github.com/pkg/errors"
)

// EITData represents an EIT data
// Page: 36 | Chapter: 5.2.4 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf
Expand All @@ -24,47 +29,92 @@ type EITDataEvent struct {
}

// parseEITSection parses an EIT section
func parseEITSection(i []byte, offset *int, offsetSectionsEnd int, tableIDExtension uint16) (d *EITData) {
// Init
func parseEITSection(i *astibyte.Iterator, offsetSectionsEnd int, tableIDExtension uint16) (d *EITData, err error) {
// Create data
d = &EITData{ServiceID: tableIDExtension}

// Get next 2 bytes
var bs []byte
if bs, err = i.NextBytes(2); err != nil {
err = errors.Wrap(err, "astits: fetching next bytes failed")
return
}

// Transport stream ID
d.TransportStreamID = uint16(i[*offset])<<8 | uint16(i[*offset+1])
*offset += 2
d.TransportStreamID = uint16(bs[0])<<8 | uint16(bs[1])

// Get next 2 bytes
if bs, err = i.NextBytes(2); err != nil {
err = errors.Wrap(err, "astits: fetching next bytes failed")
return
}

// Original network ID
d.OriginalNetworkID = uint16(i[*offset])<<8 | uint16(i[*offset+1])
*offset += 2
d.OriginalNetworkID = uint16(bs[0])<<8 | uint16(bs[1])

// Get next byte
var b byte
if b, err = i.NextByte(); err != nil {
err = errors.Wrap(err, "astits: fetching next byte failed")
return
}

// Segment last section number
d.SegmentLastSectionNumber = uint8(i[*offset])
*offset += 1
d.SegmentLastSectionNumber = uint8(b)

// Get next byte
if b, err = i.NextByte(); err != nil {
err = errors.Wrap(err, "astits: fetching next byte failed")
return
}

// Last table ID
d.LastTableID = uint8(i[*offset])
*offset += 1
d.LastTableID = uint8(b)

// Loop until end of section data is reached
for *offset < offsetSectionsEnd {
for i.Offset() < offsetSectionsEnd {
// Get next 2 bytes
if bs, err = i.NextBytes(2); err != nil {
err = errors.Wrap(err, "astits: fetching next bytes failed")
return
}

// Event ID
var e = &EITDataEvent{}
e.EventID = uint16(i[*offset])<<8 | uint16(i[*offset+1])
*offset += 2
e.EventID = uint16(bs[0])<<8 | uint16(bs[1])

// Start time
e.StartTime = parseDVBTime(i, offset)
if e.StartTime, err = parseDVBTime(i); err != nil {
err = errors.Wrap(err, "astits: parsing DVB time")
return
}

// Duration
e.Duration = parseDVBDurationSeconds(i, offset)
if e.Duration, err = parseDVBDurationSeconds(i); err != nil {
err = errors.Wrap(err, "astits: parsing DVB duration seconds failed")
return
}

// Get next byte
if b, err = i.NextByte(); err != nil {
err = errors.Wrap(err, "astits: fetching next byte failed")
return
}

// Running status
e.RunningStatus = uint8(i[*offset]) >> 5
e.RunningStatus = uint8(b) >> 5

// Free CA mode
e.HasFreeCSAMode = uint8(i[*offset]&0x10) > 0
e.HasFreeCSAMode = uint8(b&0x10) > 0

// We need to rewind since the current byte is used by the descriptor as well
i.FastForward(-1)

// Descriptors
e.Descriptors = parseDescriptors(i, offset)
if e.Descriptors, err = parseDescriptors(i); err != nil {
err = errors.Wrap(err, "astits: parsing descriptors failed")
return
}

// Add event
d.Events = append(d.Events, e)
Expand Down
5 changes: 3 additions & 2 deletions data_eit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/asticode/go-astitools/binary"
"github.com/stretchr/testify/assert"
"github.com/asticode/go-astitools/byte"
)

var eit = &EITData{
Expand Down Expand Up @@ -39,8 +40,8 @@ func eitBytes() []byte {
}

func TestParseEITSection(t *testing.T) {
var offset int
var b = eitBytes()
d := parseEITSection(b, &offset, len(b), uint16(1))
d, err := parseEITSection(astibyte.NewIterator(b), len(b), uint16(1))
assert.Equal(t, d, eit)
assert.NoError(t, err)
}
55 changes: 42 additions & 13 deletions data_nit.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package astits

import (
astibyte "github.com/asticode/go-astitools/byte"
"github.com/pkg/errors"
)

// NITData represents a NIT data
// Page: 29 | Chapter: 5.2.1 | Link: https://www.dvb.org/resources/public/standards/a38_dvb-si_specification.pdf
type NITData struct {
Expand All @@ -16,31 +21,55 @@ type NITDataTransportStream struct {
}

// parseNITSection parses a NIT section
func parseNITSection(i []byte, offset *int, tableIDExtension uint16) (d *NITData) {
// Init
func parseNITSection(i *astibyte.Iterator, tableIDExtension uint16) (d *NITData, err error) {
// Create data
d = &NITData{NetworkID: tableIDExtension}

// Network descriptors
d.NetworkDescriptors = parseDescriptors(i, offset)
if d.NetworkDescriptors, err = parseDescriptors(i); err != nil {
err = errors.Wrap(err, "astits: parsing descriptors failed")
return
}

// Get next bytes
var bs []byte
if bs, err = i.NextBytes(2); err != nil {
err = errors.Wrap(err, "astits: fetching next bytes failed")
return
}

// Transport stream loop length
var transportStreamLoopLength = int(uint16(i[*offset]&0xf)<<8 | uint16(i[*offset+1]))
*offset += 2
transportStreamLoopLength := int(uint16(bs[0]&0xf)<<8 | uint16(bs[1]))

// Transport stream loop
transportStreamLoopLength += *offset
for *offset < transportStreamLoopLength {
offsetEnd := i.Offset() + transportStreamLoopLength
for i.Offset() < offsetEnd {
// Create transport stream
ts := &NITDataTransportStream{}

// Get next bytes
if bs, err = i.NextBytes(2); err != nil {
err = errors.Wrap(err, "astits: fetching next bytes failed")
return
}

// Transport stream ID
var ts = &NITDataTransportStream{}
ts.TransportStreamID = uint16(i[*offset])<<8 | uint16(i[*offset+1])
*offset += 2
ts.TransportStreamID = uint16(bs[0])<<8 | uint16(bs[1])

// Get next bytes
if bs, err = i.NextBytes(2); err != nil {
err = errors.Wrap(err, "astits: fetching next bytes failed")
return
}

// Original network ID
ts.OriginalNetworkID = uint16(i[*offset])<<8 | uint16(i[*offset+1])
*offset += 2
ts.OriginalNetworkID = uint16(bs[0])<<8 | uint16(bs[1])

// Transport descriptors
ts.TransportDescriptors = parseDescriptors(i, offset)
if ts.TransportDescriptors, err = parseDescriptors(i); err != nil {
err = errors.Wrap(err, "astits: parsing descriptors failed")
return
}

// Append transport stream
d.TransportStreams = append(d.TransportStreams, ts)
Expand Down
7 changes: 4 additions & 3 deletions data_nit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package astits
import (
"testing"

"github.com/asticode/go-astitools/binary"
astibinary "github.com/asticode/go-astitools/binary"
astibyte "github.com/asticode/go-astitools/byte"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -31,8 +32,8 @@ func nitBytes() []byte {
}

func TestParseNITSection(t *testing.T) {
var offset int
var b = nitBytes()
d := parseNITSection(b, &offset, uint16(1))
d, err := parseNITSection(astibyte.NewIterator(b), uint16(1))
assert.Equal(t, d, nit)
assert.NoError(t, err)
}
24 changes: 18 additions & 6 deletions data_pat.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package astits

import (
astibyte "github.com/asticode/go-astitools/byte"
"github.com/pkg/errors"
)

// PATData represents a PAT data
// https://en.wikipedia.org/wiki/Program-specific_information
type PATData struct {
Expand All @@ -14,17 +19,24 @@ type PATProgram struct {
}

// parsePATSection parses a PAT section
func parsePATSection(i []byte, offset *int, offsetSectionsEnd int, tableIDExtension uint16) (d *PATData) {
// Init
func parsePATSection(i *astibyte.Iterator, offsetSectionsEnd int, tableIDExtension uint16) (d *PATData, err error) {
// Create data
d = &PATData{TransportStreamID: tableIDExtension}

// Loop until end of section data is reached
for *offset < offsetSectionsEnd {
for i.Offset() < offsetSectionsEnd {
// Get next bytes
var bs []byte
if bs, err = i.NextBytes(4); err != nil {
err = errors.Wrap(err, "astits: fetching next bytes failed")
return
}

// Append program
d.Programs = append(d.Programs, &PATProgram{
ProgramMapID: uint16(i[*offset+2]&0x1f)<<8 | uint16(i[*offset+3]),
ProgramNumber: uint16(i[*offset])<<8 | uint16(i[*offset+1]),
ProgramMapID: uint16(bs[2]&0x1f)<<8 | uint16(bs[3]),
ProgramNumber: uint16(bs[0])<<8 | uint16(bs[1]),
})
*offset += 4
}
return
}
5 changes: 3 additions & 2 deletions data_pat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/asticode/go-astitools/binary"
"github.com/stretchr/testify/assert"
"github.com/asticode/go-astitools/byte"
)

var pat = &PATData{
Expand All @@ -27,8 +28,8 @@ func patBytes() []byte {
}

func TestParsePATSection(t *testing.T) {
var offset int
var b = patBytes()
d := parsePATSection(b, &offset, len(b), uint16(1))
d, err := parsePATSection(astibyte.NewIterator(b), len(b), uint16(1))
assert.Equal(t, d, pat)
assert.NoError(t, err)
}
Loading

0 comments on commit 8d58895

Please sign in to comment.