Completed
Push — master ( d25395...d83c14 )
by Jan
15s queued 14s
created

FrameReader.ts ➔ convertValue   B

Complexity

Conditions 6

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 22
rs 8.6666
c 0
b 0
f 0
cc 6
1
import { SplitBuffer, } from "./ID3Util"
2
import * as ID3Util from "./ID3Util"
3
4
type DataType = "string" | "number" | "buffer"
5
6
export class FrameReader {
7
    private _encoding: number
8
    private _splitBuffer: SplitBuffer
9
10
    constructor(
11
        buffer: Buffer,
12
        encodingBytePosition?: number,
13
        consumeEncodingByte = true
14
    ) {
15
        if (!buffer || !(buffer instanceof Buffer)) {
16
            buffer = Buffer.alloc(0)
17
        }
18
        if (
19
            encodingBytePosition !== undefined &&
20
            Number.isInteger(encodingBytePosition)
21
        ) {
22
            this._encoding = buffer[encodingBytePosition] ? buffer[encodingBytePosition] : 0x00
23
            if (consumeEncodingByte) {
24
                buffer = encodingBytePosition === 0 ?
25
                    buffer.subarray(1) :
26
                    Buffer.concat([
27
                        buffer.subarray(0, encodingBytePosition),
28
                        buffer.subarray(encodingBytePosition)
29
                    ])
30
            }
31
        } else {
32
            this._encoding = 0x00
33
        }
34
        this._splitBuffer = new SplitBuffer(null, buffer.subarray(0))
35
    }
36
37
    consumeStaticValue(
38
        dataType: 'string',
39
        size?: number | null,
40
        encoding?: number
41
    ): string
42
    consumeStaticValue(
43
        dataType: 'number',
44
        size?: number | null,
45
        encoding?: number
46
    ): number
47
    consumeStaticValue(
48
        dataType: 'buffer',
49
        size?: number | null,
50
        encoding?: number
51
    ): Buffer
52
    consumeStaticValue(
53
    ): Buffer
54
    consumeStaticValue(
55
        dataType: DataType = 'buffer',
56
        size?: number | null,
57
        encoding = this._encoding
58
    ) {
59
        return this._consumeByFunction(
60
            // TODO check if this._splitBuffer.remainder can be null!
61
            // eslint-disable-next-line
62
            () => staticValueFromBuffer(this._splitBuffer.remainder!, size),
63
            dataType,
64
            encoding
65
        )
66
    }
67
68
    consumeNullTerminatedValue(
69
        dataType: 'string',
70
        encoding?: number
71
     ): string
72
     consumeNullTerminatedValue(
73
        dataType: 'number',
74
        encoding?: number
75
     ): number
76
    consumeNullTerminatedValue(
77
        dataType: DataType,
78
        encoding = this._encoding
79
    ) {
80
        return this._consumeByFunction(
81
            // TODO check if this._splitBuffer.remainder can be null!
82
            // eslint-disable-next-line
83
            () => nullTerminatedValueFromBuffer(this._splitBuffer.remainder!, encoding),
84
            dataType,
85
            encoding
86
        )
87
    }
88
89
    private _consumeByFunction(
90
        fn: () => SplitBuffer,
91
        dataType: DataType,
92
        encoding: number
93
    ) {
94
        if (
95
            !this._splitBuffer.remainder ||
96
            this._splitBuffer.remainder.length === 0
97
        ) {
98
            return undefined
99
        }
100
        this._splitBuffer = fn()
101
        if (dataType) {
102
            return convertValue(this._splitBuffer.value, dataType, encoding)
103
        }
104
        return this._splitBuffer.value
105
    }
106
}
107
108
function convertValue(
109
    buffer: Buffer | number | string | null,
110
    dataType: DataType,
111
    encoding = 0x00
112
) {
113
    if (!buffer) {
114
        return undefined
115
    }
116
    if (!(buffer instanceof Buffer)) {
117
        return buffer
118
    }
119
    if (buffer.length === 0) {
120
        return undefined
121
    }
122
    if (dataType === "number") {
123
        return parseInt(buffer.toString('hex'), 16)
124
    }
125
    if (dataType === "string") {
126
        return ID3Util.bufferToDecodedString(buffer, encoding)
127
    }
128
    return buffer
129
}
130
131
function staticValueFromBuffer(
132
    buffer: Buffer,
133
    size?: number | null
134
): SplitBuffer {
135
    size = size ?? buffer.length
136
    if (buffer.length > size) {
137
        return new SplitBuffer(
138
            buffer.subarray(0, size), buffer.subarray(size)
139
        )
140
    }
141
    return new SplitBuffer(buffer.subarray(0), null)
142
}
143
144
function nullTerminatedValueFromBuffer(
145
    buffer: Buffer,
146
    encoding = 0x00
147
): SplitBuffer {
148
    return ID3Util.splitNullTerminatedBuffer(buffer, encoding)
149
}
150