using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
#if (CORE || NETFX)
using System.Diagnostics;
#endif
#if NET45
using System.Threading.Tasks;
using System.Collections;
#endif
namespace FluentFTP {
///
/// Extension methods related to FTP tasks
///
public static class FtpExtensions {
///
/// Converts the specified path into a valid FTP file system path
///
/// The file system path
/// A path formatted for FTP
public static string GetFtpPath(this string path) {
if (String.IsNullOrEmpty(path))
return "./";
path = path.Replace('\\', '/');
path = Regex.Replace(path, "[/]+", "/");
path = path.TrimEnd('/');
if (path.Length == 0)
path = "/";
return path;
}
///
/// Creates a valid FTP path by appending the specified segments to this string
///
/// This string
/// The path segments to append
/// A valid FTP path
public static string GetFtpPath(this string path, params string[] segments) {
if (String.IsNullOrEmpty(path))
path = "./";
foreach (string part in segments) {
if (part != null) {
if (path.Length > 0 && !path.EndsWith("/"))
path += "/";
path += Regex.Replace(part.Replace('\\', '/'), "[/]+", "/").TrimEnd('/');
}
}
path = Regex.Replace(path.Replace('\\', '/'), "[/]+", "/").TrimEnd('/');
if (path.Length == 0)
path = "/";
/*if (!path.StartsWith("/") || !path.StartsWith("./"))
path = "./" + path;*/
return path;
}
///
/// Gets the parent directory path (formatted for a FTP server)
///
/// The path
/// The parent directory path
public static string GetFtpDirectoryName(this string path) {
string tpath = (path == null ? "" : path.GetFtpPath());
if (tpath.Length == 0 || tpath == "/")
return "/";
int lastslash = tpath.LastIndexOf('/');
if (lastslash < 0)
return ".";
if (lastslash == 0)
return "/";
return tpath.Substring(0, lastslash);
}
/*public static string GetFtpDirectoryName(this string path) {
if (path == null || path.Length == 0 || path.GetFtpPath() == "/")
return "/";
return System.IO.Path.GetDirectoryName(path).GetFtpPath();
}*/
///
/// Gets the file name and extension from the path
///
/// The full path to the file
/// The file name
public static string GetFtpFileName(this string path) {
string tpath = (path == null ? null : path);
int lastslash = -1;
if (tpath == null)
return null;
lastslash = tpath.LastIndexOf('/');
if (lastslash < 0)
return tpath;
lastslash += 1;
if (lastslash >= tpath.Length)
return tpath;
return tpath.Substring(lastslash, tpath.Length - lastslash);
}
/*public static string GetFtpFileName(this string path) {
return System.IO.Path.GetFileName(path).GetFtpPath();
}*/
private static string[] FtpDateFormats = { "yyyyMMddHHmmss", "yyyyMMddHHmmss'.'f", "yyyyMMddHHmmss'.'ff", "yyyyMMddHHmmss'.'fff", "MMM dd yyyy","MMM d yyyy","MMM dd HH:mm","MMM d HH:mm" };
///
/// Tries to convert the string FTP date representation into a object
///
/// The date
/// UTC/Local Time
/// A object representing the date, or if there was a problem
public static DateTime GetFtpDate(this string date, DateTimeStyles style) {
DateTime parsed;
if (DateTime.TryParseExact(date, FtpDateFormats, CultureInfo.InvariantCulture, style, out parsed)) {
return parsed;
}
return DateTime.MinValue;
}
private static string[] sizePostfix = { "bytes", "KB", "MB", "GB", "TB" };
///
/// Converts a file size in bytes to a string representation (eg. 12345 becomes 12.3 KB)
///
public static string FileSizeToString(this int bytes) {
return ((long)bytes).FileSizeToString();
}
///
/// Converts a file size in bytes to a string representation (eg. 12345 becomes 12.3 KB)
///
public static string FileSizeToString(this uint bytes) {
return ((long)bytes).FileSizeToString();
}
///
/// Converts a file size in bytes to a string representation (eg. 12345 becomes 12.3 KB)
///
public static string FileSizeToString(this ulong bytes) {
return ((long)bytes).FileSizeToString();
}
///
/// Converts a file size in bytes to a string representation (eg. 12345 becomes 12.3 KB)
///
public static string FileSizeToString(this long bytes) {
int order = 0;
double len = bytes;
while (len >= 1024 && order < sizePostfix.Length - 1) {
order++;
len = len / 1024;
}
return String.Format("{0:0.#} {1}", len, sizePostfix[order]);
}
#if NET45
///
/// This creates a that represents a pair of begin and end methods
/// that conform to the Asynchronous Programming Model pattern. This extends the maximum amount of arguments from
/// to 4 from a 3.
///
/// The type of the first argument passed to the delegate
/// The type of the second argument passed to the delegate
/// The type of the third argument passed to the delegate
/// The type of the forth argument passed to the delegate
/// The type of the result.
/// The used
/// The delegate that begins the asynchronous operation
/// The delegate that ends the asynchronous operation
/// The first argument passed to the delegate
/// The second argument passed to the delegate
/// The third argument passed to the delegate
/// The forth argument passed to the delegate
/// An object containing data to be used by the delegate
/// The created that represents the asynchronous operation
///
/// beginMethod is null
/// or
/// endMethod is null
///
public static Task FromAsync(this TaskFactory factory,
Func beginMethod,
Func endMethod,
TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, object state) {
if (beginMethod == null)
throw new ArgumentNullException("beginMethod");
if (endMethod == null)
throw new ArgumentNullException("endMethod");
TaskCompletionSource tcs = new TaskCompletionSource(state, factory.CreationOptions);
try {
AsyncCallback callback = delegate(IAsyncResult asyncResult) {
tcs.TrySetResult(endMethod(asyncResult));
};
beginMethod(arg1, arg2, arg3, arg4, callback, state);
}
catch {
tcs.TrySetResult(default(TResult));
throw;
}
return tcs.Task;
}
#endif
///
/// Validates that the FtpError flags set are not in an invalid combination.
///
/// The error handling options set
/// True if a valid combination, otherwise false
public static bool IsValidCombination(this FtpError options) {
return options != (FtpError.Stop | FtpError.Throw) &&
options != (FtpError.Throw | FtpError.Stop | FtpError.DeleteProcessed);
}
///
/// Checks if every character in the string is whitespace, or the string is null.
///
public static bool IsNullOrWhiteSpace(string value) {
if (value == null) return true;
for (int i = 0; i < value.Length; i++) {
if (!Char.IsWhiteSpace(value[i])) return false;
}
return true;
}
///
/// Checks if the string is null or 0 length.
///
public static bool IsBlank(this string value) {
return value == null || value.Length == 0;
}
#if NET45
///
/// Checks if the array is null or 0 length.
///
public static bool IsBlank(this IList value) {
return value == null || value.Count == 0;
}
///
/// Checks if the array is null or 0 length.
///
public static bool IsBlank(this IEnumerable value) {
if (value == null){
return true;
}
if (value is IList){
return ((IList)value).Count == 0;
}
if (value is byte[]){
return ((byte[])value).Length == 0;
}
return false;
}
#endif
///
/// Join the given strings by a delimiter.
///
public static string Join(this string[] values, string delimiter) {
return string.Join(delimiter, values);
}
///
/// Join the given strings by a delimiter.
///
public static string Join(this List values, string delimiter) {
#if NET20 || NET35
return string.Join(delimiter, values.ToArray());
#else
return string.Join(delimiter, values);
#endif
}
///
/// Adds a prefix to the given strings, returns a new array.
///
public static string[] AddPrefix(this string[] values, string prefix, bool trim = false) {
List results = new List();
foreach (string v in values) {
string txt = prefix + (trim ? v.Trim() : v);
results.Add(txt);
}
return results.ToArray();
}
///
/// Adds a prefix to the given strings, returns a new array.
///
public static List AddPrefix(this List values, string prefix, bool trim = false) {
List results = new List();
foreach (string v in values) {
string txt = prefix + (trim ? v.Trim() : v);
results.Add(txt);
}
return results;
}
///
/// Adds a prefix to the given strings, returns a new array.
///
public static List ItemsToString(this object[] args) {
List results = new List();
if (args == null) {
return results;
}
foreach (object v in args) {
string txt;
if (v == null){
txt = "null";
} else if (v is string) {
txt = ("\"" + v as string + "\"");
} else {
txt = v.ToString();
}
results.Add(txt);
}
return results;
}
#if NET20 || NET35
public static bool HasFlag(this FtpHashAlgorithm flags, FtpHashAlgorithm flag) {
return (flags & flag) == flag;
}
public static bool HasFlag(this FtpCapability flags, FtpCapability flag) {
return (flags & flag) == flag;
}
public static bool HasFlag(this FtpVerify flags, FtpVerify flag) {
return (flags & flag) == flag;
}
public static bool HasFlag(this FtpError flags, FtpError flag) {
return (flags & flag) == flag;
}
public static void Restart(this Stopwatch watch) {
watch.Stop();
watch.Start();
}
#endif
}
}