From 3808678a59899102d63b4b1fa3e26c09d188e10e Mon Sep 17 00:00:00 2001 From: lordwelch Date: Fri, 17 May 2019 10:59:10 -0700 Subject: [PATCH] cleanup cleanup test files and separate into a main package and a library package in prep for writing mpls files --- cmd/mpls/main.go | 29 ++ mpls.go | 292 +++++++++++++ parse.go | 567 ++++++-------------------- testFiles/timmy.narnian.us/00000.mpls | Bin 168 -> 0 bytes testFiles/timmy.narnian.us/00002.mpls | Bin 184 -> 0 bytes testFiles/timmy.narnian.us/00003.mpls | Bin 168 -> 0 bytes testFiles/timmy.narnian.us/00005.mpls | Bin 168 -> 0 bytes testFiles/timmy.narnian.us/00008.mpls | Bin 196 -> 0 bytes testFiles/timmy.narnian.us/00020.mpls | Bin 168 -> 0 bytes testFiles/timmy.narnian.us/00021.mpls | Bin 168 -> 0 bytes testFiles/timmy.narnian.us/00050.mpls | Bin 168 -> 0 bytes testFiles/timmy.narnian.us/00051.mpls | Bin 184 -> 0 bytes testFiles/timmy.narnian.us/00100.mpls | Bin 6852 -> 0 bytes testFiles/timmy.narnian.us/00101.mpls | Bin 4824 -> 0 bytes testFiles/timmy.narnian.us/00110.mpls | Bin 280 -> 0 bytes testFiles/timmy.narnian.us/00120.mpls | Bin 280 -> 0 bytes testFiles/timmy.narnian.us/00201.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00202.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00203.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00204.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00205.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00206.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00207.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00208.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00209.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00210.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00211.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00212.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00213.mpls | Bin 248 -> 0 bytes testFiles/timmy.narnian.us/00214.mpls | Bin 408 -> 0 bytes testFiles/timmy.narnian.us/00215.mpls | Bin 2488 -> 0 bytes testFiles/timmy.narnian.us/00900.mpls | Bin 154 -> 0 bytes testFiles/timmy.narnian.us/00901.mpls | Bin 154 -> 0 bytes 33 files changed, 440 insertions(+), 448 deletions(-) create mode 100644 cmd/mpls/main.go create mode 100644 mpls.go delete mode 100644 testFiles/timmy.narnian.us/00000.mpls delete mode 100644 testFiles/timmy.narnian.us/00002.mpls delete mode 100644 testFiles/timmy.narnian.us/00003.mpls delete mode 100644 testFiles/timmy.narnian.us/00005.mpls delete mode 100644 testFiles/timmy.narnian.us/00008.mpls delete mode 100644 testFiles/timmy.narnian.us/00020.mpls delete mode 100644 testFiles/timmy.narnian.us/00021.mpls delete mode 100644 testFiles/timmy.narnian.us/00050.mpls delete mode 100644 testFiles/timmy.narnian.us/00051.mpls delete mode 100644 testFiles/timmy.narnian.us/00100.mpls delete mode 100644 testFiles/timmy.narnian.us/00101.mpls delete mode 100644 testFiles/timmy.narnian.us/00110.mpls delete mode 100644 testFiles/timmy.narnian.us/00120.mpls delete mode 100644 testFiles/timmy.narnian.us/00201.mpls delete mode 100644 testFiles/timmy.narnian.us/00202.mpls delete mode 100644 testFiles/timmy.narnian.us/00203.mpls delete mode 100644 testFiles/timmy.narnian.us/00204.mpls delete mode 100644 testFiles/timmy.narnian.us/00205.mpls delete mode 100644 testFiles/timmy.narnian.us/00206.mpls delete mode 100644 testFiles/timmy.narnian.us/00207.mpls delete mode 100644 testFiles/timmy.narnian.us/00208.mpls delete mode 100644 testFiles/timmy.narnian.us/00209.mpls delete mode 100644 testFiles/timmy.narnian.us/00210.mpls delete mode 100644 testFiles/timmy.narnian.us/00211.mpls delete mode 100644 testFiles/timmy.narnian.us/00212.mpls delete mode 100644 testFiles/timmy.narnian.us/00213.mpls delete mode 100644 testFiles/timmy.narnian.us/00214.mpls delete mode 100644 testFiles/timmy.narnian.us/00215.mpls delete mode 100644 testFiles/timmy.narnian.us/00900.mpls delete mode 100644 testFiles/timmy.narnian.us/00901.mpls diff --git a/cmd/mpls/main.go b/cmd/mpls/main.go new file mode 100644 index 0000000..37b7dc0 --- /dev/null +++ b/cmd/mpls/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "io" + "os" + "path/filepath" + + "timmy.narnian.us/mpls" + + "github.com/kr/pretty" +) + +func main() { + var ( + file io.Reader + Mpls mpls.MPLS + err error + ) + file, err = os.Open(filepath.Clean(os.Args[1])) + if err != nil { + panic(err) + } + + Mpls, err = mpls.Parse(file) + pretty.Println(Mpls) + if err != nil { + panic(err) + } +} diff --git a/mpls.go b/mpls.go new file mode 100644 index 0000000..be604e4 --- /dev/null +++ b/mpls.go @@ -0,0 +1,292 @@ +package mpls + +// User Operation mask table +const ( + UOChapterSearchMask = 1 << iota + UOTimeSearchMask + UOSkipToNextPointMask + UOSkipBackToPreviousPointMask + UOForwardPlayMask + UOBackwardPlayMask + UOPlayMask + UOStopMask + UOPauseOnMask + UOPauseOffMask + UOStillOffMask + UOResumeMask + UOMoveUpSelectedButtonMask + UOMoveDownSelectedButtonMask + UOMoveLeftSelectedButtonMask + UOMoveRightSelectedButtonMask + UOSelectButtonMask + UOActivateAndActivateMask + UOSelectAndActivateMask + UOAudioChangeMask + UOPgTextstChangeMask + UOAngleChangeMask + UOPopupOnMask + UOPopupOffMask + UOSelectMenuLanguageMask +) + +// Playlist Flags +const ( + PFPlaylistRandomAccess = 1 << iota + PFAudioMixApp + PFLosslessMayBypassMixer + PFreserved +) + +// Angle Flags +const ( + AFIsDifferentAudios = 1 << (iota + 7) + AFIsSeamlessAngleChange +) + +// VideoType +const ( + VTMPEG1Video = 0x01 + VTMPEG2Video = 0x02 + VTVC1 = 0xea + VTH264 = 0x1b +) + +// AudioType +const ( + ATMPEG1Audio = 0x03 + ATMPEG2Audio = 0x04 + ATLPCM = 0x80 + ATAC3 = 0x81 + ATDTS = 0x82 + ATTRUEHD = 0x83 + ATAC3Plus = 0x84 + ATDTSHD = 0x85 + ATDTSHDMaster = 0x86 +) + +// OtherType +const ( + PresentationGraphics = 0x90 + InteractiveGraphics = 0x91 + TextSubtitle = 0x92 +) + +// VideoFormat +const ( + VFReserved = iota + VF480I + VF576I + VF480P + VF1080I + VF720P + VF1080P + VF576P +) + +// FrameRate +const ( + FRReserved = iota + FR23976 // 23.976 + FR24 // 24 + FR25 // 25 + FR2997 // 29.97 + FR50 // 50 + FR5994 // 59.94 +) + +// AspectRatio +const ( + ARReserved = 0 + AR43 = 2 //4:3 + AR169 = 3 //16:9 +) + +// AudioPresentation +const ( + APReserved = 0 + APMono = 1 + APDualMono = 2 + APStereo = 3 + APMulti = 6 + APCombo = 12 +) + +// SampleRate +const ( + SRReserved = 0 + SR48 = 1 + SR96 = 4 + SR192 = 5 + SR48192 = 12 // 48/192 + SR4896 = 14 // 48/96 +) + +// CharacterCode +const ( + ReservedCharacterCode = iota + UTF8 + UTF16 + ShiftJIS // Japanese + KSC5601 // Korean + GB18030 // Chinese + GB2312 // Chinese + BIG5 // Chinese +) // Chinese + +// MPLS is a struct representing an MPLS file +type MPLS struct { + FileType string + Version string + PlaylistStart int + PlaylistMarkStart int + ExtensionDataStart int + AppInfoPlaylist AppInfoPlaylist + Playlist Playlist + MarkPlaylist PlaylistMark +} + +// AppInfoPlaylist sucks +type AppInfoPlaylist struct { + Len int + PlaybackType byte + PlaybackCount uint16 + PlaylistFlags uint16 + UOMask uint64 +} + +// Playlist sucks +type Playlist struct { + Len int + PlayItemCount uint16 + SubPathCount uint16 + PlayItems []PlayItem + SubPaths []SubPath +} + +// PlayItem contains information about a an item in the playlist +type PlayItem struct { + Len uint16 + Flags uint16 // multiangle/connection condition + InTime int + OutTime int + UOMask uint64 + RandomAccessFlag byte + AngleCount byte + AngleFlags byte + StillMode byte + StillTime uint16 + Clpi CLPI + Angles []CLPI + StreamTable STNTable +} + +// STNTable STream Number Table +type STNTable struct { + Len uint16 // Reserved uint16 + PrimaryVideoStreamCount byte + PrimaryAudioStreamCount byte + PrimaryPGStreamCount byte + PrimaryIGStreamCount byte + SecondaryVideoStreamCount byte + SecondaryAudioStreamCount byte + PIPPGStreamCount byte + PrimaryVideoStreams []PrimaryStream + PrimaryAudioStreams []PrimaryStream + PrimaryPGStreams []PrimaryStream + PrimaryIGStreams []PrimaryStream + SecondaryAudioStreams []SecondaryAudioStream + SecondaryVideoStreams []SecondaryVideoStream +} + +// PrimaryStream holds a stream entry and attributes +type PrimaryStream struct { + StreamEntry + StreamAttributes +} + +// SecondaryStream holds stream references +type SecondaryStream struct { + RefrenceEntryCount byte + StreamIDs []byte +} + +// SecondaryAudioStream holds a primary stream and a secondary stream +type SecondaryAudioStream struct { + PrimaryStream + ExtraAttributes SecondaryStream +} + +// SecondaryVideoStream holds a primary stream and a secondary stream for the video +// and a secondary stream for the Presentation Graphics/pip +type SecondaryVideoStream struct { + PrimaryStream + ExtraAttributes SecondaryStream + PGStream SecondaryStream +} + +// StreamEntry holds the information for the data stream +type StreamEntry struct { + Len byte + Type byte + PID uint16 + SubPathID byte + SubClipID byte +} + +// StreamAttributes holds metadata about the data stream +type StreamAttributes struct { + Len byte + Encoding byte + Format byte + Rate byte + CharacterCode byte + Language string +} + +// CLPI contains the fiLename and the codec ID +type CLPI struct { + ClipFile string + ClipID string // M2TS + STCID byte +} + +type SubPath struct { + Len int + Type byte + PlayItemCount byte + Flags uint16 + SubPlayItems []SubPlayItem +} + +// SubPlayItem contains information about a PlayItem in the subpath +type SubPlayItem struct { + Len uint16 + Flags byte // multiangle/connection condition + StartOfPlayitem uint32 + InTime int + OutTime int + UOMask uint64 + RandomAccessFlag byte + AngleCount byte + AngleFlags byte + StillMode byte + StillTime uint16 + PlayItemID uint16 + Clpi CLPI + Angles []CLPI + StreamTable STNTable +} + +type PlaylistMark struct { + Len uint64 + MarkCount uint16 + Marks []Mark +} + +type Mark struct { + Type byte + PlayItemRef uint16 + Time uint32 + PID uint16 + Duration uint32 +} diff --git a/parse.go b/parse.go index 76859c6..3ffe783 100644 --- a/parse.go +++ b/parse.go @@ -1,4 +1,4 @@ -package main +package mpls import ( "bytes" @@ -7,301 +7,8 @@ import ( "io" "io/ioutil" "os" - "path/filepath" - "text/tabwriter" ) -// User Operation mask table -const ( - UOChapterSearchMask = 1 << iota - UOTimeSearchMask - UOSkipToNextPointMask - UOSkipBackToPreviousPointMask - UOForwardPlayMask - UOBackwardPlayMask - UOPlayMask - UOStopMask - UOPauseOnMask - UOPauseOffMask - UOStillOffMask - UOResumeMask - UOMoveUpSelectedButtonMask - UOMoveDownSelectedButtonMask - UOMoveLeftSelectedButtonMask - UOMoveRightSelectedButtonMask - UOSelectButtonMask - UOActivateAndActivateMask - UOSelectAndActivateMask - UOAudioChangeMask - UOPgTextstChangeMask - UOAngleChangeMask - UOPopupOnMask - UOPopupOffMask - UOSelectMenuLanguageMask -) - -// Playlist Flags -const ( - PFPlaylistRandomAccess = 1 << iota - PFAudioMixApp - PFLosslessMayBypassMixer - PFreserved -) - -// Angle Flags -const ( - AFIsDifferentAudios = 1 << (iota + 7) - AFIsSeamlessAngleChange -) - -// VideoType -const ( - VTMPEG1Video = 0x01 - VTMPEG2Video = 0x02 - VTVC1 = 0xea - VTH264 = 0x1b -) - -// AudioType -const ( - ATMPEG1Audio = 0x03 - ATMPEG2Audio = 0x04 - ATLPCM = 0x80 - ATAC3 = 0x81 - ATDTS = 0x82 - ATTRUEHD = 0x83 - ATAC3Plus = 0x84 - ATDTSHD = 0x85 - ATDTSHDMaster = 0x86 -) - -// OtherType -const ( - PresentationGraphics = 0x90 - InteractiveGraphics = 0x91 - TextSubtitle = 0x92 -) - -// VideoFormat -const ( - VFReserved = iota - VF480I - VF576I - VF480P - VF1080I - VF720P - VF1080P - VF576P -) - -// FrameRate -const ( - FRReserved = iota - FR23976 // 23.976 - FR24 // 24 - FR25 // 25 - FR2997 // 29.97 - FR50 // 50 - FR5994 // 59.94 -) - -// AspectRatio -const ( - ARReserved = 0 - AR43 = 2 //4:3 - AR169 = 3 //16:9 -) - -// AudioPresentation -const ( - APReserved = 0 - APMono = 1 - APDualMono = 2 - APStereo = 3 - APMulti = 6 - APCombo = 12 -) - -// SampleRate -const ( - SRReserved = 0 - SR48 = 1 - SR96 = 4 - SR192 = 5 - SR48192 = 12 // 48/192 - SR4896 = 14 // 48/96 -) - -// CharacterCode -const ( - ReservedCharacterCode = iota - UTF8 - UTF16 - ShiftJIS // Japanese - KSC5601 // Korean - GB18030 // Chinese - GB2312 // Chinese - BIG5 // Chinese -) // Chinese - -// MPLS is a struct representing an MPLS file -type MPLS struct { - FileType string - Version string - PlaylistStart int - PlaylistMarkStart int - ExtensionDataStart int - AppInfoPlaylist AppInfoPlaylist - Playlist Playlist - MarkPlaylist PlaylistMark -} - -// AppInfoPlaylist sucks -type AppInfoPlaylist struct { - Len int - PlaybackType byte - PlaybackCount uint16 - PlaylistFlags uint16 - UOMask uint64 -} - -// Playlist sucks -type Playlist struct { - Len int - PlayItemCount uint16 - SubPathCount uint16 - PlayItems []PlayItem - SubPaths []SubPath -} - -// PlayItem contains information about a an item in the playlist -type PlayItem struct { - Len uint16 - Flags uint16 // multiangle/connection condition - InTime int - OutTime int - UOMask uint64 - RandomAccessFlag byte - AngleCount byte - AngleFlags byte - StillMode byte - StillTime uint16 - Clpi CLPI - Angles []CLPI - StreamTable STNTable -} - -// STNTable STream Number Table -type STNTable struct { - Len uint16 // Reserved uint16 - PrimaryVideoStreamCount byte - PrimaryAudioStreamCount byte - PrimaryPGStreamCount byte - PrimaryIGStreamCount byte - SecondaryVideoStreamCount byte - SecondaryAudioStreamCount byte - PIPPGStreamCount byte - PrimaryVideoStreams []PrimaryStream - PrimaryAudioStreams []PrimaryStream - PrimaryPGStreams []PrimaryStream - PrimaryIGStreams []PrimaryStream - SecondaryAudioStreams []SecondaryAudioStream - SecondaryVideoStreams []SecondaryVideoStream -} - -// PrimaryStream holds a stream entry and attributes -type PrimaryStream struct { - StreamEntry - StreamAttributes -} - -// SecondaryStream holds stream references -type SecondaryStream struct { - RefrenceEntryCount byte - StreamIDs []byte -} - -// SecondaryAudioStream holds a primary stream and a secondary stream -type SecondaryAudioStream struct { - PrimaryStream - ExtraAttributes SecondaryStream -} - -// SecondaryVideoStream holds a primary stream and a secondary stream for the video -// and a secondary stream for the Presentation Graphics/pip -type SecondaryVideoStream struct { - PrimaryStream - ExtraAttributes SecondaryStream - PGStream SecondaryStream -} - -// StreamEntry holds the information for the data stream -type StreamEntry struct { - Len byte - Type byte - PID uint16 - SubPathID byte - SubClipID byte -} - -// StreamAttributes holds metadata about the data stream -type StreamAttributes struct { - Len byte - Encoding byte - Format byte - Rate byte - CharacterCode byte - Language string -} - -// CLPI contains the fiLename and the codec ID -type CLPI struct { - ClipFile string - ClipID string // M2TS - STCID byte -} - -type SubPath struct { - Len int - Type byte - PlayItemCount byte - Flags uint16 - SubPlayItems []SubPlayItem -} - -// SubPlayItem contains information about a PlayItem in the subpath -type SubPlayItem struct { - Len uint16 - Flags byte // multiangle/connection condition - StartOfPlayitem uint32 - InTime int - OutTime int - UOMask uint64 - RandomAccessFlag byte - AngleCount byte - AngleFlags byte - StillMode byte - StillTime uint16 - PlayItemID uint16 - Clpi CLPI - Angles []CLPI - StreamTable STNTable -} - -type PlaylistMark struct { - Len uint64 - MarkCount uint16 - Marks []Mark -} - -type Mark struct { - Type byte - PlayItemRef uint16 - Time uint32 - PID uint16 - Duration uint32 -} - type errReader struct { RS *bytes.Reader err error @@ -331,36 +38,6 @@ func (er *errReader) Seek(offset int64, whence int) (int64, error) { return n64, er.err } -func main() { - var ( - file io.Reader - Mpls MPLS - err error - ) - file, err = os.Open(filepath.Clean(os.Args[1])) - if err != nil { - panic(err) - } - twriter = tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0) - write = func(name string, v interface{}, bin []byte) { - fmt.Fprintf(twriter, "name: %s\tint: %d\tBinary: %08b\tHex: % X\n", name, v, bin, bin) - } - empty = func() { - fmt.Fprintf(twriter, "\t\t\t\n") - } - - Mpls, err = Parse(file) - twriter.Flush() - fmt.Println(Mpls) - panic(err) -} - -var ( - twriter *tabwriter.Writer - write func(string, interface{}, []byte) - empty func() -) - // Parse parses an MPLS file into an MPLS struct func Parse(reader io.Reader) (mpls MPLS, err error) { var ( @@ -379,9 +56,10 @@ func Parse(reader io.Reader) (mpls MPLS, err error) { // Parse reads MPLS data from an io.ReadSeeker func (mpls *MPLS) Parse(file []byte) error { var ( - buf [10]byte - n int - err error + buf [10]byte + n int + err error + start int64 ) reader := &errReader{ @@ -389,8 +67,6 @@ func (mpls *MPLS) Parse(file []byte) error { err: nil, } - fmt.Fprintln(twriter, "Parsing MPLS file\n") - n, err = reader.Read(buf[:8]) if err != nil || n != 8 { return err @@ -405,25 +81,30 @@ func (mpls *MPLS) Parse(file []byte) error { mpls.FileType = str[:4] mpls.Version = str[4:8] - write("FileType", mpls.FileType, buf[:4]) - write("Version", mpls.Version, buf[4:8]) mpls.PlaylistStart, _ = readInt32(reader, buf[:]) - write("Playlist Start", mpls.PlaylistStart, buf[:4]) mpls.PlaylistMarkStart, _ = readInt32(reader, buf[:]) - write("Playlist Mark Start", mpls.PlaylistMarkStart, buf[:4]) mpls.ExtensionDataStart, _ = readInt32(reader, buf[:]) - write("Extension Data Start", mpls.ExtensionDataStart, buf[:4]) _, _ = reader.Seek(20, io.SeekCurrent) _ = mpls.AppInfoPlaylist.parse(reader) - _, _ = reader.Seek(int64(mpls.PlaylistStart), io.SeekStart) + start, _ = reader.Seek(0, io.SeekCurrent) + if start != int64(mpls.PlaylistStart) { + fmt.Fprintf(os.Stderr, "Playlist doesn't start at the right place. Current position is %d position should be %d\n", start, int64(mpls.PlaylistStart)) + } + _, _ = reader.Seek(int64(mpls.PlaylistStart), io.SeekStart) _ = mpls.Playlist.parse(reader) + + start, _ = reader.Seek(0, io.SeekCurrent) + if start != int64(mpls.PlaylistMarkStart) { + fmt.Fprintf(os.Stderr, "Mark Playlist doesn't start at the right place. Current position is %d position should be %d\n", start, int64(mpls.PlaylistStart)) + } + // _ = mpls.MarkPlaylist.parse(reader) return reader.err @@ -432,27 +113,29 @@ func (mpls *MPLS) Parse(file []byte) error { // parse reads AppInfoPlaylist data from an *errReader func (aip *AppInfoPlaylist) parse(reader *errReader) error { var ( - buf [10]byte + buf [10]byte + start int64 + end int64 ) - fmt.Fprintln(twriter, "\nParsing App Info Playlist\n") - aip.Len, _ = readInt32(reader, buf[:]) - write("Length", aip.Len, buf[:4]) - _, _ = reader.Read(buf[:1]) + start, _ = reader.Seek(0, io.SeekCurrent) + + _, _ = reader.Read(buf[:2]) aip.PlaybackType = buf[1] - write("Playback Type", aip.PlaybackType, buf[:1]) aip.PlaybackCount, _ = readUInt16(reader, buf[:]) - write("Playback Count", aip.PlaybackCount, buf[:2]) aip.UOMask, _ = readUInt64(reader, buf[:]) - write("UO Mask", aip.UOMask, buf[:8]) aip.PlaylistFlags, _ = readUInt16(reader, buf[:]) - write("Flags", aip.PlaylistFlags, buf[:2]) + + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(aip.Len)) { + fmt.Fprintf(os.Stderr, "App Info Playlist is not aligned. App Info Playlist started at %d current position is %d position should be %d\n", start, end, start+int64(aip.Len)) + } return reader.err } @@ -460,22 +143,21 @@ func (aip *AppInfoPlaylist) parse(reader *errReader) error { // parse reads Playlist data from an *errReader func (p *Playlist) parse(reader *errReader) error { var ( - buf [10]byte - err error + buf [10]byte + err error + start int64 + end int64 ) - fmt.Fprintln(twriter, "\nParsing Playlist\n") - p.Len, _ = readInt32(reader, buf[:]) - write("Length", p.Len, buf[:4]) + + start, _ = reader.Seek(0, io.SeekCurrent) _, _ = reader.Seek(2, io.SeekCurrent) p.PlayItemCount, _ = readUInt16(reader, buf[:]) - write("Play Item Count", p.PlayItemCount, buf[:2]) p.SubPathCount, _ = readUInt16(reader, buf[:]) - write("Sub Path Count", p.SubPathCount, buf[:2]) for i := 0; i < int(p.PlayItemCount); i++ { var item PlayItem @@ -495,20 +177,26 @@ func (p *Playlist) parse(reader *errReader) error { p.SubPaths = append(p.SubPaths, item) } + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(p.Len)) { + fmt.Fprintf(os.Stderr, "Playlist is not aligned. Playlist started at %d current position is %d position should be %d\n", start, end, start+int64(p.Len)) + } + return reader.err } // parse reads PlayItem data from an *errReader func (pi *PlayItem) parse(reader *errReader) error { var ( - buf [10]byte - err error + buf [10]byte + err error + start int64 + end int64 ) - fmt.Fprintln(twriter, "\nParsing Play Item\n") - pi.Len, _ = readUInt16(reader, buf[:]) - write("length", pi.Len, buf[:2]) + + start, _ = reader.Seek(0, io.SeekCurrent) _, _ = reader.Read(buf[:9]) @@ -519,45 +207,32 @@ func (pi *PlayItem) parse(reader *errReader) error { pi.Clpi.ClipFile = str[:5] pi.Clpi.ClipID = str[5:9] - write("Clip ID", pi.Clpi.ClipFile, buf[:5]) - write("Clip Type", pi.Clpi.ClipID, buf[5:9]) - pi.Flags, _ = readUInt16(reader, buf[:]) - write("Flags", pi.Flags, buf[:2]) _, _ = reader.Read(buf[:1]) pi.Clpi.STCID = buf[0] - write("STC ID", pi.Clpi.STCID, buf[:1]) pi.InTime, _ = readInt32(reader, buf[:]) - write("Start Time", pi.InTime, buf[:4]) pi.OutTime, _ = readInt32(reader, buf[:]) - write("End Time", pi.OutTime, buf[:4]) pi.UOMask, _ = readUInt64(reader, buf[:]) - write("UO Mask", pi.UOMask, buf[:8]) _, _ = reader.Read(buf[:2]) pi.RandomAccessFlag = buf[0] - write("Random Access Flag", pi.RandomAccessFlag, buf[:1]) pi.StillMode = buf[1] - write("Still Mode", pi.StillMode, buf[1:2]) pi.StillTime, _ = readUInt16(reader, buf[:]) - write("Still Time", pi.StillTime, buf[:2]) if pi.Flags&1<<3 == 1 { _, _ = reader.Read(buf[:2]) pi.AngleCount = buf[0] - write("Angle Count", pi.AngleCount, buf[:1]) pi.AngleFlags = buf[1] - write("Angle Flags", pi.AngleFlags, buf[1:2]) for i := 0; i < int(pi.AngleCount); i++ { var angle CLPI @@ -567,13 +242,17 @@ func (pi *PlayItem) parse(reader *errReader) error { return err } angle.STCID = buf[0] - write("STC ID", angle.STCID, buf[:1]) pi.Angles = append(pi.Angles, angle) } } _ = pi.StreamTable.parse(reader) + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(pi.Len)) { + fmt.Fprintf(os.Stderr, "playitem is not aligned. Playitem started at %d current position is %d position should be %d\n", start, end, start+int64(pi.Len)) + } + return reader.err } @@ -587,8 +266,6 @@ func (clpi *CLPI) parse(reader *errReader) error { str := string(buf[:9]) clpi.ClipFile = str[:5] clpi.ClipID = str[5:9] - write("Clip ID", clpi.ClipFile, buf[:5]) - write("Clip Type", clpi.ClipID, buf[5:9]) // clpi.STCID = buf[9] return reader.err @@ -597,35 +274,29 @@ func (clpi *CLPI) parse(reader *errReader) error { // parse reads PrimaryStream data from an *errReader func (stnt *STNTable) parse(reader *errReader) error { var ( - buf [10]byte - err error + buf [10]byte + err error + start int64 + end int64 ) - fmt.Fprintln(twriter, "\nParsing Stream Table\n") stnt.Len, _ = readUInt16(reader, buf[:]) - write("Length", stnt.Len, buf[:2]) + + start, _ = reader.Seek(0, io.SeekCurrent) _, _ = reader.Read(buf[:9]) stnt.PrimaryVideoStreamCount = buf[2] - write("Primary Video Count", stnt.PrimaryVideoStreamCount, buf[1:2]) stnt.PrimaryAudioStreamCount = buf[3] - write("Primary Audio Count", stnt.PrimaryAudioStreamCount, buf[2:3]) stnt.PrimaryPGStreamCount = buf[4] - write("Primary PG Count", stnt.PrimaryPGStreamCount, buf[3:4]) stnt.PrimaryIGStreamCount = buf[5] - write("Primary IG Count", stnt.PrimaryIGStreamCount, buf[4:5]) stnt.SecondaryAudioStreamCount = buf[6] - write("Secondary Audio Count", stnt.SecondaryAudioStreamCount, buf[5:6]) stnt.SecondaryVideoStreamCount = buf[7] - write("Secondary Video Count", stnt.SecondaryVideoStreamCount, buf[6:7]) stnt.PIPPGStreamCount = buf[8] - write("PIP PG Count", stnt.PIPPGStreamCount, buf[7:8]) _, _ = reader.Seek(5, io.SeekCurrent) for i := 0; i < int(stnt.PrimaryVideoStreamCount); i++ { var stream PrimaryStream - fmt.Fprintln(twriter, "\nParsing Video Stream\n") err = stream.parse(reader) if err != nil { return err @@ -635,7 +306,6 @@ func (stnt *STNTable) parse(reader *errReader) error { for i := 0; i < int(stnt.PrimaryAudioStreamCount); i++ { var stream PrimaryStream - fmt.Fprintln(twriter, "\nParsing Audio Stream\n") err = stream.parse(reader) if err != nil { return err @@ -645,7 +315,6 @@ func (stnt *STNTable) parse(reader *errReader) error { for i := 0; i < int(stnt.PrimaryPGStreamCount); i++ { var stream PrimaryStream - fmt.Fprintln(twriter, "\nParsing PG Stream\n") err = stream.parse(reader) if err != nil { return err @@ -655,7 +324,6 @@ func (stnt *STNTable) parse(reader *errReader) error { for i := 0; i < int(stnt.PrimaryIGStreamCount); i++ { var stream PrimaryStream - fmt.Fprintln(twriter, "\nParsing IG Stream\n") err = stream.parse(reader) if err != nil { return err @@ -665,7 +333,6 @@ func (stnt *STNTable) parse(reader *errReader) error { for i := 0; i < int(stnt.SecondaryAudioStreamCount); i++ { var stream SecondaryAudioStream - fmt.Fprintln(twriter, "\nParsing Audio Stream\n") err = stream.parse(reader) if err != nil { return err @@ -675,7 +342,6 @@ func (stnt *STNTable) parse(reader *errReader) error { for i := 0; i < int(stnt.SecondaryVideoStreamCount); i++ { var stream SecondaryVideoStream - fmt.Fprintln(twriter, "\nParsing Video Stream\n") err = stream.parse(reader) if err != nil { return err @@ -683,6 +349,11 @@ func (stnt *STNTable) parse(reader *errReader) error { stnt.SecondaryVideoStreams = append(stnt.SecondaryVideoStreams, stream) } + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(stnt.Len)) { + fmt.Fprintf(os.Stderr, "STN Table is not aligned. STN Table started at %d current position is %d position should be %d\n", start, end, start+int64(stnt.Len)) + } + return reader.err } @@ -692,17 +363,13 @@ func (ss *SecondaryStream) parse(reader *errReader) error { buf [10]byte ) - fmt.Fprintln(twriter, "\nParsing Secondary Stream\n") - _, _ = reader.Read(buf[:2]) ss.RefrenceEntryCount = buf[0] - write("Reference Entry Count", ss.RefrenceEntryCount, buf[:1]) ss.StreamIDs = make([]byte, ss.RefrenceEntryCount) _, _ = reader.Read(ss.StreamIDs) if ss.RefrenceEntryCount%2 != 0 { _, _ = reader.Seek(1, io.SeekCurrent) } - write("Stream IDs", ss.StreamIDs, ss.StreamIDs) return reader.err } @@ -736,31 +403,34 @@ func (ps *PrimaryStream) parse(reader *errReader) error { // parse reads Stream data from an *errReader func (se *StreamEntry) parse(reader *errReader) error { var ( - buf [10]byte + buf [10]byte + start int64 + end int64 ) - _, _ = reader.Read(buf[:]) + _, _ = reader.Read(buf[:1]) se.Len = buf[0] - write("Length", se.Len, buf[:1]) - se.Type = buf[1] - write("Type", se.Type, buf[1:2]) + + start, _ = reader.Seek(0, io.SeekCurrent) + + _, _ = reader.Read(buf[:9]) + se.Type = buf[0] switch se.Type { case 1: - se.PID = binary.BigEndian.Uint16(buf[2:4]) - write("PID", se.PID, buf[2:4]) + se.PID = binary.BigEndian.Uint16(buf[1:3]) case 2, 4: - se.SubPathID = buf[2] - write("Sub Path ID", se.SubPathID, buf[2:3]) - se.SubClipID = buf[3] - write("Sub Clip ID", se.SubClipID, buf[3:4]) - se.PID = binary.BigEndian.Uint16(buf[4:6]) - write("PID", se.PID, buf[2:4]) - case 3: - se.SubPathID = buf[2] - write("Sub Path ID", se.SubPathID, buf[2:3]) + se.SubPathID = buf[1] + se.SubClipID = buf[2] se.PID = binary.BigEndian.Uint16(buf[3:5]) - write("PID", se.PID, buf[2:4]) + case 3: + se.SubPathID = buf[1] + se.PID = binary.BigEndian.Uint16(buf[2:4]) + } + + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(se.Len)) { + fmt.Fprintf(os.Stderr, "Stream Entry is not aligned. Stream Entry started at %d current position is %d position should be %d\n", start, end, start+int64(se.Len)) } return reader.err @@ -769,16 +439,20 @@ func (se *StreamEntry) parse(reader *errReader) error { // parse reads Stream data from an *errReader func (sa *StreamAttributes) parse(reader *errReader) error { var ( - buf [10]byte + buf [10]byte + start int64 + end int64 ) - empty() - _, _ = reader.Read(buf[:2]) + + _, _ = reader.Read(buf[:1]) sa.Len = buf[0] - sa.Encoding = buf[1] - write("Length", sa.Len, buf[:1]) - write("Encoding", sa.Encoding, buf[1:2]) + start, _ = reader.Seek(0, io.SeekCurrent) + + _, _ = reader.Read(buf[:1]) + + sa.Encoding = buf[0] switch sa.Encoding { case VTMPEG1Video, VTMPEG2Video, VTVC1, VTH264: @@ -786,8 +460,6 @@ func (sa *StreamAttributes) parse(reader *errReader) error { sa.Format = buf[0] & 0xf0 >> 4 sa.Rate = buf[0] & 0x0F - write("Format", sa.Format, buf[:1]) - write("Rate", sa.Rate, buf[:1]) _, _ = reader.Seek(3, io.SeekCurrent) case ATMPEG1Audio, ATMPEG2Audio, ATLPCM, ATAC3, ATDTS, ATTRUEHD, ATAC3Plus, ATDTSHD, ATDTSHDMaster: @@ -796,15 +468,11 @@ func (sa *StreamAttributes) parse(reader *errReader) error { sa.Format = buf[0] & 0xf0 >> 4 sa.Rate = buf[0] & 0x0F sa.Language = string(buf[1:4]) - write("Format", sa.Format, buf[:1]) - write("Rate", sa.Rate, buf[:1]) - write("Language", sa.Language, buf[1:4]) case PresentationGraphics, InteractiveGraphics: _, _ = reader.Read(buf[:3]) sa.Language = string(buf[:3]) - write("Language", sa.Language, buf[1:4]) _, _ = reader.Seek(1, io.SeekCurrent) case TextSubtitle: @@ -812,35 +480,36 @@ func (sa *StreamAttributes) parse(reader *errReader) error { sa.CharacterCode = buf[0] sa.Language = string(buf[1:4]) - write("Character Code", sa.CharacterCode, buf[:1]) - write("Language", sa.Language, buf[1:4]) default: fmt.Fprintf(os.Stderr, "warning: unrecognized encoding: '%02X'\n", sa.Encoding) } + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(sa.Len)) { + fmt.Fprintf(os.Stderr, "Stream Attributes is not aligned. Stream Attributes started at %d current position is %d position should be %d\n", start, end, start+int64(sa.Len)) + } + return reader.err } func (sp *SubPath) parse(reader *errReader) error { var ( - buf [10]byte - err error + buf [10]byte + err error + start int64 + end int64 ) - fmt.Fprintln(twriter, "\nParsing Sub Path\n") - sp.Len, _ = readInt32(reader, buf[:]) - write("Length", sp.Len, buf[:4]) - _, _ = reader.Read(buf[:1]) - sp.Type = buf[0] - write("Type", sp.Type, buf[:1]) + start, _ = reader.Seek(0, io.SeekCurrent) + + _, _ = reader.Read(buf[:2]) + sp.Type = buf[1] sp.Flags, _ = readUInt16(reader, buf[:]) - write("Flags", sp.Flags, buf[:2]) _, _ = reader.Read(buf[:2]) sp.PlayItemCount = buf[1] - write("Play Item Count", sp.PlayItemCount, buf[:1]) for i := 0; i < int(sp.PlayItemCount); i++ { var item SubPlayItem @@ -851,46 +520,44 @@ func (sp *SubPath) parse(reader *errReader) error { sp.SubPlayItems = append(sp.SubPlayItems, item) } + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(sp.Len)) { + fmt.Fprintf(os.Stderr, "Subpath is not aligned. Subpath started at %d current position is %d position should be %d\n", start, end, start+int64(sp.Len)) + } + return reader.err } func (spi *SubPlayItem) parse(reader *errReader) error { var ( - buf [10]byte - err error + buf [10]byte + err error + start int64 + end int64 ) - fmt.Fprintln(twriter, "\nParsing Play Item\n") - spi.Len, _ = readUInt16(reader, buf[:]) - write("Length", spi.Len, buf[:2]) + + start, _ = reader.Seek(0, io.SeekCurrent) _ = spi.Clpi.parse(reader) _, _ = reader.Read(buf[:4]) spi.Flags = buf[2] - write("Flags", spi.Flags, buf[:2]) spi.Clpi.STCID = buf[3] - write("STC ID", spi.Clpi.STCID, buf[2:3]) spi.InTime, _ = readInt32(reader, buf[:]) - write("Start Time", spi.InTime, buf[:4]) spi.OutTime, _ = readInt32(reader, buf[:]) - write("End Time", spi.OutTime, buf[:4]) spi.PlayItemID, _ = readUInt16(reader, buf[:]) - write("Play Item ID", spi.PlayItemID, buf[:2]) spi.StartOfPlayitem, _ = readUInt32(reader, buf[:]) - write("Start Of Play Item", spi.StartOfPlayitem, buf[:4]) if spi.Flags&1<<3 == 1 { _, _ = reader.Read(buf[:2]) spi.AngleCount = buf[0] spi.AngleFlags = buf[1] - write("Angle Count", spi.AngleCount, buf[:1]) - write("Angle Flags", spi.AngleFlags, buf[1:2]) for i := 0; i < int(spi.AngleCount); i++ { var angle CLPI @@ -900,11 +567,15 @@ func (spi *SubPlayItem) parse(reader *errReader) error { return err } angle.STCID = buf[0] - write("STC ID", angle.STCID, buf[2:3]) spi.Angles = append(spi.Angles, angle) } } + end, _ = reader.Seek(0, io.SeekCurrent) + if end != (start + int64(spi.Len)) { + fmt.Fprintf(os.Stderr, "Subplayitem is not aligned. Subplayitem started at %d current position is %d position should be %d\n", start, end, start+int64(spi.Len)) + } + return reader.err } diff --git a/testFiles/timmy.narnian.us/00000.mpls b/testFiles/timmy.narnian.us/00000.mpls deleted file mode 100644 index c13df538ea300c3ff56f165d06c93eee16d9ed82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmeYb@Ci0BGB99ZV6Xz>HXz0Y_!t<`q&$FpkeGu35E%Iyg#-h+jI;k7U|eGI97U}h lL?KL!lTknr!e)Jy2w})EFoDbh>Hhy8ECk{$;dlw*0RYIl6D|M% diff --git a/testFiles/timmy.narnian.us/00002.mpls b/testFiles/timmy.narnian.us/00002.mpls deleted file mode 100644 index 41a86e415b68d026ba4184de7c044b71c9f2b45d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmeYb@Ci0BGB99ZV6Xz>X+Vq%@G&p~rI`QzcYvvg05U*g0R})|>}wPf4CFG-{&RqF ziS8trA~3B7R0vWD1)Pimf)FO_t3)7!lM%{gU~NoH%}WOg$uTg2%m$hE|36qQh_{4s HDuf3B^&l5C diff --git a/testFiles/timmy.narnian.us/00003.mpls b/testFiles/timmy.narnian.us/00003.mpls deleted file mode 100644 index 99753a48da551fac3d43c02306972b68aca5e9be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmeYb@Ci0BGB99ZV6Xz>HXz0Y_!t<`q&$FpkeGu35SaNIg#-h+jI;k7U|gVl2}P|O lL?KL!lTknr!e)Jy2w})EFoDbh>Hhy8ECk}s|9%z10|3L~6W#y- diff --git a/testFiles/timmy.narnian.us/00005.mpls b/testFiles/timmy.narnian.us/00005.mpls deleted file mode 100644 index cd72d10131354d468a047af506522cf6e3508ccf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmeYb@Ci0BGB99ZV6Xz>HXz0Y_!t<`q&$FpkeGvkfq|isuTe-akjpsx&jH5O-w&Xu mm4hgRiE%Ot2twGbuM!~)IR++>Ss>m2|AU1HXz0Y_!t<`q&$FpkeGvkfq|ikuTe-akjpsx&jH2_v&&G_ w%0U#u#5frR1R-qJSBVgY6$1;%ERgR1|G`2a-l97}NW7K1pCIuzHXz0Y_!t<`q&$FpkeGvkfq|*HuTe-akjpsx&jH5yIh`nK mHXz0Y_!t<`q&$FpkeGvkfq|)ouTe-akjpsx&jH5yIh`nK mHXz0Y_!t<`q&$FpkeGu35SaTKg#-h+jI;k7V4R=RiK12x kq7Wv=$tWNQVY9wUgfQe7m_TNMbpQVk76S3+J9I;M0K9q<-2eap diff --git a/testFiles/timmy.narnian.us/00051.mpls b/testFiles/timmy.narnian.us/00051.mpls deleted file mode 100644 index 7ca5f993a8d6961798d2bfa39c83295eef7b7c5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmeYb@Ci0BGB99ZV6Xz>X+Vq%@G&r=NkstpAh7@g0|QeNU!#yzAPA9XeU%7ga56%<46Kcbsd?!@Avp#nkl7&9{{IK71@SJf;D_)4?V%Nz diff --git a/testFiles/timmy.narnian.us/00100.mpls b/testFiles/timmy.narnian.us/00100.mpls deleted file mode 100644 index 30445d2da850443a8a9b8eebc5e7139e5f7f7198..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6852 zcmeYb@Ci0BGB99ZV6b9fkh}+^aRELCMz9n=h;#sA$pt_{7Kk4h0D+;eQAjXQ3Aa<{ z2JW>n;XrW&*vG)Y$ifEab217DLO86i5`hd(MktqowJk90jM2lo)Ap`1fX^hAEti-P&I9mHpWng^3- zh4Df15FeU=eaOndz1ES9`>_2osFe_ESoqKq=EK8QY&;Kz)Q6o94Go|^_t-_NNSem*pX`S5;fo#2jjlZKxU&7eLM z++o@wc;R=z@bjTL%!e1g{1!d8^w{w8p#{{3qGuP>i2h{*wIL8-IMj!Ru=-H+&o4nS zan7R%?*UoE!G}h$`cO=qSz1hIqv-JSA*?kvGNn*F!oJU%H7c2zh}K)PV>O*l_PRx7m=&J&Z{ c^rHyDQ_w%}3+G8GzS>j_=gBAwr$YSz0M_l5KL7v# diff --git a/testFiles/timmy.narnian.us/00101.mpls b/testFiles/timmy.narnian.us/00101.mpls deleted file mode 100644 index e892cb8d23373c07050daa576e8738b6cf754679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4824 zcmeYb@Ci0BGB99ZV6b9f5c~wBaRELCMz9n=h;#sA!7V^S9*8Fx7#J8^_!@--1C?+) zzjWXZ=I{fGBS0Pl10y2~oX^Q9APC{GzDfi#I2oZ_2G+L3)Vy>~Mj@zL)(Jo^P+kaP zHv{X0w4y{1p9!jeLU93@&kW-iceaB?%#mB$j}rTYy9_9>jZbKn>64qGBJX>h*#;x8s3>Mvj*HnhUQQg310Z} zTlC!0V*~CY6JuByO$oorXKVRoz+GerE009~{1Oxs=R7*#E;2EJh7q4^#TCBAm2v~_ zA|qJt7t>kYCAsYI(*bvp2`u;X&38M`FQAe=;4U(PrEJOF&tFLU{L>n67nztr(-FVO z>^%N&^S=+ci;Q5gCY|_CT82Tocfeg_0xKc;-*MLoR6m(N;4U(PxkyH2qpnPu_<;d; zkqM-o&B`E9#-Jx~O2uKoU1S6+vt@d_*2-QpE*o$cnZR5maLBDkFiSFdz+GevE3;+a z^tUK<+=O*+APyUdzKAKToh_JF@JjHajm^M^5v?1$QV|O zC@~}iC<{-N9#9uCFg#)q0FC8vPi)JW++?zu-Jxu^F6o2%bdE{@ZXKzZ3_%Dx4=MU9k5ioF^))mD&mCiOX&J bQH07eI^)@G&qlFxc#2{qF!%u?omw0^$Gz5b!k$2?i=*oc-qj z<920Um?AK($H2e{)C~iii~@oXHtVZIAcK=p5Gu>sXqcLp4l&Ub*~HTa55shWX;MvO bV9;S;2KfNwzW@KhW&j7eI^)@G&qlFxc#2{qF!%u?omw0^$Gz5b!k$2?i=*oc-qj z<920Um?AK($H2e{)C~iii~@oXHtVZIAcK<;%4J|}G)&D)hnQ%JY~tyIhhe(GG^r*s bFz7HagM0vT-~az$Gk}go<87b60U`$gq(~Ye0+(@G&r=NzDNAL1GgO3=E7deT_nbfn4rr#|zxgHcOzW z%>ycAWPuBDG71PnIIOP{fecPYD3^h?EipAOos&@rs+M&EkPDO-g4)eGA+0D8#Akx) jpHN%?<}<_i1^GoFrW^wk$Za6k{QnP@1Mwbi5QgvoTk{;_ diff --git a/testFiles/timmy.narnian.us/00202.mpls b/testFiles/timmy.narnian.us/00202.mpls deleted file mode 100644 index 9c3b0e5203a2272114f61f158c2871c5f730ffbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B*Re2qeafn4qnug>x`eF{TS zn+H_L$O0GQWE2pDa9Cd@0vVi)P%Z;&TViTnIwzwLR4wZSAQvbv1ht!WLRwKGh|dJo lKcTn)%x8x23-XIVOgRQ7klR46`Trj*2jub8&wmKv0RT<&AIAUy diff --git a/testFiles/timmy.narnian.us/00203.mpls b/testFiles/timmy.narnian.us/00203.mpls deleted file mode 100644 index ce2de61d6fb85c9dda36f124076cdea3b8de3199..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B*ReT_nbfn1(xM}2rD<~5_J z%>ycAWPuBDG71PnIIOP{fecPYD3^h?EipAOos&@rs+M&EkPDO-g4)eGA+0D8#Akx) kpHN%?<}<_i1^GoFrW^wk$Za6k{QnP@1M+yqd{#hs05dxrMgRZ+ diff --git a/testFiles/timmy.narnian.us/00204.mpls b/testFiles/timmy.narnian.us/00204.mpls deleted file mode 100644 index ce065cac8da0d6da5b691ecb6b9ffdc202fe9c20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B++e2qeafm~jt8*6yG#2%rj z%>ycAWPuBDG71PnIIOP{fecPYD3^h?EipAOos&@rs+M&EkPDO-g4)eGA+0D8#Akx) jpHN%?<}<_i1^GoFrW^wk$Za6k{QnP@1MwO*DMNSwV?P|* diff --git a/testFiles/timmy.narnian.us/00205.mpls b/testFiles/timmy.narnian.us/00205.mpls deleted file mode 100644 index 9b8b8a5a749a32397797dd15e9075ecba83916b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B++eT_nbfn44x;Wzn&ZC|0N z%>ycAWPuBDG71PnIIOP{fecPYD3^h?EipAOos&@rs+M&EkPDO-g4)eGA+0D8#Akx) kpHN%?<}<_i1^GoFrW^wk$Za6k{QnP@1M>LzdsHDj07z9FJpcdz diff --git a/testFiles/timmy.narnian.us/00206.mpls b/testFiles/timmy.narnian.us/00206.mpls deleted file mode 100644 index bf388a2bc73d69b99932d850027c2b5157cd3357..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B+6e2qeafm}Y>iYt6mxmZ!u z<^dHlvcQEn83hC(9M)HfKn5oxl*_={mYABC&dDeQRm(a7$OXy^LG5OpkXDok;xj?@ jPbe+`^O<4%g8U*7Q;vZNYe0+(@G&r=NzDNAL1GgO3=B+6eT_nbfn2`%Zs+;_M!iK* zn+H_L$O0GQWE2pDa9Cd@0vVi)P%Z;&TViTnIwzwLR4wZSAQvbv1ht!WLRwKGh|dJo kKcTn)%x8x23-XIVOgRQ7klR46`Trj*2jcx^+za6W0PZ{Ye0+(@G&r=NzDNAL1GgO3=B-ne2qeafn0u(*?Ihr@18?Z zn+H_L$O0GQWE2pDa9Cd@0vVi)P%Z;&TViTnIwzwLR4wZSAQvbv1ht!WLRwKGh|dJo jKcTn)%x8x23-XIVOgRQ7klR46`Trj*2jV?c^@s2Pt-~DQ diff --git a/testFiles/timmy.narnian.us/00209.mpls b/testFiles/timmy.narnian.us/00209.mpls deleted file mode 100644 index 77ceed228cb393bc0c8102251e1e57cf85914887..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B-neT_nbfn5G~+;sxkdl#Xo z%>ycAWPuBDG71PnIIOP{fecPYD3^h?EipAOos&@rs+M&EkPDO-g4)eGA+0D8#Akx) kpHN%?<}<_i1^GoFrW^wk$Za6k{QnP@1M&pY*YrVn0C?~nAOHXW diff --git a/testFiles/timmy.narnian.us/00210.mpls b/testFiles/timmy.narnian.us/00210.mpls deleted file mode 100644 index 1421428df8865a03093f0335042796ecebdcf2d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B*xe2qeafn0$y20el8Uv{FX z%>ycAWPuBDG71PnIIOP{fecPYD3^h?EipAOos&@rs+M&EkPDO-g4)eGA+0D8#Akx) kpHN%?<}<_i1^GoFrW^wk$Za6k{QnP@1MxOr`3>O#07x1f_y7O^ diff --git a/testFiles/timmy.narnian.us/00211.mpls b/testFiles/timmy.narnian.us/00211.mpls deleted file mode 100644 index 9aac2fee381df40e08d6013c9489c8575ab04ab8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B*xeT_nbfn0$@ZasoArqfZ> z<^dHlvcQEn83hC(9M)HfKn5oxl*_={mYABC&dDeQRm(a7$OXy^LG5OpkXDok;xj?@ kPbe+`^O<4%g8U*7Q;vZNYe0+(@G&r=NzDNAL1GgO3=B*Se2qeafn33~f>(lj51m9& zn+H_L$O0GQWE2pDa9Cd@0vVi)P%Z;&TViTnIwzwLR4wZSAQvbv1ht!WLRwKGh|dJo kKcTn)%x8x23-XIVOgRQ7klR46`Trj*2jcB+dkf(K0R3+sy#N3J diff --git a/testFiles/timmy.narnian.us/00213.mpls b/testFiles/timmy.narnian.us/00213.mpls deleted file mode 100644 index 8e191a2e49e3232bfc23d91d9dd9155afc872c87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 248 zcmeYb@Ci0BGB99ZV6Xz>Ye0+(@G&r=NzDNAL1GgO3=B*SeT_nbfn328{Axl4FW;i5 z%>ycAWPuBDG71PnIIOP{fecPYD3^h?EipAOos&@rs+M&EkPDO-g4)eGA+0D8#Akx) kpHN%?<}<_i1^GoFrW^wk$Za6k{QnP@1M-A&v#TIH0BZXjTmS$7 diff --git a/testFiles/timmy.narnian.us/00214.mpls b/testFiles/timmy.narnian.us/00214.mpls deleted file mode 100644 index 900f85e00004808240e2eec9373eb5268d24b67c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmeYb@Ci0BGB99ZV6b9fV9Ws0xBwpmBdQdm7Ld;b#1jmFz{1xkBp9efs9G^!=);cv zC~EV7W;3$Dg*X`n1R)&OSBXFdCnJ>0z}l9WnwQSWC;(eW3B?6qJ~ND8kY5CGk*P7*MXU@$@47>Ug_;jQR6t33yNH27hk+Rsf}rsE{~zoM RMg~TZ+Ymfqq3}Zx9so5SF^d2I diff --git a/testFiles/timmy.narnian.us/00215.mpls b/testFiles/timmy.narnian.us/00215.mpls deleted file mode 100644 index 5f9a93259fbdc516ac923ebaa68c51518798586d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2488 zcmeYb@Ci0BGB99ZV6b9f;J5^&aRELCMpP+|DL_6y5Kk~LFfg|CH3|s^D&dZHyukfz zvjmFTJO&0vMi#gbC!>HMgv0tO5y;?VgmM{J+Y(dr(m5H0plVqs0J%VUA*kJ~6Vi$j zL3}2t{t3keU_LX9Uyxq}agm7u%taqwo#koz6b3aCLJf$E452RKnRe8NS7KiCz`Mu@ z>LOmH8*6yG#2yX2i;Q6|ni77KPuTX=z`Mu<>LNbbiYt6mxmX9@MW!$p&38M`_c!Y8 zz`Mu{>LPxT*?Ihr@17fY7n#Fc^p3kuAbankfp?Jw)I|bi40;0Fzw8`%7s1MGfkSRR zf-$Dk2i!%burgaPt>Bg5-a{t`-bJu7Tkr(Gnoz;ZfzN9OuyiC;t(Y(LVaNV~4HXz0Y_!t-wQVt-d2M~kA91ILB4GesZLV|%@#@T-kFfQ|v j1}T68Ifz0SpOaBQ5W;4Cl?Y)7fV2Wt0d@cX4-x_Z!;KFg diff --git a/testFiles/timmy.narnian.us/00901.mpls b/testFiles/timmy.narnian.us/00901.mpls deleted file mode 100644 index 41aa12efb0c3f6d9253ecdd4f071e5cfcc4f4a5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmeYb@Ci0BGB99ZV6Xz>HXz0Y_!t-wQVt-d2M~kA91ILB4GevaLV|%@#@T-kFfQ|v j1}T68Ifz0SpOaBQ5W;4Cl?Y)7fV2Wt0d@cX4-x_Z!`%-c