From 162dbe56c9cf1d90efddf2b201c1d1aa03a54ae8 Mon Sep 17 00:00:00 2001 From: atanasovg Date: Tue, 29 Apr 2014 11:52:45 +0300 Subject: [PATCH] Added merge_module function. Added text module (currently having encoding only). Updated the FileSystem File object with readText, writeText methods (removed the FileReader, FileWriter classes). --- Application/application.android.ts | 5 +- Application/application.ios.ts | 6 +- BCL.csproj | 9 ++ FileSystem/file_system.d.ts | 74 ++++++------- FileSystem/file_system.ts | 130 ++++++++++------------- FileSystem/file_system_access.android.ts | 36 ++++--- FileSystem/file_system_access.d.ts | 6 +- FileSystem/file_system_access.ios.ts | 19 +++- Utils/module_merge.ts | 7 ++ http/http.ts | 2 +- text/index.ts | 2 + text/text.android.ts | 8 ++ text/text.d.ts | 11 ++ text/text.ios.ts | 8 ++ 14 files changed, 189 insertions(+), 134 deletions(-) create mode 100644 Utils/module_merge.ts create mode 100644 text/index.ts create mode 100644 text/text.android.ts create mode 100644 text/text.d.ts create mode 100644 text/text.ios.ts diff --git a/Application/application.android.ts b/Application/application.android.ts index 0b94554b7..aa23f6c7a 100644 --- a/Application/application.android.ts +++ b/Application/application.android.ts @@ -1,11 +1,10 @@ import app_common_module = require("Application/application_common"); -var currentApp = app_common_module.Application.current; // merge the exports of the application_common file with the exports of this file declare var exports; -exports.TargetOS = app_common_module.TargetOS; -exports.Application = app_common_module.Application; +require("Utils/module_merge").merge(app_common_module, exports); +var currentApp = app_common_module.Application.current; var callbacks = android.app.Application.ActivityLifecycleCallbacks; var initEvents = function () { diff --git a/Application/application.ios.ts b/Application/application.ios.ts index 5fc521eff..6bf3dc484 100644 --- a/Application/application.ios.ts +++ b/Application/application.ios.ts @@ -21,12 +21,12 @@ log("JavaScript loading ended."); */ import app_common_module = require("Application/application_common"); -var currentApp = app_common_module.Application.current; // merge the exports of the application_common file with the exports of this file declare var exports; -exports.TargetOS = app_common_module.TargetOS; -exports.Application = app_common_module.Application; +require("Utils/module_merge").merge(app_common_module, exports); + +var currentApp = app_common_module.Application.current; // TODO: Declarations export var init = function (nativeApp: any) { diff --git a/BCL.csproj b/BCL.csproj index a7d8f6673..e12b2fcbc 100644 --- a/BCL.csproj +++ b/BCL.csproj @@ -119,6 +119,14 @@ location.d.ts + + + text.d.ts + + + + text.d.ts + user_preferences.d.ts @@ -126,6 +134,7 @@ user_preferences.d.ts + diff --git a/FileSystem/file_system.d.ts b/FileSystem/file_system.d.ts index 886105e0b..f9ec4a1c2 100644 --- a/FileSystem/file_system.d.ts +++ b/FileSystem/file_system.d.ts @@ -52,14 +52,14 @@ export declare class File extends FileSystemEntity { public static fromPath(path: string, onError?: (error: any) => any): File; /** - * Creates a FileReader object over this file and locks the file until the reader is released. + * Reads the content of the file as a string using the specified encoding (defaults to UTF-8). */ - public openRead(): FileReader; + public readText(onSuccess: (content: string) => any, onError?: (error: any) => any, encoding?: string); /** - * Creates a FileWriter object over this file and locks the file until the writer is released. + * Writes the provided string to the file, using the specified encoding (defaults to UTF-8). */ - public openWrite(): FileWriter; + public writeText(content: string, onSuccess?: () => any, onError?: (error: any) => any, encoding?: string); } export declare class Folder extends FileSystemEntity { @@ -110,7 +110,7 @@ export declare class Folder extends FileSystemEntity { If the callback returns false this will mean for the iteration to stop. */ public eachEntity(onEntity: (entity: FileSystemEntity) => boolean, onError?: (error: any) => any); - } +} /** * Provides access to the top-level Folders instances that are accessible from the application. Use these as entry points to access the FileSystem. @@ -127,39 +127,39 @@ export declare module knownFolders { export function temp(): Folder; } -/** - * Base class for FileReader and FileWriter APIs. - */ -export declare class FileAccess { - constructor(file: File); +///** +// * Base class for FileReader and FileWriter APIs. +// */ +//export declare class FileAccess { +// constructor(file: File); - /** - * Unlocks the file and allows other operations over it. - */ - public release(); +// /** +// * Unlocks the file and allows other operations over it. +// */ +// public release(); - /** - * Gets the underlying File instance. - */ - file: File; -} +// /** +// * Gets the underlying File instance. +// */ +// file: File; +//} -/** - * Enables reading the content of a File entity. - */ -export declare class FileReader extends FileAccess { -/** -* Reads the content of the underlying File as a UTF8 encoded string. -*/ -public readText(onSuccess: (content: string) => any, onError?: (error: any) => any); -} +///** +// * Enables reading the content of a File entity. +// */ +//export declare class FileReader extends FileAccess { +///** +//* Reads the content of the underlying File as a UTF8 encoded string. +//*/ +//public readText(onSuccess: (content: string) => any, onError?: (error: any) => any); +//} -/** - * Enables saving data to a File entity. - */ -export declare class FileWriter extends FileAccess { - /** - * Enables saving string to a File entity. - */ - public writeText(content: string, onSuccess?: () => any, onError?: (error: any) => any); -} \ No newline at end of file +///** +// * Enables saving data to a File entity. +// */ +//export declare class FileWriter extends FileAccess { +// /** +// * Enables saving string to a File entity. +// */ +// public writeText(content: string, onSuccess?: () => any, onError?: (error: any) => any); +//} \ No newline at end of file diff --git a/FileSystem/file_system.ts b/FileSystem/file_system.ts index 7374ea7df..fedf16224 100644 --- a/FileSystem/file_system.ts +++ b/FileSystem/file_system.ts @@ -162,31 +162,15 @@ export class File extends FileSystemEntity { } /** - * Checks whether a File with the specified path already exists. - */ + * Checks whether a File with the specified path already exists. + */ public static exists(path: string): boolean { return getFileAccess().fileExists(path); } /** - * Creates a FileReader object over this file and locks the file until the reader is released. - */ - public openRead(): FileReader { - this.checkAccess(); - return new FileReader(this); - } - - /** - * Creates a FileWriter object over this file and locks the file until the writer is released. - */ - public openWrite(): FileWriter { - this.checkAccess(); - return new FileWriter(this); - } - - /** - * Gets the extension of the entity. - */ + * Gets the extension of the entity. + */ get extension(): string { return this[extensionProperty]; } @@ -198,11 +182,63 @@ export class File extends FileSystemEntity { return this[fileLockedProperty]; } + /** + * Reads the content of the file as a string using the specified encoding (defaults to UTF-8). + */ + public readText(onSuccess: (content: string) => any, onError?: (error: any) => any, encoding?: string) { + if (!onSuccess) { + return; + } + + this.checkAccess(); + this[fileLockedProperty] = true; + + var that = this; + var localSuccess = function (content: string) { + that[fileLockedProperty] = false; + onSuccess(content); + } + + var localError = function (error) { + that[fileLockedProperty] = false; + if (onError) { + onError(error); + } + } + + // TODO: Asyncronous + getFileAccess().readText(this.path, localSuccess, localError, encoding); + } + + /** + * Writes the provided string to the file, using the specified encoding. Any previous content will be overwritten. + */ + public writeText(content: string, onSuccess?: () => any, onError?: (error: any) => any, encoding?: string) { + this.checkAccess(); + this[fileLockedProperty] = true; + + var that = this; + var localSuccess = function () { + that[fileLockedProperty] = false; + if (onSuccess) { + onSuccess(); + } + }; + + var localError = function (error) { + that[fileLockedProperty] = false; + if (onError) { + onError(error); + } + }; + + // TODO: Asyncronous + getFileAccess().writeText(this.path, content, localSuccess, localError, encoding); + } + private checkAccess() { if (this.isLocked) { - throw { - message: "Cannot access a locked file." - }; + throw new Error("Cannot access a locked file."); } } } @@ -371,52 +407,4 @@ export module knownFolders { return _temp; } -} - -/** -* Base class for FileReader and FileWriter APIs. -*/ -export class FileAccess { - private _file; - - constructor(file: File) { - this._file = file; - this._file[fileLockedProperty] = true; - } - - /** - * Unlocks the file and allows other operations over it. - */ - public release() { - this._file[fileLockedProperty] = false; - this._file = undefined; - } - - /** - * Gets the underlying File instance. - */ - get file(): File { - return this._file; - } -} - -/** -* Enables reading the content of a File entity. -*/ -export class FileReader extends FileAccess { - /** - * Reads the content of the underlying File as a UTF8 encoded string. - */ - public readText(onSuccess: (content: string) => any, onError?: (error: any) => any) { - getFileAccess().readText(this.file.path, onSuccess, onError); - } -} - -/** -* Enables saving data to a File entity. -*/ -export class FileWriter extends FileAccess { - public writeText(content: string, onSuccess?: () => any, onError?: (error: any) => any) { - getFileAccess().writeText(this.file.path, content, onSuccess, onError); - } } \ No newline at end of file diff --git a/FileSystem/file_system_access.android.ts b/FileSystem/file_system_access.android.ts index 710a609f1..44d75749d 100644 --- a/FileSystem/file_system_access.android.ts +++ b/FileSystem/file_system_access.android.ts @@ -1,8 +1,7 @@ -import app_module = require("Application/application"); - +import appModule = require("Application/application"); +import textModule = require("text/text"); export class FileSystemAccess { - private _encoding = "UTF-8"; private _pathSeparator = java.io.File.separator; public getLastModified(path: string): Date { @@ -212,22 +211,27 @@ export class FileSystemAccess { } public getDocumentsFolderPath(): string { - var context = app_module.Application.current.android.context; - var dir: java.io.File = context.getFilesDir(); + var context = appModule.Application.current.android.context; + var dir = context.getFilesDir(); return dir.getAbsolutePath(); } public getTempFolderPath(): string { - var context = app_module.Application.current.android.context; - var dir: java.io.File = context.getCacheDir(); + var context = appModule.Application.current.android.context; + var dir = context.getCacheDir(); return dir.getAbsolutePath(); } - public readText(path: string, onSuccess: (content: string) => any, onError?: (error: any) => any) { + public readText(path: string, onSuccess: (content: string) => any, onError?: (error: any) => any, encoding?: string) { try { var javaFile = new java.io.File(path); var stream = new java.io.FileInputStream(javaFile); - var reader = new java.io.InputStreamReader(stream, this._encoding); + + var actualEncoding = encoding; + if (!actualEncoding) { + actualEncoding = textModule.encoding.UTF_8; + } + var reader = new java.io.InputStreamReader(stream, actualEncoding); var bufferedReader = new java.io.BufferedReader(reader); // TODO: We will need to read the entire file to a CharBuffer instead of reading it line by line @@ -243,8 +247,9 @@ export class FileSystemAccess { if (result.length > 0) { // add the new line manually to the result // TODO: Try with CharBuffer at a later stage, when the Bridge allows it - // result += "\n"; + result += "\n"; } + result += line; } @@ -260,15 +265,20 @@ export class FileSystemAccess { } } - public writeText(path: string, content: string, onSuccess?: () => any, onError?: (error: any) => any) { + public writeText(path: string, content: string, onSuccess?: () => any, onError?: (error: any) => any, encoding?: string) { try { var javaFile = new java.io.File(path); var stream = new java.io.FileOutputStream(javaFile); - var writer = new java.io.OutputStreamWriter(stream, this._encoding); + + var actualEncoding = encoding; + if (!actualEncoding) { + actualEncoding = textModule.encoding.UTF_8; + } + var writer = new java.io.OutputStreamWriter(stream, actualEncoding); writer.write(content); writer.close(); - + if (onSuccess) { onSuccess(); } diff --git a/FileSystem/file_system_access.d.ts b/FileSystem/file_system_access.d.ts index 093dfb0e0..8f793ed0e 100644 --- a/FileSystem/file_system_access.d.ts +++ b/FileSystem/file_system_access.d.ts @@ -20,8 +20,10 @@ export declare class FileSystemAccess { rename(path: string, newPath: string, onSuccess?: () => any, onError?: (error: any) => any): void; getDocumentsFolderPath(): string; getTempFolderPath(): string; - readText(path: string, onSuccess: (content: string) => any, onError?: (error: any) => any); - writeText(path: string, content: string, onSuccess?: () => any, onError?: (error: any) => any); + + readText(path: string, onSuccess: (content: string) => any, onError?: (error: any) => any, encoding?: string); + writeText(path: string, content: string, onSuccess?: () => any, onError?: (error: any) => any, encoding?: string); + getFileExtension(path: string): string; } \ No newline at end of file diff --git a/FileSystem/file_system_access.ios.ts b/FileSystem/file_system_access.ios.ts index c00196065..279431c49 100644 --- a/FileSystem/file_system_access.ios.ts +++ b/FileSystem/file_system_access.ios.ts @@ -1,5 +1,6 @@ import app_module = require("Application/application"); import utilsModule = require("Utils/utils_ios"); +import textModule = require("text/text"); // TODO: Implement all the APIs receiving callback using async blocks // TODO: Check whether we need try/catch blocks for the iOS implementation @@ -225,8 +226,13 @@ export class FileSystemAccess { return this.getKnownPath(this.cachesDir); } - public readText(path: string, onSuccess: (content: string) => any, onError?: (error: any) => any) { - var nsString = Foundation.NSString.stringWithContentsOfFileEncodingError(path, this.NSUTF8StringEncoding, null); + public readText(path: string, onSuccess: (content: string) => any, onError?: (error: any) => any, encoding?: string) { + var actualEncoding = encoding; + if (!actualEncoding) { + actualEncoding = textModule.encoding.UTF_8; + } + + var nsString = Foundation.NSString.stringWithContentsOfFileEncodingError(path, actualEncoding, null); if (!nsString) { if (onError) { onError(new Error("Failed to read file at path '" + path + "'")); @@ -236,11 +242,16 @@ export class FileSystemAccess { } } - public writeText(path: string, content: string, onSuccess?: () => any, onError?: (error: any) => any) { + public writeText(path: string, content: string, onSuccess?: () => any, onError?: (error: any) => any, encoding?: string) { var nsString = Foundation.NSString.initWithString(content); + var actualEncoding = encoding; + if (!actualEncoding) { + actualEncoding = textModule.encoding.UTF_8; + } + // TODO: verify the useAuxiliaryFile parameter should be false - if (!nsString.writeToFileAtomicallyEncodingError(path, false, this.NSUTF8StringEncoding, null)) { + if (!nsString.writeToFileAtomicallyEncodingError(path, false, actualEncoding, null)) { if (onError) { onError(new Error("Failed to write to file '" + path + "'")); } diff --git a/Utils/module_merge.ts b/Utils/module_merge.ts new file mode 100644 index 000000000..a88a565e3 --- /dev/null +++ b/Utils/module_merge.ts @@ -0,0 +1,7 @@ +// This method iterates all the keys in the source exports object and copies them to the destination exports one. +// Note: the method will not check for naming collisions and will override any already existing entries in the destination exports. +export var merge = function (sourceExports: any, destExports: any) { + for (var key in sourceExports) { + destExports[key] = sourceExports[key]; + } +} \ No newline at end of file diff --git a/http/http.ts b/http/http.ts index ae19f5429..19031681d 100644 --- a/http/http.ts +++ b/http/http.ts @@ -4,7 +4,7 @@ import http = require("http/http_request"); // merge request declare var exports; -exports.request = http.request; +require("Utils/module_merge").merge(http, exports); /** * Gets string from url. diff --git a/text/index.ts b/text/index.ts new file mode 100644 index 000000000..3e898eb13 --- /dev/null +++ b/text/index.ts @@ -0,0 +1,2 @@ +declare var module, require; +module.exports = require("text/text"); \ No newline at end of file diff --git a/text/text.android.ts b/text/text.android.ts new file mode 100644 index 000000000..c94c44641 --- /dev/null +++ b/text/text.android.ts @@ -0,0 +1,8 @@ +export module encoding { + export var ISO_8859_1 = "ISO-8859-1"; + export var US_ASCII = "US-ASCII"; + export var UTF_16 = "UTF-16"; + export var UTF_16BE = "UTF-16BE"; + export var UTF_16LE = "UTF-16LE"; + export var UTF_8 = "UTF-8"; +} \ No newline at end of file diff --git a/text/text.d.ts b/text/text.d.ts new file mode 100644 index 000000000..35c5e2c0c --- /dev/null +++ b/text/text.d.ts @@ -0,0 +1,11 @@ +/** +* Defines the supported character encodings. +*/ +export declare module encoding { + export var ISO_8859_1: any; + export var US_ASCII: any; + export var UTF_16: any; + export var UTF_16BE: any; + export var UTF_16LE: any; + export var UTF_8: any; +} \ No newline at end of file diff --git a/text/text.ios.ts b/text/text.ios.ts new file mode 100644 index 000000000..228c03df5 --- /dev/null +++ b/text/text.ios.ts @@ -0,0 +1,8 @@ +export module encoding { + export var ISO_8859_1 = 5; //NSISOLatin1StringEncoding + export var US_ASCII = 1; //NSASCIIStringEncoding + export var UTF_16 = 10; //NSUnicodeStringEncoding + export var UTF_16BE = 0x90000100; //NSUTF16BigEndianStringEncoding + export var UTF_16LE = 0x94000100; //NSUTF16LittleEndianStringEncoding + export var UTF_8 = 4; //NSUTF8StringEncoding +} \ No newline at end of file