/* * PhoneGap is available under *either* the terms of the modified BSD license *or* the * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. * * Copyright (c) 2005-2011, Nitobi Software Inc. * Copyright (c) 2011, Microsoft Corporation * Copyright (c) 2011, Sergey Grebnov. */ using System; using System.Collections.Generic; using System.IO; using System.IO.IsolatedStorage; using System.Runtime.Serialization; using System.Security; using System.Text; namespace WP7GapClassLib.PhoneGap.Commands { /// /// Provides access to isolated storage /// public class File : BaseCommand { // Error codes public const int NOT_FOUND_ERR = 1; public const int SECURITY_ERR = 2; public const int ABORT_ERR = 3; public const int NOT_READABLE_ERR = 4; public const int ENCODING_ERR = 5; public const int NO_MODIFICATION_ALLOWED_ERR = 6; public const int INVALID_STATE_ERR = 7; public const int SYNTAX_ERR = 8; public const int INVALID_MODIFICATION_ERR = 9; public const int QUOTA_EXCEEDED_ERR = 10; public const int TYPE_MISMATCH_ERR = 11; public const int PATH_EXISTS_ERR = 12; // File system options public const int TEMPORARY = 0; public const int PERSISTENT = 1; public const int RESOURCE = 2; public const int APPLICATION = 3; /// /// Temporary directory name /// private readonly string TMP_DIRECTORY_NAME = "tmp"; /// /// Represents error code for callback /// [DataContract] public class ErrorCode { /// /// Error code /// [DataMember(IsRequired = true, Name = "code")] public int Code { get; set; } /// /// Creates ErrorCode object /// public ErrorCode(int code) { this.Code = code; } } /// /// Represents File action options. /// [DataContract] public class FileOptions { /// /// File path /// [DataMember(Name = "fileName")] public string FilePath { get; set; } /// /// Full entryPath /// [DataMember(Name = "fullPath")] public string FullPath { get; set; } /// /// Directory name /// [DataMember(Name = "dirName")] public string DirectoryName { get; set; } /// /// Path to create file/directory /// [DataMember(Name = "path")] public string Path { get; set; } /// /// The encoding to use to encode the file's content. Default is UTF8. /// [DataMember(Name = "encoding")] public string Encoding { get; set; } /// /// Uri to get file /// [DataMember(Name = "uri")] public string Uri { get; set; } /// /// Size to truncate file /// [DataMember(Name = "size")] public long Size { get; set; } /// /// Data to write in file /// [DataMember(Name = "data")] public string Data { get; set; } /// /// Position the writing starts with /// [DataMember(Name = "position")] public int Position { get; set; } /// /// Type of file system requested /// [DataMember(Name = "type")] public int FileSystemType { get; set; } /// /// New file/directory name /// [DataMember(Name = "newName")] public string NewName { get; set; } /// /// Destination directory to copy/move file/directory /// [DataMember(Name = "parent")] public FileEntry Parent { get; set; } /// /// Options for getFile/getDirectory methods /// [DataMember(Name = "options")] public CreatingOptions CreatingOpt { get; set; } /// /// Creates options object with default parameters /// public FileOptions() { this.SetDefaultValues(new StreamingContext()); } /// /// Initializes default values for class fields. /// Implemented in separate method because default constructor is not invoked during deserialization. /// /// [OnDeserializing()] public void SetDefaultValues(StreamingContext context) { this.Encoding = "UTF-8"; this.FilePath = ""; this.FileSystemType = -1; } } /// /// Stores image info /// [DataContract] public class FileMetadata { [DataMember(Name = "fileName")] public string FileName { get; set; } [DataMember(Name = "fullPath")] public string FullPath { get; set; } [DataMember(Name = "type")] public string Type { get; set; } [DataMember(Name = "lastModifiedDate")] public string LastModifiedDate { get; set; } [DataMember(Name = "size")] public long Size { get; set; } public FileMetadata(string filePath) { using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if ((string.IsNullOrEmpty(filePath)) || (!isoFile.FileExists(filePath))) { throw new FileNotFoundException("File doesn't exist"); } //TODO get file size the other way if possible using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile)) { this.Size = stream.Length; } this.FullPath = filePath; this.FileName = System.IO.Path.GetFileName(filePath); this.Type = MimeTypeMapper.GetMimeType(filePath); this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString(); } } } /// /// Represents file or directory modification metadata /// [DataContract] public class ModificationMetadata { /// /// Modification time /// [DataMember] public string modificationTime { get; set; } } /// /// Represents file or directory entry /// [DataContract] public class FileEntry { /// /// File type /// [DataMember(Name = "isFile")] public bool IsFile { get; set; } /// /// Directory type /// [DataMember(Name = "isDirectory")] public bool IsDirectory { get; set; } /// /// File/directory name /// [DataMember(Name = "name")] public string Name { get; set; } /// /// Full path to file/directory /// [DataMember(Name = "fullPath")] public string FullPath { get; set; } public static FileEntry GetEntry(string filePath) { try { FileEntry entry = new FileEntry(filePath); return entry; } catch (Exception) { return null; } } /// /// Creates object and sets necessary properties /// /// private FileEntry(string filePath) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentException(); } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { this.IsFile = isoFile.FileExists(filePath); this.IsDirectory = isoFile.DirectoryExists(filePath); if (IsFile) { this.Name = Path.GetFileName(filePath); } else if (IsDirectory) { this.Name = this.GetDirectoryName(filePath); if (string.IsNullOrEmpty(Name)) { this.Name = "/"; } } else { throw new FileNotFoundException(); } this.FullPath = new Uri(filePath).LocalPath; } } /// /// Extracts directory name from path string /// Path should refer to a directory, for example \foo\ or /foo. /// /// /// private string GetDirectoryName(string path) { if (String.IsNullOrEmpty(path)) { return path; } string[] split = path.Split(new char[] {'/', '\\'}, StringSplitOptions.RemoveEmptyEntries); if (split.Length < 1) { return null; } else { return split[split.Length-1]; } } } /// /// Represents info about requested file system /// [DataContract] public class FileSystemInfo { /// /// file system type /// [DataMember(Name = "name", IsRequired = true)] public string Name { get; set; } /// /// Root directory entry /// [DataMember(Name = "root", EmitDefaultValue = false)] public FileEntry Root { get; set; } /// /// Creates class instance /// /// /// Root directory public FileSystemInfo(string name, FileEntry rootEntry = null) { Name = name; Root = rootEntry; } } [DataContract] public class CreatingOptions { /// /// Create file/directory if is doesn't exist /// [DataMember(Name = "create")] public bool Create { get; set; } /// /// Generate an exception if create=true and file/directory already exists /// [DataMember(Name = "exclusive")] public bool Exclusive { get; set; } } /// /// File options /// private FileOptions fileOptions; /// /// Gets amount of free space available for Isolated Storage /// /// No options is needed for this method public void getFreeDiskSpace(string options) { try { using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace)); } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } } /// /// Check if file exists /// /// File path public void testFileExists(string options) { IsDirectoryOrFileExist(options, false); } /// /// Check if directory exists /// /// directory name public void testDirectoryExists(string options) { IsDirectoryOrFileExist(options, true); } /// /// Check if file or directory exist /// /// File path/Directory name /// Flag to recognize what we should check public void IsDirectoryOrFileExist(string options, bool isDirectory) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { bool isExist; if (isDirectory) { isExist = isoFile.DirectoryExists(fileOptions.DirectoryName); } else { isExist = isoFile.FileExists(fileOptions.FilePath); } DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist)); } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } public void readAsDataURL(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } string base64URL = null; using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if (!isoFile.FileExists(fileOptions.FilePath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } string mimeType = MimeTypeMapper.GetMimeType(fileOptions.FilePath); using (IsolatedStorageFileStream stream = isoFile.OpenFile(fileOptions.FilePath, FileMode.Open, FileAccess.Read)) { string base64String = GetFileContent(stream); base64URL = "data:" + mimeType + ";base64," + base64String; } } DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL)); } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } } public void readAsText(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } string text; using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if (!isoFile.FileExists(fileOptions.FilePath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } Encoding encoding = Encoding.GetEncoding(fileOptions.Encoding); using (TextReader reader = new StreamReader(isoFile.OpenFile(fileOptions.FilePath, FileMode.Open, FileAccess.Read), encoding)) { text = reader.ReadToEnd(); } } DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text)); } catch (ArgumentException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(ENCODING_ERR))); } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } } public void truncate(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } long streamLength = 0; using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if (!isoFile.FileExists(fileOptions.FilePath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } using (FileStream stream = new IsolatedStorageFileStream(fileOptions.FilePath, FileMode.Open, FileAccess.ReadWrite, isoFile)) { if (0 <= fileOptions.Size && fileOptions.Size < stream.Length) { stream.SetLength(fileOptions.Size); } streamLength = stream.Length; } } DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength)); } catch (ArgumentException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(ENCODING_ERR))); } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } } public void write(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if (string.IsNullOrEmpty(fileOptions.Data)) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { // create the file if not exists if (!isoFile.FileExists(fileOptions.FilePath)) { var file = isoFile.CreateFile(fileOptions.FilePath); file.Close(); } using (FileStream stream = new IsolatedStorageFileStream(fileOptions.FilePath, FileMode.Open, FileAccess.ReadWrite, isoFile)) { if (0 <= fileOptions.Position && fileOptions.Position < stream.Length) { stream.SetLength(fileOptions.Position); } using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Seek(0, SeekOrigin.End); writer.Write(fileOptions.Data.ToCharArray()); } } } DispatchCommandResult(new PluginResult(PluginResult.Status.OK, fileOptions.Data.Length)); } catch (ArgumentException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(ENCODING_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(INVALID_MODIFICATION_ERR))); } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } } /// /// Look up metadata about this entry. /// /// filePath to entry public void getMetadata(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if (isoFile.FileExists(fileOptions.FullPath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() {modificationTime = isoFile.GetLastWriteTime(fileOptions.FullPath).DateTime.ToString()}, "window.localFileSystem._castDate")); } else if (isoFile.DirectoryExists(fileOptions.FullPath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(fileOptions.FullPath).DateTime.ToString() }, "window.localFileSystem._castDate")); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } } /// /// Returns a File that represents the current state of the file that this FileEntry represents. /// /// filePath to entry /// public void getFileMetadata(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } FileMetadata metaData = new FileMetadata(fileOptions.FullPath); DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData, "window.localFileSystem._castDate")); } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } catch (FileNotFoundException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } /// /// Look up the parent DirectoryEntry containing this Entry. /// If this Entry is the root of IsolatedStorage, its parent is itself. /// /// public void getParent(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if (string.IsNullOrEmpty(fileOptions.FullPath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { FileEntry entry; if (isoFile.FileExists(fileOptions.FullPath) || isoFile.DirectoryExists(fileOptions.FullPath)) { string path = this.GetParentDirectory(fileOptions.FullPath); entry = FileEntry.GetEntry(path); DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry, "window.localFileSystem._castEntry")); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_READABLE_ERR))); } } public void remove(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if (isoFile.FileExists(fileOptions.FullPath)) { isoFile.DeleteFile(fileOptions.FullPath); } else { if (isoFile.DirectoryExists(fileOptions.FullPath)) { isoFile.DeleteDirectory(fileOptions.FullPath); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } } DispatchCommandResult(new PluginResult(PluginResult.Status.OK)); } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(INVALID_MODIFICATION_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } public void removeRecursively(string options) { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if (string.IsNullOrEmpty(fileOptions.FullPath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } removeDirRecursively(fileOptions.FullPath); DispatchCommandResult(new PluginResult(PluginResult.Status.OK)); } public void readEntries(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if (string.IsNullOrEmpty(fileOptions.FullPath)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if (isoFile.DirectoryExists(fileOptions.FullPath)) { string path = File.AddSlashToDirectory(fileOptions.FullPath); List entries = new List(); string[] files = isoFile.GetFileNames(path + "*"); string[] dirs = isoFile.GetDirectoryNames(path + "*"); foreach (string file in files) { entries.Add(FileEntry.GetEntry(path + file)); } foreach (string dir in dirs) { entries.Add(FileEntry.GetEntry(path + dir + "/")); } DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries, "window.localFileSystem._castEntries")); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } public void requestFileSystem(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if (fileOptions.Size != 0) { using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { long availableSize = isoFile.AvailableFreeSpace; if (fileOptions.Size > availableSize) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(QUOTA_EXCEEDED_ERR))); return; } } } if (fileOptions.FileSystemType == PERSISTENT) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/")), "window.localFileSystem._castFS")); } else if (fileOptions.FileSystemType == TEMPORARY) { using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication()) { if (!isoStorage.FileExists(TMP_DIRECTORY_NAME)) { isoStorage.CreateDirectory(TMP_DIRECTORY_NAME); } } string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/"; DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder)), "window.localFileSystem._castFS")); } else if (fileOptions.FileSystemType == RESOURCE) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource"), "window.localFileSystem._castFS")); } else if (fileOptions.FileSystemType == APPLICATION) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application"), "window.localFileSystem._castFS")); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (FileNotFoundException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } public void resolveLocalFileSystemURI(string options) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if (!Uri.IsWellFormedUriString(fileOptions.Uri, UriKind.RelativeOrAbsolute)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(ENCODING_ERR))); return; } string path = (new Uri(Uri.UnescapeDataString(fileOptions.Uri))).LocalPath; FileEntry uriEntry = FileEntry.GetEntry(path); if (uriEntry != null) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry, "window.localFileSystem._castEntry")); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } public void copyTo(string options) { TransferTo(options, false); } public void moveTo(string options) { TransferTo(options, true); } public void getFile(string options) { GetFileOrDirectory(options, false); } public void getDirectory(string options) { GetFileOrDirectory(options, true); } #region internal functionality /// /// Retrieves the parent directory name of the specified path, /// /// Path /// Parent directory name private string GetParentDirectory(string path) { if (String.IsNullOrEmpty(path) || path == "/") { return "/"; } if (path.EndsWith(@"/") || path.EndsWith(@"\")) { return this.GetParentDirectory(Path.GetDirectoryName(path)); } return Path.GetDirectoryName(path); } private void removeDirRecursively(string fullPath) { try { using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { if (isoFile.DirectoryExists(fullPath)) { string path = File.AddSlashToDirectory(fullPath); string[] files = isoFile.GetFileNames(path + "*"); if (files.Length > 0) { foreach (string file in files) { isoFile.DeleteFile(path + file); } } string[] dirs = isoFile.GetDirectoryNames(path + "*"); if (dirs.Length > 0) { foreach (string dir in dirs) { removeDirRecursively(path + dir + "/"); } } isoFile.DeleteDirectory(Path.GetDirectoryName(path)); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } private void TransferTo(string options, bool move) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if ((fileOptions.Parent == null) || (string.IsNullOrEmpty(fileOptions.Parent.FullPath)) || (string.IsNullOrEmpty(fileOptions.FullPath))) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } string parentPath = File.AddSlashToDirectory(fileOptions.Parent.FullPath); string currentPath = fileOptions.FullPath; using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { bool isFileExist = isoFile.FileExists(currentPath); bool isDirectoryExist = isoFile.DirectoryExists(currentPath); bool isParentExist = isoFile.DirectoryExists(parentPath); if (((!isFileExist) && (!isDirectoryExist)) || (!isParentExist)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } string newName; string newPath; if (isFileExist) { newName = (string.IsNullOrEmpty(fileOptions.NewName)) ? Path.GetFileName(currentPath) : fileOptions.NewName; newPath = Path.Combine(parentPath, newName); // remove destination file if exists, in other case there will be exception if (!newPath.Equals(currentPath) && isoFile.FileExists(newPath)) { isoFile.DeleteFile(newPath); } if (move) { isoFile.MoveFile(currentPath, newPath); } else { isoFile.CopyFile(currentPath, newPath, true); } } else { newName = (string.IsNullOrEmpty(fileOptions.NewName)) ? currentPath : fileOptions.NewName; newPath = Path.Combine(parentPath, newName); if (move) { // remove destination directory if exists, in other case there will be exception // target directory should be empty if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath)) { isoFile.DeleteDirectory(newPath); } isoFile.MoveDirectory(currentPath, newPath); } else { this.CopyDirectory(currentPath, newPath, isoFile); } } FileEntry entry = FileEntry.GetEntry(newPath); if (entry != null) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry, "window.localFileSystem._castEntry")); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (FileNotFoundException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } catch (ArgumentException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(ENCODING_ERR))); } catch (IsolatedStorageException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(INVALID_MODIFICATION_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile) { string path = File.AddSlashToDirectory(sourceDir); if (!isoFile.DirectoryExists(destDir)) { isoFile.CreateDirectory(destDir); } destDir = File.AddSlashToDirectory(destDir); string[] files = isoFile.GetFileNames(path + "*"); if (files.Length > 0) { foreach (string file in files) { isoFile.CopyFile(path + file, destDir + file); } } string[] dirs = isoFile.GetDirectoryNames(path + "*"); if (dirs.Length > 0) { foreach (string dir in dirs) { CopyDirectory(path + dir, destDir + dir, isoFile); } } } private void GetFileOrDirectory(string options, bool getDirectory) { try { try { fileOptions = JSON.JsonHelper.Deserialize(options); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION)); return; } if ((string.IsNullOrEmpty(fileOptions.Path)) || (string.IsNullOrEmpty(fileOptions.FullPath))) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } string path; try { path = Path.Combine(fileOptions.FullPath, fileOptions.Path); } catch (Exception ex) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(ENCODING_ERR))); return; } using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication()) { bool isFile = isoFile.FileExists(path); bool isDirectory = isoFile.DirectoryExists(path); bool create = (fileOptions.CreatingOpt == null) ? false : fileOptions.CreatingOpt.Create; bool exclusive = (fileOptions.CreatingOpt == null) ? false : fileOptions.CreatingOpt.Exclusive; if (create) { if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path))) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(PATH_EXISTS_ERR))); return; } if ((getDirectory) && (!isDirectory)) { isoFile.CreateDirectory(path); } else { if ((!getDirectory) && (!isFile)) { IsolatedStorageFileStream fileStream = isoFile.CreateFile(path); fileStream.Close(); } } } else { if ((!isFile) && (!isDirectory)) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); return; } if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile))) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(TYPE_MISMATCH_ERR))); return; } } FileEntry entry = FileEntry.GetEntry(path); if (entry != null) { DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry, "window.localFileSystem._castEntry")); } else { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } } } catch (SecurityException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(SECURITY_ERR))); } catch (FileNotFoundException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NOT_FOUND_ERR))); } catch (DirectoryNotFoundException e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(PATH_EXISTS_ERR))); } catch (Exception e) { DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, new ErrorCode(NO_MODIFICATION_ALLOWED_ERR))); } } private static string AddSlashToDirectory(string dirPath) { if (dirPath.EndsWith("/")) { return dirPath; } else { return dirPath + "/"; } } /// /// Returns file content in a form of base64 string /// /// File stream /// Base64 representation of the file private string GetFileContent(Stream stream) { int streamLength = (int)stream.Length; byte[] fileData = new byte[streamLength + 1]; stream.Read(fileData, 0, streamLength); stream.Close(); return Convert.ToBase64String(fileData); } #endregion } }