From e858ef1cf5997cf68e781372db33aa8c2dfd6e91 Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Sat, 17 Aug 2013 13:38:10 +0200 Subject: [PATCH] Rewrote FileBackedList to use virtual functions instead of functors, because the lambda functors are no longer instance methods in the new Mono compiler --- Duplicati/Library/Utility/FileBackedList.cs | 70 +++++++++++---------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/Duplicati/Library/Utility/FileBackedList.cs b/Duplicati/Library/Utility/FileBackedList.cs index 2ca9baebf..5c18b91c4 100644 --- a/Duplicati/Library/Utility/FileBackedList.cs +++ b/Duplicati/Library/Utility/FileBackedList.cs @@ -28,7 +28,7 @@ namespace Duplicati.Library.Utility /// Typical usage of this list is for storing log messages, /// that occasionally grows and produces out-of-memory errors /// - public class FileBackedList : IEnumerable, IDisposable + public abstract class FileBackedList : IEnumerable, IDisposable { private class StreamEnumerator : IEnumerator, System.Collections.IEnumerator { @@ -100,30 +100,22 @@ namespace Duplicati.Library.Utility private Library.Utility.TempFile m_file; private Stream m_stream; private long m_count; - - private Func m_getSize; - private Action m_serialize; - private Func m_deserialize; - + public bool IsFileBacked { get { return !(m_stream is MemoryStream); } } public long SwitchToFileLimit { get; set; } - public FileBackedList(Func getSize, Action serialize, Func deserialize) + public FileBackedList() { m_file = null; m_stream = new MemoryStream(); m_count = 0; - - m_getSize = getSize; - m_serialize = serialize; - m_deserialize = deserialize; - + this.SwitchToFileLimit = 10 * 1024 * 1024; } public void Add(T value) { - long size = m_getSize(value); + long size = GetSize(value); if (m_stream is MemoryStream && (m_stream.Length + size) > this.SwitchToFileLimit) { m_file = new Library.Utility.TempFile(); @@ -136,7 +128,7 @@ namespace Duplicati.Library.Utility } m_stream.Write(BitConverter.GetBytes(size), 0, 8); - m_serialize(value, m_stream); + Serialize(value, m_stream); m_count++; } @@ -156,13 +148,17 @@ namespace Duplicati.Library.Utility m_file.Dispose(); m_file = null; } - } - + } + + protected abstract long GetSize(T value); + protected abstract void Serialize(T value, Stream stream); + protected abstract T Deserialize(Stream stream, long length); + #region IEnumerable implementation public IEnumerator GetEnumerator() { - return new StreamEnumerator(m_stream, m_deserialize, this); + return new StreamEnumerator(m_stream, this.Deserialize, this); } #endregion @@ -187,27 +183,37 @@ namespace Duplicati.Library.Utility public class FileBackedStringList : FileBackedList { private byte[] m_buf; + public System.Text.Encoding m_encoding; + /// /// Initializes a new instance of the class. /// /// The text encoding to use, defaults to UTF8 public FileBackedStringList(System.Text.Encoding encoding = null) - : base( - (value) => { - m_buf = (encoding ?? System.Text.Encoding.UTF8).GetBytes(value); - return m_buf.Length; - }, - (value, stream) => { - stream.Write(m_buf, 0, m_buf.Length); - m_buf = null; - }, - (stream, length) => { - var buf = new byte[length]; - Utility.ForceStreamRead(stream, buf, buf.Length); - return (encoding ?? System.Text.Encoding.UTF8).GetString(buf, 0, buf.Length); - }) { - } + m_encoding = encoding ?? System.Text.Encoding.UTF8; + } + + protected override long GetSize(string value) + { + m_buf = m_encoding.GetBytes(value); + return m_buf.Length; + } + + protected override void Serialize(string value, Stream stream) + { + stream.Write(m_buf, 0, m_buf.Length); + m_buf = null; + } + + protected override string Deserialize(Stream stream, long length) + { + if (m_buf == null || m_buf.Length < length) + m_buf = new byte[length]; + Utility.ForceStreamRead(stream, m_buf, (int)length); + return (m_encoding ?? System.Text.Encoding.UTF8).GetString(m_buf, 0, (int)length); + } + } }