diff semiconginev2/thirdparty/zippy/zippy.nim @ 1218:56781cc0fc7c compiletime-tests

did: renamge main package
author sam <sam@basx.dev>
date Wed, 17 Jul 2024 21:01:37 +0700
parents semicongine/old/thirdparty/zippy/zippy.nim@239adab121a3
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/semiconginev2/thirdparty/zippy/zippy.nim	Wed Jul 17 21:01:37 2024 +0700
@@ -0,0 +1,177 @@
+import zippy/adler32, zippy/common, zippy/crc, zippy/deflate,
+    zippy/gzip, zippy/inflate, zippy/internal
+
+when (NimMajor, NimMinor, NimPatch) >= (1, 6, 0):
+  import std/sysrand
+else:
+  import std/random, std/times
+
+export common
+
+proc compress*(
+  src: pointer,
+  len: int,
+  level = DefaultCompression,
+  dataFormat = dfGzip
+): string {.raises: [ZippyError].} =
+  ## Compresses src and returns the compressed data.
+  let src = cast[ptr UncheckedArray[uint8]](src)
+
+  case dataFormat:
+  of dfGzip:
+    result.setLen(10)
+    result[0] = 31.char
+    result[1] = 139.char
+    result[2] = 8.char
+    result[3] = (1.uint8 shl 3).char # Set the fname flag
+
+    block: # https://github.com/guzba/zippy/issues/61
+      let htbLen =
+        when (NimMajor, NimMinor, NimPatch) >= (1, 6, 0):
+          var urand: array[1, uint8]
+          if not urandom(urand):
+            raise newException(ZippyError, "Failed to generate random number")
+          (urand[0] mod 26).int
+        else:
+          let now = getTime()
+          var rand = initRand(now.toUnix * 1_000_000_000 + now.nanosecond)
+          (rand.next() mod 26).int # mod the uint first to ensure a positive int
+      # Add up to 26 characters as the gzip header file name
+      for i in 0 ..< htbLen:
+        result.add (97 + i).char
+      result.add '\0'
+
+    deflate(result, src, len, level)
+
+    let
+      checksum = crc32(src, len)
+      isize = len
+
+    result.add(((checksum shr 0) and 255).char)
+    result.add(((checksum shr 8) and 255).char)
+    result.add(((checksum shr 16) and 255).char)
+    result.add(((checksum shr 24) and 255).char)
+
+    result.add(((isize shr 0) and 255).char)
+    result.add(((isize shr 8) and 255).char)
+    result.add(((isize shr 16) and 255).char)
+    result.add(((isize shr 24) and 255).char)
+
+  of dfZlib:
+    const
+      cm = 8.uint8
+      cinfo = 7.uint8
+      cmf = (cinfo shl 4) or cm
+      fcheck = (31.uint32 - (cmf.uint32 * 256) mod 31).uint8
+
+    result.setLen(2)
+    result[0] = cmf.char
+    result[1] = fcheck.char
+
+    deflate(result, src, len, level)
+
+    let checksum = adler32(src, len)
+
+    result.add(((checksum shr 24) and 255).char)
+    result.add(((checksum shr 16) and 255).char)
+    result.add(((checksum shr 8) and 255).char)
+    result.add(((checksum shr 0) and 255).char)
+
+  of dfDeflate:
+    deflate(result, src, len, level)
+
+  else:
+    raise newException(ZippyError, "Invalid data format " & $dfDetect)
+
+proc compress*(
+  src: string,
+  level = DefaultCompression,
+  dataFormat = dfGzip
+): string {.raises: [ZippyError].} =
+  compress(src.cstring, src.len, level, dataFormat)
+
+proc compress*(
+  src: seq[uint8],
+  level = DefaultCompression,
+  dataFormat = dfGzip
+): seq[uint8] {.raises: [ZippyError].} =
+  cast[seq[uint8]](compress(cast[string](src).cstring, src.len, level, dataFormat))
+
+proc uncompress*(
+  src: pointer,
+  len: int,
+  dataFormat = dfDetect
+): string {.raises: [ZippyError].} =
+  ## Uncompresses src and returns the uncompressed data.
+  let src = cast[ptr UncheckedArray[uint8]](src)
+
+  case dataFormat:
+  of dfDetect:
+    if (
+      len > 18 and
+      src[0].uint8 == 31 and src[1].uint8 == 139 and src[2].uint8 == 8 and
+      (src[3].uint8 and 0b11100000) == 0
+    ):
+      return uncompress(src, len, dfGzip)
+
+    if (
+      len > 6 and
+      (src[0].uint8 and 0b00001111) == 8 and
+      (src[0].uint8 shr 4) <= 7 and
+      ((src[0].uint16 * 256) + src[1].uint8) mod 31 == 0
+    ):
+      return uncompress(src, len, dfZlib)
+
+    raise newException(ZippyError, "Unable to detect compressed data format")
+
+  of dfGzip:
+    uncompressGzip(result, src, len)
+
+  of dfZlib:
+    if len < 6:
+      failUncompress()
+
+    let
+      cmf = src[0].uint8
+      flg = src[1].uint8
+      cm = cmf and 0b00001111
+      cinfo = cmf shr 4
+
+    if cm != 8: # DEFLATE
+      raise newException(ZippyError, "Unsupported compression method")
+
+    if cinfo > 7.uint8:
+      raise newException(ZippyError, "Invalid compression info")
+
+    if ((cmf.uint16 * 256) + flg.uint16) mod 31 != 0:
+      raise newException(ZippyError, "Invalid header")
+
+    if (flg and 0b00100000) != 0: # FDICT
+      raise newException(ZippyError, "Preset dictionary is not yet supported")
+
+    inflate(result, src, len, 2)
+
+    let checksum = (
+      src[len - 4].uint32 shl 24 or
+      src[len - 3].uint32 shl 16 or
+      src[len - 2].uint32 shl 8 or
+      src[len - 1].uint32
+    )
+
+    if checksum != adler32(result):
+      raise newException(ZippyError, "Checksum verification failed")
+
+  of dfDeflate:
+    inflate(result, src, len, 0)
+
+proc uncompress*(
+  src: string,
+  dataFormat = dfDetect
+): string {.raises: [ZippyError].} =
+  uncompress(src.cstring, src.len, dataFormat)
+
+proc uncompress*(
+  src: seq[uint8],
+  dataFormat = dfDetect
+): seq[uint8] {.raises: [ZippyError].} =
+  cast[seq[uint8]](uncompress(cast[string](src).cstring, src.len, dataFormat))