diff --git a/src/KeePassLib2Android/KeePassLib2Android.csproj b/src/KeePassLib2Android/KeePassLib2Android.csproj index a7fdc014..d925d883 100644 --- a/src/KeePassLib2Android/KeePassLib2Android.csproj +++ b/src/KeePassLib2Android/KeePassLib2Android.csproj @@ -113,7 +113,6 @@ - diff --git a/src/KeePassLib2Android/Serialization/AsynchronousBufferedXmlReader.cs b/src/KeePassLib2Android/Serialization/AsynchronousBufferedXmlReader.cs deleted file mode 100644 index d10ba1cb..00000000 --- a/src/KeePassLib2Android/Serialization/AsynchronousBufferedXmlReader.cs +++ /dev/null @@ -1,367 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Threading; -using System.Xml; -using System.Diagnostics; - -namespace KeePassLib.Serialization -{ - public class AsynchronousBufferedXmlReader : XmlReader - { - /// - /// An element which indicates the end of the XML document has been reached. - /// - private static readonly Element EndMarker = new Element(); - - /// - /// The next buffered element available for reading. - /// Volatility: only read/written to by non-buffering thread. Passed to the buffer thread as an initial parameter. - /// - Element mBufferQueueHead = new Element(); // Start off with the pre-document element. No content, yet. - - private readonly Thread mWorkerThread; - private readonly AutoResetEvent mWaitForBuffer = new AutoResetEvent(false); - /// - /// True while the reader thread is stalled waiting for buffering. - /// Volaitlity: Only written by read thread. Only read by buffer thread - /// - private volatile bool mWaitingForBuffer; - -#if TRACE - private Stopwatch mReadWaitTimer = new Stopwatch(); - private Stopwatch mBufferCompletedTimer = new Stopwatch(); -#endif - - /// - /// Testing helper method - /// - /// - /// - public static XmlReader FullyBuffer(Stream input) - { - var reader = new AsynchronousBufferedXmlReader(); - reader.ReadStreamWorker(input); - return reader; - } - - private AsynchronousBufferedXmlReader() - { - // Once the end is reached, it stays there. - EndMarker.NextElement = EndMarker; - } - - public AsynchronousBufferedXmlReader(Stream input) : this() - { - mWorkerThread = new Thread(ReadStreamWorker) { Name = GetType().Name }; - mWorkerThread.Start(input); - } - - #region Buffering - private void ReadStreamWorker(object state) - { - var input = (Stream)state; - - var xr = XmlReader.Create(input, KdbxFile.CreateStdXmlReaderSettings()); - - /// - /// The last buffered element available for reading. - /// - Element bufferQueueTail = mBufferQueueHead; - - /// - /// The element currently being buffered. Not yet available for reading. - /// - Element currentElement = null; - - while (xr.Read()) - { - switch (xr.NodeType) - { - case XmlNodeType.Element: - // Start a new element - if (currentElement != null) - { - // Add the previous current element to the tail of the buffer - bufferQueueTail.NextElement = currentElement; - bufferQueueTail = currentElement; - if (mWaitingForBuffer) mWaitForBuffer.Set(); // Signal that a new element is available in the buffer - } - - currentElement = new Element { Name = xr.Name }; - - // Process attributes - current optimisation, all elements have 0 or 1 attribute - if (xr.MoveToNextAttribute()) - { -#if DEBUG - Debug.Assert(xr.AttributeCount == 1); - currentElement.AttributeName = xr.Name; -#endif - currentElement.AttributeValue = xr.Value; - } - - currentElement.IsEmpty = xr.IsEmptyElement; - - break; - - case XmlNodeType.Text: - currentElement.Value = xr.Value; - currentElement.IsEmpty = true; // Mark as empty because it will have no end element written for it - break; - - case XmlNodeType.EndElement: - Debug.Assert(currentElement != null, "Ending an element that was never started"); - - // If this is an element with children (not one with a value) add an end element marker to the queue - if (currentElement.Value == null || currentElement.Name != xr.Name) - { - bufferQueueTail.NextElement = currentElement; - bufferQueueTail = currentElement; - if (mWaitingForBuffer) mWaitForBuffer.Set(); // Signal that a new element is available in the buffer - - currentElement = new Element { Name = xr.Name, IsEndElement = true }; - } - break; - } - } - - // Conclude the document, add the final element to the buffer and mark the ending - currentElement.NextElement = EndMarker; - bufferQueueTail.NextElement = currentElement; - bufferQueueTail = currentElement; - mWaitForBuffer.Set(); // Signal that final element is available in the buffer (regardless of wait flag, to avoid race condition) -#if TRACE - mBufferCompletedTimer.Start(); -#endif - } - #endregion - - private class Element - { - /// - /// Link to the next buffered element. - /// Volatility: Written to by buffer thread only. Read by both threads - /// - public volatile Element NextElement; - - public string Name; - - /// - /// If this element marks the end of an xml element with child nodes, the IsEndElement will be true, and Value must be null. - /// - public bool IsEndElement; - - /// - /// Set true if this represents an empty element - /// - public bool IsEmpty; - - /// - /// If Value is non-null, then there will be no corresponding Element with IsEndElement created. - /// - public string Value; - - // Currently KDBX has a maximum of one attribute per element, so no need for a dictionary here, and the name is only used for debug asserts -#if DEBUG - public string AttributeName; -#endif - public string AttributeValue; - } - - #region Custom XmlReader implementation for usage by KdbxFile only - public override bool Read() - { - Element nextElement; - while ((nextElement = mBufferQueueHead.NextElement) == null) - { -#if TRACE - mReadWaitTimer.Start(); -#endif - mWaitingForBuffer = true; - mWaitForBuffer.WaitOne(); - mWaitingForBuffer = false; - -#if TRACE - mReadWaitTimer.Stop(); -#endif - } - mBufferQueueHead = mBufferQueueHead.NextElement; - - -#if TRACE - if (mBufferQueueHead == EndMarker) - { - Debug.WriteLine(String.Format("Asynchronous Buffered XmlReader waited for a total of: {0}ms, buffer completed {1}ms ahead of read", mReadWaitTimer.ElapsedMilliseconds, mBufferCompletedTimer.ElapsedMilliseconds)); - } -#endif - return mBufferQueueHead != EndMarker; - } - - public override string ReadElementString() - { - var result = mBufferQueueHead.Value ?? String.Empty; // ReadElementString returns empty strings for null content - Read(); // Read element string always skips to the start of the next element - return result; - } - - public override XmlNodeType NodeType - { - get - { - return mBufferQueueHead.IsEndElement ? XmlNodeType.EndElement : XmlNodeType.Element; - } - } - - public override bool IsEmptyElement - { - get - { - return mBufferQueueHead.IsEmpty; - } - } - - public override string Name - { - get - { - return mBufferQueueHead.Name; - } - } - - public override bool HasAttributes - { - get - { - return mBufferQueueHead.AttributeValue != null; - } - } - - public override bool MoveToAttribute(string name) - { -#if DEBUG - Debug.Assert(mBufferQueueHead.AttributeName == name); -#endif - - return true; - } - - public override string Value - { - get - { - return mBufferQueueHead.AttributeValue; - } - } - - - public override bool MoveToElement() - { - return true; - } - #endregion - - #region Unimplemented XmlReader overrides - - public override int AttributeCount - { - get { throw new NotImplementedException(); } - } - - public override string BaseURI - { - get { throw new NotImplementedException(); } - } - - public override void Close() - { - throw new NotImplementedException(); - } - - public override int Depth - { - get { throw new NotImplementedException(); } - } - - public override bool EOF - { - get { throw new NotImplementedException(); } - } - - public override string GetAttribute(int i) - { - throw new NotImplementedException(); - } - - public override string GetAttribute(string name, string namespaceURI) - { - throw new NotImplementedException(); - } - - public override string GetAttribute(string name) - { - throw new NotImplementedException(); - } - - public override bool HasValue - { - get { throw new NotImplementedException(); } - } - - public override string LocalName - { - get { throw new NotImplementedException(); } - } - - public override string LookupNamespace(string prefix) - { - throw new NotImplementedException(); - } - - public override bool MoveToAttribute(string name, string ns) - { - throw new NotImplementedException(); - } - - public override bool MoveToFirstAttribute() - { - throw new NotImplementedException(); - } - - public override bool MoveToNextAttribute() - { - throw new NotImplementedException(); - } - - public override XmlNameTable NameTable - { - get { throw new NotImplementedException(); } - } - - public override string NamespaceURI - { - get { throw new NotImplementedException(); } - } - - public override string Prefix - { - get { throw new NotImplementedException(); } - } - - public override bool ReadAttributeValue() - { - throw new NotImplementedException(); - } - - public override ReadState ReadState - { - get { throw new NotImplementedException(); } - } - - public override void ResolveEntity() - { - throw new NotImplementedException(); - } - #endregion - } -} diff --git a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs index 65c2aa55..03456962 100644 --- a/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs +++ b/src/KeePassLib2Android/Serialization/KdbxFile.Read.cs @@ -70,8 +70,6 @@ namespace KeePassLib.Serialization Debug.Assert(sSource != null); if(sSource == null) throw new ArgumentNullException("sSource"); - var stopWatch = Stopwatch.StartNew(); - m_format = kdbFormat; m_slLogger = slLogger; @@ -129,33 +127,7 @@ namespace KeePassLib.Serialization } else m_randomStream = null; // No random stream for plain-text files - Debug.WriteLine(String.Format("Crypto setup: {0}ms", stopWatch.ElapsedMilliseconds)); - stopWatch.Restart(); - - /* - var memStream = new MemoryStream((int)hashedStream.Length); - CopyStream(readerStream, memStream); - readerStream = memStream; - Debug.WriteLine(String.Format("CopyStream: {0}ms", stopWatch.ElapsedMilliseconds)); - - - stopWatch.Restart(); - */ - - //var bufferedXmlReader = AsynchronousBufferedXmlReader.FullyBuffer(readerStream); - //Debug.WriteLine(String.Format("ReadToBuffer: {0}ms", stopWatch.ElapsedMilliseconds)); - - if (Java.Lang.Runtime.GetRuntime().AvailableProcessors() > 1) - { - ReadDocumentStreamed(new AsynchronousBufferedXmlReader(readerStream), hashedStream); - Debug.WriteLine(String.Format("ReadDocumentStreamed: {0}ms multi-threaded", stopWatch.ElapsedMilliseconds)); - } - else - { - ReadXmlStreamed(readerStream, hashedStream); - Debug.WriteLine(String.Format("ReadXmlStreamed: {0}ms single-threaded", stopWatch.ElapsedMilliseconds)); - } - stopWatch.Restart(); + ReadXmlStreamed(readerStream, hashedStream); // ReadXmlDom(readerStream); readerStream.Close(); @@ -166,26 +138,9 @@ namespace KeePassLib.Serialization { throw new CryptographicException(KLRes.FileCorrupted); } - finally - { - - CommonCleanUpRead(sSource, hashedStream); - Debug.WriteLine(String.Format("Close and Clean Up: {0}ms", stopWatch.ElapsedMilliseconds)); - } + finally { CommonCleanUpRead(sSource, hashedStream); } } - /* - public static void CopyStream(Stream input, Stream output) - { - byte[] buffer = new byte[32768]; - int read; - while ((read = input.Read(buffer, 0, buffer.Length)) > 0) - { - output.Write(buffer, 0, read); - } - output.Seek(0, SeekOrigin.Begin); - }*/ - private void CommonCleanUpRead(Stream sSource, HashingStreamEx hashedStream) { hashedStream.Close(); diff --git a/src/keepass2android/Database.cs b/src/keepass2android/Database.cs index 6e03e980..c8eee74d 100644 --- a/src/keepass2android/Database.cs +++ b/src/keepass2android/Database.cs @@ -120,8 +120,6 @@ namespace keepass2android public void LoadData(Context ctx, IOConnectionInfo iocInfo, String password, String keyfile, UpdateStatus status) { - var stopWatch = System.Diagnostics.Stopwatch.StartNew(); - mIoc = iocInfo; KeePassLib.PwDatabase pwDatabase = new KeePassLib.PwDatabase(); @@ -140,14 +138,8 @@ namespace keepass2android } } - System.Diagnostics.Debug.WriteLine(String.Format("LoadData Pre-open: {0}ms", stopWatch.ElapsedMilliseconds)); - stopWatch.Restart(); - pwDatabase.Open(iocInfo, key, status); - System.Diagnostics.Debug.WriteLine(String.Format("LoadData Open: {0}ms", stopWatch.ElapsedMilliseconds)); - stopWatch.Restart(); - if (iocInfo.IsLocalFile()) { mLastChangeDate = System.IO.File.GetLastWriteTimeUtc(iocInfo.Path); @@ -163,8 +155,6 @@ namespace keepass2android Loaded = true; pm = pwDatabase; searchHelper = new SearchDbHelper(ctx); - - System.Diagnostics.Debug.WriteLine(String.Format("LoadData Post-open: {0}ms", stopWatch.ElapsedMilliseconds)); } bool quickUnlockEnabled = false; @@ -197,7 +187,12 @@ namespace keepass2android public PwGroup Search(SearchParameters searchParams) { - return searchHelper.search(this, searchParams); + return Search(searchParams, null); + } + + public PwGroup Search(SearchParameters searchParams, IDictionary resultContexts) + { + return searchHelper.search(this, searchParams, resultContexts); }