guix
guix

Reputation: 105

C# function returning a Stream

Let me explain what I'm trying to do: I write a Filetype plugin for Paint.NET and I want the plugin to test various custom encoding methods and save the file with the method that produce the smallest filesize.

Here is my actual code (simplified a lot just to demonstrate what I want to do). That worked, except, well, see the comment:

private void encode1(Stream output)
{
    output.WriteByte(0xAA);
}
private void encode2(Stream output)
{
    output.WriteByte(0xAA);
    output.WriteByte(0xBB);
}

protected override void OnSave(Stream output)
{
    if (saveSmallest)
    {
        // I can't find a clean way to test for the smallest stream size
        // and then use the encoder that produced the smallest stream...
    }
    else if (selectedEncoder == 1)
    {
        encode1(output);
    }
    else if (selectedEncoder == 2)
    {
        encode2(output);
    }
}

So here is what I tried (also simplified but the idea is here), but it didn't work, nothing was written in the file in any cases and I have no idea why:

private Stream encode1()
{
    Stream output = new MemoryStream();
    output.WriteByte(0xAA);
    return output;
}
private Stream encode2()
{
    Stream output = new MemoryStream();
    output.WriteByte(0xAA);
    output.WriteByte(0xBB);
    return output;
}

private void copyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[128];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write(buffer, 0, read);
    }
}

protected override void OnSave(Stream output)
{
    if (saveSmallest)
    {
        // get encoders's streams
        Stream[] outputs =
        {
            encode1(),
            encode2(),
            //other encoders here
        };

        // Find the smallest stream
        int smallest = 0;
        for (int i = 1; i < outputs.Length; i++)
        {
            if (outputs[i].Length < outputs[smallest].Length)
            {
                smallest = i;
            }
        }
        //Copy the smallest into the final output
        //output = outputs[smallest];
        copyStream(outputs[smallest], output);
    }
    else if (selectedEncoder == 1)
    {
        //output = encode1();
        copyStream(encode1(), output);
    }
    else if (selectedEncoder == 2)
    {
        //output = encode2();
        copyStream(encode2(), output);
    }
}

I also tried working with bytes array instead of Stream, but the problem with bytes is that I must declare a byte array that is really big, because I have obviously no idea of how much bytes will be required to encode. It could be millions...

I am beginner in C#. Please tell me why it doesn't work at all, and how I can fix it, or if you have any idea how to improve. But please don't write complex code that takes 2kb more once compiled, I would like the code to be small, simple and efficient. I feel better with lower level programming... Thanks in advance!

Upvotes: 3

Views: 4059

Answers (1)

neeKo
neeKo

Reputation: 4280

Try Stream.Seek(0l, SeekOrigin.Begin); before you copy the stream.

Upvotes: 3

Related Questions