Exemple #1
0
        public static void ServerWriteNegativeOffsetThrows()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
            {
                Assert.Throws <ArgumentOutOfRangeException>(() => server.Write(new byte[5], -1, 1));

                // array is checked first
                Assert.Throws <ArgumentNullException>(() => server.Write(null, -1, 1));
            }
        }
Exemple #2
0
        /// <summary>
        /// Send an object to the specified anonymous out pipe.
        /// </summary>
        /// <param name="pipeWriter">The pipe to write to.</param>
        /// <param name="obj">The object to send.</param>
        public static void SendObjectToPipe(AnonymousPipeServerStream pipeWriter, object obj)
        {
            var objStream = ReflectionUtilities.BinarySerialise(obj) as MemoryStream;

            // Write the number of bytes
            var numBytes  = Convert.ToInt32(objStream.Length);
            var intBuffer = BitConverter.GetBytes(numBytes);

            pipeWriter.Write(intBuffer, 0, 4);

            // Write the objStream.
            pipeWriter.Write(objStream.ToArray(), 0, numBytes);
        }
Exemple #3
0
    public void ForNonSeekable(string input, params string[] lines)
    {
        using (var s = new AnonymousPipeServerStream())
            using (var c = new AnonymousPipeClientStream(s.GetClientHandleAsString()))
            {
                var bytes = Encoding.ASCII.GetBytes(input);
                s.Write(bytes, 0, bytes.Length);
                s.Close();

                var skipLF = false;
                foreach (var line in lines)
                {
                    Assert.Equal(line, c.ReadProtocolLineWithEnd(skipLF));
                    skipLF = (line.Last() == '\r');
                }
            }

        using (var s = new AnonymousPipeServerStream())
            using (var c = new AnonymousPipeClientStream(s.GetClientHandleAsString()))
            {
                var bytes = Encoding.ASCII.GetBytes(input);
                s.Write(bytes, 0, bytes.Length);
                s.Close();

                var skipLF = false;
                foreach (var line in lines)
                {
                    Assert.Equal(line.TrimEnd(LineEnds), c.ReadProtocolLine(skipLF));
                    skipLF = (line.Last() == '\r');
                }
            }
    }
Exemple #4
0
        private void Encoder_Data_Available(object sender, VideoEventArgs e)
        {
            frame++;

            framebytes = e.payload.outbytes;

            lastframe       = e.payload.uncompressedFrame;
            lastframestride = e.payload.stride;
            lastframeheight = e.payload.height;
            lastframewidth  = e.payload.width;


            if (isConnected)
            {
                VideoStream.Write(e.payload.result, 0, e.payload.outbytes);
                VideoStream.Flush();
                VideoStream.WaitForPipeDrain();

                video.ReturnWork(e.payload);
            }
            if (enableWriteToFile && binaryVideoWriter != null)
            {
                binaryVideoWriter.Write(e.payload.result, 0, e.payload.outbytes);
                binaryVideoWriter.Flush();
            }
        }
        public void ServerClosesPipe_ClientReceivesEof()
        {
            using (var pipe = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable))
                using (var remote = RemoteExecutor.Invoke(new Action <string>(ChildFunc), pipe.GetClientHandleAsString()))
                {
                    pipe.DisposeLocalCopyOfClientHandle();
                    pipe.Write(new byte[] { 1, 2, 3, 4, 5 }, 0, 5);

                    pipe.Dispose();

                    Assert.True(remote.Process.WaitForExit(30_000));
                }

            void ChildFunc(string clientHandle)
            {
                using (var pipe = new AnonymousPipeClientStream(PipeDirection.In, clientHandle))
                {
                    for (int i = 1; i <= 5; i++)
                    {
                        Assert.Equal(i, pipe.ReadByte());
                    }
                    Assert.Equal(-1, pipe.ReadByte());
                }
            }
        }
Exemple #6
0
 public static void ServerWriteBufferNullThrows()
 {
     // force different constructor path
     using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None))
     {
         Assert.Throws <ArgumentNullException>(() => server.Write(null, 0, 1));
     }
 }
Exemple #7
0
        public void Write(byte[] buffer, int offset, int count)
        {
            if (!m_Started)
            {
                return;
            }

            m_Server.Write(buffer, offset, count);
        }
 public static void ServerWriteBufferNullThrows()
 {
     // force different constructor path
     using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None))
     {
         Assert.Throws<ArgumentNullException>(() => server.Write(null, 0, 1));
         Assert.Throws<ArgumentNullException>(() => NotReachable(server.WriteAsync(null, 0, 1)));
     }
 }
        public static void ServerWriteNegativeCountThrows()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
            {
                Assert.Throws <ArgumentOutOfRangeException>(() => server.Write(new byte[5], 0, -1));

                // offset is checked before count
                Assert.Throws <ArgumentOutOfRangeException>(() => server.Write(new byte[1], -1, -1));

                // array is checked first
                Assert.Throws <ArgumentNullException>(() => server.Write(null, -1, -1));

                Assert.Throws <ArgumentOutOfRangeException>(() => NotReachable(server.WriteAsync(new byte[5], 0, -1)));

                // offset is checked before count
                Assert.Throws <ArgumentOutOfRangeException>(() => NotReachable(server.WriteAsync(new byte[1], -1, -1)));

                // array is checked first
                Assert.Throws <ArgumentNullException>(() => NotReachable(server.WriteAsync(null, -1, -1)));
            }
        }
Exemple #10
0
        public static void ServerReadOnlyThrows()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.In))
            {
                Assert.Throws <NotSupportedException>(() => server.Write(new byte[5], 0, 5));

                Assert.Throws <NotSupportedException>(() => server.WriteByte(123));

                Assert.Throws <NotSupportedException>(() => server.Flush());

                Assert.Throws <NotSupportedException>(() => server.OutBufferSize);

                Assert.Throws <NotSupportedException>(() => server.WaitForPipeDrain());
            }
        }
Exemple #11
0
        public static void ClonedClient_ActsAsOriginalClient()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
                using (AnonymousPipeClientStream clientBase = new AnonymousPipeClientStream(PipeDirection.In, server.ClientSafePipeHandle))
                    using (AnonymousPipeClientStream client = new AnonymousPipeClientStream(PipeDirection.In, clientBase.SafePipeHandle))
                    {
                        Assert.True(server.IsConnected);
                        Assert.True(client.IsConnected);

                        byte[] sent     = new byte[] { 123 };
                        byte[] received = new byte[] { 0 };
                        server.Write(sent, 0, 1);

                        Assert.Equal(1, client.Read(received, 0, 1));
                        Assert.Equal(sent[0], received[0]);
                    }
        }
Exemple #12
0
        //Fonction permettant l'écriture vers la couche Réseau
        public void ecrire_vers_reseau(string str)
        {
            //Affichage de la primitive à envoyer
            Utility.AfficherDansConsole("Transport vers Reseau : " + str, Constantes.TRANSPORT_RESEAU_COLOR);
            str += Constantes.FIN_PRIMITIVE;

            try{
                pipe_sem.WaitOne();
                //Transformation de la chaîne de caractère en tableau de Bytes
                byte[] bytes = Encoding.UTF8.GetBytes(str);
                //Envoie du tableau dans le Pipe vers la couche Réseau
                transportOut.Write(bytes, 0, str.Length);
            }catch (IOException e) {
                //Affichage du message d'erreur, s'il y en a un
                Utility.AfficherDansConsole(e.Message, Constantes.ERREUR_COLOR);
            }finally{
                pipe_sem.Release();
            }
        }
Exemple #13
0
    public static void ServerSendsByteClientReceives()
    {
        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
        {
            Assert.True(server.IsConnected);
            using (AnonymousPipeClientStream client = new AnonymousPipeClientStream(PipeDirection.In, server.ClientSafePipeHandle))
            {
                Assert.True(server.IsConnected);
                Assert.True(client.IsConnected);

                byte[] sent     = new byte[] { 123 };
                byte[] received = new byte[] { 0 };
                server.Write(sent, 0, 1);

                Assert.Equal(1, client.Read(received, 0, 1));
                Assert.Equal(sent[0], received[0]);
            }
        }
    }
Exemple #14
0
    public static void ServerPInvokeChecks()
    {
        // calling every API related to server and client to detect any bad PInvokes
        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
        {
            Task clientTask = Task.Run(() => StartClient(PipeDirection.In, server.ClientSafePipeHandle));

            Assert.False(server.CanRead);
            Assert.False(server.CanSeek);
            Assert.False(server.CanTimeout);
            Assert.True(server.CanWrite);
            Assert.False(string.IsNullOrWhiteSpace(server.GetClientHandleAsString()));
            Assert.False(server.IsAsync);
            Assert.True(server.IsConnected);
            Assert.Equal(0, server.OutBufferSize);
            Assert.Equal(PipeTransmissionMode.Byte, server.ReadMode);
            Assert.NotNull(server.SafePipeHandle);
            Assert.Equal(PipeTransmissionMode.Byte, server.TransmissionMode);

            server.Write(new byte[] { 123 }, 0, 1);
            server.WriteAsync(new byte[] { 124 }, 0, 1).Wait();
            server.Flush();
            server.WaitForPipeDrain();

            clientTask.Wait();
            server.DisposeLocalCopyOfClientHandle();
        }

        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.In))
        {
            Task clientTask = Task.Run(() => StartClient(PipeDirection.Out, server.ClientSafePipeHandle));

            Assert.Equal(4096, server.InBufferSize);
            byte[] readData = new byte[] { 0, 1 };
            Assert.Equal(1, server.Read(readData, 0, 1));
            Assert.Equal(1, server.ReadAsync(readData, 1, 1).Result);
            Assert.Equal(123, readData[0]);
            Assert.Equal(124, readData[1]);

            clientTask.Wait();
        }
    }
    public static void ServerSendsByteClientReceives()
    {
        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
        {
            Assert.True(server.IsConnected);
            using (AnonymousPipeClientStream client = new AnonymousPipeClientStream(PipeDirection.In, server.GetClientHandleAsString()))
            {
                Assert.True(server.IsConnected);
                Assert.True(client.IsConnected);

                byte[] sent     = new byte[] { 123 };
                byte[] received = new byte[] { 0 };
                server.Write(sent, 0, 1);

                Assert.Equal(1, client.Read(received, 0, 1));
                Assert.Equal(sent[0], received[0]);
            }
            Assert.Throws <System.IO.IOException>(() => server.WriteByte(5));
        }
    }
        //Focntion permettant l'écriture d'une chaîne de caractère vers la couche transport
        public void ecrire_vers_transport(string str)
        {
            //Affichage de la chaîne à écrire
            Utility.AfficherDansConsole("Reseau vers Transport : " + str, Constantes.TRANSPORT_RESEAU_COLOR);
            str += Constantes.FIN_PRIMITIVE;

            try
            {
                pipe_sem.WaitOne();
                byte[] bytes = Encoding.UTF8.GetBytes(str);             //Transformartion de la chaîne en tableau de Bytes
                reseauOut.Write(bytes, 0, str.Length);                  //Écriture du tableau dans le pipe vers transport
            }
            catch (IOException e)
            {
                //Affichage du message d'erreur, s'il y a lieu
                Utility.AfficherDansConsole(e.Message, Constantes.ERREUR_COLOR);
            }finally{
                pipe_sem.Release();
            }
        }
        public static void ClonedClient_ActsAsOriginalClient()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
            {
                using (AnonymousPipeClientStream clientBase = new AnonymousPipeClientStream(PipeDirection.In, server.GetClientHandleAsString()))
                {
                    using (AnonymousPipeClientStream client = new AnonymousPipeClientStream(PipeDirection.In, clientBase.SafePipeHandle))
                    {
                        Assert.True(server.IsConnected);
                        Assert.True(client.IsConnected);

                        byte[] sent = new byte[] { 123 };
                        byte[] received = new byte[] { 0 };
                        server.Write(sent, 0, 1);

                        Assert.Equal(1, client.Read(received, 0, 1));
                        Assert.Equal(sent[0], received[0]);
                    }
                }
            }
        }
        public static void ServerWriteArrayOutOfBoundsThrows()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
            {
                // offset out of bounds
                Assert.Throws <ArgumentException>(null, () => server.Write(new byte[1], 1, 1));

                // offset out of bounds for 0 count read
                Assert.Throws <ArgumentException>(null, () => server.Write(new byte[1], 2, 0));

                // offset out of bounds even for 0 length buffer
                Assert.Throws <ArgumentException>(null, () => server.Write(new byte[0], 1, 0));

                // combination offset and count out of bounds
                Assert.Throws <ArgumentException>(null, () => server.Write(new byte[2], 1, 2));

                // edges
                Assert.Throws <ArgumentException>(null, () => server.Write(new byte[0], int.MaxValue, 0));
                Assert.Throws <ArgumentException>(null, () => server.Write(new byte[0], int.MaxValue, int.MaxValue));

                Assert.Throws <ArgumentException>(() => server.Write(new byte[5], 3, 4));

                // offset out of bounds
                Assert.Throws <ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[1], 1, 1)));

                // offset out of bounds for 0 count read
                Assert.Throws <ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[1], 2, 0)));

                // offset out of bounds even for 0 length buffer
                Assert.Throws <ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[0], 1, 0)));

                // combination offset and count out of bounds
                Assert.Throws <ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[2], 1, 2)));

                // edges
                Assert.Throws <ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[0], int.MaxValue, 0)));
                Assert.Throws <ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[0], int.MaxValue, int.MaxValue)));

                Assert.Throws <ArgumentException>(() => NotReachable(server.WriteAsync(new byte[5], 3, 4)));
            }
        }
Exemple #19
0
    public static void ServerPInvokeChecks()
    {
        // calling every API related to server and client to detect any bad PInvokes
        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
        {
            Task clientTask = StartClientAsync(PipeDirection.In, server.ClientSafePipeHandle);

            Console.WriteLine("server.CanRead = {0}", server.CanRead);
            Console.WriteLine("server.CanSeek = {0}", server.CanSeek);
            Console.WriteLine("server.CanTimeout = {0}", server.CanTimeout);
            Console.WriteLine("server.CanWrite = {0}", server.CanWrite);
            Console.WriteLine("server.GetClientHandleAsString() = {0}", server.GetClientHandleAsString());
            Console.WriteLine("server.IsAsync = {0}", server.IsAsync);
            Console.WriteLine("server.IsConnected = {0}", server.IsConnected);
            Console.WriteLine("server.OutBufferSize = {0}", server.OutBufferSize);
            Console.WriteLine("server.ReadMode = {0}", server.ReadMode);
            Console.WriteLine("server.SafePipeHandle = {0}", server.SafePipeHandle);
            Console.WriteLine("server.TransmissionMode = {0}", server.TransmissionMode);
            server.Write(new byte[] { 123 }, 0, 1);
            server.WriteAsync(new byte[] { 124 }, 0, 1).Wait();
            server.Flush();
            Console.WriteLine("Waiting for Pipe Drain.");
            server.WaitForPipeDrain();
            clientTask.Wait();
            server.DisposeLocalCopyOfClientHandle();
        }
        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.In))
        {
            Task clientTask = StartClientAsync(PipeDirection.Out, server.ClientSafePipeHandle);

            Console.WriteLine("server.InBufferSize = {0}", server.InBufferSize);
            byte[] readData = new byte[] { 0, 1 };
            server.Read(readData, 0, 1);
            server.ReadAsync(readData, 1, 1).Wait();
            Assert.Equal(123, readData[0]);
            Assert.Equal(124, readData[1]);
        }
    }
        public static void ClonedServer_ActsAsOriginalServer()
        {
            using (AnonymousPipeServerStream serverBase = new AnonymousPipeServerStream(PipeDirection.Out))
            {
                using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out, serverBase.SafePipeHandle, serverBase.ClientSafePipeHandle))
                {
                    Assert.True(server.IsConnected);
                    using (AnonymousPipeClientStream client = new AnonymousPipeClientStream(PipeDirection.In, server.GetClientHandleAsString()))
                    {
                        Assert.True(server.IsConnected);
                        Assert.True(client.IsConnected);

                        byte[] sent     = new byte[] { 123 };
                        byte[] received = new byte[] { 0 };
                        server.Write(sent, 0, 1);

                        Assert.Equal(1, client.Read(received, 0, 1));
                        Assert.Equal(sent[0], received[0]);
                    }
                    Assert.Throws <IOException>(() => server.WriteByte(5));
                }
            }
        }
Exemple #21
0
        private void Audio_DataAvailable(object sender, WaveInEventArgs e)
        {
            if (e.BytesRecorded == 0)
            {
                return;
            }
            var buffer = e.Buffer;

            if (!recording)
            {
                return;
            }
            sourceProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
            //using (var str = new RawSourceWaveStream(buffer, 0, e.BytesRecorded, audio.WaveFormat))//need to preserve this?
            //{


            //var six = new WaveFloatTo16Provider(sourceProvider);
            byte[] output = new byte[e.BytesRecorded / 2];

            //var volout = new StereoToMonoProvider16(six);

            monovolumeprovider.LeftVolume  = (1f - videorecordingsettings.audioBalance) * videorecordingsettings.leftVolume * 2;
            monovolumeprovider.RightVolume = (videorecordingsettings.audioBalance) * videorecordingsettings.rightVolume * 2;

            //var formatconv = new WaveFormatConversionProvider(new WaveFormat(24000, 16, 1), volout);


            //byte[] output = new byte[bytesread / 2];
            var bytesread = formatconv.Read(output, 0, e.BytesRecorded);

            int control = 0;

            if (audioframe == 0)
            {
                control = 1;
            }
            audioframe++;

            if (isConnected)
            {
                AudioStream.Write(BitConverter.GetBytes(control), 0, sizeof(int));
                AudioStream.Write(BitConverter.GetBytes(bytesread), 0, sizeof(int));
                AudioStream.Write(BitConverter.GetBytes(formatconv.WaveFormat.SampleRate), 0, sizeof(int));                        //volout
                AudioStream.Write(BitConverter.GetBytes(formatconv.WaveFormat.AverageBytesPerSecond), 0, sizeof(int));
                AudioStream.Write(output, 0, bytesread);
                AudioStream.Flush();
                AudioStream.WaitForPipeDrain();
            }
            if (enableWriteToFile && binaryAudioWriter != null)
            {
                binaryAudioWriter.Write(BitConverter.GetBytes(control), 0, sizeof(int));
                binaryAudioWriter.Write(BitConverter.GetBytes(bytesread), 0, sizeof(int));
                binaryAudioWriter.Write(BitConverter.GetBytes(formatconv.WaveFormat.SampleRate), 0, sizeof(int));
                binaryAudioWriter.Write(BitConverter.GetBytes(formatconv.WaveFormat.AverageBytesPerSecond), 0, sizeof(int));
                //AudioStream.Write(BitConverter.GetBytes(volout.WaveFormat.SampleRate), 0, sizeof(int));
                //AudioStream.Write(BitConverter.GetBytes(volout.WaveFormat.AverageBytesPerSecond), 0, sizeof(int));
                binaryAudioWriter.Write(output, 0, bytesread);
                binaryAudioWriter.Flush();
            }
            audiolengthmonitor = bytesread;
            //}
        }
        public static void ServerWriteNegativeCountThrows()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
            {
                Assert.Throws<ArgumentOutOfRangeException>(() => server.Write(new byte[5], 0, -1));

                // offset is checked before count
                Assert.Throws<ArgumentOutOfRangeException>(() => server.Write(new byte[1], -1, -1));

                // array is checked first
                Assert.Throws<ArgumentNullException>(() => server.Write(null, -1, -1));

                Assert.Throws<ArgumentOutOfRangeException>(() => NotReachable(server.WriteAsync(new byte[5], 0, -1)));

                // offset is checked before count
                Assert.Throws<ArgumentOutOfRangeException>(() => NotReachable(server.WriteAsync(new byte[1], -1, -1)));

                // array is checked first
                Assert.Throws<ArgumentNullException>(() => NotReachable(server.WriteAsync(null, -1, -1)));
            }
        }
        public static void ServerReadOnlyThrows()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.In))
            {
                Assert.Throws<NotSupportedException>(() => server.Write(new byte[5], 0, 5));

                Assert.Throws<NotSupportedException>(() => server.WriteByte(123));

                Assert.Throws<NotSupportedException>(() => server.Flush());

                Assert.Throws<NotSupportedException>(() => server.OutBufferSize);

                Assert.Throws<NotSupportedException>(() => server.WaitForPipeDrain());

                Assert.Throws<NotSupportedException>(() => NotReachable(server.WriteAsync(new byte[5], 0, 5)));
            }
        }
        public static void ServerWriteArrayOutOfBoundsThrows()
        {
            using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out))
            {
                // offset out of bounds
                Assert.Throws<ArgumentException>(null, () => server.Write(new byte[1], 1, 1));

                // offset out of bounds for 0 count read
                Assert.Throws<ArgumentException>(null, () => server.Write(new byte[1], 2, 0));

                // offset out of bounds even for 0 length buffer
                Assert.Throws<ArgumentException>(null, () => server.Write(new byte[0], 1, 0));

                // combination offset and count out of bounds
                Assert.Throws<ArgumentException>(null, () => server.Write(new byte[2], 1, 2));

                // edges
                Assert.Throws<ArgumentException>(null, () => server.Write(new byte[0], int.MaxValue, 0));
                Assert.Throws<ArgumentException>(null, () => server.Write(new byte[0], int.MaxValue, int.MaxValue));

                Assert.Throws<ArgumentException>(() => server.Write(new byte[5], 3, 4));

                // offset out of bounds
                Assert.Throws<ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[1], 1, 1)));

                // offset out of bounds for 0 count read
                Assert.Throws<ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[1], 2, 0)));

                // offset out of bounds even for 0 length buffer
                Assert.Throws<ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[0], 1, 0)));

                // combination offset and count out of bounds
                Assert.Throws<ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[2], 1, 2)));

                // edges
                Assert.Throws<ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[0], int.MaxValue, 0)));
                Assert.Throws<ArgumentException>(null, () => NotReachable(server.WriteAsync(new byte[0], int.MaxValue, int.MaxValue)));

                Assert.Throws<ArgumentException>(() => NotReachable(server.WriteAsync(new byte[5], 3, 4)));
            }
        }
        public R <(string, Thread, TimeSpan?), LocalStr> StreamSongToPipeHandle(string spotifyTrackUri)
        {
            var trackId = SpotifyApi.UriToTrackId(spotifyTrackUri);

            if (!trackId.Ok)
            {
                return(new LocalStr("Cannot stream this URI from spotify."));
            }

            if (state == State.NotSetUp)
            {
                return(new LocalStr("Spotify API access was not set up correctly. Cannot play from spotify."));
            }

            if (state != State.Idle)
            {
                throw new InvalidOperationException(
                          $"Tried to stream spotify song while the system was not idle (current state: {state})."
                          );
            }

            // Launch Librespot.
            state = State.LaunchingLibrespot;
            Log.Debug("Launching Librespot...");
            var processOption = LaunchLibrespot();

            if (!processOption.Ok)
            {
                return(processOption.Error);
            }

            void Fail(string msg)
            {
                Log.Debug("Failed to start song on spotify: " + msg);
            }

            TimeSpan duration = default;

            for (var i = 0; i < SongStartRetries; i++)
            {
                Log.Debug($"Starting to play song on spotify, try {i}...");

                // Start song.
                var playResult = api.Request(
                    () => api.Client.Player.ResumePlayback(new PlayerResumePlaybackRequest {
                    DeviceId = deviceId,
                    Uris     = new List <string> {
                        spotifyTrackUri
                    }
                })
                    );
                if (!playResult.Ok)
                {
                    Fail(playResult.Error.ToString());
                    continue;
                }

                // Check if the song actually started playing.
                for (var j = 0; j < 2; j++)
                {
                    if (j == 1)
                    {
                        // Wait before the second check.
                        Thread.Sleep(SongStartRecheckAfter);
                    }

                    var checkResult = api.Request(() => api.Client.Player.GetCurrentPlayback());
                    if (!checkResult.Ok)
                    {
                        Fail(checkResult.Error.ToString());
                        continue;
                    }

                    var currentlyPlaying = checkResult.Value;

                    if (currentlyPlaying.CurrentlyPlayingType != "track")
                    {
                        Fail("No track is currently playing.");
                        continue;
                    }

                    var track = (FullTrack)currentlyPlaying.Item;

                    if (
                        currentlyPlaying.IsPlaying &&
                        currentlyPlaying.Device.Id == deviceId &&
                        track.Id == trackId.Value
                        )
                    {
                        duration = TimeSpan.FromMilliseconds(track.DurationMs);
                        state    = State.StreamRunning;
                        break;
                    }

                    Fail(
                        $"Song not playing yet on spotify." +
                        $" IsPlaying: {currentlyPlaying.IsPlaying}," +
                        $" DeviceId: {currentlyPlaying.Device.Id} (should be {deviceId})," +
                        $" TrackId: {track.Id} (should be {trackId.Value})."
                        );
                }

                if (state == State.StreamRunning)
                {
                    Log.Trace("Song is playing on spotify now.");
                    break;
                }
            }

            // Start audio streaming to ffmpeg.
            Log.Debug("Starting stream...");
            var pipeServer = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
            var handle     = "pipe:" + pipeServer.GetClientHandleAsString();

            var totalBytesSent = 0;

            void ExitLibrespot(string message, bool stats = true)
            {
                pipeServer.Dispose();

                if (!process.HasExitedSafe())
                {
                    process.Kill();
                }
                process.Close();

                state = State.Idle;

                var msg = message;

                if (stats)
                {
                    msg += $" Sent {byteSizeFormatter.Format(totalBytesSent)} bytes in total.";
                }
                Log.Debug(msg);
            }

            if (state != State.StreamRunning)
            {
                var msg = $"Song did not start playing after {SongStartRetries} retries.";
                ExitLibrespot(msg, false);
                return(new LocalStr(msg));
            }

            var byteReaderThread = new Thread(() => {
                var buffer = new byte[BytesPerChunk];
                while (true)
                {
                    int bytesRead;
                    try {
                        bytesRead = process.StandardOutput.BaseStream.Read(buffer, 0, BytesPerChunk);
                    } catch (IOException e) {
                        ExitLibrespot($"Reading from Librespot failed: {e}.");
                        return;
                    }

                    if (bytesRead == 0)
                    {
                        // Librespot exited, no more data coming.
                        ExitLibrespot("All spotify streaming data sent to ffmpeg.");
                        return;
                    }

                    try {
                        pipeServer.Write(buffer, 0, bytesRead);
                    } catch (IOException) {
                        ExitLibrespot("Ffmpeg went away before all spotify stream data was sent.");
                        return;
                    }

                    if (totalBytesSent == 0)
                    {
                        // Necessary to dispose the handle after ffmpeg connected to receive notice when ffmpeg exits.
                        pipeServer.DisposeLocalCopyOfClientHandle();
                    }

                    totalBytesSent += bytesRead;
                }
            })
            {
                IsBackground = true
            };

            return(handle, byteReaderThread, duration);
        }
Exemple #26
0
 public void SendMessage(ReadOnlySpan <byte> bytes)
 {
     _pipeServer.Write(bytes);
 }
    public static async Task ServerPInvokeChecks()
    {
        // calling every API related to server and client to detect any bad PInvokes
        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.None, 4096))
        {
            Task clientTask = Task.Run(() => StartClient(PipeDirection.In, server.ClientSafePipeHandle));

            Assert.False(server.CanRead);
            Assert.False(server.CanSeek);
            Assert.False(server.CanTimeout);
            Assert.True(server.CanWrite);
            Assert.False(string.IsNullOrWhiteSpace(server.GetClientHandleAsString()));
            Assert.False(server.IsAsync);
            Assert.True(server.IsConnected);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ||
                RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Assert.True(server.OutBufferSize > 0);
            }
            else
            {
                Assert.Throws <PlatformNotSupportedException>(() => server.OutBufferSize);
            }
            Assert.Equal(PipeTransmissionMode.Byte, server.ReadMode);
            Assert.NotNull(server.SafePipeHandle);
            Assert.Equal(PipeTransmissionMode.Byte, server.TransmissionMode);

            server.Write(new byte[] { 123 }, 0, 1);
            await server.WriteAsync(new byte[] { 124 }, 0, 1);

            server.Flush();
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                server.WaitForPipeDrain();
            }
            else
            {
                Assert.Throws <PlatformNotSupportedException>(() => server.WaitForPipeDrain());
            }

            await clientTask;
            server.DisposeLocalCopyOfClientHandle();
        }

        using (AnonymousPipeServerStream server = new AnonymousPipeServerStream(PipeDirection.In))
        {
            Task clientTask = Task.Run(() => StartClient(PipeDirection.Out, server.ClientSafePipeHandle));

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Equal(4096, server.InBufferSize);
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Assert.True(server.InBufferSize > 0);
            }
            else
            {
                Assert.Throws <PlatformNotSupportedException>(() => server.InBufferSize);
            }
            byte[] readData = new byte[] { 0, 1 };
            Assert.Equal(1, server.Read(readData, 0, 1));
            Assert.Equal(1, server.ReadAsync(readData, 1, 1).Result);
            Assert.Equal(123, readData[0]);
            Assert.Equal(124, readData[1]);

            await clientTask;
        }
    }
        /// <summary>
        /// Creates a child domain.
        /// </summary>
        public ChildDomain AddChildDomain(ProcessStartInfo startInfo, IAmASerializer serializer = null, IGenerateProxies proxyGenerator = null)
        {
            //if the path is missing then
            if (startInfo == null)
            {
                throw new ArgumentNullException(nameof(startInfo));
            }

            var childProcess = new Process
            {
                StartInfo = startInfo
            };

            proxyGenerator = proxyGenerator ?? DefaultProxyFactory.Instance;
            serializer     = serializer ?? DefaultSerializer.Instance;

            var debuggerEnabled = Debugger.IsAttached && DebuggingSupported;

            var read  = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
            var write = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);

            startInfo.Environment[connectionStringVarName] =
                $"pid={Current.Process.Id}&" +
                $"write={write.GetClientHandleAsString()}&" +
                $"read={read.GetClientHandleAsString()}&" +
                $"debug={(debuggerEnabled ? 1 : 0)}&" +
                $"serializer={HttpUtility.UrlEncode(serializer.Name)}&" +
                $"proxyGenerator={HttpUtility.UrlEncode(proxyGenerator.Name)}";
            startInfo.UseShellExecute = false;

            childProcess.EnableRaisingEvents = true;

            childProcess.Start();

            read.DisposeLocalCopyOfClientHandle();
            write.DisposeLocalCopyOfClientHandle();

            if (debuggerEnabled)
            {
                if (!TryToAttachDebugger(childProcess.Id))
                {
                    debuggerEnabled = false;
                }

                //signal to the child process to continue now that the debugger is attached
                read.Write(new byte[1], 0, 1);
            }

            //NOTE: the read and write streams are switched for the server side
            var child = new ChildDomain(childProcess, debuggerEnabled, new Connection(this, serializer, proxyGenerator, write, read));

            children[childProcess.Id] = child;

            child.Process.Exited += (sender, eventArgs) => children.TryRemove(childProcess.Id, out _);

            if (child.Process.HasExited)
            {
                children.TryRemove(childProcess.Id, out _);
            }

            return(child);
        }