Skip to content

Commit 149042d

Browse files
committed
Expose fine-parsing functions as utils
1 parent 6c87d59 commit 149042d

4 files changed

Lines changed: 3310 additions & 3272 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"@types/jest": "^24.0.18",
3535
"@types/node": "^12.7.11",
3636
"jest": "^24.9.0",
37+
"prettier": "^2.5.1",
3738
"rimraf": "^3.0.2",
3839
"ts-jest": "^24.3.0",
3940
"tslint": "^5.20.1",

src/java-props.ts

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {decodeLine, encodeLine, LineReader} from './utils';
1+
import {decodeLine, encodeLine, rawParse} from './utils';
22

33
export interface Properties {
44
[key: string]: string;
@@ -18,49 +18,10 @@ export interface Properties {
1818
*/
1919
export function parse(str: string): Properties {
2020
const result: Properties = Object.create(null);
21-
const lr = new LineReader(str);
22-
let line;
23-
while ((line = lr.readLine()) !== undefined) {
24-
let keyLen = 0;
25-
let valueStart = line.length;
26-
let hasSep = false;
27-
let backslash = false;
28-
29-
const lineLen = line.length;
30-
let pos = 0;
31-
for (; pos < lineLen; pos++) {
32-
const c = line[pos];
33-
if ((c === '=' || c === ':') && !backslash) {
34-
valueStart = keyLen + 1;
35-
hasSep = true;
36-
break;
37-
} else if ((c === ' ' || c === '\t' || c === '\f') && !backslash) {
38-
valueStart = keyLen + 1;
39-
break;
40-
}
41-
if (c === '\\') {
42-
backslash = !backslash;
43-
} else {
44-
backslash = false;
45-
}
46-
keyLen++;
47-
}
48-
while (valueStart < lineLen) {
49-
const c = line[valueStart];
50-
if (c !== ' ' && c !== '\t' && c !== '\f') {
51-
if (!hasSep && (c === '=' || c === ':')) {
52-
hasSep = true;
53-
} else {
54-
break;
55-
}
56-
}
57-
valueStart++;
58-
}
59-
60-
const key = decodeLine(line.substring(0, keyLen));
61-
const value = decodeLine(line.substring(valueStart));
62-
result[key] = value;
63-
}
21+
rawParse(str, (res) => {
22+
const key = decodeLine(res.line.substring(0, res.sepStart));
23+
result[key] = decodeLine(res.line.substring(res.valueStart));
24+
});
6425
return result;
6526
}
6627

src/utils.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,60 @@ const UNICODE_PATTERN = /^[0-9a-fA-F]{4}$/;
44
const ENCODE_PATTERN = /(?:[\u0000-\u001F\\\u007F-\uFFFF])/g;
55
const ENCODE_KEY_PATTERN = /(?:[\u0000-\u0020!#:=\\\u007F-\uFFFF])/g; // ENCODE_PATTERN with separators + comments
66

7+
export interface ParsedLine {
8+
line: string;
9+
sepStart: number;
10+
valueStart: number;
11+
}
12+
13+
export function rawParse(str: string, consumeFn: (res: ParsedLine) => void): void {
14+
const lr = new LineReader(str);
15+
let line;
16+
while ((line = lr.readLine()) !== undefined) {
17+
consumeFn(rawParseLine(line));
18+
}
19+
}
20+
21+
export function rawParseLine(line: string): ParsedLine {
22+
let keyLen = 0;
23+
let valueStart = line.length;
24+
let hasSep = false;
25+
let backslash = false;
26+
27+
const lineLen = line.length;
28+
let pos = 0;
29+
for (; pos < lineLen; pos++) {
30+
const c = line[pos];
31+
if ((c === '=' || c === ':') && !backslash) {
32+
valueStart = keyLen + 1;
33+
hasSep = true;
34+
break;
35+
} else if ((c === ' ' || c === '\t' || c === '\f') && !backslash) {
36+
valueStart = keyLen + 1;
37+
break;
38+
}
39+
if (c === '\\') {
40+
backslash = !backslash;
41+
} else {
42+
backslash = false;
43+
}
44+
keyLen++;
45+
}
46+
while (valueStart < lineLen) {
47+
const c = line[valueStart];
48+
if (c !== ' ' && c !== '\t' && c !== '\f') {
49+
if (!hasSep && (c === '=' || c === ':')) {
50+
hasSep = true;
51+
} else {
52+
break;
53+
}
54+
}
55+
valueStart++;
56+
}
57+
58+
return {line, sepStart: keyLen, valueStart};
59+
}
60+
761
export function decodeLine(line: string): string {
862
return line.replace(DECODE_PATTERN, (_, unicode, char) => {
963
if (unicode !== undefined) {
@@ -61,9 +115,9 @@ export function encodeLine(line: string, isKey?: boolean): string {
61115
export const convertLine = decodeLine;
62116

63117
export class LineReader {
64-
private readonly str: string;
65-
private readonly strLen: number;
66-
private pos = 0;
118+
public readonly str: string;
119+
public readonly strLen: number;
120+
public pos = 0;
67121

68122
public constructor(str: string) {
69123
this.str = str;

0 commit comments

Comments
 (0)