Repository: pdeljanov/Symphonia (language: rust)

Issue:
[Task] Test on a big-endian virtual machine
Symphonia should work properly on both big and little-endian devices. x86/x86_64 and ARM devices are all little-endian, but Power (and MIPS?) architecture devices can run in big-endian mode.

Therefore, let's explore using a virtual machine (QEMU?) to test if Symphonia works on big-endian devices and fix any issues found. If at all feasible, could this also be integrated into CI?


Discussion / hints:
[cross](https://github.com/rust-embedded/cross) sounds like it might work here. They support MIPS for compilation and test running.

Fix patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2ea64404..ee44d7bd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -39,12 +39,16 @@ jobs:
         args: --all --all-features --exclude symphonia-play
 
   test:
-    name: Test ${{ matrix.os }}
+    name: Test ${{ matrix.config.target }} on ${{ matrix.config.os }}
 
-    runs-on: ${{ matrix.os }}
+    runs-on: ${{ matrix.config.os }}
     strategy:
       matrix:
-        os: [ubuntu-latest, macos-latest, "windows-latest"]
+        config:
+          - { os: ubuntu-latest, target: x86_64-unknown-linux-gnu, use-cross: false }
+          - { os: macos-latest, target: x86_64-apple-darwin, use-cross: false }
+          - { os: windows-latest, target: x86_64-pc-windows-msvc, use-cross: false }
+          - { os: ubuntu-latest, target: powerpc-unknown-linux-gnu, use-cross: true }
 
     steps:
       - name: Checkout
@@ -60,19 +64,22 @@ jobs:
         uses: actions-rs/cargo@v1
         with:
           command: test
-          args: --all --exclude symphonia-play
+          args: --target ${{ matrix.config.target }} --all --exclude symphonia-play
+          use-cross: ${{ matrix.config.use-cross }}
 
       - name: Test all features
         uses: actions-rs/cargo@v1
         with:
           command: test
-          args: --all --all-features --exclude symphonia-play
+          args: --target ${{ matrix.config.target }} --all --all-features --exclude symphonia-play
+          use-cross: ${{ matrix.config.use-cross }}
 
       - name: Test documentation
         uses: actions-rs/cargo@v1
         with:
           command: test
-          args: --all --all-features --doc --exclude symphonia-play
+          args: --target ${{ matrix.config.target }} --all --all-features --doc --exclude symphonia-play
+          use-cross: ${{ matrix.config.use-cross }}
 
 
 # Uncomment to check formatting
diff --git a/symphonia-core/src/io/media_source_stream.rs b/symphonia-core/src/io/media_source_stream.rs
index b16b9a64..92975306 100644
--- a/symphonia-core/src/io/media_source_stream.rs
+++ b/symphonia-core/src/io/media_source_stream.rs
@@ -469,7 +469,7 @@ mod tests {
 
         for quad in bytes.chunks_mut(4) {
             lcg = lcg.wrapping_mul(1664525).wrapping_add(1013904223);
-            for (src, dest) in quad.iter_mut().zip(&lcg.to_ne_bytes()) {
+            for (src, dest) in quad.iter_mut().zip(&lcg.to_le_bytes()) {
                 *src = *dest;
             }
         }
@@ -537,7 +537,7 @@ mod tests {
     fn verify_mss_seek_buffered() {
         let data = generate_random_bytes(1024 * 1024);
 
-        let ms = Cursor::new(data.clone());
+        let ms = Cursor::new(data);
         let mut mss = MediaSourceStream::new(Box::new(ms), Default::default());
 
         assert_eq!(mss.read_buffer_len(), 0);
@@ -562,4 +562,41 @@ mod tests {
 
         assert_eq!(upper, mss.read_byte().unwrap());
     }
+
+    #[test]
+    fn verify_reading_be() {
+        let data = generate_random_bytes(1024 * 1024);
+
+        let ms = Cursor::new(data);
+        let mut mss = MediaSourceStream::new(Box::new(ms), Default::default());
+
+        // For slightly cleaner floats
+        mss.ignore_bytes(2).unwrap();
+
+        assert_eq!(mss.read_be_f32().unwrap(), -72818055000000000000000000000.0);
+        assert_eq!(mss.read_be_f64().unwrap(), -0.000000000000011582640453292664);
+
+        assert_eq!(mss.read_be_u16().unwrap(), 32624);
+        assert_eq!(mss.read_be_u24().unwrap(), 6739677);
+        assert_eq!(mss.read_be_u32().unwrap(), 1569552917);
+        assert_eq!(mss.read_be_u64().unwrap(), 6091217585348000864);
+    }
+
+    #[test]
+    fn verify_reading_le() {
+        let data = generate_random_bytes(1024 * 1024);
+
+        let ms = Cursor::new(data);
+        let mut mss = MediaSourceStream::new(Box::new(ms), Default::default());
+
+        mss.ignore_bytes(1024).unwrap();
+
+        assert_eq!(mss.read_f32().unwrap(), -0.00000000000000000000000000048426285);
+        assert_eq!(mss.read_f64().unwrap(), -6444325820119113.0);
+
+        assert_eq!(mss.read_u16().unwrap(), 36195);
+        assert_eq!(mss.read_u24().unwrap(), 6710386);
+        assert_eq!(mss.read_u32().unwrap(), 2378776723);
+        assert_eq!(mss.read_u64().unwrap(), 5170196279331153683);
+    }
 }
diff --git a/symphonia-core/src/io/mod.rs b/symphonia-core/src/io/mod.rs
index f9f86fb7..c3c01914 100644
--- a/symphonia-core/src/io/mod.rs
+++ b/symphonia-core/src/io/mod.rs
@@ -232,21 +232,21 @@ pub trait ReadBytes {
         Ok(u64::from_be_bytes(buf))
     }
 
-    /// Reads four bytes from the stream and interprets them as a 32-bit little-endiann IEEE-754
+    /// Reads four bytes from the stream and interprets them as a 32-bit little-endian IEEE-754
     /// floating-point value.
     #[inline(always)]
     fn read_f32(&mut self) -> io::Result<f32> {
         Ok(f32::from_le_bytes(self.read_quad_bytes()?))
     }
 
-    /// Reads four bytes from the stream and interprets them as a 32-bit big-endiann IEEE-754
+    /// Reads four bytes from the stream and interprets them as a 32-bit big-endian IEEE-754
     /// floating-point value.
     #[inline(always)]
     fn read_be_f32(&mut self) -> io::Result<f32> {
         Ok(f32::from_be_bytes(self.read_quad_bytes()?))
     }
 
-    /// Reads four bytes from the stream and interprets them as a 64-bit little-endiann IEEE-754
+    /// Reads four bytes from the stream and interprets them as a 64-bit little-endian IEEE-754
     /// floating-point value.
     #[inline(always)]
     fn read_f64(&mut self) -> io::Result<f64> {
@@ -255,7 +255,7 @@ pub trait ReadBytes {
         Ok(f64::from_le_bytes(buf))
     }
 
-    /// Reads four bytes from the stream and interprets them as a 64-bit big-endiann IEEE-754
+    /// Reads four bytes from the stream and interprets them as a 64-bit big-endian IEEE-754
     /// floating-point value.
     #[inline(always)]
     fn read_be_f64(&mut self) -> io::Result<f64> {


Test patch: