// Copyright Keysight Technologies 2012-2019
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, you can obtain one at http://mozilla.org/MPL/2.0/.
using System;
using System.Collections.Generic;
namespace OpenTap
{
///
/// Identifies a string as a file path.
///
public class FilePathAttribute : FileDependencyAttribute, IAnnotation
{
///
/// Default file extension for this file path.
///
public string FileExtension { get; private set; }
///
/// Boolean setting. When true, raises a prompt for permission to overwrite the file if it already exists.
/// If false, no prompt is raised and the file is overwritten.
///
public bool OverwritePrompt { get; private set; }
///
/// The behavior of the file path dialog associated with this file path.
///
public BehaviorChoice Behavior { get; private set; }
public string Filter { get; private set; }
public int Mode { get; private set; }
/// Constructor for the FilePathAttribute.
/// Provided for backward compatibility.
public FilePathAttribute()
{
Behavior = BehaviorChoice.Open;
FileExtension = "";
}
class InvalidFilterSpecification : FormatException
{
string filter;
public InvalidFilterSpecification(string filter)
{
this.filter = filter;
}
public override string Message => $"Invalid file filter specification: '{filter}'";
}
static readonly HashSet invalidchars = System.IO.Path.GetInvalidFileNameChars().ToHashSet();
void validateFileFilter(string str)
{
if (string.IsNullOrEmpty(str)) return;
if (str.Contains("*.") == false) return;
var s = str.Split('|');
if (s.Length % 2 == 1) throw new InvalidFilterSpecification(str);
for(int i = 0; i < s.Length; i += 2)
{
var value = s[i + 1];
if (value.Contains("*.") == false)
throw new InvalidFilterSpecification($"'{value}' must start with '*'.");
if(value.Contains(","))
throw new InvalidFilterSpecification($"'{value}' must not contain ','. Use ';' to separate values.");
var filters = value.Split(';');
foreach(var filter in filters)
{
var filter2 = filter.Trim();
if(filter2.StartsWith("*.") == false)
throw new InvalidFilterSpecification(str);
filter2 = filter2.Substring(2);
if (filter2 == "*")
continue;
foreach(var chr in filter2)
{
if(invalidchars.Contains(chr))
throw new InvalidFilterSpecification($"'{str}': '{filter}' must not contain '{chr}'.");
}
}
}
}
/// Constructor that takes BehaviourChoice and fileExtension parameters for the FilePathAttribute.
///
/// File extension or filter. Simple file extensions can be used like this: txt, csv, .... Or a filter extression can be used, for example "Text Document (*.txt) | *.txt. See examples for more info."
public FilePathAttribute(BehaviorChoice behavior = BehaviorChoice.Open,
string fileExtension = "", int mode = 0)
// note default value cannot be null when using VS2010. see http://stackoverflow.com/questions/15048847/attribute-argument-must-be-a-constant-expression
{
Behavior = behavior;
FileExtension = fileExtension;
Mode = mode;
validateFileFilter(FileExtension);
}
///
/// Describes how the file should be used on access.
///
public enum BehaviorChoice
{
///
/// Opens the file.
///
Open,
///
/// Saves the file. Provides a warning if file already exists.
///
Save
};
}
}