support multiple modifiers
This commit is contained in:
parent
48af85e4a6
commit
2735d8e089
37
parse.nim
37
parse.nim
|
@ -74,7 +74,6 @@ proc parseModifierName(input: string,
|
||||||
op: char,
|
op: char,
|
||||||
name: string] =
|
name: string] =
|
||||||
assert(packet.cursor < input.len())
|
assert(packet.cursor < input.len())
|
||||||
const operators = ['=', ':', '+', '-', '?']
|
|
||||||
if packet.cursor == input.high():
|
if packet.cursor == input.high():
|
||||||
result.complete = false
|
result.complete = false
|
||||||
return
|
return
|
||||||
|
@ -82,8 +81,6 @@ proc parseModifierName(input: string,
|
||||||
packet.cursor.inc()
|
packet.cursor.inc()
|
||||||
return (true, '\0', nil)
|
return (true, '\0', nil)
|
||||||
result.op = input[packet.cursor]
|
result.op = input[packet.cursor]
|
||||||
if not (result.op in operators):
|
|
||||||
raise new(ValueError) # invalid operator
|
|
||||||
packet.cursor.inc()
|
packet.cursor.inc()
|
||||||
if result.op == '?':
|
if result.op == '?':
|
||||||
if input[packet.cursor] != '\n':
|
if input[packet.cursor] != '\n':
|
||||||
|
@ -163,6 +160,10 @@ proc parseData(input: string,
|
||||||
result.value = input[packet.cursor .. packet.cursor + packet.remainingPartLen - 1]
|
result.value = input[packet.cursor .. packet.cursor + packet.remainingPartLen - 1]
|
||||||
packet.remainingPartLen = -1
|
packet.remainingPartLen = -1
|
||||||
|
|
||||||
|
proc isModifierName(input: string, cursor: int): bool =
|
||||||
|
const operators = ['=', ':', '+', '-', '?']
|
||||||
|
input[cursor] in operators
|
||||||
|
|
||||||
proc newPacket*(): PsycPacket =
|
proc newPacket*(): PsycPacket =
|
||||||
PsycPacket(routingHeader: newSeq[Modifier](),
|
PsycPacket(routingHeader: newSeq[Modifier](),
|
||||||
entityHeader: newSeq[Modifier](),
|
entityHeader: newSeq[Modifier](),
|
||||||
|
@ -191,6 +192,10 @@ proc parse*(input: string,
|
||||||
result.needMoreInput = true
|
result.needMoreInput = true
|
||||||
case packet.state:
|
case packet.state:
|
||||||
of ParseState.RoutingModifierName:
|
of ParseState.RoutingModifierName:
|
||||||
|
if not isModifierName(input, packet.cursor):
|
||||||
|
packet.state = ParseState.ContentLength
|
||||||
|
result.needMoreInput = false
|
||||||
|
else:
|
||||||
let (complete, op, name) = parseModifierName(input, packet)
|
let (complete, op, name) = parseModifierName(input, packet)
|
||||||
if complete:
|
if complete:
|
||||||
result.needMoreInput = false
|
result.needMoreInput = false
|
||||||
|
@ -201,7 +206,7 @@ proc parse*(input: string,
|
||||||
let (complete, value) = parseModifierSimpleValue(input, packet)
|
let (complete, value) = parseModifierSimpleValue(input, packet)
|
||||||
result.needMoreInput = not complete
|
result.needMoreInput = not complete
|
||||||
if complete and value.len() > 0:
|
if complete and value.len() > 0:
|
||||||
packet.state = ParseState.ContentLength
|
packet.state = ParseState.RoutingModifierName
|
||||||
if packet.routingHeader[^1].value.isNil():
|
if packet.routingHeader[^1].value.isNil():
|
||||||
packet.routingHeader[^1].value = ""
|
packet.routingHeader[^1].value = ""
|
||||||
packet.routingHeader[^1].value.add(value)
|
packet.routingHeader[^1].value.add(value)
|
||||||
|
@ -213,6 +218,10 @@ proc parse*(input: string,
|
||||||
packet.state = ParseState.EntityModifierName
|
packet.state = ParseState.EntityModifierName
|
||||||
packet.contentLength = value
|
packet.contentLength = value
|
||||||
of ParseState.EntityModifierName:
|
of ParseState.EntityModifierName:
|
||||||
|
if not input.isModifierName(packet.cursor):
|
||||||
|
packet.state = ParseState.Method
|
||||||
|
result.needMoreInput = false
|
||||||
|
else:
|
||||||
let oldCursor = packet.cursor
|
let oldCursor = packet.cursor
|
||||||
let (complete, op, name) = parseModifierName(input, packet)
|
let (complete, op, name) = parseModifierName(input, packet)
|
||||||
packet.entityHeaderLen += packet.cursor - oldCursor
|
packet.entityHeaderLen += packet.cursor - oldCursor
|
||||||
|
@ -227,7 +236,7 @@ proc parse*(input: string,
|
||||||
result.needMoreInput = not complete
|
result.needMoreInput = not complete
|
||||||
packet.entityHeaderLen += (packet.cursor - oldCursor)
|
packet.entityHeaderLen += (packet.cursor - oldCursor)
|
||||||
if complete:
|
if complete:
|
||||||
packet.state = ParseState.Method
|
packet.state = ParseState.EntityModifierName
|
||||||
if not value.isNil():
|
if not value.isNil():
|
||||||
if packet.entityHeader[^1].value.isNil():
|
if packet.entityHeader[^1].value.isNil():
|
||||||
packet.entityHeader[^1].value = ""
|
packet.entityHeader[^1].value = ""
|
||||||
|
@ -258,28 +267,30 @@ suite "parser tests":
|
||||||
var packet = newPacket()
|
var packet = newPacket()
|
||||||
|
|
||||||
test "state sync":
|
test "state sync":
|
||||||
let input = ":_target\tpsyc://ve.symlynx.com/@blog\n\n?\n|\n"
|
let input = ":_target\talice\n\n?\n|\n"
|
||||||
while packet.state != ParseState.Complete:
|
while packet.state != ParseState.Complete:
|
||||||
discard parse(input, packet)
|
discard parse(input, packet)
|
||||||
check(packet.routingHeader.len() == 1)
|
check(packet.routingHeader.len() == 1)
|
||||||
check(packet.routingHeader[0] == Modifier(op: ':',
|
check(packet.routingHeader[0] == Modifier(op: ':',
|
||||||
name: "_target",
|
name: "_target",
|
||||||
value: "psyc://ve.symlynx.com/@blog"))
|
value: "alice"))
|
||||||
check(packet.entityHeader.len() == 1)
|
check(packet.entityHeader.len() == 1)
|
||||||
check(packet.entityHeader[0] == Modifier(op: '?', name: nil, value: nil))
|
check(packet.entityHeader[0] == Modifier(op: '?', name: nil, value: nil))
|
||||||
|
|
||||||
test "simple-arg":
|
test "simple-arg":
|
||||||
let input = ":_target\tpsyc://ve.symlynx.com/@blog\n\n:_test\thello\n|\n"
|
let input = ":_target\talice\n\n:_hello\tworld\n:_hallo\twelt\n|\n"
|
||||||
while packet.state != ParseState.Complete:
|
while packet.state != ParseState.Complete:
|
||||||
discard parse(input, packet)
|
discard parse(input, packet)
|
||||||
check(packet.entityHeader.len() == 1)
|
check(packet.entityHeader.len() == 2)
|
||||||
check(packet.entityHeader[0] == Modifier(op: ':', name: "_test", value: "hello"))
|
check(packet.entityHeader[0] == Modifier(op: ':', name: "_hello", value: "world"))
|
||||||
|
check(packet.entityHeader[1] == Modifier(op: ':', name: "_hallo", value: "welt"))
|
||||||
|
|
||||||
test "binary-arg":
|
test "binary-arg":
|
||||||
let input = ":_target\tpsyc://ve.symlynx.com/@blog\n\n:_test 5\thello\n|\n"
|
let input = ":_target\talice\n\n:_hello 5\tworld\n:_hallo 4\twelt\n|\n"
|
||||||
while packet.state != ParseState.Complete:
|
while packet.state != ParseState.Complete:
|
||||||
discard parse(input, packet)
|
discard parse(input, packet)
|
||||||
check(packet.entityHeader.len() == 1)
|
check(packet.entityHeader.len() == 2)
|
||||||
check(packet.entityHeader[0] == Modifier(op: ':', name: "_test", value: "hello"))
|
check(packet.entityHeader[0] == Modifier(op: ':', name: "_hello", value: "world"))
|
||||||
|
check(packet.entityHeader[1] == Modifier(op: ':', name: "_hallo", value: "welt"))
|
||||||
|
|
||||||
echo "parser tests completed"
|
echo "parser tests completed"
|
||||||
|
|
Loading…
Reference in New Issue