#region Disclaimer / License
// Copyright (C) 2011, Kenneth Skovhede
// http://www.hexad.dk, opensource@hexad.dk
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Duplicati.Library.Main
{
///
/// This class is responsible for naming remote files,
/// and parsing remote filenames
///
internal class FilenameStrategy
{
//In Duplicati 1.0 there is only one manifest file, and it is called manifest or M in short mode
//Issue# 58 introduced a backup manifest. Since 1.0 does not verify the manifest version number,
// the name manifest/M is not used, which prevents 1.0 clients from reading the manifests and volumes.
//The new names are manifestA and manifestB (A/B in short mode).
//Future versions of Duplicati always verify the version number to avoid reading/writing data to a format
// that is not supported.
//
//These are the strings that are used:
private const string MANIFEST_OLD = "manifest";
private const string MANIFEST_A = "manifestA";
private const string MANIFEST_B = "manifestB";
private const string MANIFEST_OLD_SHORT = "M";
private const string MANIFEST_A_SHORT = "A";
private const string MANIFEST_B_SHORT = "B";
private const string CONTENT = "content";
private const string SIGNATURE = "signature";
private const string FULL = "full";
private const string INCREMENTAL = "inc";
private const string CONTENT_SHORT = "C";
private const string SIGNATURE_SHORT = "S";
private const string FULL_SHORT = "F";
private const string INCREMENTAL_SHORT = "I";
private const string VOLUME = "vol";
private const string DELETE_TRANSACTION_FILENAME = "delete.transaction";
//Note: Actually the K should be Z which is more correct as it is forced to be Z, but Z as a format specifier is fairly undocumented
private const string TIMESTAMP_FORMAT = "yyyyMMdd'T'HHmmssK";
private bool m_useOldFilenames;
private bool m_useShortFilenames;
private string m_timeSeparator;
private string m_prefix;
private readonly Regex m_oldFilenameRegExp;
private readonly Regex m_filenameRegExp;
private readonly Regex m_shortRegExp;
private readonly Regex m_verificationRegExp;
private readonly Regex m_deleteTransactionRegExp;
///
/// A cache used to ensure that filenames are consistent,
/// even if the timezone changes in between filename generation
///
private Dictionary m_timeStringCache;
public FilenameStrategy(string prefix)
: this(prefix, null, false, false)
{
}
public FilenameStrategy(string prefix, string timeSeparator, bool useShortNames, bool oldFilenames)
{
m_prefix = prefix;
m_timeSeparator = timeSeparator;
m_useShortFilenames = useShortNames;
m_useOldFilenames = oldFilenames;
m_shortRegExp = new Regex(
string.Format(@"(?{0})\-(?({1}|{2}|{3}|{4}|{5}))(?({6}|{7}))(?