Skip to content

Commit

Permalink
Add multiline parse support for model
Browse files Browse the repository at this point in the history
  • Loading branch information
nodece committed Apr 17, 2019
1 parent 7c67f72 commit 9143514
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 12 deletions.
1 change: 0 additions & 1 deletion examples/rbac_policy.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ p, alice, data1, read
p, bob, data2, write
p, data2_admin, data2, read
p, data2_admin, data2, write

g, alice, data2_admin
46 changes: 35 additions & 11 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ export class Config {
private static DEFAULT_SECTION = 'default';
private static DEFAULT_COMMENT = '#';
private static DEFAULT_COMMENT_SEM = ';';
private static DEFAULT_MULTI_LINE_SEPARATOR = '\\';

private data: Map<string, Map<string, string>>;

constructor() {
private constructor() {
this.data = new Map<string, Map<string, string>>();
}

Expand Down Expand Up @@ -75,33 +76,56 @@ export class Config {
}

private parseBuffer(buf: Buffer): void {
let section = '';
const lines = buf.toString().split('\n');
const linesCount = lines.length;
let section = '';
let currentLine = '';

lines.forEach((n, index) => {
const line = n.trim();
const lineNumber = index + 1;
if (!line) {
return;
}

if (line.startsWith(Config.DEFAULT_COMMENT)) {
return;
} else if (line.startsWith(Config.DEFAULT_COMMENT_SEM)) {
if (line.startsWith(Config.DEFAULT_COMMENT) || line.startsWith(Config.DEFAULT_COMMENT_SEM)) {
return;
} else if (line.startsWith('[') && line.endsWith(']')) {
if (currentLine.length !== 0) {
this.write(section, lineNumber - 1, currentLine);
currentLine = '';
}
section = line.substring(1, line.length - 1);
} else {
const equalIndex = line.indexOf('=');
if (equalIndex === -1) {
throw new Error(`parse the content error : line ${index + 1}`);
let shouldWrite = false;
if (line.includes(Config.DEFAULT_MULTI_LINE_SEPARATOR)) {
currentLine += line.substring(0, line.length - 1).trim();
// when the last line has a "\" string
if (lineNumber + 1 === linesCount) {
shouldWrite = true;
}
} else {
currentLine += line;
shouldWrite = true;
}
if (shouldWrite) {
this.write(section, lineNumber, currentLine);
currentLine = '';
}
const key = line.substring(0, equalIndex);
const value = line.substring(equalIndex + 1);
this.addConfig(section, key.trim(), value.trim());
}
});
}

private write(section: string, lineNum: number, line: string) {
const equalIndex = line.indexOf('=');
if (equalIndex === -1) {
throw new Error(`parse the content error : line ${lineNum}`);
}
const key = line.substring(0, equalIndex);
const value = line.substring(equalIndex + 1);
this.addConfig(section, key.trim(), value.trim());
}

public getBool(key: string): boolean {
return !!this.get(key);
}
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import * as Util from './util';

export * from './config';
export * from './enforcer';
export * from './effect';
export * from './model';
Expand Down
25 changes: 25 additions & 0 deletions test/config/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Config } from '../../src';

const config = Config.newConfig('test/config/testini.ini');

describe('multi-line test', () => {
it('should config.get("multi1::name") to equal r.sub==p.sub&&r.obj==p.obj', function() {
expect(config.get('multi1::name')).toEqual('r.sub==p.sub&&r.obj==p.obj');
});

it('should config.get("multi2::name") to equal r.sub==p.sub&&r.obj==p.obj', function() {
expect(config.get('multi2::name')).toEqual('r.sub==p.sub&&r.obj==p.obj');
});

it('should config.get("multi3::name") to equal r.sub==p.sub&&r.obj==p.obj', function() {
expect(config.get('multi3::name')).toEqual('r.sub==p.sub&&r.obj==p.obj');
});

it('should config.get("multi4::name") to equal r.sub==p.sub&&r.obj==p.obj', function() {
expect(config.get('multi4::name')).toEqual('');
});

it('should config.get("multi5::name") to equal r.sub==p.sub&&r.obj==p.obj', function() {
expect(config.get('multi5::name')).toEqual('r.sub==p.sub&&r.obj==p.obj');
});
});
47 changes: 47 additions & 0 deletions test/config/testini.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# test config
debug = true
url = act.wiki

; redis config
[redis]
redis.key = push1,push2

; mysql config
[mysql]
mysql.dev.host = 127.0.0.1
mysql.dev.user = root
mysql.dev.pass = 123456
mysql.dev.db = test

mysql.master.host = 10.0.0.1
mysql.master.user = root
mysql.master.pass = 89dds)2$#d
mysql.master.db = act

; math config
[math]
math.i64 = 64
math.f64 = 64.1

# multi-line test
[multi1]
name = r.sub==p.sub \
&&r.obj==p.obj\
\
[multi2]
name = r.sub==p.sub \
&&r.obj==p.obj

[multi3]
name = r.sub==p.sub \
&&r.obj==p.obj

[multi4]
name = \
\
\

[multi5]
name = r.sub==p.sub \
&&r.obj==p.obj\
\

0 comments on commit 9143514

Please sign in to comment.