Showing posts with label Telerik. Show all posts
Showing posts with label Telerik. Show all posts

Thursday, 27 September 2012

Testing Telerik ZIPLibrary

The ZIP library I've been testing came with Telerik WPF Controls bundle. I assume that its interface and usage does not differ significantly if at all in Telerik Silverlight, WinForm and ASP.NET libraries.

Start using the library with adding the reference to Telerik.Windows.Zip.

Files can be compressed by calling either Add or AddStream methods of ZipPackage class. The second method allows choosing between compression algorithms.


private static void TestCompress()
{
    using (var compressedFile = File.Create(@"c:\temp\documents.zip"))
    {
        using (var zipPackage = ZipPackage.Create(compressedFile))
        {
            //zipPackage.Add(
            //    Directory.GetFiles(@"c:\temp").Where(
            //        item => new[] { ".doc", ".docx" }.Contains(Path.GetExtension(item))));

            foreach (var file in Directory.GetFiles(@"c:\temp").Where(
                    item => new[] { ".doc", ".docx" }.Contains(Path.GetExtension(item))))
            {
                zipPackage.AddStream(
                    File.OpenRead(file), 
                    Path.GetFileName(file), 
                    ZipCompression.Deflate64, 
                    DateTime.Now);
            }
        }
    }
}

File extraction is performed through accessing ZipPackageEntries collection of the ZipPackage.



private static void TestDecompress()
{
    const string SourceCompressedFile = @"C:\temp\documents.zip";

    using (var sourceStream = File.OpenRead(SourceCompressedFile))
    {
        using (var zipPackage = ZipPackage.Open(sourceStream))
        {
            foreach (var zipPackageEntry in 
                zipPackage.ZipPackageEntries.OrderByDescending(item => item.FileNameInZip))
            {
                Console.WriteLine(zipPackageEntry.FileNameInZip);

                using (var openInputStream = zipPackageEntry.OpenInputStream())
                {
                    using (var outputStream = 
                        File.Create(@"c:\temp\aa\" + zipPackageEntry.FileNameInZip))
                    {
                        openInputStream.CopyTo(outputStream);
                    }
                }
            }
        }
    }
}


The compression ratio is acceptable -- slightly below the WinZip's level and almost on par with the Windows' level.

Dec. 21, 2012: The following pair of methods shows how to work with strings. Note that Base64 conversion is used for handling zero bytes. Due to that do not expect getting any significant gain, or even any gain at all, on strings shorter than 1K.


private static string CompressString(string source)
{
    using (var memoryStream = 
        new MemoryStream())
    using (var outputStream = 
        new ZipOutputStream(memoryStream, ZipCompression.Default))
    using (var writer = 
        new StreamWriter(outputStream))
    {
        writer.Write(source);
        writer.Flush();
        return Convert.ToBase64String(memoryStream.ToArray());
    }
}

private static string DecompressString(string source)
{
    using (var memoryStream = 
        new MemoryStream(Convert.FromBase64String(source)))
    using (var inputStream = 
        new ZipInputStream(memoryStream))
    using (var reader = 
        new StreamReader(inputStream, Encoding.UTF8))
    {
        return reader.ReadToEnd();
    }
}

Tuesday, 14 August 2012

Telerik WPF RadDatePicker, XML serialization, handling null values

To support blank values, an instance of the RadDatePicker must be bound to a value of DateTime? (nullable) type. Otherwise wiping out control's value does not change the bound value at all. Even more, it displays a nasty red border around the control.

If a bound value is a member of class intended to be serialized and de-serialized, it should be attributed in a specific way.

a) Apparently a member of DateTime? type stored in XML attribute, but only XML element should be used for that. An example is below.


private DateTime? _startDate;


[XmlElementAttribute(
    Form = System.Xml.Schema.XmlSchemaForm.Unqualified, 
    IsNullable = true)]
public DateTime? StartDate
{
    get
    {
        return this._startDate;
    }

    set
    {
        this._startDate = value;
        this.OnPropertyChanged("StartDate");
    }
}


The IsNullable parameter has to be either omitted or set to True.

b) Optionally you may include ShouldSerialize method as below. Note that the method's name must end with the member's name.


public bool ShouldSerializeStartDate()
{
    return this.StartDate.HasValue;
}


With such method present, an element with null value will be completely removed from serialization output. 

With no ShouldSerialize method implemented, such element will stay in the output but will hold no value.

<SampleEntity>
<StartDate xsi:nil="true" />
<EndDate>2012-07-31T00:00:00</EndDate>
</SampleEntity>

This post I conclude with two generic serialization routines.

public static string SerializeInstance<T>(this T instance)
{
    var serializer = new XmlSerializer(typeof(T));

    var stringBuilder = new StringBuilder();

    var settings = new XmlWriterSettings
    {
        ConformanceLevel = ConformanceLevel.Document,
        OmitXmlDeclaration = true
    };


    using (var writer = XmlWriter.Create(stringBuilder, settings))
    {
        serializer.Serialize(writer, instance);
        return stringBuilder.ToString();
    }
}

public static T DeserializeInstance<T>(string content)
{
    var serializer = new XmlSerializer(typeof(T));

    using (var reader = new StringReader(content ?? string.Empty))
    {
        var instance = (T)serializer.Deserialize(reader);
        return instance;
    }
}