diff --git a/async_postgres/pg_types/accessors.nim b/async_postgres/pg_types/accessors.nim index 9759af2..1f934ee 100644 --- a/async_postgres/pg_types/accessors.nim +++ b/async_postgres/pg_types/accessors.nim @@ -145,24 +145,20 @@ proc getStr*(row: Row, col: int): string = ) of 700: # float4 if clen == 4: - var bits = uint32( + let bits = uint32( (uint32(b[off]) shl 24) or (uint32(b[off + 1]) shl 16) or (uint32(b[off + 2]) shl 8) or uint32(b[off + 3]) ) - var f: float32 - copyMem(addr f, addr bits, 4) - return $f + return $cast[float32](bits) of 701: # float8 if clen == 8: - var bits = uint64( + let bits = uint64( (uint64(b[off]) shl 56) or (uint64(b[off + 1]) shl 48) or (uint64(b[off + 2]) shl 40) or (uint64(b[off + 3]) shl 32) or (uint64(b[off + 4]) shl 24) or (uint64(b[off + 5]) shl 16) or (uint64(b[off + 6]) shl 8) or uint64(b[off + 7]) ) - var f: float64 - copyMem(addr f, addr bits, 8) - return $f + return $cast[float64](bits) of OidNumeric: return $decodeNumericBinary(b.toOpenArray(off, off + clen - 1)) else: @@ -246,24 +242,19 @@ proc getFloat*(row: Row, col: int): float64 = raise newException(PgTypeError, "Column " & $col & " is NULL") if row.isBinaryCol(col): if clen == 8: - var bits: uint64 let b = row.data.buf - bits = + let bits = (uint64(b[off]) shl 56) or (uint64(b[off + 1]) shl 48) or (uint64(b[off + 2]) shl 40) or (uint64(b[off + 3]) shl 32) or (uint64(b[off + 4]) shl 24) or (uint64(b[off + 5]) shl 16) or (uint64(b[off + 6]) shl 8) or uint64(b[off + 7]) - copyMem(addr result, addr bits, 8) - return + return cast[float64](bits) elif clen == 4: - var bits: uint32 let b = row.data.buf - bits = + let bits = (uint32(b[off]) shl 24) or (uint32(b[off + 1]) shl 16) or (uint32(b[off + 2]) shl 8) or uint32(b[off + 3]) - var f32: float32 - copyMem(addr f32, addr bits, 4) - return float64(f32) + return float64(cast[float32](bits)) discard parseFloat(row.bufView(off, clen), result) proc getFloat32*(row: Row, col: int): float32 = @@ -273,13 +264,11 @@ proc getFloat32*(row: Row, col: int): float32 = raise newException(PgTypeError, "Column " & $col & " is NULL") if row.isBinaryCol(col): if clen == 4: - var bits: uint32 let b = row.data.buf - bits = + let bits = (uint32(b[off]) shl 24) or (uint32(b[off + 1]) shl 16) or (uint32(b[off + 2]) shl 8) or uint32(b[off + 3]) - copyMem(addr result, addr bits, 4) - return + return cast[float32](bits) var f: float64 if parseFloat(row.bufView(off, clen), f) == 0: raise newException(PgTypeError, "Column " & $col & ": invalid float32 value") diff --git a/async_postgres/pg_types/core.nim b/async_postgres/pg_types/core.nim index 60a1964..2aeebbb 100644 --- a/async_postgres/pg_types/core.nim +++ b/async_postgres/pg_types/core.nim @@ -972,10 +972,9 @@ proc fromBE64*(data: openArray[byte]): int64 = proc decodeFloat64BE*(data: openArray[byte], offset: int = 0): float64 = ## Decode a big-endian 64-bit float from bytes at the given offset. - var bits: uint64 - bits = + let bits = (uint64(data[offset]) shl 56) or (uint64(data[offset + 1]) shl 48) or (uint64(data[offset + 2]) shl 40) or (uint64(data[offset + 3]) shl 32) or (uint64(data[offset + 4]) shl 24) or (uint64(data[offset + 5]) shl 16) or (uint64(data[offset + 6]) shl 8) or uint64(data[offset + 7]) - copyMem(addr result, addr bits, 8) + cast[float64](bits) diff --git a/async_postgres/pg_types/decoding.nim b/async_postgres/pg_types/decoding.nim index 9825685..a567cf0 100644 --- a/async_postgres/pg_types/decoding.nim +++ b/async_postgres/pg_types/decoding.nim @@ -140,20 +140,20 @@ proc decodeInetBinary*(data: openArray[byte]): tuple[address: IpAddress, mask: u proc decodePointBinary*(data: openArray[byte], off: int): PgPoint = ## Decode a point from 16 bytes at offset. - var xBits = uint64( + let xBits = uint64( (uint64(data[off]) shl 56) or (uint64(data[off + 1]) shl 48) or (uint64(data[off + 2]) shl 40) or (uint64(data[off + 3]) shl 32) or (uint64(data[off + 4]) shl 24) or (uint64(data[off + 5]) shl 16) or (uint64(data[off + 6]) shl 8) or uint64(data[off + 7]) ) - var yBits = uint64( + let yBits = uint64( (uint64(data[off + 8]) shl 56) or (uint64(data[off + 9]) shl 48) or (uint64(data[off + 10]) shl 40) or (uint64(data[off + 11]) shl 32) or (uint64(data[off + 12]) shl 24) or (uint64(data[off + 13]) shl 16) or (uint64(data[off + 14]) shl 8) or uint64(data[off + 15]) ) - copyMem(addr result.x, addr xBits, 8) - copyMem(addr result.y, addr yBits, 8) + result.x = cast[float64](xBits) + result.y = cast[float64](yBits) proc decodeBinaryArray*( data: openArray[byte] diff --git a/async_postgres/pg_types/encoding.nim b/async_postgres/pg_types/encoding.nim index 257868a..75f6dc1 100644 --- a/async_postgres/pg_types/encoding.nim +++ b/async_postgres/pg_types/encoding.nim @@ -28,6 +28,11 @@ template writeBytesAt*(dst: var openArray[byte], pos: int, src: openArray[byte]) if src.len > 0: copyMem(addr dst[pos], addr src[0], src.len) +template appendBytes*(buf: var seq[byte], src: openArray[byte]) = + ## Append src bytes to the end of buf. No-op when src is empty. + if src.len > 0: + buf.add(src) + proc toPgParamInline*(v: int16): PgParamInline = result.oid = OidInt2 result.format = 1 @@ -1118,10 +1123,7 @@ proc addBind*( else: let data = p.value.get buf.addInt32(int32(data.len)) - if data.len > 0: - let oldLen = buf.len - buf.setLen(oldLen + data.len) - copyMem(addr buf[oldLen], addr data[0], data.len) + buf.appendBytes(data) # Result format codes buf.addInt16(int16(resultFormats.len)) for f in resultFormats: @@ -1196,16 +1198,11 @@ proc writeParamValue*(buf: var seq[byte], v: bool) = proc writeParamValue*(buf: var seq[byte], v: string) = buf.addInt32(int32(v.len)) if v.len > 0: - let o = buf.len - buf.setLen(o + v.len) - copyMem(addr buf[o], addr v[0], v.len) + buf.appendBytes(v.toOpenArrayByte(0, v.high)) proc writeParamValue*(buf: var seq[byte], v: seq[byte]) = buf.addInt32(int32(v.len)) - if v.len > 0: - let o = buf.len - buf.setLen(o + v.len) - copyMem(addr buf[o], addr v[0], v.len) + buf.appendBytes(v) proc writeParamValue*(buf: var seq[byte], v: PgNumeric) = writeParamValue(buf, $v)