Tabs not spaces u nerds. (#18)

This commit is contained in:
kixelated 2023-05-23 12:04:27 -07:00 committed by GitHub
parent dfe5cc1771
commit f4c8c6cf89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 2027 additions and 2094 deletions

10
.editorconfig Normal file
View File

@ -0,0 +1,10 @@
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = tab
indent_size = 4
max_line_length = 120

View File

@ -26,8 +26,8 @@ jobs:
- name: test - name: test
run: cargo test --verbose run: cargo test --verbose
- name: fmt
run: cargo fmt --check
- name: clippy - name: clippy
run: cargo clippy run: cargo clippy
- name: fmt
run: cargo fmt --check

View File

@ -25,8 +25,5 @@ jobs:
- name: build - name: build
run: yarn build run: yarn build
- name: fmt
run: yarn prettier --check .
- name: lint - name: lint
run: yarn lint run: yarn lint

4
server/.rustfmt.toml Normal file
View File

@ -0,0 +1,4 @@
# i die on this hill
hard_tabs = true
max_width = 120

View File

@ -1,3 +0,0 @@
{
"rust-analyzer.showUnlinkedFileNotification": false
}

View File

@ -163,11 +163,7 @@ pub fn read_atom<R: Read>(reader: &mut R) -> anyhow::Result<Vec<u8>> {
1 => { 1 => {
reader.read_exact(&mut buf)?; reader.read_exact(&mut buf)?;
let size_large = u64::from_be_bytes(buf); let size_large = u64::from_be_bytes(buf);
anyhow::ensure!( anyhow::ensure!(size_large >= 16, "impossible extended box size: {}", size_large);
size_large >= 16,
"impossible extended box size: {}",
size_large
);
reader.take(size_large - 16) reader.take(size_large - 16)
} }

View File

@ -17,11 +17,7 @@ pub struct Session {
impl transport::App for Session { impl transport::App for Session {
// Process any updates to a session. // Process any updates to a session.
fn poll( fn poll(&mut self, conn: &mut quiche::Connection, session: &mut webtransport::ServerSession) -> anyhow::Result<()> {
&mut self,
conn: &mut quiche::Connection,
session: &mut webtransport::ServerSession,
) -> anyhow::Result<()> {
loop { loop {
let event = match session.poll(conn) { let event = match session.poll(conn) {
Err(webtransport::Error::Done) => break, Err(webtransport::Error::Done) => break,

View File

@ -3,10 +3,6 @@ use std::time;
use quiche::h3::webtransport; use quiche::h3::webtransport;
pub trait App: Default { pub trait App: Default {
fn poll( fn poll(&mut self, conn: &mut quiche::Connection, session: &mut webtransport::ServerSession) -> anyhow::Result<()>;
&mut self,
conn: &mut quiche::Connection,
session: &mut webtransport::ServerSession,
) -> anyhow::Result<()>;
fn timeout(&self) -> Option<time::Duration>; fn timeout(&self) -> Option<time::Duration>;
} }

View File

@ -48,8 +48,7 @@ impl<T: app::App> Server<T> {
let mut quic = quiche::Config::new(quiche::PROTOCOL_VERSION).unwrap(); let mut quic = quiche::Config::new(quiche::PROTOCOL_VERSION).unwrap();
quic.load_cert_chain_from_pem_file(&config.cert).unwrap(); quic.load_cert_chain_from_pem_file(&config.cert).unwrap();
quic.load_priv_key_from_pem_file(&config.key).unwrap(); quic.load_priv_key_from_pem_file(&config.key).unwrap();
quic.set_application_protos(quiche::h3::APPLICATION_PROTOCOL) quic.set_application_protos(quiche::h3::APPLICATION_PROTOCOL).unwrap();
.unwrap();
quic.set_max_idle_timeout(5000); quic.set_max_idle_timeout(5000);
quic.set_max_recv_udp_payload_size(MAX_DATAGRAM_SIZE); quic.set_max_recv_udp_payload_size(MAX_DATAGRAM_SIZE);
quic.set_max_send_udp_payload_size(MAX_DATAGRAM_SIZE); quic.set_max_send_udp_payload_size(MAX_DATAGRAM_SIZE);
@ -154,9 +153,7 @@ impl<T: app::App> Server<T> {
conn.quiche.recv(src, info)?; conn.quiche.recv(src, info)?;
if conn.session.is_none() && conn.quiche.is_established() { if conn.session.is_none() && conn.quiche.is_established() {
conn.session = Some(webtransport::ServerSession::with_transport( conn.session = Some(webtransport::ServerSession::with_transport(&mut conn.quiche)?)
&mut conn.quiche,
)?)
} }
continue; continue;
@ -165,9 +162,7 @@ impl<T: app::App> Server<T> {
// TODO is this needed here? // TODO is this needed here?
if conn.session.is_none() && conn.quiche.is_established() { if conn.session.is_none() && conn.quiche.is_established() {
conn.session = Some(webtransport::ServerSession::with_transport( conn.session = Some(webtransport::ServerSession::with_transport(&mut conn.quiche)?)
&mut conn.quiche,
)?)
} }
continue; continue;
@ -200,15 +195,7 @@ impl<T: app::App> Server<T> {
if token.is_empty() { if token.is_empty() {
let new_token = mint_token(&hdr, &from); let new_token = mint_token(&hdr, &from);
let len = quiche::retry( let len = quiche::retry(&hdr.scid, &hdr.dcid, &scid, &new_token, hdr.version, &mut dst).unwrap();
&hdr.scid,
&hdr.dcid,
&scid,
&new_token,
hdr.version,
&mut dst,
)
.unwrap();
let dst = &dst[..len]; let dst = &dst[..len];
@ -237,8 +224,7 @@ impl<T: app::App> Server<T> {
log::debug!("new connection: dcid={:?} scid={:?}", hdr.dcid, scid); log::debug!("new connection: dcid={:?} scid={:?}", hdr.dcid, scid);
let mut conn = let mut conn = quiche::accept(&conn_id, odcid.as_ref(), local_addr, from, &mut self.quic)?;
quiche::accept(&conn_id, odcid.as_ref(), local_addr, from, &mut self.quic)?;
// Log each session with QLOG if the ENV var is set. // Log each session with QLOG if the ENV var is set.
if let Some(dir) = std::env::var_os("QLOGDIR") { if let Some(dir) = std::env::var_os("QLOGDIR") {
@ -251,10 +237,7 @@ impl<T: app::App> Server<T> {
let writer = match std::fs::File::create(&path) { let writer = match std::fs::File::create(&path) {
Ok(f) => std::io::BufWriter::new(f), Ok(f) => std::io::BufWriter::new(f),
Err(e) => panic!( Err(e) => panic!("Error creating qlog file attempted path was {:?}: {}", path, e),
"Error creating qlog file attempted path was {:?}: {}",
path, e
),
}; };
conn.set_qlog( conn.set_qlog(
@ -371,10 +354,7 @@ fn mint_token(hdr: &quiche::Header, src: &std::net::SocketAddr) -> Vec<u8> {
/// ///
/// Note that this function is only an example and doesn't do any cryptographic /// Note that this function is only an example and doesn't do any cryptographic
/// authenticate of the token. *It should not be used in production system*. /// authenticate of the token. *It should not be used in production system*.
fn validate_token<'a>( fn validate_token<'a>(src: &std::net::SocketAddr, token: &'a [u8]) -> Option<quiche::ConnectionId<'a>> {
src: &std::net::SocketAddr,
token: &'a [u8],
) -> Option<quiche::ConnectionId<'a>> {
if token.len() < 6 { if token.len() < 6 {
return None; return None;
} }

View File

@ -18,23 +18,13 @@ struct Stream {
impl Streams { impl Streams {
// Write the data to the given stream, buffering it if needed. // Write the data to the given stream, buffering it if needed.
pub fn send( pub fn send(&mut self, conn: &mut quiche::Connection, id: u64, buf: &[u8], fin: bool) -> anyhow::Result<()> {
&mut self,
conn: &mut quiche::Connection,
id: u64,
buf: &[u8],
fin: bool,
) -> anyhow::Result<()> {
if buf.is_empty() && !fin { if buf.is_empty() && !fin {
return Ok(()); return Ok(());
} }
// Get the index of the stream, or add it to the list of streams. // Get the index of the stream, or add it to the list of streams.
let pos = self let pos = self.ordered.iter().position(|s| s.id == id).unwrap_or_else(|| {
.ordered
.iter()
.position(|s| s.id == id)
.unwrap_or_else(|| {
// Create a new stream // Create a new stream
let stream = Stream { let stream = Stream {
id, id,
@ -101,10 +91,7 @@ impl Streams {
fn insert(&mut self, conn: &mut quiche::Connection, stream: Stream) -> usize { fn insert(&mut self, conn: &mut quiche::Connection, stream: Stream) -> usize {
// Look for the position to insert the stream. // Look for the position to insert the stream.
let pos = match self let pos = match self.ordered.binary_search_by_key(&stream.order, |s| s.order) {
.ordered
.binary_search_by_key(&stream.order, |s| s.order)
{
Ok(pos) | Err(pos) => pos, Ok(pos) | Err(pos) => pos,
}; };

View File

@ -1,12 +1,8 @@
/* eslint-env node */ /* eslint-env node */
module.exports = { module.exports = {
extends: [ extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier",
],
parser: "@typescript-eslint/parser", parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint"], plugins: ["@typescript-eslint", "prettier"],
root: true, root: true,
ignorePatterns: ["dist", "node_modules"], ignorePatterns: ["dist", "node_modules"],
rules: { rules: {
@ -22,5 +18,6 @@ module.exports = {
caughtErrorsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_",
}, },
], ],
"prettier/prettier": 2, // Means error
}, },
} }

View File

@ -1,3 +0,0 @@
{
"semi": false
}

4
web/.prettierrc.yaml Normal file
View File

@ -0,0 +1,4 @@
# note: root .editorconfig is used
# Don't insert semi-colons unless needed
semi: false

View File

@ -17,6 +17,7 @@
"@typescript-eslint/parser": "^5.59.7", "@typescript-eslint/parser": "^5.59.7",
"eslint": "^8.41.0", "eslint": "^8.41.0",
"eslint-config-prettier": "^8.8.0", "eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"parcel": "^2.8.0", "parcel": "^2.8.0",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"typescript": "^5.0.4" "typescript": "^5.0.4"

View File

@ -69,11 +69,7 @@ declare module "mp4box" {
stop(): void stop(): void
flush(): void flush(): void
setExtractionOptions( setExtractionOptions(id: number, user: any, options: ExtractionOptions): void
id: number,
user: any,
options: ExtractionOptions
): void
} }
export function createFile(): MP4File export function createFile(): MP4File
@ -108,11 +104,7 @@ declare module "mp4box" {
const LITTLE_ENDIAN: boolean const LITTLE_ENDIAN: boolean
export class DataStream { export class DataStream {
constructor( constructor(buffer?: ArrayBuffer, byteOffset?: number, littleEndian?: boolean)
buffer?: ArrayBuffer,
byteOffset?: number,
littleEndian?: boolean
)
getPosition(): number getPosition(): number
get byteLength(): number get byteLength(): number

View File

@ -20,10 +20,7 @@ export default class Audio {
} }
// Insert the frame into the queue sorted by timestamp. // Insert the frame into the queue sorted by timestamp.
if ( if (this.queue.length > 0 && this.queue[this.queue.length - 1].timestamp <= frame.timestamp) {
this.queue.length > 0 &&
this.queue[this.queue.length - 1].timestamp <= frame.timestamp
) {
// Fast path because we normally append to the end. // Fast path because we normally append to the end.
this.queue.push(frame) this.queue.push(frame)
} else { } else {

View File

@ -57,11 +57,7 @@ export default class Decoder {
const raw = await stream.peek(4) const raw = await stream.peek(4)
// TODO this doesn't support when size = 0 (until EOF) or size = 1 (extended size) // TODO this doesn't support when size = 0 (until EOF) or size = 1 (extended size)
const size = new DataView( const size = new DataView(raw.buffer, raw.byteOffset, raw.byteLength).getUint32(0)
raw.buffer,
raw.byteOffset,
raw.byteLength
).getUint32(0)
const atom = await stream.bytes(size) const atom = await stream.bytes(size)
// Make a copy of the atom because mp4box only accepts an ArrayBuffer unfortunately // Make a copy of the atom because mp4box only accepts an ArrayBuffer unfortunately
@ -158,15 +154,11 @@ export default class Decoder {
} }
} }
function isAudioDecoder( function isAudioDecoder(decoder: AudioDecoder | VideoDecoder): decoder is AudioDecoder {
decoder: AudioDecoder | VideoDecoder
): decoder is AudioDecoder {
return decoder instanceof AudioDecoder return decoder instanceof AudioDecoder
} }
function isVideoDecoder( function isVideoDecoder(decoder: AudioDecoder | VideoDecoder): decoder is VideoDecoder {
decoder: AudioDecoder | VideoDecoder
): decoder is VideoDecoder {
return decoder instanceof VideoDecoder return decoder instanceof VideoDecoder
} }

View File

@ -71,10 +71,7 @@ export default class Player {
} }
onSegment(segment: Message.Segment) { onSegment(segment: Message.Segment) {
this.worker.postMessage({ segment }, [ this.worker.postMessage({ segment }, [segment.buffer.buffer, segment.reader])
segment.buffer.buffer,
segment.reader,
])
} }
async play() { async play() {

View File

@ -15,16 +15,12 @@ export class Buffer {
constructor(channels: number, capacity: number) { constructor(channels: number, capacity: number) {
// Store the current state in a separate ring buffer. // Store the current state in a separate ring buffer.
this.state = new SharedArrayBuffer( this.state = new SharedArrayBuffer(STATE.LENGTH * Int32Array.BYTES_PER_ELEMENT)
STATE.LENGTH * Int32Array.BYTES_PER_ELEMENT
)
// Create a buffer for each audio channel // Create a buffer for each audio channel
this.channels = [] this.channels = []
for (let i = 0; i < channels; i += 1) { for (let i = 0; i < channels; i += 1) {
const buffer = new SharedArrayBuffer( const buffer = new SharedArrayBuffer(capacity * Float32Array.BYTES_PER_ELEMENT)
capacity * Float32Array.BYTES_PER_ELEMENT
)
this.channels.push(buffer) this.channels.push(buffer)
} }

View File

@ -23,10 +23,7 @@ export default class Video {
} }
// Insert the frame into the queue sorted by timestamp. // Insert the frame into the queue sorted by timestamp.
if ( if (this.queue.length > 0 && this.queue[this.queue.length - 1].timestamp <= frame.timestamp) {
this.queue.length > 0 &&
this.queue[this.queue.length - 1].timestamp <= frame.timestamp
) {
// Fast path because we normally append to the end. // Fast path because we normally append to the end.
this.queue.push(frame) this.queue.push(frame)
} else { } else {

View File

@ -29,11 +29,7 @@ class Renderer extends AudioWorkletProcessor {
} }
// Inputs and outputs in groups of 128 samples. // Inputs and outputs in groups of 128 samples.
process( process(inputs: Float32Array[][], outputs: Float32Array[][], _parameters: Record<string, Float32Array>): boolean {
inputs: Float32Array[][],
outputs: Float32Array[][],
_parameters: Record<string, Float32Array>
): boolean {
if (!this.ring) { if (!this.ring) {
// Paused // Paused
return true return true

View File

@ -74,15 +74,8 @@ export default class Reader {
} }
} }
const result = new Uint8Array( const result = new Uint8Array(this.buffer.buffer, this.buffer.byteOffset, size)
this.buffer.buffer, this.buffer = new Uint8Array(this.buffer.buffer, this.buffer.byteOffset + size)
this.buffer.byteOffset,
size
)
this.buffer = new Uint8Array(
this.buffer.buffer,
this.buffer.byteOffset + size
)
r.releaseLock() r.releaseLock()
@ -110,11 +103,7 @@ export default class Reader {
} }
} }
const result = new Uint8Array( const result = new Uint8Array(this.buffer.buffer, this.buffer.byteOffset, size)
this.buffer.buffer,
this.buffer.byteOffset,
size
)
r.releaseLock() r.releaseLock()
@ -170,11 +159,7 @@ export default class Reader {
// NOTE: Returns a BigInt instead of a Number // NOTE: Returns a BigInt instead of a Number
async vint64(): Promise<bigint> { async vint64(): Promise<bigint> {
const peek = await this.peek(1) const peek = await this.peek(1)
const first = new DataView( const first = new DataView(peek.buffer, peek.byteOffset, peek.byteLength).getUint8(0)
peek.buffer,
peek.byteOffset,
peek.byteLength
).getUint8(0)
const size = (first & 0xc0) >> 6 const size = (first & 0xc0) >> 6
switch (size) { switch (size) {

View File

@ -1265,6 +1265,13 @@ eslint-config-prettier@^8.8.0:
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348"
integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==
eslint-plugin-prettier@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b"
integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==
dependencies:
prettier-linter-helpers "^1.0.0"
eslint-scope@^5.1.1: eslint-scope@^5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz"
@ -1374,6 +1381,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-diff@^1.1.2:
version "1.3.0"
resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0"
integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
fast-glob@^3.2.9: fast-glob@^3.2.9:
version "3.2.12" version "3.2.12"
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz"
@ -1989,6 +2001,13 @@ prelude-ls@^1.2.1:
resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
prettier-linter-helpers@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
dependencies:
fast-diff "^1.1.2"
prettier@^2.8.8: prettier@^2.8.8:
version "2.8.8" version "2.8.8"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"