[C#/C++] Code Adaptation for xDelta/VCDIFF wrapper

Discussion in 'Mixed Languages' started by CODYQX4, Mar 22, 2013.

  1. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,232
    150
    #1 CODYQX4, Mar 22, 2013
    Last edited by a moderator: Apr 20, 2017
    For once, there now exists a C# library to decode and encode xdelta patches (encode = make, decode = apply).

    Previously, you could only decode using an old library called MiscUtil, which had a lot of extra stuff anyway.

    Here, I found a C# library that wraps C++ (which xdelta is normally written in):
    https://github.com/winkel/vcdiff-dotnet


    Take a look at the C# code, once you include the compiled DLL in your .NET app, you can use those methods.

    But look at the example and I could use adjustments for this to be more useful:
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    namespace LowLevelApiUsage
    {
        class Program
        {
            static void Main(string[] args)
            {
                EncodingExample();
                DecodingExample();
            }
    
            static void EncodingExample()
            {
                byte[] sourceFile = File.ReadAllBytes(@"C:\tmp\diff\test.7z");
                List<byte> result = new List<byte>();
    
                using (VCDiffDotNet.LowLevel.Encoder encoder = new VCDiffDotNet.LowLevel.Encoder())
                {
                    encoder.InitEncoder(sourceFile, true, true, false, false);
    
                    byte[] partialOutput;
                    var ret = encoder.StartEncoding(out partialOutput);
                    result.AddRange(partialOutput);
    
                    byte[] partOfTargetFile = File.ReadAllBytes(@"C:\tmp\diff\test-new.7z");
                    ret = encoder.EncodeChunk(partOfTargetFile, out partialOutput);
                    result.AddRange(partialOutput);
    
                    ret = encoder.FinishEncoding(out partialOutput);
                    result.AddRange(partialOutput);
                }
    
                byte[] patchFile = result.ToArray();
                File.WriteAllBytes(@"C:\tmp\diff\test.patch", patchFile);
            }
    
            static void DecodingExample()
            {
                byte[] sourceFile = File.ReadAllBytes(@"C:\tmp\diff\test.7z");
                List<byte> result = new List<byte>();
    
                using (VCDiffDotNet.LowLevel.Decoder decoder = new VCDiffDotNet.LowLevel.Decoder())
                {
                    int maxSize = 1 << 24;
                    decoder.InitDecoder(sourceFile, true, maxSize, maxSize);
                    decoder.StartDecoding();
    
                    byte[] partialOutput;
                    byte[] partOfPatchFile = File.ReadAllBytes(@"C:\tmp\diff\test.patch");
                    decoder.DecodeChunk(partOfPatchFile, out partialOutput);
                    result.AddRange(partialOutput);
    
                    decoder.FinishDecoding();
                }
    
                byte[] targetFile = result.ToArray();
                File.WriteAllBytes(@"C:\tmp\diff\test-patched.7z", targetFile);
            }
        }
    }
    
    See how it takes a byte array and he's doing a File.ReadAllBytes? That really isn't going to fly for large files.

    MiscUtil used a stream so as to not load it all into memory (because I can't put 2 200MB cabs into RAM, it will run like crap and may run out of memory).


    If anyone could adapt that code to use streams, it would be indispensable.

    PS: How I use MiscUtil in MTK to patch a file:
    Code:
                            
    using (FileStream original = File.OpenRead(originalFile))
    {
         using (Stream patchStream = new MemoryStream(Convert.FromBase64String(patchDataBase64)))
         {
              using (FileStream target = File.Open(targetFile, FileMode.OpenOrCreate, FileAccess.ReadWrite))
              {
                   VcdiffDecoder.Decode(original, patchStream, target);
              }
         }
    }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. CODYQX4

    CODYQX4 MDL Developer

    Sep 4, 2009
    4,803
    45,232
    150
    #2 CODYQX4, Mar 23, 2013
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Hm, maybe it already does what I need?

    Code:
    VCDiff decoder = new VCDiff()
    decoder.Patch(original, patch, target)
    
    EDIT: Doesn't work for me.

    Code:
                            // Execute Patcher
                            using (FileStream original = File.OpenRead(originalFile))
                            {
                                using (Stream patchStream = new MemoryStream(Convert.FromBase64String(patchDataBase64)))
                                {
                                    using (FileStream target = File.Open(targetFile, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                                    {
                                        using (VCDiff decoder = new VCDiff())
                                        {
                                            decoder.Patch(original, patchStream, target);                                    
                                        }
                                    }
                                }
                            }
    
    Throws an exception with the message "EncodeChuck(...)". A totally worthless message that helps in no way shape or form.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...