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