mirror of https://github.com/4yn/slidershim
draft redboard i/o
parent
6124dee2db
commit
adea9e3a45
|
@ -3,6 +3,8 @@
|
|||
"cmake.sourceDirectory": "${workspaceFolder}/src-serial",
|
||||
"cmake.buildDirectory": "${workspaceFolder}/src-serial/build",
|
||||
"files.associations": {
|
||||
"*.sage": "python",
|
||||
"*.svx": "mdx",
|
||||
"xstring": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"atomic": "cpp",
|
||||
|
@ -75,6 +77,8 @@
|
|||
"xlocbuf": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xloctime": "cpp"
|
||||
"xloctime": "cpp",
|
||||
"lib.rs.h": "c",
|
||||
"lzfx.h": "c"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
target/
|
|
@ -0,0 +1,182 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe98ba1789d56fb3db3bee5e032774d4f421b685de7ba703643584ba24effbe"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4ce20f6b8433da4841b1dadfb9468709868022d829d5ca1f2ffbda928455ea3"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20888d9e1d2298e2ff473cee30efe7d5036e437857ab68bbfea84c74dba91da2"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fa16a70dd58129e4dfffdff535fb1bce66673f7bbeec4a5a1765a504e1ccd84"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzfx"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scratch"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "lzfx"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
cxx = "1.0"
|
||||
|
||||
[build-dependencies]
|
||||
cxx-build = "1.0"
|
|
@ -0,0 +1,13 @@
|
|||
fn main() {
|
||||
cxx_build::bridge("src/lib.rs")
|
||||
.file("src/lzfx.cc")
|
||||
.file("src/lzfxbridge.cc")
|
||||
.flag_if_supported("-std=c++14")
|
||||
.compile("cxxbridge-demo");
|
||||
|
||||
println!("cargo:rerun-if-changed=src/lib.rs");
|
||||
println!("cargo:rerun-if-changed=src/lzfx.cc");
|
||||
println!("cargo:rerun-if-changed=src/lzfxbridge.cc");
|
||||
println!("cargo:rerun-if-changed=include/lzfx.h");
|
||||
println!("cargo:rerun-if-changed=include/lzfxbridge.h");
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Andrew Collette <andrew.collette at gmail.com>
|
||||
* http://lzfx.googlecode.com
|
||||
*
|
||||
* Implements an LZF-compatible compressor/decompressor based on the liblzf
|
||||
* codebase written by Marc Lehmann. This code is released under the BSD
|
||||
* license. License and original copyright statement follow.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LZFX_H
|
||||
#define LZFX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Documented behavior, including function signatures and error codes,
|
||||
is guaranteed to remain unchanged for releases with the same major
|
||||
version number. Releases of the same major version are also able
|
||||
to read each other's output, although the output itself is not
|
||||
guaranteed to be byte-for-byte identical.
|
||||
*/
|
||||
#define LZFX_VERSION_MAJOR 0
|
||||
#define LZFX_VERSION_MINOR 1
|
||||
#define LZFX_VERSION_STRING "0.1"
|
||||
|
||||
/* Hashtable size (2**LZFX_HLOG entries) */
|
||||
#ifndef LZFX_HLOG
|
||||
#define LZFX_HLOG 16
|
||||
#endif
|
||||
|
||||
/* Predefined errors. */
|
||||
#define LZFX_ESIZE -1 /* Output buffer too small */
|
||||
#define LZFX_ECORRUPT -2 /* Invalid data for decompression */
|
||||
#define LZFX_EARGS -3 /* Arguments invalid (NULL) */
|
||||
|
||||
/* Buffer-to buffer compression.
|
||||
|
||||
Supply pre-allocated input and output buffers via ibuf and obuf, and
|
||||
their size in bytes via ilen and olen. Buffers may not overlap.
|
||||
|
||||
On success, the function returns a non-negative value and the argument
|
||||
olen contains the compressed size in bytes. On failure, a negative
|
||||
value is returned and olen is not modified.
|
||||
*/
|
||||
int lzfx_compress(const void *ibuf, unsigned int ilen,
|
||||
void *obuf, unsigned int *olen);
|
||||
|
||||
/* Buffer-to-buffer decompression.
|
||||
|
||||
Supply pre-allocated input and output buffers via ibuf and obuf, and
|
||||
their size in bytes via ilen and olen. Buffers may not overlap.
|
||||
|
||||
On success, the function returns a non-negative value and the argument
|
||||
olen contains the uncompressed size in bytes. On failure, a negative
|
||||
value is returned.
|
||||
|
||||
If the failure code is LZFX_ESIZE, olen contains the minimum buffer size
|
||||
required to hold the decompressed data. Otherwise, olen is not modified.
|
||||
|
||||
Supplying a zero *olen is a valid and supported strategy to determine the
|
||||
required buffer size. This does not require decompression of the entire
|
||||
stream and is consequently very fast. Argument obuf may be NULL in
|
||||
this case only.
|
||||
*/
|
||||
int lzfx_decompress(const void *ibuf, unsigned int ilen,
|
||||
void *obuf, unsigned int *olen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
#include "rust/cxx.h"
|
||||
|
||||
uint32_t compress(const rust::Vec<uint8_t> &data, rust::Vec<uint8_t> &out);
|
||||
|
||||
uint32_t decompress(const rust::Vec<uint8_t> &data, rust::Vec<uint8_t> &out);
|
|
@ -0,0 +1,13 @@
|
|||
#[cxx::bridge]
|
||||
mod ffi {
|
||||
unsafe extern "C++" {
|
||||
include!("lzfx/include/lzfxbridge.h");
|
||||
|
||||
fn compress(data: &Vec<u8>, out: &mut Vec<u8>) -> u32;
|
||||
|
||||
fn decompress(data: &Vec<u8>, out: &mut Vec<u8>) -> u32;
|
||||
}
|
||||
}
|
||||
|
||||
pub use ffi::compress;
|
||||
pub use ffi::decompress;
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Andrew Collette <andrew.collette at gmail.com>
|
||||
* http://lzfx.googlecode.com
|
||||
*
|
||||
* Implements an LZF-compatible compressor/decompressor based on the liblzf
|
||||
* codebase written by Marc Lehmann. This code is released under the BSD
|
||||
* license. License and original copyright statement follow.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000-2008 Marc Alexander Lehmann <schmorp@schmorp.de>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modifica-
|
||||
* tion, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
||||
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
||||
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
||||
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "lzfx/include/lzfx.h"
|
||||
|
||||
#define LZFX_HSIZE (1 << (LZFX_HLOG))
|
||||
|
||||
/* We need this for memset */
|
||||
#ifdef __cplusplus
|
||||
#include <cstring>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#define fx_expect_false(expr) __builtin_expect((expr) != 0, 0)
|
||||
#define fx_expect_true(expr) __builtin_expect((expr) != 0, 1)
|
||||
#else
|
||||
#define fx_expect_false(expr) (expr)
|
||||
#define fx_expect_true(expr) (expr)
|
||||
#endif
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef const u8 *LZSTATE[LZFX_HSIZE];
|
||||
|
||||
/* Define the hash function */
|
||||
#define LZFX_FRST(p) (((p[0]) << 8) | p[1])
|
||||
#define LZFX_NEXT(v, p) (((v) << 8) | p[2])
|
||||
#define LZFX_IDX(h) (((h >> (3 * 8 - LZFX_HLOG)) - h) & (LZFX_HSIZE - 1))
|
||||
|
||||
/* These cannot be changed, as they are related to the compressed format. */
|
||||
#define LZFX_MAX_LIT (1 << 5)
|
||||
#define LZFX_MAX_OFF (1 << 13)
|
||||
#define LZFX_MAX_REF ((1 << 8) + (1 << 3))
|
||||
|
||||
static int lzfx_getsize(const void *ibuf, unsigned int ilen, unsigned int *olen);
|
||||
|
||||
/* Compressed format
|
||||
|
||||
There are two kinds of structures in LZF/LZFX: literal runs and back
|
||||
references. The length of a literal run is encoded as L - 1, as it must
|
||||
contain at least one byte. Literals are encoded as follows:
|
||||
|
||||
000LLLLL <L+1 bytes>
|
||||
|
||||
Back references are encoded as follows. The smallest possible encoded
|
||||
length value is 1, as otherwise the control byte would be recognized as
|
||||
a literal run. Since at least three bytes must match for a back reference
|
||||
to be inserted, the length is encoded as L - 2 instead of L - 1. The
|
||||
offset (distance to the desired data in the output buffer) is encoded as
|
||||
o - 1, as all offsets are at least 1. The binary format is:
|
||||
|
||||
LLLooooo oooooooo for backrefs of real length < 9 (1 <= L < 7)
|
||||
111ooooo LLLLLLLL oooooooo for backrefs of real length >= 9 (L > 7)
|
||||
*/
|
||||
int lzfx_compress(const void *const ibuf, const unsigned int ilen,
|
||||
void *obuf, unsigned int *const olen)
|
||||
{
|
||||
|
||||
/* Hash table; an array of u8*'s which point
|
||||
to various locations in the input buffer */
|
||||
const u8 *htab[LZFX_HSIZE];
|
||||
|
||||
const u8 **hslot; /* Pointer to entry in hash table */
|
||||
unsigned int hval; /* Hash value generated by macros above */
|
||||
const u8 *ref; /* Pointer to candidate match location in input */
|
||||
|
||||
const u8 *ip = (const u8 *)ibuf;
|
||||
const u8 *const in_end = ip + ilen;
|
||||
|
||||
u8 *op = (u8 *)obuf;
|
||||
const u8 *const out_end = (olen == NULL ? NULL : op + *olen);
|
||||
|
||||
int lit; /* # of bytes in current literal run */
|
||||
|
||||
#if defined(WIN32) && defined(_M_X64)
|
||||
unsigned _int64 off; /* workaround for missing POSIX compliance */
|
||||
#else
|
||||
unsigned long off;
|
||||
#endif
|
||||
|
||||
if (olen == NULL)
|
||||
return LZFX_EARGS;
|
||||
if (ibuf == NULL)
|
||||
{
|
||||
if (ilen != 0)
|
||||
return LZFX_EARGS;
|
||||
*olen = 0;
|
||||
return 0;
|
||||
}
|
||||
if (obuf == NULL)
|
||||
return LZFX_EARGS;
|
||||
|
||||
memset(htab, 0, sizeof(htab));
|
||||
|
||||
/* Start a literal run. Whenever we do this the output pointer is
|
||||
advanced because the current byte will hold the encoded length. */
|
||||
lit = 0;
|
||||
op++;
|
||||
|
||||
hval = LZFX_FRST(ip);
|
||||
|
||||
while (ip + 2 < in_end)
|
||||
{ /* The NEXT macro reads 2 bytes ahead */
|
||||
|
||||
hval = LZFX_NEXT(hval, ip);
|
||||
hslot = htab + LZFX_IDX(hval);
|
||||
|
||||
ref = *hslot;
|
||||
*hslot = ip;
|
||||
|
||||
if (ref < ip && (off = ip - ref - 1) < LZFX_MAX_OFF && ip + 4 < in_end /* Backref takes up to 3 bytes, so don't bother */
|
||||
&& ref > (u8 *)ibuf && ref[0] == ip[0] && ref[1] == ip[1] && ref[2] == ip[2])
|
||||
{
|
||||
|
||||
unsigned int len = 3; /* We already know 3 bytes match */
|
||||
const unsigned int maxlen = in_end - ip - 2 > LZFX_MAX_REF ? LZFX_MAX_REF : in_end - ip - 2;
|
||||
|
||||
/* lit == 0: op + 3 must be < out_end (because we undo the run)
|
||||
lit != 0: op + 3 + 1 must be < out_end */
|
||||
if (fx_expect_false(op - !lit + 3 + 1 >= out_end))
|
||||
return LZFX_ESIZE;
|
||||
|
||||
op[-lit - 1] = lit - 1; /* Terminate literal run */
|
||||
op -= !lit; /* Undo run if length is zero */
|
||||
|
||||
/* Start checking at the fourth byte */
|
||||
while (len < maxlen && ref[len] == ip[len])
|
||||
len++;
|
||||
|
||||
len -= 2; /* We encode the length as #octets - 2 */
|
||||
|
||||
/* Format 1: [LLLooooo oooooooo] */
|
||||
if (len < 7)
|
||||
{
|
||||
*op++ = (off >> 8) + (len << 5);
|
||||
*op++ = off;
|
||||
|
||||
/* Format 2: [111ooooo LLLLLLLL oooooooo] */
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (off >> 8) + (7 << 5);
|
||||
*op++ = len - 7;
|
||||
*op++ = off;
|
||||
}
|
||||
|
||||
lit = 0;
|
||||
op++;
|
||||
|
||||
ip += len + 1; /* ip = initial ip + #octets -1 */
|
||||
|
||||
if (fx_expect_false(ip + 3 >= in_end))
|
||||
{
|
||||
ip++; /* Code following expects exit at bottom of loop */
|
||||
break;
|
||||
}
|
||||
|
||||
hval = LZFX_FRST(ip);
|
||||
hval = LZFX_NEXT(hval, ip);
|
||||
htab[LZFX_IDX(hval)] = ip;
|
||||
|
||||
ip++; /* ip = initial ip + #octets */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep copying literal bytes */
|
||||
|
||||
if (fx_expect_false(op >= out_end))
|
||||
return LZFX_ESIZE;
|
||||
|
||||
lit++;
|
||||
*op++ = *ip++;
|
||||
|
||||
if (fx_expect_false(lit == LZFX_MAX_LIT))
|
||||
{
|
||||
op[-lit - 1] = lit - 1; /* stop run */
|
||||
lit = 0;
|
||||
op++; /* start run */
|
||||
}
|
||||
|
||||
} /* if() found match in htab */
|
||||
|
||||
} /* while(ip < ilen -2) */
|
||||
|
||||
/* At most 3 bytes remain in input. We therefore need 4 bytes available
|
||||
in the output buffer to store them (3 data + ctrl byte).*/
|
||||
if (op + 3 > out_end)
|
||||
return LZFX_ESIZE;
|
||||
|
||||
while (ip < in_end)
|
||||
{
|
||||
|
||||
lit++;
|
||||
*op++ = *ip++;
|
||||
|
||||
if (fx_expect_false(lit == LZFX_MAX_LIT))
|
||||
{
|
||||
op[-lit - 1] = lit - 1;
|
||||
lit = 0;
|
||||
op++;
|
||||
}
|
||||
}
|
||||
|
||||
op[-lit - 1] = lit - 1;
|
||||
op -= !lit;
|
||||
|
||||
*olen = op - (u8 *)obuf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decompressor */
|
||||
int lzfx_decompress(const void *ibuf, unsigned int ilen,
|
||||
void *obuf, unsigned int *olen)
|
||||
{
|
||||
|
||||
u8 const *ip = (const u8 *)ibuf;
|
||||
u8 const *const in_end = ip + ilen;
|
||||
u8 *op = (u8 *)obuf;
|
||||
u8 const *const out_end = (olen == NULL ? NULL : op + *olen);
|
||||
|
||||
unsigned int remain_len = 0;
|
||||
int rc;
|
||||
|
||||
if (olen == NULL)
|
||||
return LZFX_EARGS;
|
||||
if (ibuf == NULL)
|
||||
{
|
||||
if (ilen != 0)
|
||||
return LZFX_EARGS;
|
||||
*olen = 0;
|
||||
return 0;
|
||||
}
|
||||
if (obuf == NULL)
|
||||
{
|
||||
if (olen != 0)
|
||||
return LZFX_EARGS;
|
||||
return lzfx_getsize(ibuf, ilen, olen);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
unsigned int ctrl = *ip++;
|
||||
|
||||
/* Format 000LLLLL: a literal byte string follows, of length L+1 */
|
||||
if (ctrl < (1 << 5))
|
||||
{
|
||||
|
||||
ctrl++;
|
||||
|
||||
if (fx_expect_false(op + ctrl > out_end))
|
||||
{
|
||||
--ip; /* Rewind to control byte */
|
||||
goto guess;
|
||||
}
|
||||
if (fx_expect_false(ip + ctrl > in_end))
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
do
|
||||
*op++ = *ip++;
|
||||
while (--ctrl);
|
||||
|
||||
/* Format #1 [LLLooooo oooooooo]: backref of length L+1+2
|
||||
^^^^^ ^^^^^^^^
|
||||
A B
|
||||
#2 [111ooooo LLLLLLLL oooooooo] backref of length L+7+2
|
||||
^^^^^ ^^^^^^^^
|
||||
A B
|
||||
In both cases the location of the backref is computed from the
|
||||
remaining part of the data as follows:
|
||||
|
||||
location = op - A*256 - B - 1
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
unsigned int len = (ctrl >> 5);
|
||||
u8 *ref = op - ((ctrl & 0x1f) << 8) - 1;
|
||||
|
||||
if (len == 7)
|
||||
len += *ip++; /* i.e. format #2 */
|
||||
|
||||
len += 2; /* len is now #octets */
|
||||
|
||||
if (fx_expect_false(op + len > out_end))
|
||||
{
|
||||
ip -= (len >= 9) ? 2 : 1; /* Rewind to control byte */
|
||||
goto guess;
|
||||
}
|
||||
if (fx_expect_false(ip >= in_end))
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
ref -= *ip++;
|
||||
|
||||
if (fx_expect_false(ref < (u8 *)obuf))
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
do
|
||||
*op++ = *ref++;
|
||||
while (--len);
|
||||
}
|
||||
|
||||
} while (ip < in_end);
|
||||
|
||||
*olen = op - (u8 *)obuf;
|
||||
|
||||
return 0;
|
||||
|
||||
guess:
|
||||
rc = lzfx_getsize(ip, ilen - (ip - (u8 *)ibuf), &remain_len);
|
||||
if (rc >= 0)
|
||||
*olen = remain_len + (op - (u8 *)obuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Guess len. No parameters may be NULL; this is not checked. */
|
||||
static int lzfx_getsize(const void *ibuf, unsigned int ilen, unsigned int *olen)
|
||||
{
|
||||
|
||||
u8 const *ip = (const u8 *)ibuf;
|
||||
u8 const *const in_end = ip + ilen;
|
||||
int tot_len = 0;
|
||||
|
||||
while (ip < in_end)
|
||||
{
|
||||
|
||||
unsigned int ctrl = *ip++;
|
||||
|
||||
if (ctrl < (1 << 5))
|
||||
{
|
||||
|
||||
ctrl++;
|
||||
|
||||
if (ip + ctrl > in_end)
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
tot_len += ctrl;
|
||||
ip += ctrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
unsigned int len = (ctrl >> 5);
|
||||
|
||||
if (len == 7)
|
||||
{ /* i.e. format #2 */
|
||||
len += *ip++;
|
||||
}
|
||||
|
||||
len += 2; /* len is now #octets */
|
||||
|
||||
if (ip >= in_end)
|
||||
return LZFX_ECORRUPT;
|
||||
|
||||
ip++; /* skip the ref byte */
|
||||
|
||||
tot_len += len;
|
||||
}
|
||||
}
|
||||
|
||||
*olen = tot_len;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#include "lzfx/include/lzfx.h"
|
||||
#include "lzfx/include/lzfxbridge.h"
|
||||
#include "lzfx/src/lib.rs.h"
|
||||
|
||||
uint32_t compress(const rust::Vec<uint8_t> &data, rust::Vec<uint8_t> &out)
|
||||
{
|
||||
std::vector<uint8_t> databuf(data.begin(), data.end());
|
||||
std::vector<uint8_t> outbuf;
|
||||
outbuf.resize(out.capacity());
|
||||
unsigned int olen = out.capacity();
|
||||
int ret = lzfx_compress(&databuf[0], databuf.size(), &outbuf[0], &olen);
|
||||
outbuf.resize(olen);
|
||||
std::copy(
|
||||
outbuf.begin(), outbuf.end(),
|
||||
std::back_inserter(out));
|
||||
return olen;
|
||||
}
|
||||
|
||||
uint32_t decompress(const rust::Vec<uint8_t> &data, rust::Vec<uint8_t> &out)
|
||||
{
|
||||
|
||||
std::vector<uint8_t> databuf(data.begin(), data.end());
|
||||
std::vector<uint8_t> outbuf;
|
||||
outbuf.resize(out.capacity());
|
||||
unsigned int olen = out.capacity();
|
||||
int ret = lzfx_decompress(&databuf[0], databuf.size(), &outbuf[0], &olen);
|
||||
outbuf.resize(olen);
|
||||
std::copy(
|
||||
outbuf.begin(), outbuf.end(),
|
||||
std::back_inserter(out));
|
||||
return olen;
|
||||
}
|
|
@ -462,7 +462,7 @@ checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
|
|||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -658,9 +658,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.117"
|
||||
version = "0.2.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
|
||||
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
|
||||
|
||||
[[package]]
|
||||
name = "libudev"
|
||||
|
@ -721,6 +721,14 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzfx"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mach"
|
||||
version = "0.1.2"
|
||||
|
@ -781,24 +789,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.7.14"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"miow",
|
||||
"ntapi",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -814,15 +811,6 @@ dependencies = [
|
|||
"void",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
|
@ -951,7 +939,7 @@ dependencies = [
|
|||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-sys",
|
||||
"windows-sys 0.32.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1102,11 +1090,11 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
version = "1.0.67"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
||||
checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1352,6 +1340,7 @@ dependencies = [
|
|||
"interception",
|
||||
"ipconfig",
|
||||
"log",
|
||||
"lzfx",
|
||||
"palette",
|
||||
"parking_lot",
|
||||
"phf 0.10.1",
|
||||
|
@ -1453,16 +1442,17 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.16.1"
|
||||
version = "1.20.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c27a64b625de6d309e8c57716ba93021dccf1b3b5c97edd6d3dd2d2135afc0a"
|
||||
checksum = "5b57956f83355511a714cba847e66ad8700bf7e8a596b5016f4eae18954cc8d0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"winapi",
|
||||
]
|
||||
|
@ -1576,6 +1566,12 @@ version = "0.3.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.19"
|
||||
|
@ -1658,6 +1654,12 @@ version = "0.10.2+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.5"
|
||||
|
@ -1707,43 +1709,109 @@ version = "0.32.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_aarch64_msvc 0.32.0",
|
||||
"windows_i686_gnu 0.32.0",
|
||||
"windows_i686_msvc 0.32.0",
|
||||
"windows_x86_64_gnu 0.32.0",
|
||||
"windows_x86_64_msvc 0.32.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.7.0"
|
||||
|
|
|
@ -33,6 +33,7 @@ vigem-client = { version = "0.1.2", features = ["unstable"] }
|
|||
winapi = "0.3.9"
|
||||
interception = {path = "../src-interception" }
|
||||
ipconfig = "0.3.0"
|
||||
lzfx = {path = "../src-lzfx" }
|
||||
|
||||
# webserver
|
||||
hyper = { version="0.14.16", features= ["server", "http1", "http2", "tcp", "stream", "runtime"] }
|
||||
|
|
|
@ -7,6 +7,7 @@ pub enum HardwareSpec {
|
|||
Yuancon,
|
||||
Yubideck,
|
||||
YubideckThree,
|
||||
HoriPad,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -58,6 +59,10 @@ impl DeviceMode {
|
|||
spec: HardwareSpec::YubideckThree,
|
||||
disable_air: v["disableAirStrings"].as_bool()?,
|
||||
},
|
||||
"hori" => DeviceMode::Hardware {
|
||||
spec: HardwareSpec::HoriPad,
|
||||
disable_air: v["disableAirStrings"].as_bool()?,
|
||||
},
|
||||
"diva" => DeviceMode::DivaSlider {
|
||||
port: v["divaSerialPort"].as_str()?.to_string(),
|
||||
brightness: u8::try_from(v["divaBrightness"].as_i64()?).ok()?,
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
use log::{error, info};
|
||||
use rusb::{self, DeviceHandle, GlobalContext};
|
||||
use std::{
|
||||
borrow::BorrowMut,
|
||||
error::Error,
|
||||
mem::swap,
|
||||
ops::{Deref, DerefMut},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use lzfx::compress;
|
||||
|
||||
use crate::{
|
||||
shared::{
|
||||
utils::{Buffer, ShimError},
|
||||
|
@ -18,30 +21,43 @@ use crate::{
|
|||
use super::config::HardwareSpec;
|
||||
|
||||
type HidReadCallback = fn(&Buffer, &mut SliderInput) -> ();
|
||||
type HidLedCallback = fn(&mut Buffer, &mut Buffer, &SliderLights) -> ();
|
||||
type HidLedCallback = fn(&mut Vec<LedSpec>, &SliderLights) -> ();
|
||||
|
||||
enum WriteType {
|
||||
Bulk,
|
||||
Interrupt,
|
||||
}
|
||||
|
||||
pub struct LedSpec {
|
||||
led_write_type: WriteType,
|
||||
led_endpoint: u8,
|
||||
led_buf: Buffer,
|
||||
}
|
||||
|
||||
impl LedSpec {
|
||||
fn new(led_write_type: WriteType, led_endpoint: u8) -> Self {
|
||||
Self {
|
||||
led_write_type,
|
||||
led_endpoint,
|
||||
led_buf: Buffer::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HidJob {
|
||||
state: SliderState,
|
||||
|
||||
vid: u16,
|
||||
pid: u16,
|
||||
read_endpoint: u8,
|
||||
led_endpoint: u8,
|
||||
disable_air: bool,
|
||||
|
||||
read_endpoint: u8,
|
||||
read_callback: HidReadCallback,
|
||||
read_buf: Buffer,
|
||||
last_read_buf: Buffer,
|
||||
|
||||
led_write_type: WriteType,
|
||||
led_specs: Vec<LedSpec>,
|
||||
led_callback: HidLedCallback,
|
||||
led_buf: Buffer,
|
||||
led_buf_two: Buffer,
|
||||
|
||||
handle: Option<DeviceHandle<GlobalContext>>,
|
||||
}
|
||||
|
@ -51,27 +67,28 @@ impl HidJob {
|
|||
state: SliderState,
|
||||
vid: u16,
|
||||
pid: u16,
|
||||
read_endpoint: u8,
|
||||
led_endpoint: u8,
|
||||
disable_air: bool,
|
||||
|
||||
read_endpoint: u8,
|
||||
read_callback: HidReadCallback,
|
||||
led_type: WriteType,
|
||||
|
||||
led_specs: Vec<LedSpec>,
|
||||
led_callback: HidLedCallback,
|
||||
) -> Self {
|
||||
Self {
|
||||
state,
|
||||
vid,
|
||||
pid,
|
||||
read_endpoint,
|
||||
led_endpoint,
|
||||
disable_air,
|
||||
|
||||
read_callback,
|
||||
read_endpoint,
|
||||
read_buf: Buffer::new(),
|
||||
last_read_buf: Buffer::new(),
|
||||
led_write_type: led_type,
|
||||
|
||||
led_callback,
|
||||
led_buf: Buffer::new(),
|
||||
led_buf_two: Buffer::new(),
|
||||
led_specs,
|
||||
|
||||
handle: None,
|
||||
}
|
||||
}
|
||||
|
@ -82,9 +99,8 @@ impl HidJob {
|
|||
state.clone(),
|
||||
0x1ccf,
|
||||
0x2333,
|
||||
0x84,
|
||||
0x03,
|
||||
*disable_air,
|
||||
0x84,
|
||||
|buf, input| {
|
||||
if buf.len != 11 {
|
||||
return;
|
||||
|
@ -103,8 +119,9 @@ impl HidJob {
|
|||
input.air.copy_from_slice(&bits[28..34]);
|
||||
input.extra[0..2].copy_from_slice(&bits[26..28]);
|
||||
},
|
||||
WriteType::Bulk,
|
||||
|buf, _, lights| {
|
||||
vec![LedSpec::new(WriteType::Bulk, 0x03)],
|
||||
|led_specs, lights| {
|
||||
let buf = led_specs[0].led_buf.borrow_mut();
|
||||
buf.len = 240;
|
||||
buf.data[0] = 'B' as u8;
|
||||
buf.data[1] = 'L' as u8;
|
||||
|
@ -125,9 +142,8 @@ impl HidJob {
|
|||
state.clone(),
|
||||
0x1ccf,
|
||||
0x2333,
|
||||
0x84,
|
||||
0x03,
|
||||
*disable_air,
|
||||
0x84,
|
||||
|buf, input| {
|
||||
if buf.len != 36 {
|
||||
return;
|
||||
|
@ -140,8 +156,9 @@ impl HidJob {
|
|||
input.air.copy_from_slice(&bits[0..6]);
|
||||
input.extra[0..2].copy_from_slice(&bits[6..8]);
|
||||
},
|
||||
WriteType::Bulk,
|
||||
|buf, _, lights| {
|
||||
vec![LedSpec::new(WriteType::Bulk, 0x03)],
|
||||
|led_specs, lights| {
|
||||
let buf = led_specs[0].led_buf.borrow_mut();
|
||||
buf.len = 240;
|
||||
buf.data[0] = 'B' as u8;
|
||||
buf.data[1] = 'L' as u8;
|
||||
|
@ -175,9 +192,8 @@ impl HidJob {
|
|||
state.clone(),
|
||||
0x1973,
|
||||
0x2001,
|
||||
0x81,
|
||||
0x02,
|
||||
*disable_air,
|
||||
0x81,
|
||||
|buf, input| {
|
||||
if buf.len != 34 && buf.len != 35 {
|
||||
return;
|
||||
|
@ -191,8 +207,9 @@ impl HidJob {
|
|||
input.extra[2 - i] = (buf.data[1] >> i) & 1;
|
||||
}
|
||||
},
|
||||
WriteType::Interrupt,
|
||||
|buf, _, lights| {
|
||||
vec![LedSpec::new(WriteType::Interrupt, 0x02)],
|
||||
|led_specs, lights| {
|
||||
let buf = led_specs[0].led_buf.borrow_mut();
|
||||
buf.len = 31 * 2;
|
||||
for (buf_chunk, state_chunk) in buf
|
||||
.data
|
||||
|
@ -209,9 +226,8 @@ impl HidJob {
|
|||
state.clone(),
|
||||
0x1973,
|
||||
0x2001,
|
||||
0x81, // Need to confirm
|
||||
0x02, // Need to confirm
|
||||
*disable_air,
|
||||
0x81, // Need to confirm
|
||||
|buf, input| {
|
||||
if buf.len != 45 && buf.len != 46 {
|
||||
return;
|
||||
|
@ -226,8 +242,10 @@ impl HidJob {
|
|||
input.extra[2 - i] = (buf.data[1] >> i) & 1;
|
||||
}
|
||||
},
|
||||
WriteType::Interrupt,
|
||||
|buf, _, lights| {
|
||||
vec![LedSpec::new(WriteType::Interrupt, 0x02)],
|
||||
|led_specs, lights| {
|
||||
let buf = led_specs[0].led_buf.borrow_mut();
|
||||
|
||||
buf.len = 62;
|
||||
|
||||
let lights_nibbles: Vec<u8> = lights
|
||||
|
@ -258,9 +276,8 @@ impl HidJob {
|
|||
state.clone(),
|
||||
0x1973,
|
||||
0x2001,
|
||||
0x81, // Need to confirm
|
||||
0x02, // Need to confirm
|
||||
*disable_air,
|
||||
0x81, // Need to confirm
|
||||
|buf, input| {
|
||||
if buf.len != 45 && buf.len != 46 {
|
||||
return;
|
||||
|
@ -275,33 +292,111 @@ impl HidJob {
|
|||
input.extra[2 - i] = (buf.data[1] >> i) & 1;
|
||||
}
|
||||
},
|
||||
WriteType::Interrupt,
|
||||
|buf, buf_two, lights| {
|
||||
buf.len = 61;
|
||||
buf.data[0] = 0;
|
||||
buf_two.len = 61;
|
||||
buf_two.data[0] = 1;
|
||||
vec![
|
||||
LedSpec::new(WriteType::Interrupt, 0x02),
|
||||
LedSpec::new(WriteType::Interrupt, 0x02),
|
||||
],
|
||||
|led_specs, lights| {
|
||||
if let [led_spec_a, led_spec_b] = led_specs.as_mut_slice() {
|
||||
let buf_a = &mut led_spec_a.led_buf;
|
||||
let buf_b = &mut led_spec_b.led_buf;
|
||||
|
||||
for (buf_chunk, state_chunk) in buf.data[1..61]
|
||||
.chunks_mut(3)
|
||||
.zip(lights.ground.chunks(3).skip(11).take(20).rev())
|
||||
{
|
||||
buf_chunk[0] = state_chunk[0];
|
||||
buf_chunk[1] = state_chunk[1];
|
||||
buf_chunk[2] = state_chunk[2];
|
||||
buf_a.len = 61;
|
||||
buf_a.data[0] = 0;
|
||||
buf_b.len = 61;
|
||||
buf_b.data[0] = 1;
|
||||
|
||||
for (buf_chunk, state_chunk) in buf_a.data[1..61]
|
||||
.chunks_mut(3)
|
||||
.zip(lights.ground.chunks(3).skip(11).take(20).rev())
|
||||
{
|
||||
buf_chunk[0] = state_chunk[0];
|
||||
buf_chunk[1] = state_chunk[1];
|
||||
buf_chunk[2] = state_chunk[2];
|
||||
}
|
||||
|
||||
for (buf_chunk, state_chunk) in buf_b.data[1..34]
|
||||
.chunks_mut(3)
|
||||
.zip(lights.ground.chunks(3).take(11).rev())
|
||||
{
|
||||
buf_chunk[0] = state_chunk[0];
|
||||
buf_chunk[1] = state_chunk[1];
|
||||
buf_chunk[2] = state_chunk[2];
|
||||
}
|
||||
|
||||
buf_b.data[34..37].copy_from_slice(&lights.air_left[3..6]);
|
||||
buf_b.data[37..40].copy_from_slice(&lights.air_right[3..6]);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
},
|
||||
),
|
||||
HardwareSpec::HoriPad => Self::new(
|
||||
state.clone(),
|
||||
0x0f0d,
|
||||
0x0092,
|
||||
*disable_air,
|
||||
0x84,
|
||||
|buf, input| {
|
||||
if buf.len != 9 {
|
||||
return;
|
||||
}
|
||||
|
||||
for (buf_chunk, state_chunk) in buf_two.data[1..34]
|
||||
.chunks_mut(3)
|
||||
.zip(lights.ground.chunks(3).take(11).rev())
|
||||
{
|
||||
buf_chunk[0] = state_chunk[0];
|
||||
buf_chunk[1] = state_chunk[1];
|
||||
buf_chunk[2] = state_chunk[2];
|
||||
let bits: Vec<u8> = buf.data[1..8]
|
||||
.iter()
|
||||
.flat_map(|x| (0..8).map(move |i| ((x ^ 128) >> i) & 1))
|
||||
.collect();
|
||||
for i in 0..32 {
|
||||
input.ground[i] = bits[7 * 8 - 1 - i] * 255;
|
||||
}
|
||||
input.air.copy_from_slice(&bits[0..6]);
|
||||
|
||||
buf_two.data[34..37].copy_from_slice(&lights.air_left[3..6]);
|
||||
buf_two.data[37..40].copy_from_slice(&lights.air_right[3..6]);
|
||||
input.extra[0] = 0;
|
||||
input.extra[1] = 0;
|
||||
input.extra[2] = 0;
|
||||
},
|
||||
vec![
|
||||
LedSpec::new(WriteType::Interrupt, 0x04),
|
||||
LedSpec::new(WriteType::Interrupt, 0x05),
|
||||
LedSpec::new(WriteType::Interrupt, 0x06),
|
||||
LedSpec::new(WriteType::Interrupt, 0x0b),
|
||||
],
|
||||
|led_specs, lights| {
|
||||
if let [led_spec_ga, led_spec_gb, led_spec_air, led_spec_comp] = led_specs.as_mut_slice()
|
||||
{
|
||||
let buf_ga = &mut led_spec_ga.led_buf;
|
||||
let buf_gb = &mut led_spec_gb.led_buf;
|
||||
let buf_air = &mut led_spec_air.led_buf;
|
||||
let buf_comp = &mut led_spec_comp.led_buf;
|
||||
|
||||
let light_rgb_buf: Vec<u8> = lights
|
||||
.ground
|
||||
.iter()
|
||||
.chain(lights.air_left.iter())
|
||||
.chain(lights.air_right.iter())
|
||||
.map(|x| *x)
|
||||
.collect();
|
||||
let light_brg_buf: Vec<u8> = light_rgb_buf
|
||||
.chunks(3)
|
||||
.map(|x| [x[2], x[0], x[1]])
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
let mut light_brg_buf_compress: Vec<u8> = vec![];
|
||||
light_brg_buf_compress.reserve(512);
|
||||
compress(&light_brg_buf, &mut light_brg_buf_compress);
|
||||
// info!("raw {:?}", light_brg_buf);
|
||||
// info!("compress {:?}", light_brg_buf_compress);
|
||||
|
||||
if light_brg_buf_compress.len() < 63 {
|
||||
buf_comp.data[0..light_brg_buf_compress.len()]
|
||||
.copy_from_slice(light_brg_buf_compress.as_slice());
|
||||
} else {
|
||||
buf_ga.data[0..48].copy_from_slice(&light_brg_buf[0..48]);
|
||||
buf_gb.data[0..45].copy_from_slice(&light_brg_buf[48..(48 + 45)]);
|
||||
buf_air.data[0..18].copy_from_slice(&light_brg_buf[(48 + 45)..(48 + 45 + 18)]);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
}
|
||||
|
@ -379,50 +474,30 @@ impl ThreadJob for HidJob {
|
|||
{
|
||||
let mut lights_handle = self.state.lights.lock();
|
||||
if lights_handle.dirty {
|
||||
(self.led_callback)(
|
||||
&mut self.led_buf,
|
||||
&mut self.led_buf_two,
|
||||
lights_handle.deref(),
|
||||
);
|
||||
(self.led_callback)(&mut self.led_specs, lights_handle.deref());
|
||||
lights_handle.dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if self.led_buf.len != 0 {
|
||||
let res = (match self.led_write_type {
|
||||
WriteType::Bulk => handle.write_bulk(self.led_endpoint, self.led_buf.slice(), TIMEOUT),
|
||||
WriteType::Interrupt => {
|
||||
handle.write_interrupt(self.led_endpoint, &self.led_buf.slice(), TIMEOUT)
|
||||
for led_spec in self.led_specs.iter_mut() {
|
||||
if led_spec.led_buf.len != 0 {
|
||||
let res = (match led_spec.led_write_type {
|
||||
WriteType::Bulk => {
|
||||
handle.write_bulk(led_spec.led_endpoint, &led_spec.led_buf.slice(), TIMEOUT)
|
||||
}
|
||||
WriteType::Interrupt => {
|
||||
handle.write_interrupt(led_spec.led_endpoint, &led_spec.led_buf.slice(), TIMEOUT)
|
||||
}
|
||||
})
|
||||
.map_err(|e| {
|
||||
// debug!("Device write error {}", e);
|
||||
e
|
||||
})
|
||||
.unwrap_or(0);
|
||||
if res == led_spec.led_buf.len + 1 {
|
||||
work = true;
|
||||
led_spec.led_buf.len = 0;
|
||||
}
|
||||
})
|
||||
.map_err(|e| {
|
||||
// debug!("Device write error {}", e);
|
||||
e
|
||||
})
|
||||
.unwrap_or(0);
|
||||
if res == self.led_buf.len + 1 {
|
||||
// work = true;
|
||||
self.led_buf.len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if self.led_buf_two.len != 0 {
|
||||
let res = (match self.led_write_type {
|
||||
WriteType::Bulk => {
|
||||
handle.write_bulk(self.led_endpoint, self.led_buf_two.slice(), TIMEOUT)
|
||||
}
|
||||
WriteType::Interrupt => {
|
||||
handle.write_interrupt(self.led_endpoint, &self.led_buf_two.slice(), TIMEOUT)
|
||||
}
|
||||
})
|
||||
.map_err(|e| {
|
||||
// debug!("Device write error {}", e);
|
||||
e
|
||||
})
|
||||
.unwrap_or(0);
|
||||
if res == self.led_buf_two.len + 1 {
|
||||
// work = true;
|
||||
self.led_buf_two.len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1750,6 +1750,14 @@ dependencies = [
|
|||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzfx"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mac"
|
||||
version = "0.1.1"
|
||||
|
@ -2977,6 +2985,7 @@ dependencies = [
|
|||
"interception",
|
||||
"ipconfig",
|
||||
"log",
|
||||
"lzfx",
|
||||
"palette",
|
||||
"parking_lot 0.12.1",
|
||||
"phf 0.10.1",
|
||||
|
|
|
@ -198,6 +198,7 @@
|
|||
<option value="yuancon">Yuancon Laverita, HID Firmware</option>
|
||||
<option value="yubideck">大四 / Yubideck, HID Firmware 1.0</option>
|
||||
<option value="yubideck-three">大四 / Yubideck, HID Firmware 3.0</option>
|
||||
<option value="hori">HORI Pad (Redboard / Chu Pico)</option>
|
||||
<option value="diva">Slider over Serial</option>
|
||||
<option value="brokenithm">Brokenithm</option>
|
||||
<option value="brokenithm-led">Brokenithm + Led</option>
|
||||
|
|
Loading…
Reference in New Issue