Skip to content

Commit 477fe7b

Browse files
committed
feat: b64byteLength()
1 parent 9f9aa14 commit 477fe7b

6 files changed

Lines changed: 198 additions & 0 deletions

File tree

src/lib/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
NodeDecode,
1212
NodeEncode,
1313
} from './nodejs'
14+
import { getLens, _byteLength } from './to_buffer'
1415

1516

1617
export function b64encode(
@@ -46,3 +47,16 @@ export function b64fromBuffer(buffer: ArrayBuffer | Uint8Array): string {
4647
: browserFromBuffer(buffer)
4748
return ret
4849
}
50+
51+
52+
/**
53+
* Calculate buffer.byteLength from base64
54+
*
55+
* base64 is 4/3 + up to two characters of the original data
56+
*/
57+
export function b64byteLength(base64: string): number {
58+
const lens = getLens(base64)
59+
const validLen = lens[0]
60+
const placeHoldersLen = lens[1]
61+
return _byteLength(validLen, placeHoldersLen)
62+
}

test/20_big.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/// <reference types="mocha" />
2+
3+
import {
4+
basename,
5+
join,
6+
} from '@waiting/shared-core'
7+
import * as assert from 'power-assert'
8+
import rewire = require('rewire')
9+
import { TextDecoder, TextEncoder } from 'util'
10+
11+
import { b64byteLength, b64encode } from '../src'
12+
import { fromUint8Array } from '../src/lib/from_buffer'
13+
import { toUint8Array } from '../src/lib/to_buffer'
14+
15+
import { input1, input2, input3 } from './config'
16+
import { equal } from './helper'
17+
18+
19+
const filename = basename(__filename)
20+
21+
22+
describe(filename, () => {
23+
describe('Should fromUint8Array() works with big input', () => {
24+
it('test1', () => {
25+
const big = new Uint8Array(128 * 1024 * 1024)
26+
27+
for (let i = 0, length = big.length; i < length; ++i) {
28+
big[i] = i % 256
29+
}
30+
const b64 = fromUint8Array(big)
31+
const u8arr = toUint8Array(b64)
32+
33+
assert(equal(u8arr, big))
34+
assert(b64byteLength(b64) === u8arr.length)
35+
})
36+
37+
it('test2', () => {
38+
const str = input1.concat(input2, input3).join('').repeat(500_000)
39+
const len = (str.length / 1024 / 1024).toFixed(2)
40+
const ret1 = b64encode(str, TextEncoder)
41+
const ret2 = Buffer.from(str.toString()).toString('base64')
42+
43+
console.info(`test2: string length ${len} MB`)
44+
assert(ret1 === ret2, `input: "${str.toString()}"`)
45+
})
46+
})
47+
})

test/20_to_buffer.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/// <reference types="mocha" />
2+
3+
import {
4+
basename,
5+
join,
6+
} from '@waiting/shared-core'
7+
import * as assert from 'power-assert'
8+
import rewire = require('rewire')
9+
10+
import { b64byteLength } from '../src'
11+
import { toUint8Array } from '../src/lib/to_buffer'
12+
13+
import { input8 } from './config'
14+
import { equal } from './helper'
15+
16+
17+
const filename = basename(__filename)
18+
const mods = rewire('../src/lib/from_buffer')
19+
20+
describe(filename, () => {
21+
it('Should toUint8Array() works', () => {
22+
input8.forEach(row => {
23+
const input = row[1]
24+
const actual = toUint8Array(input)
25+
const expected = Uint8Array.from(row[0])
26+
27+
assert(equal(actual, expected), 'Ensure that ' + input + ' deserialise to ' + expected)
28+
const byteLength = b64byteLength(input)
29+
assert(byteLength === expected.length, 'Ensure that ' + input + ' has byte lentgh of ' + expected.length)
30+
})
31+
})
32+
33+
})

test_browser/10_encoding.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/// <reference types="mocha" />
2+
3+
// tslint:disable-next-line
4+
import * as assert from 'power-assert'
5+
6+
import {
7+
b64decode,
8+
b64encode,
9+
} from '../src/index'
10+
11+
12+
const filename = '10_encoding.test.ts'
13+
14+
describe(filename, () => {
15+
const fnName = 'b64decode'
16+
17+
describe(`Should ${fnName}() works`, () => {
18+
it('with various encoding', () => {
19+
['A', '1', 'ascii0123'].forEach(str => {
20+
const input = str.toString()
21+
const base64 = b64encode(str)
22+
23+
const s1 = b64decode(base64, 'utf-8')
24+
assert(s1 === input, `input: "${input}" expect:"${s1}"`)
25+
26+
const s2 = b64decode(base64, 'gbk')
27+
assert(s2 === input, `input: "${input}" expect:"${s2}"`)
28+
29+
const s3 = b64decode(base64, 'gb18030')
30+
assert(s3 === input, `input: "${input}" expect:"${s3}"`)
31+
32+
const s4 = b64decode(base64, 'iso-8859-2')
33+
assert(s4 === input, `input: "${input}" expect:"${s4}"`)
34+
})
35+
})
36+
})
37+
38+
})

test_browser/20_big.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/// <reference types="mocha" />
2+
3+
import * as assert from 'power-assert'
4+
5+
import { b64decode, b64encode, b64ByteLength } from '../src'
6+
import { fromUint8Array } from '../src/lib/from_buffer'
7+
import { toUint8Array } from '../src/lib/to_buffer'
8+
9+
import { input1, input2 } from './config'
10+
import { equal } from './helper'
11+
12+
13+
const filename = '20_big.test.ts'
14+
15+
describe(filename, () => {
16+
describe('Should fromUint8Array() works with big input', () => {
17+
it('test1', () => {
18+
const big = new Uint8Array(128 * 1024 * 1024)
19+
20+
for (let i = 0, length = big.length; i < length; ++i) {
21+
big[i] = i % 256
22+
}
23+
const b64 = fromUint8Array(big)
24+
const u8arr = toUint8Array(b64)
25+
assert(equal(u8arr, big))
26+
assert(b64ByteLength(b64) === u8arr.length)
27+
})
28+
29+
it('test2', () => {
30+
const str = input1.concat(input2).join('').repeat(300_000)
31+
const len = (str.length / 1024 / 1024).toFixed(2)
32+
const ret1 = b64encode(str)
33+
const ret2 = b64decode(ret1)
34+
35+
console.info(`test2: string length ${len} MB`)
36+
assert(ret2 === str)
37+
})
38+
})
39+
})

test_browser/20_to_buffer.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/// <reference types="mocha" />
2+
3+
import * as assert from 'power-assert'
4+
5+
import { b64ByteLength } from '../src'
6+
import { toUint8Array } from '../src/lib/to_buffer'
7+
8+
import { input8 } from './config'
9+
import { equal } from './helper'
10+
11+
12+
const filename = '20_to_buffer.test.ts'
13+
14+
describe(filename, () => {
15+
it('Should toUint8Array() works', () => {
16+
input8.forEach(row => {
17+
const input = row[1]
18+
const actual = toUint8Array(input)
19+
const expected = Uint8Array.from(row[0])
20+
21+
assert(equal(actual, expected), 'Ensure that ' + input + ' deserialise to ' + expected)
22+
const byteLength = b64ByteLength(input)
23+
assert(byteLength === expected.length, 'Ensure that ' + input + ' has byte lentgh of ' + expected.length)
24+
})
25+
})
26+
27+
})

0 commit comments

Comments
 (0)