Kdbp format selection by filename. If the filename ends in .kdbp, it is assumed to be kdbp format. Otherwise, kdbx format is used. A file is always saved in the same format it is opened in.

This commit is contained in:
AlexVallat 2013-06-30 09:47:40 +01:00
parent 41e9c80456
commit b58d58771b
5 changed files with 43 additions and 37 deletions

View File

@ -588,7 +588,7 @@ namespace KeePassLib
kdbx.DetachBinaries = m_strDetachBins; kdbx.DetachBinaries = m_strDetachBins;
Stream s = IOConnection.OpenRead(ioSource); Stream s = IOConnection.OpenRead(ioSource);
kdbx.Load(s, KdbxFormat.Default, slLogger); kdbx.Load(s, KdbpFile.GetFormatToUse(ioSource), slLogger);
s.Close(); s.Close();
m_pbHashOfLastIO = kdbx.HashOfFileOnDisk; m_pbHashOfLastIO = kdbx.HashOfFileOnDisk;
@ -623,7 +623,7 @@ namespace KeePassLib
Stream s = ft.OpenWrite(); Stream s = ft.OpenWrite();
KdbxFile kdb = new KdbxFile(this); KdbxFile kdb = new KdbxFile(this);
kdb.Save(s, null, KdbxFormat.Default, slLogger); kdb.Save(s, null, KdbpFile.GetFormatToUse(m_ioSource), slLogger);
ft.CommitWrite(); ft.CommitWrite();

View File

@ -82,7 +82,7 @@ namespace KeePassLib.Serialization
BinaryReaderEx brDecrypted = null; BinaryReaderEx brDecrypted = null;
Stream readerStream = null; Stream readerStream = null;
if(kdbFormat == KdbxFormat.Default) if(kdbFormat == KdbxFormat.Default || kdbFormat == KdbxFormat.ProtocolBuffers)
{ {
br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted); br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted);
ReadHeader(br); ReadHeader(br);
@ -127,34 +127,21 @@ namespace KeePassLib.Serialization
} }
else m_randomStream = null; // No random stream for plain-text files else m_randomStream = null; // No random stream for plain-text files
// Test: read to memory
var stopWatch = Stopwatch.StartNew(); var stopWatch = Stopwatch.StartNew();
var memStream = new MemoryStream((int)hashedStream.Length);
CopyStream(readerStream, memStream);
readerStream.Close();
readerStream = memStream;
System.Diagnostics.Debug.WriteLine(String.Format("Copy input stream: {0}ms", stopWatch.ElapsedMilliseconds));
var isXml = memStream.ReadByte() == '<'; if (kdbFormat == KdbxFormat.ProtocolBuffers)
memStream.Seek(0, SeekOrigin.Begin);
if (isXml)
{ {
stopWatch.Restart();
ReadXmlStreamed(readerStream, hashedStream);
System.Diagnostics.Debug.WriteLine(String.Format("ReadXmlStreamed: {0}ms", stopWatch.ElapsedMilliseconds));
}
else
{
stopWatch.Restart();
KdbpFile.ReadDocument(m_pwDatabase, readerStream, m_pbProtectedStreamKey, m_pbHashOfHeader); KdbpFile.ReadDocument(m_pwDatabase, readerStream, m_pbProtectedStreamKey, m_pbHashOfHeader);
System.Diagnostics.Debug.WriteLine(String.Format("KdbpFile.ReadDocument: {0}ms", stopWatch.ElapsedMilliseconds)); System.Diagnostics.Debug.WriteLine(String.Format("KdbpFile.ReadDocument: {0}ms", stopWatch.ElapsedMilliseconds));
} }
else
{
ReadXmlStreamed(readerStream, hashedStream);
System.Diagnostics.Debug.WriteLine(String.Format("ReadXmlStreamed: {0}ms", stopWatch.ElapsedMilliseconds));
}
readerStream.Close(); readerStream.Close();
// GC.KeepAlive(br); // GC.KeepAlive(br);

View File

@ -101,7 +101,7 @@ namespace KeePassLib.Serialization
m_pbStreamStartBytes = cr.GetRandomBytes(32); m_pbStreamStartBytes = cr.GetRandomBytes(32);
Stream writerStream; Stream writerStream;
if(m_format == KdbxFormat.Default) if(m_format == KdbxFormat.Default || m_format == KdbxFormat.ProtocolBuffers)
{ {
WriteHeader(hashedStream); // Also flushes the stream WriteHeader(hashedStream); // Also flushes the stream
@ -122,17 +122,24 @@ namespace KeePassLib.Serialization
writerStream = hashedStream; writerStream = hashedStream;
else { Debug.Assert(false); throw new FormatException("KdbFormat"); } else { Debug.Assert(false); throw new FormatException("KdbFormat"); }
/* var stopWatch = Stopwatch.StartNew();
m_xmlWriter = new XmlTextWriter(writerStream, encNoBom);
WriteDocument(pgDataSource);
m_xmlWriter.Flush(); if (m_format == KdbxFormat.ProtocolBuffers)
m_xmlWriter.Close(); {
*/ KdbpFile.WriteDocument(m_pwDatabase, writerStream, m_pbProtectedStreamKey, m_pbHashOfHeader);
}
else
{
m_xmlWriter = new XmlTextWriter(writerStream, encNoBom);
WriteDocument(pgDataSource);
KdbpFile.WriteDocument(m_pwDatabase, writerStream, m_pbProtectedStreamKey, m_pbHashOfHeader); m_xmlWriter.Flush();
m_xmlWriter.Close();
}
writerStream.Close(); writerStream.Close();
System.Diagnostics.Debug.WriteLine(String.Format("{1}: {0}ms", stopWatch.ElapsedMilliseconds, m_format == KdbxFormat.ProtocolBuffers ? "KdbpFile.WriteDocument" : "Xml WriteDocument"));
} }
finally { CommonCleanUpWrite(sSaveTo, hashedStream); } finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
} }

View File

@ -52,7 +52,8 @@ namespace KeePassLib.Serialization
/// <summary> /// <summary>
/// Use this flag when exporting data to a plain-text XML file. /// Use this flag when exporting data to a plain-text XML file.
/// </summary> /// </summary>
PlainXml PlainXml,
ProtocolBuffers
} }
/// <summary> /// <summary>

View File

@ -1,18 +1,29 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using ProtoBuf;
using System.Drawing; using System.Drawing;
using KeePassLib.Collections;
using KeePassLib.Security;
using KeePassLib.Cryptography;
using System.IO; using System.IO;
using KeePassLib.Collections;
using KeePassLib.Cryptography;
using KeePassLib.Security;
using KeePassLib.Utility;
using ProtoBuf;
using ProtoBuf.Meta; using ProtoBuf.Meta;
namespace KeePassLib.Serialization namespace KeePassLib.Serialization
{ {
internal class KdbpFile internal class KdbpFile
{ {
public const string FileNameExtension = "kdbp";
/// <summary>
/// Determines whether the database pointed to by the specified ioc should be (de)serialised in default (xml) or protocol buffers format.
/// </summary>
public static KdbxFormat GetFormatToUse(IOConnectionInfo ioc)
{
// If the filename ends in .kdbp, use ProtocolBuffers format.
return UrlUtil.GetExtension(UrlUtil.GetFileName(ioc.Path)).Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default;
}
public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader) public static void WriteDocument(PwDatabase database, Stream stream, byte[] protectedStreamKey, byte[] hashOfHeader)
{ {
var context = new SerializationContext var context = new SerializationContext