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

View File

@ -82,7 +82,7 @@ namespace KeePassLib.Serialization
BinaryReaderEx brDecrypted = null;
Stream readerStream = null;
if(kdbFormat == KdbxFormat.Default)
if(kdbFormat == KdbxFormat.Default || kdbFormat == KdbxFormat.ProtocolBuffers)
{
br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted);
ReadHeader(br);
@ -127,34 +127,21 @@ namespace KeePassLib.Serialization
}
else m_randomStream = null; // No random stream for plain-text files
// Test: read to memory
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() == '<';
memStream.Seek(0, SeekOrigin.Begin);
if (isXml)
if (kdbFormat == KdbxFormat.ProtocolBuffers)
{
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);
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();
// GC.KeepAlive(br);

View File

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

View File

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

View File

@ -1,18 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
using ProtoBuf;
using System.Drawing;
using KeePassLib.Collections;
using KeePassLib.Security;
using KeePassLib.Cryptography;
using System.IO;
using KeePassLib.Collections;
using KeePassLib.Cryptography;
using KeePassLib.Security;
using KeePassLib.Utility;
using ProtoBuf;
using ProtoBuf.Meta;
namespace KeePassLib.Serialization
{
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)
{
var context = new SerializationContext