diff --git a/atom/genStruct.js b/atom/genStruct.js index e856fc6..95ad682 100644 --- a/atom/genStruct.js +++ b/atom/genStruct.js @@ -11,6 +11,13 @@ var atoms = { ['version', 'int8'], ['flags', 'int24'], ['left', '[]char'], + + ['$atomsCount', 'int32'], + + ['$atoms', [ + ['header', '*movieHeader'], + ['tracks', '[]*track'], + ]], ], }, @@ -324,6 +331,8 @@ var DeclReadFunc = (opts) => { return CallCheckAssign('ReadDummy', ['r', type.len], ['_']); if (name == '$atoms') return ReadAtoms(type.list); + if (name == '$atomsCount') + return CallCheckAssign('ReadDummy', ['r', type.len], ['_']); if (type.arr && type.fn != 'Bytes') return ReadArr('self.'+name, type); return ReadCommnType('self.'+name, type); @@ -365,6 +374,7 @@ var DeclWriteFunc = (opts) => { return [ `if ${name} != nil {`, field.type.arr ? WriteArr(name, field.type) : WriteCommnType(name, field.type), + atomsCount && `${atomsCount.name}++`, `}`, ]; }); @@ -388,17 +398,45 @@ var DeclWriteFunc = (opts) => { ] }; + var atomsCount; + + var WriteAtomsCountStart = (type) => { + atomsCount = { + name: 'atomsCount', + namePos: 'atomsCountPos', + type: type, + } + return [ + DeclVar(atomsCount.name, 'int'), + DeclVar(atomsCount.namePos, 'int64'), + CallCheckAssign('WriteEmptyInt', ['w', type.len], [atomsCount.namePos]), + ]; + }; + + var WriteAtomsCountEnd = (type) => { + return [ + CallCheckAssign('RefillInt', + ['w', atomsCount.namePos, atomsCount.name, atomsCount.type.len], + [] + ), + ]; + }; + var WriteField = (name, type) => { if (name == '_') return CallCheckAssign('WriteDummy', ['w', type.len], []); if (name == '$atoms') return WriteAtoms(type.list); + if (name == '$atomsCount') + return WriteAtomsCountStart(type); if (type.arr && type.fn != 'Bytes') return WriteArr('self.'+name, type); return WriteCommnType('self.'+name, type); }; - var WriteFields = () => opts.fields.map(field => WriteField(field.name, field.type)); + var WriteFields = () => opts.fields + .map(field => WriteField(field.name, field.type)) + .concat(atomsCount && WriteAtomsCountEnd()) return Func( 'Write'+opts.type, @@ -561,6 +599,8 @@ var allStmts = () => { var genStructFields = fields => fields.map(field => { if (field.name == '_') return; + if (field.name == '$atomsCount') + return; if (field.name == '$atoms') return field.type.list; return [field]; diff --git a/atom/struct.go b/atom/struct.go index 118c815..06189c0 100644 --- a/atom/struct.go +++ b/atom/struct.go @@ -9,6 +9,8 @@ type Test struct { Version int Flags int Left string + Header *MovieHeader + Tracks []*Track } func ReadTest(r *io.LimitedReader) (res *Test, err error) { @@ -23,6 +25,36 @@ func ReadTest(r *io.LimitedReader) (res *Test, err error) { if self.Left, err = ReadString(r, int(r.N)); err != nil { return } + if _, err = ReadDummy(r, 4); err != nil { + return + } + for r.N > 0 { + var cc4 string + var ar *io.LimitedReader + if ar, cc4, err = ReadAtomHeader(r, ""); err != nil { + return + } + switch cc4 { + case "mvhd": + { + if self.Header, err = ReadMovieHeader(ar); err != nil { + return + } + } + case "trak": + { + var item *Track + if item, err = ReadTrack(ar); err != nil { + return + } + self.Tracks = append(self.Tracks, item) + } + + } + if _, err = ReadDummy(ar, int(ar.N)); err != nil { + return + } + } res = self return } @@ -42,6 +74,28 @@ func WriteTest(w io.WriteSeeker, self *Test) (err error) { if err = WriteString(w, self.Left, len(self.Left)); err != nil { return } + var atomsCount int + var atomsCountPos int64 + if atomsCountPos, err = WriteEmptyInt(w, 4); err != nil { + return + } + if self.Header != nil { + if err = WriteMovieHeader(w, self.Header); err != nil { + return + } + atomsCount++ + } + if self.Tracks != nil { + for _, elem := range self.Tracks { + if err = WriteTrack(w, elem); err != nil { + return + } + } + atomsCount++ + } + if err = RefillInt(w, atomsCountPos, atomsCount, 4); err != nil { + return + } if err = aw.Close(); err != nil { return } diff --git a/atom/writer.go b/atom/writer.go index 367c1a0..f50ca06 100644 --- a/atom/writer.go +++ b/atom/writer.go @@ -48,28 +48,28 @@ type Writer struct { sizePos int64 } -func (self *Writer) WriteEmptyInt(n int) (pos int64, err error) { - if pos, err = self.Seek(0, 1); err != nil { +func WriteEmptyInt(w io.WriteSeeker, n int) (pos int64, err error) { + if pos, err = w.Seek(0, 1); err != nil { return } - if err = WriteInt(self, 0, n); err != nil { + if err = WriteInt(w, 0, n); err != nil { return } return } -func (self *Writer) RefillInt(pos int64, val int, n int) (err error) { +func RefillInt(w io.WriteSeeker, pos int64, val int, n int) (err error) { var curPos int64 - if curPos, err = self.Seek(0, 1); err != nil { + if curPos, err = w.Seek(0, 1); err != nil { return } - if _, err = self.Seek(pos, 0); err != nil { + if _, err = w.Seek(pos, 0); err != nil { return } - if err = WriteInt(self, val, n); err != nil { + if err = WriteInt(w, val, n); err != nil { return } - if _, err = self.Seek(curPos, 0); err != nil { + if _, err = w.Seek(curPos, 0); err != nil { return } return @@ -80,7 +80,7 @@ func (self *Writer) Close() (err error) { if curPos, err = self.Seek(0, 1); err != nil { return } - if err = self.RefillInt(self.sizePos, int(curPos - self.sizePos), 4); err != nil { + if err = RefillInt(self, self.sizePos, int(curPos - self.sizePos), 4); err != nil { return } if false { @@ -92,7 +92,7 @@ func (self *Writer) Close() (err error) { func WriteAtomHeader(w io.WriteSeeker, cc4 string) (res *Writer, err error) { self := &Writer{WriteSeeker: w} - if self.sizePos, err = self.WriteEmptyInt(4); err != nil { + if self.sizePos, err = WriteEmptyInt(w, 4); err != nil { return } if err = WriteString(self, cc4, 4); err != nil {