more modules updated
This commit is contained in:
parent
a6211058c5
commit
bae9a0ceac
3 changed files with 70 additions and 70 deletions
|
|
@ -103,12 +103,12 @@ type
|
||||||
|
|
||||||
proc cgiError*(msg: string) {.noreturn.} =
|
proc cgiError*(msg: string) {.noreturn.} =
|
||||||
## raises an ECgi exception with message `msg`.
|
## raises an ECgi exception with message `msg`.
|
||||||
var e: ref ECgi
|
var e: ref CgiError
|
||||||
new(e)
|
new(e)
|
||||||
e.msg = msg
|
e.msg = msg
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
proc getEncodedData(allowedMethods: set[TRequestMethod]): string =
|
proc getEncodedData(allowedMethods: set[RequestMethod]): string =
|
||||||
case getEnv("REQUEST_METHOD").string
|
case getEnv("REQUEST_METHOD").string
|
||||||
of "POST":
|
of "POST":
|
||||||
if methodPost notin allowedMethods:
|
if methodPost notin allowedMethods:
|
||||||
|
|
@ -167,7 +167,7 @@ iterator decodeData*(data: string): tuple[key, value: TaintedString] =
|
||||||
elif data[i] == '\0': break
|
elif data[i] == '\0': break
|
||||||
else: cgiError("'&' expected")
|
else: cgiError("'&' expected")
|
||||||
|
|
||||||
iterator decodeData*(allowedMethods: set[TRequestMethod] =
|
iterator decodeData*(allowedMethods: set[RequestMethod] =
|
||||||
{methodNone, methodPost, methodGet}): tuple[key, value: TaintedString] =
|
{methodNone, methodPost, methodGet}): tuple[key, value: TaintedString] =
|
||||||
## Reads and decodes CGI data and yields the (name, value) pairs the
|
## Reads and decodes CGI data and yields the (name, value) pairs the
|
||||||
## data consists of. If the client does not use a method listed in the
|
## data consists of. If the client does not use a method listed in the
|
||||||
|
|
@ -177,15 +177,15 @@ iterator decodeData*(allowedMethods: set[TRequestMethod] =
|
||||||
for key, value in decodeData(data):
|
for key, value in decodeData(data):
|
||||||
yield (key, value)
|
yield (key, value)
|
||||||
|
|
||||||
proc readData*(allowedMethods: set[TRequestMethod] =
|
proc readData*(allowedMethods: set[RequestMethod] =
|
||||||
{methodNone, methodPost, methodGet}): PStringTable =
|
{methodNone, methodPost, methodGet}): StringTableRef =
|
||||||
## Read CGI data. If the client does not use a method listed in the
|
## Read CGI data. If the client does not use a method listed in the
|
||||||
## `allowedMethods` set, an `ECgi` exception is raised.
|
## `allowedMethods` set, an `ECgi` exception is raised.
|
||||||
result = newStringTable()
|
result = newStringTable()
|
||||||
for name, value in decodeData(allowedMethods):
|
for name, value in decodeData(allowedMethods):
|
||||||
result[name.string] = value.string
|
result[name.string] = value.string
|
||||||
|
|
||||||
proc validateData*(data: PStringTable, validKeys: varargs[string]) =
|
proc validateData*(data: StringTableRef, validKeys: varargs[string]) =
|
||||||
## validates data; raises `ECgi` if this fails. This checks that each variable
|
## validates data; raises `ECgi` if this fails. This checks that each variable
|
||||||
## name of the CGI `data` occurs in the `validKeys` array.
|
## name of the CGI `data` occurs in the `validKeys` array.
|
||||||
for key, val in pairs(data):
|
for key, val in pairs(data):
|
||||||
|
|
@ -393,5 +393,5 @@ proc existsCookie*(name: string): bool =
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
const test1 = "abc\L+def xyz"
|
const test1 = "abc\L+def xyz"
|
||||||
assert UrlEncode(test1) == "abc%0A%2Bdef+xyz"
|
assert URLencode(test1) == "abc%0A%2Bdef+xyz"
|
||||||
assert UrlDecode(UrlEncode(test1)) == test1
|
assert URLdecode(URLencode(test1)) == test1
|
||||||
|
|
|
||||||
|
|
@ -30,50 +30,50 @@ type
|
||||||
|
|
||||||
{.deprecated: [TComplex: Complex].}
|
{.deprecated: [TComplex: Complex].}
|
||||||
|
|
||||||
proc `==` *(x, y: TComplex): bool =
|
proc `==` *(x, y: Complex): bool =
|
||||||
## Compare two complex numbers `x` and `y` for equality.
|
## Compare two complex numbers `x` and `y` for equality.
|
||||||
result = x.re == y.re and x.im == y.im
|
result = x.re == y.re and x.im == y.im
|
||||||
|
|
||||||
proc `=~` *(x, y: TComplex): bool =
|
proc `=~` *(x, y: Complex): bool =
|
||||||
## Compare two complex numbers `x` and `y` approximately.
|
## Compare two complex numbers `x` and `y` approximately.
|
||||||
result = abs(x.re-y.re)<EPS and abs(x.im-y.im)<EPS
|
result = abs(x.re-y.re)<EPS and abs(x.im-y.im)<EPS
|
||||||
|
|
||||||
proc `+` *(x, y: TComplex): TComplex =
|
proc `+` *(x, y: Complex): Complex =
|
||||||
## Add two complex numbers.
|
## Add two complex numbers.
|
||||||
result.re = x.re + y.re
|
result.re = x.re + y.re
|
||||||
result.im = x.im + y.im
|
result.im = x.im + y.im
|
||||||
|
|
||||||
proc `+` *(x: TComplex, y: float): TComplex =
|
proc `+` *(x: Complex, y: float): Complex =
|
||||||
## Add complex `x` to float `y`.
|
## Add complex `x` to float `y`.
|
||||||
result.re = x.re + y
|
result.re = x.re + y
|
||||||
result.im = x.im
|
result.im = x.im
|
||||||
|
|
||||||
proc `+` *(x: float, y: TComplex): TComplex =
|
proc `+` *(x: float, y: Complex): Complex =
|
||||||
## Add float `x` to complex `y`.
|
## Add float `x` to complex `y`.
|
||||||
result.re = x + y.re
|
result.re = x + y.re
|
||||||
result.im = y.im
|
result.im = y.im
|
||||||
|
|
||||||
|
|
||||||
proc `-` *(z: TComplex): TComplex =
|
proc `-` *(z: Complex): Complex =
|
||||||
## Unary minus for complex numbers.
|
## Unary minus for complex numbers.
|
||||||
result.re = -z.re
|
result.re = -z.re
|
||||||
result.im = -z.im
|
result.im = -z.im
|
||||||
|
|
||||||
proc `-` *(x, y: TComplex): TComplex =
|
proc `-` *(x, y: Complex): Complex =
|
||||||
## Subtract two complex numbers.
|
## Subtract two complex numbers.
|
||||||
result.re = x.re - y.re
|
result.re = x.re - y.re
|
||||||
result.im = x.im - y.im
|
result.im = x.im - y.im
|
||||||
|
|
||||||
proc `-` *(x: TComplex, y: float): TComplex =
|
proc `-` *(x: Complex, y: float): Complex =
|
||||||
## Subtracts float `y` from complex `x`.
|
## Subtracts float `y` from complex `x`.
|
||||||
result = x + (-y)
|
result = x + (-y)
|
||||||
|
|
||||||
proc `-` *(x: float, y: TComplex): TComplex =
|
proc `-` *(x: float, y: Complex): Complex =
|
||||||
## Subtracts complex `y` from float `x`.
|
## Subtracts complex `y` from float `x`.
|
||||||
result = x + (-y)
|
result = x + (-y)
|
||||||
|
|
||||||
|
|
||||||
proc `/` *(x, y: TComplex): TComplex =
|
proc `/` *(x, y: Complex): Complex =
|
||||||
## Divide `x` by `y`.
|
## Divide `x` by `y`.
|
||||||
var
|
var
|
||||||
r, den: float
|
r, den: float
|
||||||
|
|
@ -88,73 +88,73 @@ proc `/` *(x, y: TComplex): TComplex =
|
||||||
result.re = (x.re + r * x.im) / den
|
result.re = (x.re + r * x.im) / den
|
||||||
result.im = (x.im - r * x.re) / den
|
result.im = (x.im - r * x.re) / den
|
||||||
|
|
||||||
proc `/` *(x : TComplex, y: float ): TComplex =
|
proc `/` *(x : Complex, y: float ): Complex =
|
||||||
## Divide complex `x` by float `y`.
|
## Divide complex `x` by float `y`.
|
||||||
result.re = x.re/y
|
result.re = x.re/y
|
||||||
result.im = x.im/y
|
result.im = x.im/y
|
||||||
|
|
||||||
proc `/` *(x : float, y: TComplex ): TComplex =
|
proc `/` *(x : float, y: Complex ): Complex =
|
||||||
## Divide float `x` by complex `y`.
|
## Divide float `x` by complex `y`.
|
||||||
var num : TComplex = (x, 0.0)
|
var num : Complex = (x, 0.0)
|
||||||
result = num/y
|
result = num/y
|
||||||
|
|
||||||
|
|
||||||
proc `*` *(x, y: TComplex): TComplex =
|
proc `*` *(x, y: Complex): Complex =
|
||||||
## Multiply `x` with `y`.
|
## Multiply `x` with `y`.
|
||||||
result.re = x.re * y.re - x.im * y.im
|
result.re = x.re * y.re - x.im * y.im
|
||||||
result.im = x.im * y.re + x.re * y.im
|
result.im = x.im * y.re + x.re * y.im
|
||||||
|
|
||||||
proc `*` *(x: float, y: TComplex): TComplex =
|
proc `*` *(x: float, y: Complex): Complex =
|
||||||
## Multiply float `x` with complex `y`.
|
## Multiply float `x` with complex `y`.
|
||||||
result.re = x * y.re
|
result.re = x * y.re
|
||||||
result.im = x * y.im
|
result.im = x * y.im
|
||||||
|
|
||||||
proc `*` *(x: TComplex, y: float): TComplex =
|
proc `*` *(x: Complex, y: float): Complex =
|
||||||
## Multiply complex `x` with float `y`.
|
## Multiply complex `x` with float `y`.
|
||||||
result.re = x.re * y
|
result.re = x.re * y
|
||||||
result.im = x.im * y
|
result.im = x.im * y
|
||||||
|
|
||||||
|
|
||||||
proc `+=` *(x: var TComplex, y: TComplex) =
|
proc `+=` *(x: var Complex, y: Complex) =
|
||||||
## Add `y` to `x`.
|
## Add `y` to `x`.
|
||||||
x.re += y.re
|
x.re += y.re
|
||||||
x.im += y.im
|
x.im += y.im
|
||||||
|
|
||||||
proc `+=` *(x: var TComplex, y: float) =
|
proc `+=` *(x: var Complex, y: float) =
|
||||||
## Add `y` to the complex number `x`.
|
## Add `y` to the complex number `x`.
|
||||||
x.re += y
|
x.re += y
|
||||||
|
|
||||||
proc `-=` *(x: var TComplex, y: TComplex) =
|
proc `-=` *(x: var Complex, y: Complex) =
|
||||||
## Subtract `y` from `x`.
|
## Subtract `y` from `x`.
|
||||||
x.re -= y.re
|
x.re -= y.re
|
||||||
x.im -= y.im
|
x.im -= y.im
|
||||||
|
|
||||||
proc `-=` *(x: var TComplex, y: float) =
|
proc `-=` *(x: var Complex, y: float) =
|
||||||
## Subtract `y` from the complex number `x`.
|
## Subtract `y` from the complex number `x`.
|
||||||
x.re -= y
|
x.re -= y
|
||||||
|
|
||||||
proc `*=` *(x: var TComplex, y: TComplex) =
|
proc `*=` *(x: var Complex, y: Complex) =
|
||||||
## Multiply `y` to `x`.
|
## Multiply `y` to `x`.
|
||||||
let im = x.im * y.re + x.re * y.im
|
let im = x.im * y.re + x.re * y.im
|
||||||
x.re = x.re * y.re - x.im * y.im
|
x.re = x.re * y.re - x.im * y.im
|
||||||
x.im = im
|
x.im = im
|
||||||
|
|
||||||
proc `*=` *(x: var TComplex, y: float) =
|
proc `*=` *(x: var Complex, y: float) =
|
||||||
## Multiply `y` to the complex number `x`.
|
## Multiply `y` to the complex number `x`.
|
||||||
x.re *= y
|
x.re *= y
|
||||||
x.im *= y
|
x.im *= y
|
||||||
|
|
||||||
proc `/=` *(x: var TComplex, y: TComplex) =
|
proc `/=` *(x: var Complex, y: Complex) =
|
||||||
## Divide `x` by `y` in place.
|
## Divide `x` by `y` in place.
|
||||||
x = x / y
|
x = x / y
|
||||||
|
|
||||||
proc `/=` *(x : var TComplex, y: float) =
|
proc `/=` *(x : var Complex, y: float) =
|
||||||
## Divide complex `x` by float `y` in place.
|
## Divide complex `x` by float `y` in place.
|
||||||
x.re /= y
|
x.re /= y
|
||||||
x.im /= y
|
x.im /= y
|
||||||
|
|
||||||
|
|
||||||
proc abs*(z: TComplex): float =
|
proc abs*(z: Complex): float =
|
||||||
## Return the distance from (0,0) to `z`.
|
## Return the distance from (0,0) to `z`.
|
||||||
|
|
||||||
# optimized by checking special cases (sqrt is expensive)
|
# optimized by checking special cases (sqrt is expensive)
|
||||||
|
|
@ -174,7 +174,7 @@ proc abs*(z: TComplex): float =
|
||||||
result = y * sqrt(1.0 + temp * temp)
|
result = y * sqrt(1.0 + temp * temp)
|
||||||
|
|
||||||
|
|
||||||
proc sqrt*(z: TComplex): TComplex =
|
proc sqrt*(z: Complex): Complex =
|
||||||
## Square root for a complex number `z`.
|
## Square root for a complex number `z`.
|
||||||
var x, y, w, r: float
|
var x, y, w, r: float
|
||||||
|
|
||||||
|
|
@ -198,7 +198,7 @@ proc sqrt*(z: TComplex): TComplex =
|
||||||
result.re = z.im / (result.im + result.im)
|
result.re = z.im / (result.im + result.im)
|
||||||
|
|
||||||
|
|
||||||
proc exp*(z: TComplex): TComplex =
|
proc exp*(z: Complex): Complex =
|
||||||
## e raised to the power `z`.
|
## e raised to the power `z`.
|
||||||
var rho = exp(z.re)
|
var rho = exp(z.re)
|
||||||
var theta = z.im
|
var theta = z.im
|
||||||
|
|
@ -206,21 +206,21 @@ proc exp*(z: TComplex): TComplex =
|
||||||
result.im = rho*sin(theta)
|
result.im = rho*sin(theta)
|
||||||
|
|
||||||
|
|
||||||
proc ln*(z: TComplex): TComplex =
|
proc ln*(z: Complex): Complex =
|
||||||
## Returns the natural log of `z`.
|
## Returns the natural log of `z`.
|
||||||
result.re = ln(abs(z))
|
result.re = ln(abs(z))
|
||||||
result.im = arctan2(z.im,z.re)
|
result.im = arctan2(z.im,z.re)
|
||||||
|
|
||||||
proc log10*(z: TComplex): TComplex =
|
proc log10*(z: Complex): Complex =
|
||||||
## Returns the log base 10 of `z`.
|
## Returns the log base 10 of `z`.
|
||||||
result = ln(z)/ln(10.0)
|
result = ln(z)/ln(10.0)
|
||||||
|
|
||||||
proc log2*(z: TComplex): TComplex =
|
proc log2*(z: Complex): Complex =
|
||||||
## Returns the log base 2 of `z`.
|
## Returns the log base 2 of `z`.
|
||||||
result = ln(z)/ln(2.0)
|
result = ln(z)/ln(2.0)
|
||||||
|
|
||||||
|
|
||||||
proc pow*(x, y: TComplex): TComplex =
|
proc pow*(x, y: Complex): Complex =
|
||||||
## `x` raised to the power `y`.
|
## `x` raised to the power `y`.
|
||||||
if x.re == 0.0 and x.im == 0.0:
|
if x.re == 0.0 and x.im == 0.0:
|
||||||
if y.re == 0.0 and y.im == 0.0:
|
if y.re == 0.0 and y.im == 0.0:
|
||||||
|
|
@ -242,53 +242,53 @@ proc pow*(x, y: TComplex): TComplex =
|
||||||
result.im = s*sin(r)
|
result.im = s*sin(r)
|
||||||
|
|
||||||
|
|
||||||
proc sin*(z: TComplex): TComplex =
|
proc sin*(z: Complex): Complex =
|
||||||
## Returns the sine of `z`.
|
## Returns the sine of `z`.
|
||||||
result.re = sin(z.re)*cosh(z.im)
|
result.re = sin(z.re)*cosh(z.im)
|
||||||
result.im = cos(z.re)*sinh(z.im)
|
result.im = cos(z.re)*sinh(z.im)
|
||||||
|
|
||||||
proc arcsin*(z: TComplex): TComplex =
|
proc arcsin*(z: Complex): Complex =
|
||||||
## Returns the inverse sine of `z`.
|
## Returns the inverse sine of `z`.
|
||||||
var i: TComplex = (0.0,1.0)
|
var i: Complex = (0.0,1.0)
|
||||||
result = -i*ln(i*z + sqrt(1.0-z*z))
|
result = -i*ln(i*z + sqrt(1.0-z*z))
|
||||||
|
|
||||||
proc cos*(z: TComplex): TComplex =
|
proc cos*(z: Complex): Complex =
|
||||||
## Returns the cosine of `z`.
|
## Returns the cosine of `z`.
|
||||||
result.re = cos(z.re)*cosh(z.im)
|
result.re = cos(z.re)*cosh(z.im)
|
||||||
result.im = -sin(z.re)*sinh(z.im)
|
result.im = -sin(z.re)*sinh(z.im)
|
||||||
|
|
||||||
proc arccos*(z: TComplex): TComplex =
|
proc arccos*(z: Complex): Complex =
|
||||||
## Returns the inverse cosine of `z`.
|
## Returns the inverse cosine of `z`.
|
||||||
var i: TComplex = (0.0,1.0)
|
var i: Complex = (0.0,1.0)
|
||||||
result = -i*ln(z + sqrt(z*z-1.0))
|
result = -i*ln(z + sqrt(z*z-1.0))
|
||||||
|
|
||||||
proc tan*(z: TComplex): TComplex =
|
proc tan*(z: Complex): Complex =
|
||||||
## Returns the tangent of `z`.
|
## Returns the tangent of `z`.
|
||||||
result = sin(z)/cos(z)
|
result = sin(z)/cos(z)
|
||||||
|
|
||||||
proc cot*(z: TComplex): TComplex =
|
proc cot*(z: Complex): Complex =
|
||||||
## Returns the cotangent of `z`.
|
## Returns the cotangent of `z`.
|
||||||
result = cos(z)/sin(z)
|
result = cos(z)/sin(z)
|
||||||
|
|
||||||
proc sec*(z: TComplex): TComplex =
|
proc sec*(z: Complex): Complex =
|
||||||
## Returns the secant of `z`.
|
## Returns the secant of `z`.
|
||||||
result = 1.0/cos(z)
|
result = 1.0/cos(z)
|
||||||
|
|
||||||
proc csc*(z: TComplex): TComplex =
|
proc csc*(z: Complex): Complex =
|
||||||
## Returns the cosecant of `z`.
|
## Returns the cosecant of `z`.
|
||||||
result = 1.0/sin(z)
|
result = 1.0/sin(z)
|
||||||
|
|
||||||
|
|
||||||
proc sinh*(z: TComplex): TComplex =
|
proc sinh*(z: Complex): Complex =
|
||||||
## Returns the hyperbolic sine of `z`.
|
## Returns the hyperbolic sine of `z`.
|
||||||
result = 0.5*(exp(z)-exp(-z))
|
result = 0.5*(exp(z)-exp(-z))
|
||||||
|
|
||||||
proc cosh*(z: TComplex): TComplex =
|
proc cosh*(z: Complex): Complex =
|
||||||
## Returns the hyperbolic cosine of `z`.
|
## Returns the hyperbolic cosine of `z`.
|
||||||
result = 0.5*(exp(z)+exp(-z))
|
result = 0.5*(exp(z)+exp(-z))
|
||||||
|
|
||||||
|
|
||||||
proc `$`*(z: TComplex): string =
|
proc `$`*(z: Complex): string =
|
||||||
## Returns `z`'s string representation as ``"(re, im)"``.
|
## Returns `z`'s string representation as ``"(re, im)"``.
|
||||||
result = "(" & $z.re & ", " & $z.im & ")"
|
result = "(" & $z.re & ", " & $z.im & ")"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,19 +38,19 @@ proc len*(t: StringTableRef): int {.rtl, extern: "nst$1".} =
|
||||||
## returns the number of keys in `t`.
|
## returns the number of keys in `t`.
|
||||||
result = t.counter
|
result = t.counter
|
||||||
|
|
||||||
iterator pairs*(t: PStringTable): tuple[key, value: string] =
|
iterator pairs*(t: StringTableRef): tuple[key, value: string] =
|
||||||
## iterates over every (key, value) pair in the table `t`.
|
## iterates over every (key, value) pair in the table `t`.
|
||||||
for h in 0..high(t.data):
|
for h in 0..high(t.data):
|
||||||
if not isNil(t.data[h].key):
|
if not isNil(t.data[h].key):
|
||||||
yield (t.data[h].key, t.data[h].val)
|
yield (t.data[h].key, t.data[h].val)
|
||||||
|
|
||||||
iterator keys*(t: PStringTable): string =
|
iterator keys*(t: StringTableRef): string =
|
||||||
## iterates over every key in the table `t`.
|
## iterates over every key in the table `t`.
|
||||||
for h in 0..high(t.data):
|
for h in 0..high(t.data):
|
||||||
if not isNil(t.data[h].key):
|
if not isNil(t.data[h].key):
|
||||||
yield t.data[h].key
|
yield t.data[h].key
|
||||||
|
|
||||||
iterator values*(t: PStringTable): string =
|
iterator values*(t: StringTableRef): string =
|
||||||
## iterates over every value in the table `t`.
|
## iterates over every value in the table `t`.
|
||||||
for h in 0..high(t.data):
|
for h in 0..high(t.data):
|
||||||
if not isNil(t.data[h].key):
|
if not isNil(t.data[h].key):
|
||||||
|
|
@ -74,13 +74,13 @@ const
|
||||||
growthFactor = 2
|
growthFactor = 2
|
||||||
startSize = 64
|
startSize = 64
|
||||||
|
|
||||||
proc myhash(t: PStringTable, key: string): THash =
|
proc myhash(t: StringTableRef, key: string): THash =
|
||||||
case t.mode
|
case t.mode
|
||||||
of modeCaseSensitive: result = hashes.hash(key)
|
of modeCaseSensitive: result = hashes.hash(key)
|
||||||
of modeCaseInsensitive: result = hashes.hashIgnoreCase(key)
|
of modeCaseInsensitive: result = hashes.hashIgnoreCase(key)
|
||||||
of modeStyleInsensitive: result = hashes.hashIgnoreStyle(key)
|
of modeStyleInsensitive: result = hashes.hashIgnoreStyle(key)
|
||||||
|
|
||||||
proc myCmp(t: PStringTable, a, b: string): bool =
|
proc myCmp(t: StringTableRef, a, b: string): bool =
|
||||||
case t.mode
|
case t.mode
|
||||||
of modeCaseSensitive: result = cmp(a, b) == 0
|
of modeCaseSensitive: result = cmp(a, b) == 0
|
||||||
of modeCaseInsensitive: result = cmpIgnoreCase(a, b) == 0
|
of modeCaseInsensitive: result = cmpIgnoreCase(a, b) == 0
|
||||||
|
|
@ -93,7 +93,7 @@ proc mustRehash(length, counter: int): bool =
|
||||||
proc nextTry(h, maxHash: THash): THash {.inline.} =
|
proc nextTry(h, maxHash: THash): THash {.inline.} =
|
||||||
result = ((5 * h) + 1) and maxHash
|
result = ((5 * h) + 1) and maxHash
|
||||||
|
|
||||||
proc rawGet(t: PStringTable, key: string): int =
|
proc rawGet(t: StringTableRef, key: string): int =
|
||||||
var h: THash = myhash(t, key) and high(t.data) # start with real hash value
|
var h: THash = myhash(t, key) and high(t.data) # start with real hash value
|
||||||
while not isNil(t.data[h].key):
|
while not isNil(t.data[h].key):
|
||||||
if myCmp(t, t.data[h].key, key):
|
if myCmp(t, t.data[h].key, key):
|
||||||
|
|
@ -101,7 +101,7 @@ proc rawGet(t: PStringTable, key: string): int =
|
||||||
h = nextTry(h, high(t.data))
|
h = nextTry(h, high(t.data))
|
||||||
result = - 1
|
result = - 1
|
||||||
|
|
||||||
proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} =
|
proc `[]`*(t: StringTableRef, key: string): string {.rtl, extern: "nstGet".} =
|
||||||
## retrieves the value at ``t[key]``. If `key` is not in `t`, "" is returned
|
## retrieves the value at ``t[key]``. If `key` is not in `t`, "" is returned
|
||||||
## and no exception is raised. One can check with ``hasKey`` whether the key
|
## and no exception is raised. One can check with ``hasKey`` whether the key
|
||||||
## exists.
|
## exists.
|
||||||
|
|
@ -109,7 +109,7 @@ proc `[]`*(t: PStringTable, key: string): string {.rtl, extern: "nstGet".} =
|
||||||
if index >= 0: result = t.data[index].val
|
if index >= 0: result = t.data[index].val
|
||||||
else: result = ""
|
else: result = ""
|
||||||
|
|
||||||
proc mget*(t: PStringTable, key: string): var string {.
|
proc mget*(t: StringTableRef, key: string): var string {.
|
||||||
rtl, extern: "nstTake".} =
|
rtl, extern: "nstTake".} =
|
||||||
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
## retrieves the location at ``t[key]``. If `key` is not in `t`, the
|
||||||
## ``EInvalidKey`` exception is raised.
|
## ``EInvalidKey`` exception is raised.
|
||||||
|
|
@ -117,25 +117,25 @@ proc mget*(t: PStringTable, key: string): var string {.
|
||||||
if index >= 0: result = t.data[index].val
|
if index >= 0: result = t.data[index].val
|
||||||
else: raise newException(KeyError, "key does not exist: " & key)
|
else: raise newException(KeyError, "key does not exist: " & key)
|
||||||
|
|
||||||
proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} =
|
proc hasKey*(t: StringTableRef, key: string): bool {.rtl, extern: "nst$1".} =
|
||||||
## returns true iff `key` is in the table `t`.
|
## returns true iff `key` is in the table `t`.
|
||||||
result = rawGet(t, key) >= 0
|
result = rawGet(t, key) >= 0
|
||||||
|
|
||||||
proc rawInsert(t: PStringTable, data: var KeyValuePairSeq, key, val: string) =
|
proc rawInsert(t: StringTableRef, data: var KeyValuePairSeq, key, val: string) =
|
||||||
var h: THash = myhash(t, key) and high(data)
|
var h: THash = myhash(t, key) and high(data)
|
||||||
while not isNil(data[h].key):
|
while not isNil(data[h].key):
|
||||||
h = nextTry(h, high(data))
|
h = nextTry(h, high(data))
|
||||||
data[h].key = key
|
data[h].key = key
|
||||||
data[h].val = val
|
data[h].val = val
|
||||||
|
|
||||||
proc enlarge(t: PStringTable) =
|
proc enlarge(t: StringTableRef) =
|
||||||
var n: KeyValuePairSeq
|
var n: KeyValuePairSeq
|
||||||
newSeq(n, len(t.data) * growthFactor)
|
newSeq(n, len(t.data) * growthFactor)
|
||||||
for i in countup(0, high(t.data)):
|
for i in countup(0, high(t.data)):
|
||||||
if not isNil(t.data[i].key): rawInsert(t, n, t.data[i].key, t.data[i].val)
|
if not isNil(t.data[i].key): rawInsert(t, n, t.data[i].key, t.data[i].val)
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
|
|
||||||
proc `[]=`*(t: PStringTable, key, val: string) {.rtl, extern: "nstPut".} =
|
proc `[]=`*(t: StringTableRef, key, val: string) {.rtl, extern: "nstPut".} =
|
||||||
## puts a (key, value)-pair into `t`.
|
## puts a (key, value)-pair into `t`.
|
||||||
var index = rawGet(t, key)
|
var index = rawGet(t, key)
|
||||||
if index >= 0:
|
if index >= 0:
|
||||||
|
|
@ -151,7 +151,7 @@ proc raiseFormatException(s: string) =
|
||||||
e.msg = "format string: key not found: " & s
|
e.msg = "format string: key not found: " & s
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
proc getValue(t: PStringTable, flags: set[TFormatFlag], key: string): string =
|
proc getValue(t: StringTableRef, flags: set[FormatFlag], key: string): string =
|
||||||
if hasKey(t, key): return t[key]
|
if hasKey(t, key): return t[key]
|
||||||
# hm difficult: assume safety in taint mode here. XXX This is dangerous!
|
# hm difficult: assume safety in taint mode here. XXX This is dangerous!
|
||||||
if useEnvironment in flags: result = os.getEnv(key).string
|
if useEnvironment in flags: result = os.getEnv(key).string
|
||||||
|
|
@ -160,7 +160,7 @@ proc getValue(t: PStringTable, flags: set[TFormatFlag], key: string): string =
|
||||||
if useKey in flags: result = '$' & key
|
if useKey in flags: result = '$' & key
|
||||||
elif not (useEmpty in flags): raiseFormatException(key)
|
elif not (useEmpty in flags): raiseFormatException(key)
|
||||||
|
|
||||||
proc newStringTable*(mode: TStringTableMode): PStringTable {.
|
proc newStringTable*(mode: StringTableMode): StringTableRef {.
|
||||||
rtl, extern: "nst$1".} =
|
rtl, extern: "nst$1".} =
|
||||||
## creates a new string table that is empty.
|
## creates a new string table that is empty.
|
||||||
new(result)
|
new(result)
|
||||||
|
|
@ -169,7 +169,7 @@ proc newStringTable*(mode: TStringTableMode): PStringTable {.
|
||||||
newSeq(result.data, startSize)
|
newSeq(result.data, startSize)
|
||||||
|
|
||||||
proc newStringTable*(keyValuePairs: varargs[string],
|
proc newStringTable*(keyValuePairs: varargs[string],
|
||||||
mode: TStringTableMode): PStringTable {.
|
mode: StringTableMode): StringTableRef {.
|
||||||
rtl, extern: "nst$1WithPairs".} =
|
rtl, extern: "nst$1WithPairs".} =
|
||||||
## creates a new string table with given key value pairs.
|
## creates a new string table with given key value pairs.
|
||||||
## Example::
|
## Example::
|
||||||
|
|
@ -182,7 +182,7 @@ proc newStringTable*(keyValuePairs: varargs[string],
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
|
|
||||||
proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]],
|
proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]],
|
||||||
mode: StringTableMode = modeCaseSensitive): PStringTable {.
|
mode: StringTableMode = modeCaseSensitive): StringTableRef {.
|
||||||
rtl, extern: "nst$1WithTableConstr".} =
|
rtl, extern: "nst$1WithTableConstr".} =
|
||||||
## creates a new string table with given key value pairs.
|
## creates a new string table with given key value pairs.
|
||||||
## Example::
|
## Example::
|
||||||
|
|
@ -191,7 +191,7 @@ proc newStringTable*(keyValuePairs: varargs[tuple[key, val: string]],
|
||||||
result = newStringTable(mode)
|
result = newStringTable(mode)
|
||||||
for key, val in items(keyValuePairs): result[key] = val
|
for key, val in items(keyValuePairs): result[key] = val
|
||||||
|
|
||||||
proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {.
|
proc `%`*(f: string, t: StringTableRef, flags: set[FormatFlag] = {}): string {.
|
||||||
rtl, extern: "nstFormat".} =
|
rtl, extern: "nstFormat".} =
|
||||||
## The `%` operator for string tables.
|
## The `%` operator for string tables.
|
||||||
const
|
const
|
||||||
|
|
@ -221,7 +221,7 @@ proc `%`*(f: string, t: PStringTable, flags: set[TFormatFlag] = {}): string {.
|
||||||
add(result, f[i])
|
add(result, f[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
proc `$`*(t: PStringTable): string {.rtl, extern: "nstDollar".} =
|
proc `$`*(t: StringTableRef): string {.rtl, extern: "nstDollar".} =
|
||||||
## The `$` operator for string tables.
|
## The `$` operator for string tables.
|
||||||
if t.len == 0:
|
if t.len == 0:
|
||||||
result = "{:}"
|
result = "{:}"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue