Passed
Pull Request — master (#136)
by
unknown
01:48
created

src/FrameHeader.ts   A

Complexity

Total Complexity 14
Complexity/F 2.33

Size

Lines of Code 106
Function Count 6

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 85
mnd 8
bc 8
fnc 6
dl 0
loc 106
rs 10
bpm 1.3333
cpm 2.3333
noi 0
c 0
b 0
f 0

6 Functions

Rating   Name   Duplication   Size   Complexity  
A FrameHeader.getBuffer 0 6 1
A FrameHeader.ts ➔ extractFlags 0 30 3
A FrameHeader.ts ➔ getHeaderSize 0 3 2
A FrameHeader.ts ➔ createFromBuffer 0 18 4
A FrameHeader.ts ➔ getBodySize 0 12 3
A FrameHeader.ts ➔ getFrameSize 0 3 1
1
import * as ID3Util from './ID3Util'
2
import {
3
    FRAME_IDENTIFIERS,
4
    FRAME_ALIASES }
5
from "./definitions/FrameIdentifiers"
6
7
type Flags = {
8
    tagAlterPreservation?: boolean
9
    fileAlterPreservation?: boolean
10
    readOnly?: boolean
11
    compression?: boolean
12
    encryption?: boolean
13
    groupingIdentity?: boolean
14
    dataLengthIndicator?: boolean
15
}
16
17
class FrameHeader {
18
    private identifier: string
19
    private bodySize: number
20
    private flags: Flags
21
    constructor(identifier: string, bodySize: number, flags: Flags = {}) {
22
        this.identifier = identifier
23
        this.bodySize = bodySize
24
        this.flags = flags
25
    }
26
27
    getBuffer() {
28
        const buffer = Buffer.alloc(10)
29
        buffer.write(this.identifier, 0)
30
        buffer.writeUInt32BE(this.bodySize, 4)
31
        return buffer
32
    }
33
34
}
35
36
export function createFromBuffer(headerBuffer: Buffer, version: number) {
37
    const identifierSize = version === 2 ? 3 : 4
38
    let identifier = headerBuffer.toString('utf8', 0, identifierSize)
39
    const frameSize = getBodySize(headerBuffer, version)
40
    const flags = extractFlags(headerBuffer[8], headerBuffer[9], version)
41
42
    // Try to convert identifier for older versions
43
    if (version === 2) {
44
        const aliasesV2: Record<string, string> = FRAME_ALIASES.v2
45
        const alias = aliasesV2[identifier]
46
        if (alias) {
47
            const identifiers: Record<string, string> = FRAME_IDENTIFIERS.v34
48
            identifier = identifiers[alias]
49
        }
50
    }
51
52
    return new FrameHeader(identifier, frameSize, flags)
53
}
54
55
function extractFlags(
56
    statusFlag: number,
57
    encodingFlag: number,
58
    version: number
59
) {
60
    if (version === 3) {
61
        return {
62
            tagAlterPreservation: !!(statusFlag & 128),
63
            fileAlterPreservation: !!(statusFlag & 64),
64
            readOnly: !!(statusFlag & 32),
65
            compression: !!(encodingFlag & 128),
66
            encryption: !!(encodingFlag & 64),
67
            groupingIdentity: !!(encodingFlag & 32),
68
            dataLengthIndicator: !!(encodingFlag & 128)
69
        }
70
    }
71
    if (version === 4) {
72
        return {
73
            tagAlterPreservation: !!(statusFlag & 64),
74
            fileAlterPreservation: !!(statusFlag & 32),
75
            readOnly: !!(statusFlag & 16),
76
            groupingIdentity: !!(encodingFlag & 64),
77
            compression: !!(encodingFlag & 8),
78
            encryption: !!(encodingFlag & 4),
79
            unsynchronisation: !!(encodingFlag & 2),
80
            dataLengthIndicator: !!(encodingFlag & 1)
81
        }
82
    }
83
    return {}
84
}
85
86
export function getHeaderSize(version: number) {
87
    return version === 2 ? 6 : 10
88
}
89
90
function getBodySize(headerBuffer: Buffer, version: number) {
91
    const isEncoded = version === 4
92
93
    const bytes = version === 2 ?
94
        [headerBuffer[3], headerBuffer[4], headerBuffer[5]] :
95
        [headerBuffer[4], headerBuffer[5], headerBuffer[6], headerBuffer[7]]
96
97
    if (isEncoded) {
98
        return ID3Util.decodeSize(Buffer.from(bytes))
99
    }
100
    return Buffer.from(bytes).readUIntBE(0, bytes.length)
101
}
102
103
export function getFrameSize(buffer: Buffer, version: number) {
104
    return getHeaderSize(version) + getBodySize(buffer, version)
105
}
106