• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

benrr101 / node-taglib-sharp / 48393127

29 Oct 2023 04:39AM UTC coverage: 92.535% (-1.4%) from 93.934%
48393127

push

appveyor

benrr101
Merge branch 'release/v5.2.0'

3244 of 4129 branches covered (0.0%)

Branch coverage included in aggregate %.

2177 of 2177 new or added lines in 61 files covered. (100.0%)

26728 of 28261 relevant lines covered (94.58%)

423.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.43
/src/mpeg4/boxes/mpeg4Box.ts
1
import Mpeg4BoxHeader from "../mpeg4BoxHeader";
1✔
2
import {ByteVector} from "../../byteVector";
1✔
3
import {File} from "../../file";
4
import {ArrayUtils, Guards} from "../../utils";
1✔
5

6
/**
7
 * This class provides a generic implementation of a ISO/IEC 14496-12 box.
8
 */
9
export default abstract class Mpeg4Box {
1✔
10
    private readonly _children: Mpeg4Box[];
11

12
    private _data: ByteVector;
13
    private _handlerType: ByteVector;
14
    private _header: Mpeg4BoxHeader;
15
    private _baseDataPosition: number;
16
    private _dataPosition: number;
17

18
    /**
19
     * Protected constructor to force construction via static functions.
20
     */
21
    protected constructor() {
22
        this._children = [];
1,221✔
23
    }
24

25
    /**
26
     * Initializes a new instance of @see Mpeg4Box with a specified header and handler.
27
     * @param header A @see Mpeg4BoxHeader object describing the new instance.
28
     * @param handlerType Type of the handler box object containing the handler that applies to the
29
     * new instance, or undefined if no handler applies.
30
     */
31
    protected initializeFromHeader(header: Mpeg4BoxHeader, handlerType?: ByteVector): void {
32
        Guards.truthy(header, "header");
1,221✔
33

34
        this._header = header;
1,221✔
35
        this._baseDataPosition = header.position + header.headerSize;
1,221✔
36
        this._dataPosition = this._baseDataPosition;
1,221✔
37
        this._handlerType = handlerType;
1,221✔
38
    }
39

40
    /**
41
     * Initializes a new instance of @see Mpeg4Box with a specified box type.
42
     * @param type A @see ByteVector object containing the box type to use for the new instance.
43
     */
44
    protected initializeFromType(type: ByteVector): void {
45
        return this.initializeFromHeader(Mpeg4BoxHeader.fromType(type));
521✔
46
    }
47

48
    // #region Properties
49

50
    /**
51
     * Gets the MPEG-4 box type of the current instance.
52
     */
53
    public get boxType(): ByteVector { return this._header.boxType; }
3,913✔
54

55
    /**
56
     * Gets the child boxes of the current instance.
57
     * @internal
58
     */
59
    public get children(): Mpeg4Box[] { return this._children.slice(0); }
18✔
60

61
    /**
62
     * Gets the data contained in the current instance.
63
     */
64
    public get data(): ByteVector { return this._data; }
1,338✔
65
    /**
66
     * Sets the data contained in the current instance.
67
     */
68
    public set data(v: ByteVector) {
69
        Guards.truthy(v, "v");
508✔
70
        this._data = v;
508✔
71
    }
72

73
    /**
74
     * Gets the position of the data contained in the current instance, after any box specific headers.
75
     */
76
    public get dataPosition(): number {
77
        return this._dataPosition;
×
78
    }
79
    /**
80
     * Gets the size of the data contained in the current instance, minus the size of any box specific headers.
81
     */
82
    public get dataSize(): number { return this._header.dataSize + this._baseDataPosition - this.dataPosition; }
×
83

84
    /**
85
     * Gets the type of the handler box that applies to the current instance.
86
     */
87
    public get handlerType(): ByteVector { return this._handlerType; }
×
88

89
    /**
90
     * Gets whether or not the current instance has children.
91
     */
92
    public get hasChildren(): boolean { return this._children.length > 0; }
2✔
93

94
    /**
95
     * Gets the header of the current instance.
96
     */
97
    public get header(): Mpeg4BoxHeader { return this._header; }
×
98

99
    /**
100
     * Gets the total size of the current instance as it last appeared on disk.
101
     */
102
    public get size(): number { return this._header.totalBoxSize; }
×
103

104
    // #endregion
105

106
    // #region Public Methods
107

108
    /**
109
     * Adds a specified box to the current instance.
110
     * @param box A @see Mpeg4Box object to add to the current instance.
111
     */
112
    public addChild(box: Mpeg4Box): void {
113
        Guards.truthy(box, "box");
1,235✔
114
        this._children.push(box);
1,235✔
115
    }
116

117
    /**
118
     * Removes all children from the current instance.
119
     */
120
    public clearChildren(): void {
121
        this._children.splice(0, this._children.length);
1✔
122
    }
123

124
    /**
125
     * Gets a child box from the current instance by finding a matching box type.
126
     * @param type A @see ByteVector object containing the box type to match.
127
     * @param predicate Optional predicate to filter boxes with the provided type.
128
     * @returns TBox Box containing the matched box, or `undefined` if no match was found.
129
     */
130
    public getChild<TBox extends Mpeg4Box>(type: ByteVector, predicate?: (b: TBox) => boolean): TBox {
131
        return <TBox>this._children.find((b) => {
1,284✔
132
            return ByteVector.equals(b.boxType, type) && (!predicate || predicate(<TBox>b));
2,012!
133
        });
134
    }
135

136
    /**
137
     * Gets a child box from the current instance by finding a matching box type, searching recursively.
138
     * @param type A @see ByteVector object containing the box type to match.
139
     * @returns Mpeg4Box Matching box, or `undefined` if no matching box was found
140
     */
141
    public getChildRecursively(type: ByteVector): Mpeg4Box {
142
        // Check local children for a match
143
        const localMatch = this._children.find(b => ByteVector.equals(b.boxType, type));
×
144
        if (localMatch) {
×
145
            return localMatch;
×
146
        }
147

148
        // Recurse
149
        for (const box of this._children) {
×
150
            const childBox = box.getChildRecursively(type);
×
151

152
            if (childBox) {
×
153
                return childBox;
×
154
            }
155
        }
156

157
        return undefined;
×
158
    }
159

160
    /**
161
     * Gets all child boxes from the current instance by finding a matching box type.
162
     * @param type A @see ByteVector object containing the box type to match.
163
     * @param predicate Optional predicate to filter boxes with the provided type.
164
     * @returns Mpeg4Box[] Array of matching boxes, or `undefined` if no matching boxes was found.
165
     */
166
    public getChildren<TBox extends Mpeg4Box>(type: ByteVector, predicate?: (b: TBox) => boolean): TBox[] {
167
        return <TBox[]>this._children.filter((b) => {
1,009✔
168
            return ByteVector.equals(b.boxType, type) && (!predicate || predicate(<TBox>b));
1,286✔
169
        });
170
    }
171

172
    /**
173
     * Removes a specified box from the current instance.
174
     * @param box Box to remove from the current instance.
175
     */
176
    public removeChildByBox(box: Mpeg4Box): void {
177
        const index = this._children.indexOf(box);
×
178

179
        if (index > -1) {
×
180
            this._children.splice(index, 1);
×
181
        }
182
    }
183

184
    /**
185
     * Removes all children with a specified box type from the current instance.
186
     * @param type Type of box to remove
187
     */
188
    public removeChildByType(type: ByteVector): void {
189
        for (let i = this._children.length - 1; i >= 0; i--) {
159✔
190
            if (ByteVector.equals(this._children[i].boxType, type)) {
295✔
191
                this._children.splice(i, 1);
144✔
192
            }
193
        }
194
    }
195

196
    /**
197
     * Removes all specified boxes from the current instance.
198
     * @param boxes Collection of boxes to remove from the current instance.
199
     */
200
    public removeChildrenByBox(boxes: Mpeg4Box[]): void {
201
        if (ArrayUtils.isFalsyOrEmpty(boxes)) {
77✔
202
            // Nothing to do.
203
            return;
43✔
204
        }
205

206
        ArrayUtils.remove(this._children, e => boxes.includes(e));
116✔
207
    }
208

209
    // #endregion
210

211
    /**
212
     * Loads the data of the current instance from a specified file using the internal data position and size.
213
     * @param file The @see File from which the current instance was read and from which to read the data.
214
     * @returns ByteVector Data read from the file.
215
     */
216
    public loadData(file: File): ByteVector {
217
        Guards.truthy(file, "file");
×
218

219
        file.seek(this.dataPosition);
×
220

221
        return file.readBlock(this.dataSize);
×
222
    }
223

224
    /**
225
     * Increases the data position by a given value. This function can be used by boxes
226
     * which extend from @see Mpeg4Box to increase the data position, because the data
227
     * is located after their box specific headers.
228
     * @param value The value to add to the data position.
229
     * @returns number Data position before the increase.
230
     */
231
    public increaseDataPosition(value: number): number {
232
        Guards.safeUint(value, "value");
964✔
233

234
        const dataPositionBeforeIncrease = this._dataPosition;
964✔
235
        this._dataPosition += value;
964✔
236

237
        return dataPositionBeforeIncrease;
964✔
238
    }
239

240
    /**
241
     * Generates the headers that are specific to the box type for use in rendering.
242
     * @internal
243
     */
244
    public renderBoxHeaders(): ByteVector[] {
245
        return undefined;
×
246
    }
247
}
248

249

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc