Upate.
This commit is contained in:
parent
9c04068eac
commit
264712dcbc
23
src/module/html.wren
vendored
23
src/module/html.wren
vendored
@ -31,31 +31,31 @@ class Html {
|
||||
}
|
||||
|
||||
static decodeUtf8_(bytes) {
|
||||
var result = ""
|
||||
var parts = []
|
||||
var i = 0
|
||||
while (i < bytes.count) {
|
||||
var b = bytes[i]
|
||||
if (b < 128) {
|
||||
result = result + String.fromCodePoint(b)
|
||||
parts.add(String.fromCodePoint(b))
|
||||
i = i + 1
|
||||
} else if ((b & 0xE0) == 0xC0 && i + 1 < bytes.count) {
|
||||
var cp = ((b & 0x1F) << 6) | (bytes[i + 1] & 0x3F)
|
||||
result = result + String.fromCodePoint(cp)
|
||||
parts.add(String.fromCodePoint(cp))
|
||||
i = i + 2
|
||||
} else if ((b & 0xF0) == 0xE0 && i + 2 < bytes.count) {
|
||||
var cp = ((b & 0x0F) << 12) | ((bytes[i + 1] & 0x3F) << 6) | (bytes[i + 2] & 0x3F)
|
||||
result = result + String.fromCodePoint(cp)
|
||||
parts.add(String.fromCodePoint(cp))
|
||||
i = i + 3
|
||||
} else if ((b & 0xF8) == 0xF0 && i + 3 < bytes.count) {
|
||||
var cp = ((b & 0x07) << 18) | ((bytes[i + 1] & 0x3F) << 12) | ((bytes[i + 2] & 0x3F) << 6) | (bytes[i + 3] & 0x3F)
|
||||
result = result + String.fromCodePoint(cp)
|
||||
parts.add(String.fromCodePoint(cp))
|
||||
i = i + 4
|
||||
} else {
|
||||
result = result + String.fromCodePoint(0xFFFD)
|
||||
parts.add(String.fromCodePoint(0xFFFD))
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static urldecode(string) {
|
||||
@ -65,20 +65,21 @@ class Html {
|
||||
|
||||
static slugify(string) {
|
||||
if (!(string is String)) Fiber.abort("Argument must be a string.")
|
||||
var result = ""
|
||||
var parts = []
|
||||
var prevHyphen = true
|
||||
for (c in string.bytes) {
|
||||
if ((c >= 65 && c <= 90)) {
|
||||
result = result + String.fromCodePoint(c + 32)
|
||||
parts.add(String.fromCodePoint(c + 32))
|
||||
prevHyphen = false
|
||||
} else if ((c >= 97 && c <= 122) || (c >= 48 && c <= 57)) {
|
||||
result = result + String.fromCodePoint(c)
|
||||
parts.add(String.fromCodePoint(c))
|
||||
prevHyphen = false
|
||||
} else if (!prevHyphen) {
|
||||
result = result + "-"
|
||||
parts.add("-")
|
||||
prevHyphen = true
|
||||
}
|
||||
}
|
||||
var result = parts.join("")
|
||||
if (result.count > 0 && result[-1] == "-") {
|
||||
result = result[0..-2]
|
||||
}
|
||||
|
||||
@ -35,31 +35,31 @@ static const char* htmlModuleSource =
|
||||
" }\n"
|
||||
"\n"
|
||||
" static decodeUtf8_(bytes) {\n"
|
||||
" var result = \"\"\n"
|
||||
" var parts = []\n"
|
||||
" var i = 0\n"
|
||||
" while (i < bytes.count) {\n"
|
||||
" var b = bytes[i]\n"
|
||||
" if (b < 128) {\n"
|
||||
" result = result + String.fromCodePoint(b)\n"
|
||||
" parts.add(String.fromCodePoint(b))\n"
|
||||
" i = i + 1\n"
|
||||
" } else if ((b & 0xE0) == 0xC0 && i + 1 < bytes.count) {\n"
|
||||
" var cp = ((b & 0x1F) << 6) | (bytes[i + 1] & 0x3F)\n"
|
||||
" result = result + String.fromCodePoint(cp)\n"
|
||||
" parts.add(String.fromCodePoint(cp))\n"
|
||||
" i = i + 2\n"
|
||||
" } else if ((b & 0xF0) == 0xE0 && i + 2 < bytes.count) {\n"
|
||||
" var cp = ((b & 0x0F) << 12) | ((bytes[i + 1] & 0x3F) << 6) | (bytes[i + 2] & 0x3F)\n"
|
||||
" result = result + String.fromCodePoint(cp)\n"
|
||||
" parts.add(String.fromCodePoint(cp))\n"
|
||||
" i = i + 3\n"
|
||||
" } else if ((b & 0xF8) == 0xF0 && i + 3 < bytes.count) {\n"
|
||||
" var cp = ((b & 0x07) << 18) | ((bytes[i + 1] & 0x3F) << 12) | ((bytes[i + 2] & 0x3F) << 6) | (bytes[i + 3] & 0x3F)\n"
|
||||
" result = result + String.fromCodePoint(cp)\n"
|
||||
" parts.add(String.fromCodePoint(cp))\n"
|
||||
" i = i + 4\n"
|
||||
" } else {\n"
|
||||
" result = result + String.fromCodePoint(0xFFFD)\n"
|
||||
" parts.add(String.fromCodePoint(0xFFFD))\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static urldecode(string) {\n"
|
||||
@ -69,20 +69,21 @@ static const char* htmlModuleSource =
|
||||
"\n"
|
||||
" static slugify(string) {\n"
|
||||
" if (!(string is String)) Fiber.abort(\"Argument must be a string.\")\n"
|
||||
" var result = \"\"\n"
|
||||
" var parts = []\n"
|
||||
" var prevHyphen = true\n"
|
||||
" for (c in string.bytes) {\n"
|
||||
" if ((c >= 65 && c <= 90)) {\n"
|
||||
" result = result + String.fromCodePoint(c + 32)\n"
|
||||
" parts.add(String.fromCodePoint(c + 32))\n"
|
||||
" prevHyphen = false\n"
|
||||
" } else if ((c >= 97 && c <= 122) || (c >= 48 && c <= 57)) {\n"
|
||||
" result = result + String.fromCodePoint(c)\n"
|
||||
" parts.add(String.fromCodePoint(c))\n"
|
||||
" prevHyphen = false\n"
|
||||
" } else if (!prevHyphen) {\n"
|
||||
" result = result + \"-\"\n"
|
||||
" parts.add(\"-\")\n"
|
||||
" prevHyphen = true\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" var result = parts.join(\"\")\n"
|
||||
" if (result.count > 0 && result[-1] == \"-\") {\n"
|
||||
" result = result[0..-2]\n"
|
||||
" }\n"
|
||||
|
||||
9
src/module/http.wren
vendored
9
src/module/http.wren
vendored
@ -64,6 +64,10 @@ class HttpResponse {
|
||||
_statusCode = statusCode
|
||||
_statusText = statusText
|
||||
_headers = headers
|
||||
_normalizedHeaders = {}
|
||||
for (key in headers.keys) {
|
||||
_normalizedHeaders[Url.toLower_(key)] = headers[key]
|
||||
}
|
||||
_body = body
|
||||
}
|
||||
|
||||
@ -75,10 +79,7 @@ class HttpResponse {
|
||||
|
||||
header(name) {
|
||||
var lower = Url.toLower_(name)
|
||||
for (entry in _headers) {
|
||||
if (Url.toLower_(entry.key) == lower) return entry.value
|
||||
}
|
||||
return null
|
||||
return _normalizedHeaders.containsKey(lower) ? _normalizedHeaders[lower] : null
|
||||
}
|
||||
|
||||
json {
|
||||
|
||||
@ -68,6 +68,10 @@ static const char* httpModuleSource =
|
||||
" _statusCode = statusCode\n"
|
||||
" _statusText = statusText\n"
|
||||
" _headers = headers\n"
|
||||
" _normalizedHeaders = {}\n"
|
||||
" for (key in headers.keys) {\n"
|
||||
" _normalizedHeaders[Url.toLower_(key)] = headers[key]\n"
|
||||
" }\n"
|
||||
" _body = body\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
@ -79,10 +83,7 @@ static const char* httpModuleSource =
|
||||
"\n"
|
||||
" header(name) {\n"
|
||||
" var lower = Url.toLower_(name)\n"
|
||||
" for (entry in _headers) {\n"
|
||||
" if (Url.toLower_(entry.key) == lower) return entry.value\n"
|
||||
" }\n"
|
||||
" return null\n"
|
||||
" return _normalizedHeaders.containsKey(lower) ? _normalizedHeaders[lower] : null\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" json {\n"
|
||||
|
||||
20
src/module/jinja.wren
vendored
20
src/module/jinja.wren
vendored
@ -1612,7 +1612,7 @@ class Parser {
|
||||
|
||||
parseRaw_() {
|
||||
consumeBlockEnd_()
|
||||
var content = ""
|
||||
var parts = []
|
||||
var bracePercent = "{\%"
|
||||
var percentBrace = " \%}"
|
||||
var doubleBrace = "{{"
|
||||
@ -1628,19 +1628,20 @@ class Parser {
|
||||
if (nextName.type == Token.NAME && nextName.value == "endraw") {
|
||||
advance_()
|
||||
consumeBlockEnd_()
|
||||
return RawNode.new(content)
|
||||
return RawNode.new(parts.join(""))
|
||||
}
|
||||
|
||||
content = content + bracePercent
|
||||
parts.add(bracePercent)
|
||||
while (!isAtEnd_() && peek_().type != Token.BLOCK_END && peek_().type != Token.BLOCK_END_TRIM) {
|
||||
var t = peek_()
|
||||
if (t.value != null) {
|
||||
content = content + " " + t.value.toString
|
||||
parts.add(" ")
|
||||
parts.add(t.value.toString)
|
||||
}
|
||||
advance_()
|
||||
}
|
||||
if (!isAtEnd_()) {
|
||||
content = content + percentBrace
|
||||
parts.add(percentBrace)
|
||||
advance_()
|
||||
}
|
||||
continue
|
||||
@ -1648,23 +1649,24 @@ class Parser {
|
||||
|
||||
if (token.type == Token.VAR_START || token.type == Token.VAR_START_TRIM) {
|
||||
advance_()
|
||||
content = content + doubleBrace
|
||||
parts.add(doubleBrace)
|
||||
while (!isAtEnd_() && peek_().type != Token.VAR_END && peek_().type != Token.VAR_END_TRIM) {
|
||||
var t = peek_()
|
||||
if (t.value != null) {
|
||||
content = content + " " + t.value.toString
|
||||
parts.add(" ")
|
||||
parts.add(t.value.toString)
|
||||
}
|
||||
advance_()
|
||||
}
|
||||
if (!isAtEnd_()) {
|
||||
content = content + doubleBraceEnd
|
||||
parts.add(doubleBraceEnd)
|
||||
advance_()
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if (token.type == Token.TEXT) {
|
||||
content = content + token.value
|
||||
parts.add(token.value)
|
||||
advance_()
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1616,7 +1616,7 @@ static const char* jinjaModuleSource =
|
||||
"\n"
|
||||
" parseRaw_() {\n"
|
||||
" consumeBlockEnd_()\n"
|
||||
" var content = \"\"\n"
|
||||
" var parts = []\n"
|
||||
" var bracePercent = \"{\\%\"\n"
|
||||
" var percentBrace = \" \\%}\"\n"
|
||||
" var doubleBrace = \"{{\"\n"
|
||||
@ -1632,19 +1632,20 @@ static const char* jinjaModuleSource =
|
||||
" if (nextName.type == Token.NAME && nextName.value == \"endraw\") {\n"
|
||||
" advance_()\n"
|
||||
" consumeBlockEnd_()\n"
|
||||
" return RawNode.new(content)\n"
|
||||
" return RawNode.new(parts.join(\"\"))\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" content = content + bracePercent\n"
|
||||
" parts.add(bracePercent)\n"
|
||||
" while (!isAtEnd_() && peek_().type != Token.BLOCK_END && peek_().type != Token.BLOCK_END_TRIM) {\n"
|
||||
" var t = peek_()\n"
|
||||
" if (t.value != null) {\n"
|
||||
" content = content + \" \" + t.value.toString\n"
|
||||
" parts.add(\" \")\n"
|
||||
" parts.add(t.value.toString)\n"
|
||||
" }\n"
|
||||
" advance_()\n"
|
||||
" }\n"
|
||||
" if (!isAtEnd_()) {\n"
|
||||
" content = content + percentBrace\n"
|
||||
" parts.add(percentBrace)\n"
|
||||
" advance_()\n"
|
||||
" }\n"
|
||||
" continue\n"
|
||||
@ -1652,23 +1653,24 @@ static const char* jinjaModuleSource =
|
||||
"\n"
|
||||
" if (token.type == Token.VAR_START || token.type == Token.VAR_START_TRIM) {\n"
|
||||
" advance_()\n"
|
||||
" content = content + doubleBrace\n"
|
||||
" parts.add(doubleBrace)\n"
|
||||
" while (!isAtEnd_() && peek_().type != Token.VAR_END && peek_().type != Token.VAR_END_TRIM) {\n"
|
||||
" var t = peek_()\n"
|
||||
" if (t.value != null) {\n"
|
||||
" content = content + \" \" + t.value.toString\n"
|
||||
" parts.add(\" \")\n"
|
||||
" parts.add(t.value.toString)\n"
|
||||
" }\n"
|
||||
" advance_()\n"
|
||||
" }\n"
|
||||
" if (!isAtEnd_()) {\n"
|
||||
" content = content + doubleBraceEnd\n"
|
||||
" parts.add(doubleBraceEnd)\n"
|
||||
" advance_()\n"
|
||||
" }\n"
|
||||
" continue\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (token.type == Token.TEXT) {\n"
|
||||
" content = content + token.value\n"
|
||||
" parts.add(token.value)\n"
|
||||
" advance_()\n"
|
||||
" continue\n"
|
||||
" }\n"
|
||||
|
||||
4
src/module/json.wren
vendored
4
src/module/json.wren
vendored
@ -10,9 +10,7 @@ class Json {
|
||||
static stringify(value, indent) {
|
||||
var indentStr = ""
|
||||
if (indent is Num && indent > 0) {
|
||||
for (i in 0...indent) {
|
||||
indentStr = indentStr + " "
|
||||
}
|
||||
indentStr = " " * indent
|
||||
} else if (indent is String) {
|
||||
indentStr = indent
|
||||
}
|
||||
|
||||
@ -14,9 +14,7 @@ static const char* jsonModuleSource =
|
||||
" static stringify(value, indent) {\n"
|
||||
" var indentStr = \"\"\n"
|
||||
" if (indent is Num && indent > 0) {\n"
|
||||
" for (i in 0...indent) {\n"
|
||||
" indentStr = indentStr + \" \"\n"
|
||||
" }\n"
|
||||
" indentStr = \" \" * indent\n"
|
||||
" } else if (indent is String) {\n"
|
||||
" indentStr = indent\n"
|
||||
" }\n"
|
||||
|
||||
231
src/module/markdown.wren
vendored
231
src/module/markdown.wren
vendored
@ -467,7 +467,7 @@ class Markdown {
|
||||
}
|
||||
|
||||
static processCode_(text) {
|
||||
var result = ""
|
||||
var parts = []
|
||||
var i = 0
|
||||
var chars = text.toList
|
||||
while (i < chars.count) {
|
||||
@ -477,152 +477,169 @@ class Markdown {
|
||||
end = end + 1
|
||||
}
|
||||
if (end < chars.count) {
|
||||
var code = ""
|
||||
var codeChars = []
|
||||
for (j in (i + 1)...end) {
|
||||
code = code + chars[j]
|
||||
codeChars.add(chars[j])
|
||||
}
|
||||
result = result + "<code>" + code + "</code>"
|
||||
parts.add("<code>")
|
||||
parts.add(codeChars.join(""))
|
||||
parts.add("</code>")
|
||||
i = end + 1
|
||||
} else {
|
||||
result = result + chars[i]
|
||||
parts.add(chars[i])
|
||||
i = i + 1
|
||||
}
|
||||
} else {
|
||||
result = result + chars[i]
|
||||
parts.add(chars[i])
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static processBold_(text) {
|
||||
var result = text
|
||||
while (result.contains("**")) {
|
||||
var start = result.indexOf("**")
|
||||
var rest = result[start + 2..-1]
|
||||
var end = rest.indexOf("**")
|
||||
if (end >= 0) {
|
||||
var before = result[0...start]
|
||||
var content = rest[0...end]
|
||||
var after = rest[end + 2..-1]
|
||||
result = before + "<strong>" + content + "</strong>" + after
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
while (result.contains("__")) {
|
||||
var start = result.indexOf("__")
|
||||
var rest = result[start + 2..-1]
|
||||
var end = rest.indexOf("__")
|
||||
if (end >= 0) {
|
||||
var before = result[0...start]
|
||||
var content = rest[0...end]
|
||||
var after = rest[end + 2..-1]
|
||||
result = before + "<strong>" + content + "</strong>" + after
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
var result = processMarker_(text, "**", "<strong>", "</strong>")
|
||||
result = processMarker_(result, "__", "<strong>", "</strong>")
|
||||
return result
|
||||
}
|
||||
|
||||
static processMarker_(text, marker, openTag, closeTag) {
|
||||
var parts = []
|
||||
var pos = 0
|
||||
var markerLen = marker.count
|
||||
while (pos < text.count) {
|
||||
var start = text.indexOf(marker, pos)
|
||||
if (start < 0) {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
var rest = text[start + markerLen..-1]
|
||||
var end = rest.indexOf(marker)
|
||||
if (end < 0) {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
parts.add(text[pos...start])
|
||||
parts.add(openTag)
|
||||
parts.add(rest[0...end])
|
||||
parts.add(closeTag)
|
||||
pos = start + markerLen + end + markerLen
|
||||
}
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static processItalic_(text) {
|
||||
var result = text
|
||||
while (result.contains("*")) {
|
||||
var start = result.indexOf("*")
|
||||
if (start > 0 && result[start - 1] == "<") {
|
||||
var parts = []
|
||||
var pos = 0
|
||||
while (pos < text.count) {
|
||||
var start = text.indexOf("*", pos)
|
||||
if (start < 0) {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
var rest = result[start + 1..-1]
|
||||
if (start > 0 && text[start - 1] == "<") {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
var rest = text[start + 1..-1]
|
||||
var end = rest.indexOf("*")
|
||||
if (end >= 0 && end > 0) {
|
||||
var before = result[0...start]
|
||||
var content = rest[0...end]
|
||||
var after = rest[end + 1..-1]
|
||||
result = before + "<em>" + content + "</em>" + after
|
||||
} else {
|
||||
if (end < 0 || end == 0) {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
parts.add(text[pos...start])
|
||||
parts.add("<em>")
|
||||
parts.add(rest[0...end])
|
||||
parts.add("</em>")
|
||||
pos = start + 1 + end + 1
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static processStrikethrough_(text) {
|
||||
var result = text
|
||||
while (result.contains("~~")) {
|
||||
var start = result.indexOf("~~")
|
||||
var rest = result[start + 2..-1]
|
||||
var end = rest.indexOf("~~")
|
||||
if (end >= 0) {
|
||||
var before = result[0...start]
|
||||
var content = rest[0...end]
|
||||
var after = rest[end + 2..-1]
|
||||
result = before + "<del>" + content + "</del>" + after
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
return processMarker_(text, "~~", "<del>", "</del>")
|
||||
}
|
||||
|
||||
static processLinks_(text) {
|
||||
var result = text
|
||||
while (result.contains("](")) {
|
||||
var linkEnd = result.indexOf("](")
|
||||
var parts = []
|
||||
var pos = 0
|
||||
while (pos < text.count) {
|
||||
var linkEnd = text.indexOf("](", pos)
|
||||
if (linkEnd < 0) {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
var textStart = linkEnd
|
||||
while (textStart > 0 && result[textStart - 1] != "[") {
|
||||
while (textStart > pos && text[textStart - 1] != "[") {
|
||||
textStart = textStart - 1
|
||||
}
|
||||
if (textStart > 0 && result[textStart - 1] == "[") {
|
||||
if (textStart > pos && text[textStart - 1] == "[") {
|
||||
var urlStart = linkEnd + 2
|
||||
var urlEnd = urlStart
|
||||
while (urlEnd < result.count && result[urlEnd] != ")") {
|
||||
while (urlEnd < text.count && text[urlEnd] != ")") {
|
||||
urlEnd = urlEnd + 1
|
||||
}
|
||||
if (urlEnd < result.count) {
|
||||
var before = result[0...textStart - 1]
|
||||
var linkText = result[textStart...linkEnd]
|
||||
var url = result[urlStart...urlEnd]
|
||||
var after = result[urlEnd + 1..-1]
|
||||
result = before + "<a href=\"" + url + "\">" + linkText + "</a>" + after
|
||||
if (urlEnd < text.count) {
|
||||
parts.add(text[pos...textStart - 1])
|
||||
var linkText = text[textStart...linkEnd]
|
||||
var url = text[urlStart...urlEnd]
|
||||
parts.add("<a href=\"")
|
||||
parts.add(url)
|
||||
parts.add("\">")
|
||||
parts.add(linkText)
|
||||
parts.add("</a>")
|
||||
pos = urlEnd + 1
|
||||
} else {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
} else {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static processImages_(text) {
|
||||
var result = text
|
||||
while (result.contains("![")) {
|
||||
var start = result.indexOf("![")
|
||||
var parts = []
|
||||
var pos = 0
|
||||
while (pos < text.count) {
|
||||
var start = text.indexOf("![", pos)
|
||||
if (start < 0) {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
var altEnd = start + 2
|
||||
while (altEnd < result.count && result[altEnd] != "]") {
|
||||
while (altEnd < text.count && text[altEnd] != "]") {
|
||||
altEnd = altEnd + 1
|
||||
}
|
||||
if (altEnd < result.count && altEnd + 1 < result.count && result[altEnd + 1] == "(") {
|
||||
if (altEnd < text.count && altEnd + 1 < text.count && text[altEnd + 1] == "(") {
|
||||
var urlStart = altEnd + 2
|
||||
var urlEnd = urlStart
|
||||
while (urlEnd < result.count && result[urlEnd] != ")") {
|
||||
while (urlEnd < text.count && text[urlEnd] != ")") {
|
||||
urlEnd = urlEnd + 1
|
||||
}
|
||||
if (urlEnd < result.count) {
|
||||
var before = result[0...start]
|
||||
var alt = result[start + 2...altEnd]
|
||||
var url = result[urlStart...urlEnd]
|
||||
var after = result[urlEnd + 1..-1]
|
||||
result = before + "<img src=\"" + url + "\" alt=\"" + alt + "\">" + after
|
||||
if (urlEnd < text.count) {
|
||||
parts.add(text[pos...start])
|
||||
var alt = text[start + 2...altEnd]
|
||||
var url = text[urlStart...urlEnd]
|
||||
parts.add("<img src=\"")
|
||||
parts.add(url)
|
||||
parts.add("\" alt=\"")
|
||||
parts.add(alt)
|
||||
parts.add("\">")
|
||||
pos = urlEnd + 1
|
||||
} else {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
} else {
|
||||
parts.add(text[pos..-1])
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static fromHtml(html) { fromHtml(html, {}) }
|
||||
@ -1133,19 +1150,22 @@ class Markdown {
|
||||
}
|
||||
|
||||
static processHrFromHtml_(html) {
|
||||
var result = html
|
||||
var parts = []
|
||||
var i = 0
|
||||
while (i < result.count) {
|
||||
if (matchTagName_(result, i, "hr")) {
|
||||
while (i < html.count) {
|
||||
if (matchTagName_(html, i, "hr")) {
|
||||
var end = i
|
||||
while (end < result.count && result[end] != ">") {
|
||||
while (end < html.count && html[end] != ">") {
|
||||
end = end + 1
|
||||
}
|
||||
result = result[0...i] + "\n---\n" + result[end + 1..-1]
|
||||
parts.add("\n---\n")
|
||||
i = end + 1
|
||||
} else {
|
||||
parts.add(html[i])
|
||||
i = i + 1
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static processParagraphsFromHtml_(html) {
|
||||
@ -1155,19 +1175,22 @@ class Markdown {
|
||||
}
|
||||
|
||||
static processBrFromHtml_(html) {
|
||||
var result = html
|
||||
var parts = []
|
||||
var i = 0
|
||||
while (i < result.count) {
|
||||
if (matchTagName_(result, i, "br")) {
|
||||
while (i < html.count) {
|
||||
if (matchTagName_(html, i, "br")) {
|
||||
var end = i
|
||||
while (end < result.count && result[end] != ">") {
|
||||
while (end < html.count && html[end] != ">") {
|
||||
end = end + 1
|
||||
}
|
||||
result = result[0...i] + "\n" + result[end + 1..-1]
|
||||
parts.add("\n")
|
||||
i = end + 1
|
||||
} else {
|
||||
parts.add(html[i])
|
||||
i = i + 1
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static stripContainerTags_(html) {
|
||||
@ -1349,7 +1372,7 @@ class Markdown {
|
||||
}
|
||||
|
||||
static stripAllTags_(html) {
|
||||
var result = ""
|
||||
var parts = []
|
||||
var inTag = false
|
||||
for (c in html) {
|
||||
if (c == "<") {
|
||||
@ -1357,10 +1380,10 @@ class Markdown {
|
||||
} else if (c == ">") {
|
||||
inTag = false
|
||||
} else if (!inTag) {
|
||||
result = result + c
|
||||
parts.add(c)
|
||||
}
|
||||
}
|
||||
return result
|
||||
return parts.join("")
|
||||
}
|
||||
|
||||
static cleanupWhitespace_(text) {
|
||||
|
||||
@ -471,7 +471,7 @@ static const char* markdownModuleSource =
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processCode_(text) {\n"
|
||||
" var result = \"\"\n"
|
||||
" var parts = []\n"
|
||||
" var i = 0\n"
|
||||
" var chars = text.toList\n"
|
||||
" while (i < chars.count) {\n"
|
||||
@ -481,152 +481,169 @@ static const char* markdownModuleSource =
|
||||
" end = end + 1\n"
|
||||
" }\n"
|
||||
" if (end < chars.count) {\n"
|
||||
" var code = \"\"\n"
|
||||
" var codeChars = []\n"
|
||||
" for (j in (i + 1)...end) {\n"
|
||||
" code = code + chars[j]\n"
|
||||
" codeChars.add(chars[j])\n"
|
||||
" }\n"
|
||||
" result = result + \"<code>\" + code + \"</code>\"\n"
|
||||
" parts.add(\"<code>\")\n"
|
||||
" parts.add(codeChars.join(\"\"))\n"
|
||||
" parts.add(\"</code>\")\n"
|
||||
" i = end + 1\n"
|
||||
" } else {\n"
|
||||
" result = result + chars[i]\n"
|
||||
" parts.add(chars[i])\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" } else {\n"
|
||||
" result = result + chars[i]\n"
|
||||
" parts.add(chars[i])\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processBold_(text) {\n"
|
||||
" var result = text\n"
|
||||
" while (result.contains(\"**\")) {\n"
|
||||
" var start = result.indexOf(\"**\")\n"
|
||||
" var rest = result[start + 2..-1]\n"
|
||||
" var end = rest.indexOf(\"**\")\n"
|
||||
" if (end >= 0) {\n"
|
||||
" var before = result[0...start]\n"
|
||||
" var content = rest[0...end]\n"
|
||||
" var after = rest[end + 2..-1]\n"
|
||||
" result = before + \"<strong>\" + content + \"</strong>\" + after\n"
|
||||
" } else {\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" while (result.contains(\"__\")) {\n"
|
||||
" var start = result.indexOf(\"__\")\n"
|
||||
" var rest = result[start + 2..-1]\n"
|
||||
" var end = rest.indexOf(\"__\")\n"
|
||||
" if (end >= 0) {\n"
|
||||
" var before = result[0...start]\n"
|
||||
" var content = rest[0...end]\n"
|
||||
" var after = rest[end + 2..-1]\n"
|
||||
" result = before + \"<strong>\" + content + \"</strong>\" + after\n"
|
||||
" } else {\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" var result = processMarker_(text, \"**\", \"<strong>\", \"</strong>\")\n"
|
||||
" result = processMarker_(result, \"__\", \"<strong>\", \"</strong>\")\n"
|
||||
" return result\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processMarker_(text, marker, openTag, closeTag) {\n"
|
||||
" var parts = []\n"
|
||||
" var pos = 0\n"
|
||||
" var markerLen = marker.count\n"
|
||||
" while (pos < text.count) {\n"
|
||||
" var start = text.indexOf(marker, pos)\n"
|
||||
" if (start < 0) {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" var rest = text[start + markerLen..-1]\n"
|
||||
" var end = rest.indexOf(marker)\n"
|
||||
" if (end < 0) {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" parts.add(text[pos...start])\n"
|
||||
" parts.add(openTag)\n"
|
||||
" parts.add(rest[0...end])\n"
|
||||
" parts.add(closeTag)\n"
|
||||
" pos = start + markerLen + end + markerLen\n"
|
||||
" }\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processItalic_(text) {\n"
|
||||
" var result = text\n"
|
||||
" while (result.contains(\"*\")) {\n"
|
||||
" var start = result.indexOf(\"*\")\n"
|
||||
" if (start > 0 && result[start - 1] == \"<\") {\n"
|
||||
" var parts = []\n"
|
||||
" var pos = 0\n"
|
||||
" while (pos < text.count) {\n"
|
||||
" var start = text.indexOf(\"*\", pos)\n"
|
||||
" if (start < 0) {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" var rest = result[start + 1..-1]\n"
|
||||
" if (start > 0 && text[start - 1] == \"<\") {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" var rest = text[start + 1..-1]\n"
|
||||
" var end = rest.indexOf(\"*\")\n"
|
||||
" if (end >= 0 && end > 0) {\n"
|
||||
" var before = result[0...start]\n"
|
||||
" var content = rest[0...end]\n"
|
||||
" var after = rest[end + 1..-1]\n"
|
||||
" result = before + \"<em>\" + content + \"</em>\" + after\n"
|
||||
" } else {\n"
|
||||
" if (end < 0 || end == 0) {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" parts.add(text[pos...start])\n"
|
||||
" parts.add(\"<em>\")\n"
|
||||
" parts.add(rest[0...end])\n"
|
||||
" parts.add(\"</em>\")\n"
|
||||
" pos = start + 1 + end + 1\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processStrikethrough_(text) {\n"
|
||||
" var result = text\n"
|
||||
" while (result.contains(\"~~\")) {\n"
|
||||
" var start = result.indexOf(\"~~\")\n"
|
||||
" var rest = result[start + 2..-1]\n"
|
||||
" var end = rest.indexOf(\"~~\")\n"
|
||||
" if (end >= 0) {\n"
|
||||
" var before = result[0...start]\n"
|
||||
" var content = rest[0...end]\n"
|
||||
" var after = rest[end + 2..-1]\n"
|
||||
" result = before + \"<del>\" + content + \"</del>\" + after\n"
|
||||
" } else {\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return processMarker_(text, \"~~\", \"<del>\", \"</del>\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processLinks_(text) {\n"
|
||||
" var result = text\n"
|
||||
" while (result.contains(\"](\")) {\n"
|
||||
" var linkEnd = result.indexOf(\"](\")\n"
|
||||
" var parts = []\n"
|
||||
" var pos = 0\n"
|
||||
" while (pos < text.count) {\n"
|
||||
" var linkEnd = text.indexOf(\"](\", pos)\n"
|
||||
" if (linkEnd < 0) {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" var textStart = linkEnd\n"
|
||||
" while (textStart > 0 && result[textStart - 1] != \"[\") {\n"
|
||||
" while (textStart > pos && text[textStart - 1] != \"[\") {\n"
|
||||
" textStart = textStart - 1\n"
|
||||
" }\n"
|
||||
" if (textStart > 0 && result[textStart - 1] == \"[\") {\n"
|
||||
" if (textStart > pos && text[textStart - 1] == \"[\") {\n"
|
||||
" var urlStart = linkEnd + 2\n"
|
||||
" var urlEnd = urlStart\n"
|
||||
" while (urlEnd < result.count && result[urlEnd] != \")\") {\n"
|
||||
" while (urlEnd < text.count && text[urlEnd] != \")\") {\n"
|
||||
" urlEnd = urlEnd + 1\n"
|
||||
" }\n"
|
||||
" if (urlEnd < result.count) {\n"
|
||||
" var before = result[0...textStart - 1]\n"
|
||||
" var linkText = result[textStart...linkEnd]\n"
|
||||
" var url = result[urlStart...urlEnd]\n"
|
||||
" var after = result[urlEnd + 1..-1]\n"
|
||||
" result = before + \"<a href=\\\"\" + url + \"\\\">\" + linkText + \"</a>\" + after\n"
|
||||
" if (urlEnd < text.count) {\n"
|
||||
" parts.add(text[pos...textStart - 1])\n"
|
||||
" var linkText = text[textStart...linkEnd]\n"
|
||||
" var url = text[urlStart...urlEnd]\n"
|
||||
" parts.add(\"<a href=\\\"\")\n"
|
||||
" parts.add(url)\n"
|
||||
" parts.add(\"\\\">\")\n"
|
||||
" parts.add(linkText)\n"
|
||||
" parts.add(\"</a>\")\n"
|
||||
" pos = urlEnd + 1\n"
|
||||
" } else {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" } else {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processImages_(text) {\n"
|
||||
" var result = text\n"
|
||||
" while (result.contains(\"![\")) {\n"
|
||||
" var start = result.indexOf(\"![\")\n"
|
||||
" var parts = []\n"
|
||||
" var pos = 0\n"
|
||||
" while (pos < text.count) {\n"
|
||||
" var start = text.indexOf(\"![\", pos)\n"
|
||||
" if (start < 0) {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" var altEnd = start + 2\n"
|
||||
" while (altEnd < result.count && result[altEnd] != \"]\") {\n"
|
||||
" while (altEnd < text.count && text[altEnd] != \"]\") {\n"
|
||||
" altEnd = altEnd + 1\n"
|
||||
" }\n"
|
||||
" if (altEnd < result.count && altEnd + 1 < result.count && result[altEnd + 1] == \"(\") {\n"
|
||||
" if (altEnd < text.count && altEnd + 1 < text.count && text[altEnd + 1] == \"(\") {\n"
|
||||
" var urlStart = altEnd + 2\n"
|
||||
" var urlEnd = urlStart\n"
|
||||
" while (urlEnd < result.count && result[urlEnd] != \")\") {\n"
|
||||
" while (urlEnd < text.count && text[urlEnd] != \")\") {\n"
|
||||
" urlEnd = urlEnd + 1\n"
|
||||
" }\n"
|
||||
" if (urlEnd < result.count) {\n"
|
||||
" var before = result[0...start]\n"
|
||||
" var alt = result[start + 2...altEnd]\n"
|
||||
" var url = result[urlStart...urlEnd]\n"
|
||||
" var after = result[urlEnd + 1..-1]\n"
|
||||
" result = before + \"<img src=\\\"\" + url + \"\\\" alt=\\\"\" + alt + \"\\\">\" + after\n"
|
||||
" if (urlEnd < text.count) {\n"
|
||||
" parts.add(text[pos...start])\n"
|
||||
" var alt = text[start + 2...altEnd]\n"
|
||||
" var url = text[urlStart...urlEnd]\n"
|
||||
" parts.add(\"<img src=\\\"\")\n"
|
||||
" parts.add(url)\n"
|
||||
" parts.add(\"\\\" alt=\\\"\")\n"
|
||||
" parts.add(alt)\n"
|
||||
" parts.add(\"\\\">\")\n"
|
||||
" pos = urlEnd + 1\n"
|
||||
" } else {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" } else {\n"
|
||||
" parts.add(text[pos..-1])\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static fromHtml(html) { fromHtml(html, {}) }\n"
|
||||
@ -1137,19 +1154,22 @@ static const char* markdownModuleSource =
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processHrFromHtml_(html) {\n"
|
||||
" var result = html\n"
|
||||
" var parts = []\n"
|
||||
" var i = 0\n"
|
||||
" while (i < result.count) {\n"
|
||||
" if (matchTagName_(result, i, \"hr\")) {\n"
|
||||
" while (i < html.count) {\n"
|
||||
" if (matchTagName_(html, i, \"hr\")) {\n"
|
||||
" var end = i\n"
|
||||
" while (end < result.count && result[end] != \">\") {\n"
|
||||
" while (end < html.count && html[end] != \">\") {\n"
|
||||
" end = end + 1\n"
|
||||
" }\n"
|
||||
" result = result[0...i] + \"\\n---\\n\" + result[end + 1..-1]\n"
|
||||
" parts.add(\"\\n---\\n\")\n"
|
||||
" i = end + 1\n"
|
||||
" } else {\n"
|
||||
" parts.add(html[i])\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processParagraphsFromHtml_(html) {\n"
|
||||
@ -1159,19 +1179,22 @@ static const char* markdownModuleSource =
|
||||
" }\n"
|
||||
"\n"
|
||||
" static processBrFromHtml_(html) {\n"
|
||||
" var result = html\n"
|
||||
" var parts = []\n"
|
||||
" var i = 0\n"
|
||||
" while (i < result.count) {\n"
|
||||
" if (matchTagName_(result, i, \"br\")) {\n"
|
||||
" while (i < html.count) {\n"
|
||||
" if (matchTagName_(html, i, \"br\")) {\n"
|
||||
" var end = i\n"
|
||||
" while (end < result.count && result[end] != \">\") {\n"
|
||||
" while (end < html.count && html[end] != \">\") {\n"
|
||||
" end = end + 1\n"
|
||||
" }\n"
|
||||
" result = result[0...i] + \"\\n\" + result[end + 1..-1]\n"
|
||||
" parts.add(\"\\n\")\n"
|
||||
" i = end + 1\n"
|
||||
" } else {\n"
|
||||
" parts.add(html[i])\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static stripContainerTags_(html) {\n"
|
||||
@ -1353,7 +1376,7 @@ static const char* markdownModuleSource =
|
||||
" }\n"
|
||||
"\n"
|
||||
" static stripAllTags_(html) {\n"
|
||||
" var result = \"\"\n"
|
||||
" var parts = []\n"
|
||||
" var inTag = false\n"
|
||||
" for (c in html) {\n"
|
||||
" if (c == \"<\") {\n"
|
||||
@ -1361,10 +1384,10 @@ static const char* markdownModuleSource =
|
||||
" } else if (c == \">\") {\n"
|
||||
" inTag = false\n"
|
||||
" } else if (!inTag) {\n"
|
||||
" result = result + c\n"
|
||||
" parts.add(c)\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return result\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static cleanupWhitespace_(text) {\n"
|
||||
|
||||
@ -14,9 +14,11 @@
|
||||
|
||||
typedef struct {
|
||||
uv_tcp_t* handle;
|
||||
WrenHandle* fiber; // Fiber waiting for an operation (connect, read, write)
|
||||
WrenHandle* fiber;
|
||||
uv_connect_t* connectReq;
|
||||
uv_write_t* writeReq;
|
||||
char* readBuffer;
|
||||
size_t readBufferSize;
|
||||
} SocketData;
|
||||
|
||||
typedef struct SocketListNode {
|
||||
@ -47,6 +49,8 @@ void socketAllocate(WrenVM* vm)
|
||||
data->fiber = NULL;
|
||||
data->connectReq = NULL;
|
||||
data->writeReq = NULL;
|
||||
data->readBuffer = NULL;
|
||||
data->readBufferSize = 0;
|
||||
}
|
||||
|
||||
static void closeCallback(uv_handle_t* handle)
|
||||
@ -60,6 +64,10 @@ void socketFinalize(void* data)
|
||||
if (socketData->handle) {
|
||||
uv_close((uv_handle_t*)socketData->handle, closeCallback);
|
||||
}
|
||||
if (socketData->readBuffer) {
|
||||
free(socketData->readBuffer);
|
||||
socketData->readBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void connectCallback(uv_connect_t* req, int status)
|
||||
@ -199,14 +207,19 @@ void socketWrite(WrenVM* vm)
|
||||
|
||||
static void allocCallback(uv_handle_t* handle, size_t suggestedSize, uv_buf_t* buf)
|
||||
{
|
||||
buf->base = (char*)malloc(suggestedSize);
|
||||
buf->len = suggestedSize;
|
||||
SocketData* data = (SocketData*)handle->data;
|
||||
if (data->readBuffer == NULL || data->readBufferSize < suggestedSize) {
|
||||
free(data->readBuffer);
|
||||
data->readBuffer = (char*)malloc(suggestedSize);
|
||||
data->readBufferSize = suggestedSize;
|
||||
}
|
||||
buf->base = data->readBuffer;
|
||||
buf->len = data->readBufferSize;
|
||||
}
|
||||
|
||||
static void readCallback(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
|
||||
{
|
||||
if (nread == 0) {
|
||||
free(buf->base);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -218,22 +231,18 @@ static void readCallback(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf
|
||||
|
||||
if (nread < 0) {
|
||||
if (nread == UV_EOF) {
|
||||
free(buf->base);
|
||||
schedulerResume(fiber, true);
|
||||
wrenSetSlotNull(getVM(), 2);
|
||||
schedulerFinishResume();
|
||||
return;
|
||||
}
|
||||
free(buf->base);
|
||||
schedulerResumeError(fiber, uv_strerror(nread));
|
||||
return;
|
||||
}
|
||||
|
||||
// Return the data
|
||||
|
||||
schedulerResume(fiber, true);
|
||||
wrenSetSlotBytes(getVM(), 2, buf->base, nread);
|
||||
schedulerFinishResume();
|
||||
free(buf->base);
|
||||
}
|
||||
|
||||
void socketRead(WrenVM* vm)
|
||||
@ -333,7 +342,9 @@ static void connectionCallback(uv_stream_t* server, int status)
|
||||
sockData->fiber = NULL;
|
||||
sockData->connectReq = NULL;
|
||||
sockData->writeReq = NULL;
|
||||
|
||||
sockData->readBuffer = NULL;
|
||||
sockData->readBufferSize = 0;
|
||||
|
||||
schedulerResume(fiber, true);
|
||||
schedulerFinishResume();
|
||||
} else {
|
||||
@ -363,7 +374,7 @@ void serverBind(WrenVM* vm)
|
||||
uv_ip4_addr(host, port, &addr);
|
||||
|
||||
uv_tcp_bind(data->handle, (const struct sockaddr*)&addr, 0);
|
||||
int r = uv_listen((uv_stream_t*)data->handle, 128, connectionCallback);
|
||||
int r = uv_listen((uv_stream_t*)data->handle, 1024, connectionCallback);
|
||||
if (r != 0) {
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotString(vm, 2, uv_strerror(r));
|
||||
@ -397,6 +408,8 @@ void serverAccept(WrenVM* vm)
|
||||
sockData->fiber = NULL;
|
||||
sockData->connectReq = NULL;
|
||||
sockData->writeReq = NULL;
|
||||
sockData->readBuffer = NULL;
|
||||
sockData->readBufferSize = 0;
|
||||
} else {
|
||||
WrenHandle* fiber = wrenGetSlotHandle(vm, 1);
|
||||
data->acceptFiber = fiber;
|
||||
|
||||
26
src/module/scheduler.wren
vendored
26
src/module/scheduler.wren
vendored
@ -1,7 +1,9 @@
|
||||
class Scheduler {
|
||||
static add(callable) {
|
||||
if (__scheduled == null) __scheduled = []
|
||||
|
||||
if (__scheduled == null) {
|
||||
__scheduled = []
|
||||
__scheduleIndex = 0
|
||||
}
|
||||
__scheduled.add(Fiber.new {
|
||||
callable.call()
|
||||
runNextScheduled_()
|
||||
@ -26,22 +28,32 @@ class Scheduler {
|
||||
}
|
||||
|
||||
static scheduleTransfer_(fiber, value) {
|
||||
if (__scheduled == null) __scheduled = []
|
||||
if (__scheduled == null) {
|
||||
__scheduled = []
|
||||
__scheduleIndex = 0
|
||||
}
|
||||
__scheduled.add(Fiber.new {
|
||||
fiber.transfer(value)
|
||||
})
|
||||
}
|
||||
|
||||
static runNextScheduled_() {
|
||||
if (__scheduled == null || __scheduled.isEmpty) {
|
||||
if (__scheduled == null || __scheduleIndex >= __scheduled.count) {
|
||||
__scheduled = null
|
||||
__scheduleIndex = 0
|
||||
return Fiber.suspend()
|
||||
} else {
|
||||
return __scheduled.removeAt(0).transfer()
|
||||
}
|
||||
var fiber = __scheduled[__scheduleIndex]
|
||||
__scheduleIndex = __scheduleIndex + 1
|
||||
if (__scheduleIndex > 64 && __scheduleIndex > __scheduled.count / 2) {
|
||||
__scheduled = __scheduled[__scheduleIndex..-1]
|
||||
__scheduleIndex = 0
|
||||
}
|
||||
return fiber.transfer()
|
||||
}
|
||||
|
||||
static hasScheduled_ {
|
||||
return __scheduled != null && !__scheduled.isEmpty
|
||||
return __scheduled != null && __scheduleIndex < __scheduled.count
|
||||
}
|
||||
|
||||
foreign static captureMethods_()
|
||||
|
||||
@ -4,8 +4,10 @@
|
||||
static const char* schedulerModuleSource =
|
||||
"class Scheduler {\n"
|
||||
" static add(callable) {\n"
|
||||
" if (__scheduled == null) __scheduled = []\n"
|
||||
"\n"
|
||||
" if (__scheduled == null) {\n"
|
||||
" __scheduled = []\n"
|
||||
" __scheduleIndex = 0\n"
|
||||
" }\n"
|
||||
" __scheduled.add(Fiber.new {\n"
|
||||
" callable.call()\n"
|
||||
" runNextScheduled_()\n"
|
||||
@ -30,22 +32,32 @@ static const char* schedulerModuleSource =
|
||||
" }\n"
|
||||
"\n"
|
||||
" static scheduleTransfer_(fiber, value) {\n"
|
||||
" if (__scheduled == null) __scheduled = []\n"
|
||||
" if (__scheduled == null) {\n"
|
||||
" __scheduled = []\n"
|
||||
" __scheduleIndex = 0\n"
|
||||
" }\n"
|
||||
" __scheduled.add(Fiber.new {\n"
|
||||
" fiber.transfer(value)\n"
|
||||
" })\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static runNextScheduled_() {\n"
|
||||
" if (__scheduled == null || __scheduled.isEmpty) {\n"
|
||||
" if (__scheduled == null || __scheduleIndex >= __scheduled.count) {\n"
|
||||
" __scheduled = null\n"
|
||||
" __scheduleIndex = 0\n"
|
||||
" return Fiber.suspend()\n"
|
||||
" } else {\n"
|
||||
" return __scheduled.removeAt(0).transfer()\n"
|
||||
" }\n"
|
||||
" var fiber = __scheduled[__scheduleIndex]\n"
|
||||
" __scheduleIndex = __scheduleIndex + 1\n"
|
||||
" if (__scheduleIndex > 64 && __scheduleIndex > __scheduled.count / 2) {\n"
|
||||
" __scheduled = __scheduled[__scheduleIndex..-1]\n"
|
||||
" __scheduleIndex = 0\n"
|
||||
" }\n"
|
||||
" return fiber.transfer()\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" static hasScheduled_ {\n"
|
||||
" return __scheduled != null && !__scheduled.isEmpty\n"
|
||||
" return __scheduled != null && __scheduleIndex < __scheduled.count\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" foreign static captureMethods_()\n"
|
||||
|
||||
@ -158,11 +158,7 @@ static void queryInternal(WrenVM* vm, bool hasParams) {
|
||||
case SQLITE_BLOB: {
|
||||
int size = sqlite3_column_bytes(stmt, i);
|
||||
const unsigned char* blob = sqlite3_column_blob(stmt, i);
|
||||
wrenSetSlotNewList(vm, 4);
|
||||
for (int j = 0; j < size; j++) {
|
||||
wrenSetSlotDouble(vm, 2, (double)blob[j]);
|
||||
wrenInsertInList(vm, 4, -1, 2);
|
||||
}
|
||||
wrenSetSlotBytes(vm, 4, (const char*)blob, size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
8
src/module/wdantic.wren
vendored
8
src/module/wdantic.wren
vendored
@ -14,7 +14,7 @@ class Validator {
|
||||
if (dot < at + 2) return false
|
||||
if (dot >= value.count - 1) return false
|
||||
for (c in value) {
|
||||
var code = c.codePoints.toList[0]
|
||||
var code = c.bytes[0]
|
||||
if (c == "@" || c == "." || c == "_" || c == "-" || c == "+") continue
|
||||
if (code >= 48 && code <= 57) continue
|
||||
if (code >= 65 && code <= 90) continue
|
||||
@ -34,7 +34,7 @@ class Validator {
|
||||
if (part.count == 0 || part.count > 63) return false
|
||||
if (part[0] == "-" || part[-1] == "-") return false
|
||||
for (c in part) {
|
||||
var code = c.codePoints.toList[0]
|
||||
var code = c.bytes[0]
|
||||
if (c == "-") continue
|
||||
if (code >= 48 && code <= 57) continue
|
||||
if (code >= 65 && code <= 90) continue
|
||||
@ -56,7 +56,7 @@ class Validator {
|
||||
static httpEncoded(value) {
|
||||
if (!(value is String)) return false
|
||||
for (c in value) {
|
||||
var code = c.codePoints.toList[0]
|
||||
var code = c.bytes[0]
|
||||
if (c == "_" || c == "." || c == "~" || c == "-" || c == "+") continue
|
||||
if (c == "\%") continue
|
||||
if (code >= 48 && code <= 57) continue
|
||||
@ -79,7 +79,7 @@ class Validator {
|
||||
} else if (padCount > 0) {
|
||||
return false
|
||||
} else {
|
||||
var code = c.codePoints.toList[0]
|
||||
var code = c.bytes[0]
|
||||
if (c == "+" || c == "/") continue
|
||||
if (code >= 48 && code <= 57) continue
|
||||
if (code >= 65 && code <= 90) continue
|
||||
|
||||
@ -18,7 +18,7 @@ static const char* wdanticModuleSource =
|
||||
" if (dot < at + 2) return false\n"
|
||||
" if (dot >= value.count - 1) return false\n"
|
||||
" for (c in value) {\n"
|
||||
" var code = c.codePoints.toList[0]\n"
|
||||
" var code = c.bytes[0]\n"
|
||||
" if (c == \"@\" || c == \".\" || c == \"_\" || c == \"-\" || c == \"+\") continue\n"
|
||||
" if (code >= 48 && code <= 57) continue\n"
|
||||
" if (code >= 65 && code <= 90) continue\n"
|
||||
@ -38,7 +38,7 @@ static const char* wdanticModuleSource =
|
||||
" if (part.count == 0 || part.count > 63) return false\n"
|
||||
" if (part[0] == \"-\" || part[-1] == \"-\") return false\n"
|
||||
" for (c in part) {\n"
|
||||
" var code = c.codePoints.toList[0]\n"
|
||||
" var code = c.bytes[0]\n"
|
||||
" if (c == \"-\") continue\n"
|
||||
" if (code >= 48 && code <= 57) continue\n"
|
||||
" if (code >= 65 && code <= 90) continue\n"
|
||||
@ -60,7 +60,7 @@ static const char* wdanticModuleSource =
|
||||
" static httpEncoded(value) {\n"
|
||||
" if (!(value is String)) return false\n"
|
||||
" for (c in value) {\n"
|
||||
" var code = c.codePoints.toList[0]\n"
|
||||
" var code = c.bytes[0]\n"
|
||||
" if (c == \"_\" || c == \".\" || c == \"~\" || c == \"-\" || c == \"+\") continue\n"
|
||||
" if (c == \"\\%\") continue\n"
|
||||
" if (code >= 48 && code <= 57) continue\n"
|
||||
@ -83,7 +83,7 @@ static const char* wdanticModuleSource =
|
||||
" } else if (padCount > 0) {\n"
|
||||
" return false\n"
|
||||
" } else {\n"
|
||||
" var code = c.codePoints.toList[0]\n"
|
||||
" var code = c.bytes[0]\n"
|
||||
" if (c == \"+\" || c == \"/\") continue\n"
|
||||
" if (code >= 48 && code <= 57) continue\n"
|
||||
" if (code >= 65 && code <= 90) continue\n"
|
||||
|
||||
55
src/module/web.wren
vendored
55
src/module/web.wren
vendored
@ -21,6 +21,10 @@ class Request {
|
||||
_path = path
|
||||
_query = query
|
||||
_headers = headers
|
||||
_normalizedHeaders = {}
|
||||
for (key in headers.keys) {
|
||||
_normalizedHeaders[Str.toLower(key)] = headers[key]
|
||||
}
|
||||
_body = body
|
||||
_params = params
|
||||
_socket = socket
|
||||
@ -39,11 +43,8 @@ class Request {
|
||||
socket { _socket }
|
||||
|
||||
header(name) {
|
||||
var lower = toLower_(name)
|
||||
for (key in _headers.keys) {
|
||||
if (toLower_(key) == lower) return _headers[key]
|
||||
}
|
||||
return null
|
||||
var lower = Str.toLower(name)
|
||||
return _normalizedHeaders.containsKey(lower) ? _normalizedHeaders[lower] : null
|
||||
}
|
||||
|
||||
json {
|
||||
@ -304,16 +305,23 @@ class Response {
|
||||
}
|
||||
|
||||
build() {
|
||||
var response = "HTTP/1.1 %(_status) %(_statusText)\r\n"
|
||||
var parts = []
|
||||
parts.add("HTTP/1.1 %(_status) %(_statusText)\r\n")
|
||||
_headers["Content-Length"] = _body.bytes.count.toString
|
||||
for (name in _headers.keys) {
|
||||
response = response + name + ": " + _headers[name] + "\r\n"
|
||||
parts.add(name)
|
||||
parts.add(": ")
|
||||
parts.add(_headers[name])
|
||||
parts.add("\r\n")
|
||||
}
|
||||
for (cookie in _cookies) {
|
||||
response = response + "Set-Cookie: " + cookie + "\r\n"
|
||||
parts.add("Set-Cookie: ")
|
||||
parts.add(cookie)
|
||||
parts.add("\r\n")
|
||||
}
|
||||
response = response + "\r\n" + _body
|
||||
return response
|
||||
parts.add("\r\n")
|
||||
parts.add(_body)
|
||||
return parts.join("")
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,7 +863,7 @@ class Application {
|
||||
var contentLength = 0
|
||||
var headersComplete = false
|
||||
var headerBytes = 0
|
||||
var requestData = null
|
||||
var headerStr = null
|
||||
|
||||
while (true) {
|
||||
var chunk = socket.read()
|
||||
@ -867,30 +875,26 @@ class Application {
|
||||
totalBytes = totalBytes + chunk.bytes.count
|
||||
|
||||
if (!headersComplete) {
|
||||
requestData = chunks.join("")
|
||||
if (requestData.contains("\r\n\r\n")) {
|
||||
headerStr = headerStr == null ? chunk : headerStr + chunk
|
||||
var delimIdx = headerStr.indexOf("\r\n\r\n")
|
||||
if (delimIdx >= 0) {
|
||||
headersComplete = true
|
||||
var headerEnd = requestData.indexOf("\r\n\r\n")
|
||||
headerBytes = headerEnd + 4
|
||||
|
||||
var headerPart = requestData[0...headerEnd]
|
||||
headerBytes = delimIdx + 4
|
||||
var headerPart = headerStr[0...delimIdx]
|
||||
var headers = parseHeaders_(headerPart)
|
||||
if (headers.containsKey("Content-Length")) {
|
||||
contentLength = Num.fromString(headers["Content-Length"])
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
||||
if (totalBytes - headerBytes >= contentLength) break
|
||||
if (totalBytes >= headerBytes + contentLength) break
|
||||
}
|
||||
} else {
|
||||
if (totalBytes - headerBytes >= contentLength) break
|
||||
if (totalBytes >= headerBytes + contentLength) break
|
||||
}
|
||||
}
|
||||
|
||||
if (requestData == null || chunks.count > 1) {
|
||||
requestData = chunks.join("")
|
||||
}
|
||||
var requestData = chunks.join("")
|
||||
|
||||
var headerEnd = requestData.indexOf("\r\n\r\n")
|
||||
var headerPart = requestData[0...headerEnd]
|
||||
@ -1094,12 +1098,13 @@ class Client {
|
||||
|
||||
socket.write(request)
|
||||
|
||||
var response = ""
|
||||
var chunks = []
|
||||
while (true) {
|
||||
var chunk = socket.read()
|
||||
if (chunk == null || chunk.bytes.count == 0) break
|
||||
response = response + chunk
|
||||
chunks.add(chunk)
|
||||
}
|
||||
var response = chunks.join("")
|
||||
socket.close()
|
||||
|
||||
return parseResponse_(response)
|
||||
|
||||
@ -25,6 +25,10 @@ static const char* webModuleSource =
|
||||
" _path = path\n"
|
||||
" _query = query\n"
|
||||
" _headers = headers\n"
|
||||
" _normalizedHeaders = {}\n"
|
||||
" for (key in headers.keys) {\n"
|
||||
" _normalizedHeaders[Str.toLower(key)] = headers[key]\n"
|
||||
" }\n"
|
||||
" _body = body\n"
|
||||
" _params = params\n"
|
||||
" _socket = socket\n"
|
||||
@ -43,11 +47,8 @@ static const char* webModuleSource =
|
||||
" socket { _socket }\n"
|
||||
"\n"
|
||||
" header(name) {\n"
|
||||
" var lower = toLower_(name)\n"
|
||||
" for (key in _headers.keys) {\n"
|
||||
" if (toLower_(key) == lower) return _headers[key]\n"
|
||||
" }\n"
|
||||
" return null\n"
|
||||
" var lower = Str.toLower(name)\n"
|
||||
" return _normalizedHeaders.containsKey(lower) ? _normalizedHeaders[lower] : null\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" json {\n"
|
||||
@ -308,16 +309,23 @@ static const char* webModuleSource =
|
||||
" }\n"
|
||||
"\n"
|
||||
" build() {\n"
|
||||
" var response = \"HTTP/1.1 %(_status) %(_statusText)\\r\\n\"\n"
|
||||
" var parts = []\n"
|
||||
" parts.add(\"HTTP/1.1 %(_status) %(_statusText)\\r\\n\")\n"
|
||||
" _headers[\"Content-Length\"] = _body.bytes.count.toString\n"
|
||||
" for (name in _headers.keys) {\n"
|
||||
" response = response + name + \": \" + _headers[name] + \"\\r\\n\"\n"
|
||||
" parts.add(name)\n"
|
||||
" parts.add(\": \")\n"
|
||||
" parts.add(_headers[name])\n"
|
||||
" parts.add(\"\\r\\n\")\n"
|
||||
" }\n"
|
||||
" for (cookie in _cookies) {\n"
|
||||
" response = response + \"Set-Cookie: \" + cookie + \"\\r\\n\"\n"
|
||||
" parts.add(\"Set-Cookie: \")\n"
|
||||
" parts.add(cookie)\n"
|
||||
" parts.add(\"\\r\\n\")\n"
|
||||
" }\n"
|
||||
" response = response + \"\\r\\n\" + _body\n"
|
||||
" return response\n"
|
||||
" parts.add(\"\\r\\n\")\n"
|
||||
" parts.add(_body)\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
@ -859,7 +867,7 @@ static const char* webModuleSource =
|
||||
" var contentLength = 0\n"
|
||||
" var headersComplete = false\n"
|
||||
" var headerBytes = 0\n"
|
||||
" var requestData = null\n"
|
||||
" var headerStr = null\n"
|
||||
"\n"
|
||||
" while (true) {\n"
|
||||
" var chunk = socket.read()\n"
|
||||
@ -871,30 +879,26 @@ static const char* webModuleSource =
|
||||
" totalBytes = totalBytes + chunk.bytes.count\n"
|
||||
"\n"
|
||||
" if (!headersComplete) {\n"
|
||||
" requestData = chunks.join(\"\")\n"
|
||||
" if (requestData.contains(\"\\r\\n\\r\\n\")) {\n"
|
||||
" headerStr = headerStr == null ? chunk : headerStr + chunk\n"
|
||||
" var delimIdx = headerStr.indexOf(\"\\r\\n\\r\\n\")\n"
|
||||
" if (delimIdx >= 0) {\n"
|
||||
" headersComplete = true\n"
|
||||
" var headerEnd = requestData.indexOf(\"\\r\\n\\r\\n\")\n"
|
||||
" headerBytes = headerEnd + 4\n"
|
||||
"\n"
|
||||
" var headerPart = requestData[0...headerEnd]\n"
|
||||
" headerBytes = delimIdx + 4\n"
|
||||
" var headerPart = headerStr[0...delimIdx]\n"
|
||||
" var headers = parseHeaders_(headerPart)\n"
|
||||
" if (headers.containsKey(\"Content-Length\")) {\n"
|
||||
" contentLength = Num.fromString(headers[\"Content-Length\"])\n"
|
||||
" } else {\n"
|
||||
" break\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (totalBytes - headerBytes >= contentLength) break\n"
|
||||
" if (totalBytes >= headerBytes + contentLength) break\n"
|
||||
" }\n"
|
||||
" } else {\n"
|
||||
" if (totalBytes - headerBytes >= contentLength) break\n"
|
||||
" if (totalBytes >= headerBytes + contentLength) break\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" if (requestData == null || chunks.count > 1) {\n"
|
||||
" requestData = chunks.join(\"\")\n"
|
||||
" }\n"
|
||||
" var requestData = chunks.join(\"\")\n"
|
||||
"\n"
|
||||
" var headerEnd = requestData.indexOf(\"\\r\\n\\r\\n\")\n"
|
||||
" var headerPart = requestData[0...headerEnd]\n"
|
||||
@ -1098,12 +1102,13 @@ static const char* webModuleSource =
|
||||
"\n"
|
||||
" socket.write(request)\n"
|
||||
"\n"
|
||||
" var response = \"\"\n"
|
||||
" var chunks = []\n"
|
||||
" while (true) {\n"
|
||||
" var chunk = socket.read()\n"
|
||||
" if (chunk == null || chunk.bytes.count == 0) break\n"
|
||||
" response = response + chunk\n"
|
||||
" chunks.add(chunk)\n"
|
||||
" }\n"
|
||||
" var response = chunks.join(\"\")\n"
|
||||
" socket.close()\n"
|
||||
"\n"
|
||||
" return parseResponse_(response)\n"
|
||||
|
||||
55
src/module/yaml.wren
vendored
55
src/module/yaml.wren
vendored
@ -258,12 +258,36 @@ class YamlParser {
|
||||
if ((str[0] == "\"" && str[-1] == "\"") ||
|
||||
(str[0] == "'" && str[-1] == "'")) {
|
||||
var inner = str[1...-1]
|
||||
inner = inner.replace("\\n", "\n")
|
||||
inner = inner.replace("\\t", "\t")
|
||||
inner = inner.replace("\\\"", "\"")
|
||||
inner = inner.replace("\\'", "'")
|
||||
inner = inner.replace("\\\\", "\\")
|
||||
return inner
|
||||
var parts = []
|
||||
var i = 0
|
||||
while (i < inner.count) {
|
||||
if (inner[i] == "\\" && i + 1 < inner.count) {
|
||||
var next = inner[i + 1]
|
||||
if (next == "n") {
|
||||
parts.add("\n")
|
||||
i = i + 2
|
||||
} else if (next == "t") {
|
||||
parts.add("\t")
|
||||
i = i + 2
|
||||
} else if (next == "\"") {
|
||||
parts.add("\"")
|
||||
i = i + 2
|
||||
} else if (next == "'") {
|
||||
parts.add("'")
|
||||
i = i + 2
|
||||
} else if (next == "\\") {
|
||||
parts.add("\\")
|
||||
i = i + 2
|
||||
} else {
|
||||
parts.add(inner[i])
|
||||
i = i + 1
|
||||
}
|
||||
} else {
|
||||
parts.add(inner[i])
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
return parts.join("")
|
||||
}
|
||||
return str
|
||||
}
|
||||
@ -391,12 +415,7 @@ class Yaml {
|
||||
if (list.count == 0) return "[]"
|
||||
|
||||
var result = []
|
||||
var prefix = ""
|
||||
for (i in 0...level) {
|
||||
for (j in 0...indent) {
|
||||
prefix = prefix + " "
|
||||
}
|
||||
}
|
||||
var prefix = " " * (level * indent)
|
||||
|
||||
for (item in list) {
|
||||
if (item is Map && item.count > 0) {
|
||||
@ -415,10 +434,7 @@ class Yaml {
|
||||
}
|
||||
first = false
|
||||
} else {
|
||||
var keyPrefix = prefix
|
||||
for (j in 0...indent) {
|
||||
keyPrefix = keyPrefix + " "
|
||||
}
|
||||
var keyPrefix = prefix + (" " * indent)
|
||||
if (item[key] is Map || item[key] is List) {
|
||||
result.add(keyPrefix + key + ":")
|
||||
var nestedLines = valueStr.split("\n")
|
||||
@ -450,12 +466,7 @@ class Yaml {
|
||||
if (map.count == 0) return "{}"
|
||||
|
||||
var result = []
|
||||
var prefix = ""
|
||||
for (i in 0...level) {
|
||||
for (j in 0...indent) {
|
||||
prefix = prefix + " "
|
||||
}
|
||||
}
|
||||
var prefix = " " * (level * indent)
|
||||
|
||||
for (key in map.keys) {
|
||||
var keyStr = stringifyString_(key.toString)
|
||||
|
||||
@ -262,12 +262,36 @@ static const char* yamlModuleSource =
|
||||
" if ((str[0] == \"\\\"\" && str[-1] == \"\\\"\") ||\n"
|
||||
" (str[0] == \"'\" && str[-1] == \"'\")) {\n"
|
||||
" var inner = str[1...-1]\n"
|
||||
" inner = inner.replace(\"\\\\n\", \"\\n\")\n"
|
||||
" inner = inner.replace(\"\\\\t\", \"\\t\")\n"
|
||||
" inner = inner.replace(\"\\\\\\\"\", \"\\\"\")\n"
|
||||
" inner = inner.replace(\"\\\\'\", \"'\")\n"
|
||||
" inner = inner.replace(\"\\\\\\\\\", \"\\\\\")\n"
|
||||
" return inner\n"
|
||||
" var parts = []\n"
|
||||
" var i = 0\n"
|
||||
" while (i < inner.count) {\n"
|
||||
" if (inner[i] == \"\\\\\" && i + 1 < inner.count) {\n"
|
||||
" var next = inner[i + 1]\n"
|
||||
" if (next == \"n\") {\n"
|
||||
" parts.add(\"\\n\")\n"
|
||||
" i = i + 2\n"
|
||||
" } else if (next == \"t\") {\n"
|
||||
" parts.add(\"\\t\")\n"
|
||||
" i = i + 2\n"
|
||||
" } else if (next == \"\\\"\") {\n"
|
||||
" parts.add(\"\\\"\")\n"
|
||||
" i = i + 2\n"
|
||||
" } else if (next == \"'\") {\n"
|
||||
" parts.add(\"'\")\n"
|
||||
" i = i + 2\n"
|
||||
" } else if (next == \"\\\\\") {\n"
|
||||
" parts.add(\"\\\\\")\n"
|
||||
" i = i + 2\n"
|
||||
" } else {\n"
|
||||
" parts.add(inner[i])\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" } else {\n"
|
||||
" parts.add(inner[i])\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return parts.join(\"\")\n"
|
||||
" }\n"
|
||||
" return str\n"
|
||||
" }\n"
|
||||
@ -395,12 +419,7 @@ static const char* yamlModuleSource =
|
||||
" if (list.count == 0) return \"[]\"\n"
|
||||
"\n"
|
||||
" var result = []\n"
|
||||
" var prefix = \"\"\n"
|
||||
" for (i in 0...level) {\n"
|
||||
" for (j in 0...indent) {\n"
|
||||
" prefix = prefix + \" \"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" var prefix = \" \" * (level * indent)\n"
|
||||
"\n"
|
||||
" for (item in list) {\n"
|
||||
" if (item is Map && item.count > 0) {\n"
|
||||
@ -419,10 +438,7 @@ static const char* yamlModuleSource =
|
||||
" }\n"
|
||||
" first = false\n"
|
||||
" } else {\n"
|
||||
" var keyPrefix = prefix\n"
|
||||
" for (j in 0...indent) {\n"
|
||||
" keyPrefix = keyPrefix + \" \"\n"
|
||||
" }\n"
|
||||
" var keyPrefix = prefix + (\" \" * indent)\n"
|
||||
" if (item[key] is Map || item[key] is List) {\n"
|
||||
" result.add(keyPrefix + key + \":\")\n"
|
||||
" var nestedLines = valueStr.split(\"\\n\")\n"
|
||||
@ -454,12 +470,7 @@ static const char* yamlModuleSource =
|
||||
" if (map.count == 0) return \"{}\"\n"
|
||||
"\n"
|
||||
" var result = []\n"
|
||||
" var prefix = \"\"\n"
|
||||
" for (i in 0...level) {\n"
|
||||
" for (j in 0...indent) {\n"
|
||||
" prefix = prefix + \" \"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" var prefix = \" \" * (level * indent)\n"
|
||||
"\n"
|
||||
" for (key in map.keys) {\n"
|
||||
" var keyStr = stringifyString_(key.toString)\n"
|
||||
|
||||
7
test/html/slugify_perf.wren
vendored
Normal file
7
test/html/slugify_perf.wren
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "html" for Html
|
||||
|
||||
var long = "A" * 10000
|
||||
var result = Html.slugify(long)
|
||||
System.print(result.count) // expect: 10000
|
||||
11
test/http/header_lookup.wren
vendored
Normal file
11
test/http/header_lookup.wren
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "http" for HttpResponse
|
||||
|
||||
var headers = {}
|
||||
for (i in 0...100) {
|
||||
headers["Header-%(i)"] = "value%(i)"
|
||||
}
|
||||
var resp = HttpResponse.new_(200, "OK", headers, "")
|
||||
System.print(resp.header("header-50")) // expect: value50
|
||||
System.print(resp.header("HEADER-99")) // expect: value99
|
||||
7
test/markdown/large_bold.wren
vendored
Normal file
7
test/markdown/large_bold.wren
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "markdown" for Markdown
|
||||
|
||||
var text = "**bold** " * 100
|
||||
var result = Markdown.toHtml(text)
|
||||
System.print(result.contains("<strong>")) // expect: true
|
||||
42
test/web/concurrent_handlers.wren
vendored
Normal file
42
test/web/concurrent_handlers.wren
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "scheduler" for Scheduler
|
||||
import "timer" for Timer
|
||||
|
||||
var results = []
|
||||
var completed = 0
|
||||
|
||||
Scheduler.add {
|
||||
results.add("fiber1_start")
|
||||
Timer.sleep(1)
|
||||
results.add("fiber1_end")
|
||||
completed = completed + 1
|
||||
}
|
||||
|
||||
Scheduler.add {
|
||||
results.add("fiber2_start")
|
||||
Timer.sleep(1)
|
||||
results.add("fiber2_end")
|
||||
completed = completed + 1
|
||||
}
|
||||
|
||||
Scheduler.add {
|
||||
results.add("fiber3_start")
|
||||
Timer.sleep(1)
|
||||
results.add("fiber3_end")
|
||||
completed = completed + 1
|
||||
}
|
||||
|
||||
System.print(completed) // expect: 0
|
||||
System.print(results.count) // expect: 0
|
||||
|
||||
Timer.sleep(10)
|
||||
|
||||
System.print(completed) // expect: 3
|
||||
System.print(results.count) // expect: 6
|
||||
System.print(results.contains("fiber1_start")) // expect: true
|
||||
System.print(results.contains("fiber1_end")) // expect: true
|
||||
System.print(results.contains("fiber2_start")) // expect: true
|
||||
System.print(results.contains("fiber2_end")) // expect: true
|
||||
System.print(results.contains("fiber3_start")) // expect: true
|
||||
System.print(results.contains("fiber3_end")) // expect: true
|
||||
46
test/web/error_isolation.wren
vendored
Normal file
46
test/web/error_isolation.wren
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "scheduler" for Scheduler
|
||||
import "timer" for Timer
|
||||
|
||||
var results = []
|
||||
var errors = []
|
||||
|
||||
var handleSafe = Fn.new { |task|
|
||||
var fiber = Fiber.new {
|
||||
task.call()
|
||||
}
|
||||
var error = fiber.try()
|
||||
if (error != null) {
|
||||
errors.add(error)
|
||||
}
|
||||
}
|
||||
|
||||
Scheduler.add {
|
||||
handleSafe.call {
|
||||
results.add("good1")
|
||||
}
|
||||
}
|
||||
|
||||
Scheduler.add {
|
||||
handleSafe.call {
|
||||
Fiber.abort("intentional error")
|
||||
}
|
||||
}
|
||||
|
||||
Scheduler.add {
|
||||
handleSafe.call {
|
||||
results.add("good2")
|
||||
}
|
||||
}
|
||||
|
||||
System.print(results.count) // expect: 0
|
||||
System.print(errors.count) // expect: 0
|
||||
|
||||
Timer.sleep(10)
|
||||
|
||||
System.print(results.count) // expect: 2
|
||||
System.print(errors.count) // expect: 1
|
||||
System.print(results[0]) // expect: good1
|
||||
System.print(results[1]) // expect: good2
|
||||
System.print(errors[0]) // expect: intentional error
|
||||
41
test/web/scheduler_integration.wren
vendored
Normal file
41
test/web/scheduler_integration.wren
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
// retoor <retoor@molodetz.nl>
|
||||
|
||||
import "scheduler" for Scheduler
|
||||
import "timer" for Timer
|
||||
import "web" for SessionStore
|
||||
|
||||
var store = SessionStore.new()
|
||||
var results = []
|
||||
var taskCount = 5
|
||||
|
||||
for (i in 0...taskCount) {
|
||||
var index = i
|
||||
Scheduler.add {
|
||||
var session = store.create()
|
||||
session["task"] = index
|
||||
store.save(session)
|
||||
results.add({"id": session.id, "index": index})
|
||||
}
|
||||
}
|
||||
|
||||
System.print(results.count) // expect: 0
|
||||
|
||||
Timer.sleep(50)
|
||||
|
||||
System.print(results.count) // expect: 5
|
||||
|
||||
var uniqueIds = {}
|
||||
for (r in results) {
|
||||
uniqueIds[r["id"]] = true
|
||||
}
|
||||
System.print(uniqueIds.count) // expect: 5
|
||||
|
||||
var hasAll = true
|
||||
for (i in 0...5) {
|
||||
var found = false
|
||||
for (r in results) {
|
||||
if (r["index"] == i) found = true
|
||||
}
|
||||
if (!found) hasAll = false
|
||||
}
|
||||
System.print(hasAll) // expect: true
|
||||
Loading…
Reference in New Issue
Block a user