Small base64.nim refactor (#5755)

* Small changes (var to let)

* Some additional `var` to `let`

* Fix

* Finally removed immediate
This commit is contained in:
Daniil Yarancev 2017-04-25 21:47:26 +03:00 • committed by Dominik Picheta
commit 6ac37ee2fb

View file

@ -44,21 +44,23 @@
const const
cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" cb64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediate.} = template encodeInternal(s: typed, lineLen: int, newLine: string): untyped =
## encodes `s` into base64 representation. After `lineLen` characters, a ## encodes `s` into base64 representation. After `lineLen` characters, a
## `newline` is added. ## `newline` is added.
var total = ((len(s) + 2) div 3) * 4 var total = ((len(s) + 2) div 3) * 4
var numLines = (total + lineLen - 1) div lineLen let numLines = (total + lineLen - 1) div lineLen
if numLines > 0: inc(total, (numLines - 1) * newLine.len) if numLines > 0: inc(total, (numLines - 1) * newLine.len)
result = newString(total) result = newString(total)
var i = 0 var
var r = 0 i = 0
var currLine = 0 r = 0
currLine = 0
while i < s.len - 2: while i < s.len - 2:
var a = ord(s[i]) let
var b = ord(s[i+1]) a = ord(s[i])
var c = ord(s[i+2]) b = ord(s[i+1])
c = ord(s[i+2])
result[r] = cb64[a shr 2] result[r] = cb64[a shr 2]
result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] result[r+2] = cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)]
@ -74,8 +76,9 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat
currLine = 0 currLine = 0
if i < s.len-1: if i < s.len-1:
var a = ord(s[i]) let
var b = ord(s[i+1]) a = ord(s[i])
b = ord(s[i+1])
result[r] = cb64[a shr 2] result[r] = cb64[a shr 2]
result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] result[r+1] = cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result[r+2] = cb64[((b and 0x0F) shl 2)] result[r+2] = cb64[((b and 0x0F) shl 2)]
@ -83,7 +86,7 @@ template encodeInternal(s: expr, lineLen: int, newLine: string): stmt {.immediat
if r+4 != result.len: if r+4 != result.len:
setLen(result, r+4) setLen(result, r+4)
elif i < s.len: elif i < s.len:
var a = ord(s[i]) let a = ord(s[i])
result[r] = cb64[a shr 2] result[r] = cb64[a shr 2]
result[r+1] = cb64[(a and 3) shl 4] result[r+1] = cb64[(a and 3) shl 4]
result[r+2] = '=' result[r+2] = '='
@ -127,15 +130,17 @@ proc decode*(s: string): string =
# total is an upper bound, as we will skip arbitrary whitespace: # total is an upper bound, as we will skip arbitrary whitespace:
result = newString(total) result = newString(total)
var i = 0 var
var r = 0 i = 0
r = 0
while true: while true:
while s[i] in Whitespace: inc(i) while s[i] in Whitespace: inc(i)
if i < s.len-3: if i < s.len-3:
var a = s[i].decodeByte let
var b = s[i+1].decodeByte a = s[i].decodeByte
var c = s[i+2].decodeByte b = s[i+1].decodeByte
var d = s[i+3].decodeByte c = s[i+2].decodeByte
d = s[i+3].decodeByte
result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03)) result[r] = chr((a shl 2) and 0xff or ((b shr 4) and 0x03))
result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F)) result[r+1] = chr((b shl 4) and 0xff or ((c shr 2) and 0x0F))
@ -169,4 +174,4 @@ when isMainModule:
for t in items(tests): for t in items(tests):
assert decode(encode(t)) == t assert decode(encode(t)) == t
assert decode(encode(t, lineLen=40)) == t assert decode(encode(t, lineLen=40)) == t
assert decode(encode(t, lineLen=76)) == t assert decode(encode(t, lineLen=76)) == t