Completed
Push — master ( d83c14...87c801 )
by Jan
16s queued 16s
created

src/api/remove.ts   A

Complexity

Total Complexity 16
Complexity/F 2.67

Size

Lines of Code 94
Function Count 6

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 68
dl 0
loc 94
rs 10
c 0
b 0
f 0
wmc 16
mnd 10
bc 10
fnc 6
bpm 1.6666
cpm 2.6666
noi 0

4 Functions

Rating   Name   Duplication   Size   Complexity  
A remove.ts ➔ removeTags 0 5 2
A remove.ts ➔ removeTagsSync 0 21 4
A remove.ts ➔ removeTagsFromBuffer 0 29 4
A remove.ts ➔ removeTagsAsync 0 19 4
1
import * as fs from "fs"
2
import * as ID3Util from "../ID3Util"
3
import { isFunction } from "../util"
4
5
/**
6
 * Remove already written ID3-Frames from a buffer
7
 */
8
export function removeTagsFromBuffer(data: Buffer) {
9
    const tagPosition = ID3Util.getTagPosition(data)
10
11
    if (tagPosition === -1) {
12
        return data
13
    }
14
15
    const tagHeaderSize = 10
16
    const encodedSize = data.subarray(
17
        tagPosition + 6,
18
        tagPosition + tagHeaderSize
19
    )
20
    if (!ID3Util.isValidEncodedSize(encodedSize)) {
21
        return false
22
    }
23
24
    if (data.length >= tagPosition + tagHeaderSize) {
25
        const size = ID3Util.decodeSize(encodedSize)
26
        return Buffer.concat([
27
            data.subarray(0, tagPosition),
28
            data.subarray(tagPosition + size + tagHeaderSize)
29
        ])
30
    }
31
32
    return data
33
}
34
35
export type RemoveCallback =
36
    (error: NodeJS.ErrnoException | Error | null) => void
37
38
/**
39
 * Remove already written ID3-Frames from a file
40
 */
41
export function removeTags(filepath: string): boolean | Error
42
export function removeTags(filepath: string, callback: RemoveCallback): void
43
export function removeTags(filepath: string, callback?: RemoveCallback) {
44
    if(isFunction(callback)) {
45
        return removeTagsAsync(filepath, callback)
46
    }
47
    return removeTagsSync(filepath)
48
}
49
50
function removeTagsSync(filepath: string) {
51
    let data
52
    try {
53
        data = fs.readFileSync(filepath)
54
    } catch(error) {
55
        return error as Error
56
    }
57
58
    const newData = removeTagsFromBuffer(data)
59
    if(!newData) {
60
        return false
61
    }
62
63
    try {
64
        fs.writeFileSync(filepath, newData, 'binary')
65
    } catch(error) {
66
        return error as Error
67
    }
68
69
    return true
70
}
71
72
function removeTagsAsync(filepath: string, callback: RemoveCallback) {
73
    fs.readFile(filepath, (error, data) => {
74
        if(error) {
75
            callback(error)
76
            return
77
        }
78
79
        const newData = removeTagsFromBuffer(data)
80
        if(!newData) {
81
            callback(error)
82
            return
83
        }
84
85
        fs.writeFile(filepath, newData, 'binary', (error) => {
86
            if(error) {
87
                callback(error)
88
            } else {
89
                callback(null)
90
            }
91
        })
92
    })
93
}
94