| Index: lib/storage.js |
| =================================================================== |
| --- a/lib/storage.js |
| +++ b/lib/storage.js |
| @@ -1,45 +1,213 @@ |
| -Cu.import("resource://gre/modules/FileUtils.jsm"); |
| +let {Encoding} = require( "encoding" ); |
| +let {Logger} = require( "logger" ); |
| -let outputStream; |
| -let converterOutputStream; |
| +Cu.import( "resource://gre/modules/FileUtils.jsm" ); |
| -function createTemporaryFile(name) |
| +//------------------------------------------------------- |
| +// Storage_class |
| +//------------------------------------------------------- |
| +/** |
| + * Base class for particular storage mechanisms. Implements all storage framework methods. Necessary methods have |
| + * implementations that throw if not overridden. Optional methods have no-op implementations. |
| + * @constructor |
| + */ |
| +var Storage_class = function() |
| { |
| - let file = FileUtils.getFile("TmpD", [name]); |
| - file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); |
| - return file; |
| -} |
| - |
| -function openOutputStream(file) |
| -{ |
| - let outputStream = FileUtils.openSafeFileOutputStream(file); |
| - let converterOutputStream = Cc["@mozilla.org/intl/converter-output-stream;1"] |
| - .createInstance(Ci.nsIConverterOutputStream); |
| - converterOutputStream.init(outputStream, "UTF-8", 0, 0); |
| - return [outputStream, converterOutputStream]; |
| -} |
| - |
| -let Storage = exports.Storage = {}; |
| - |
| -Storage.init = function() |
| -{ |
| - Storage.dataFile = createTemporaryFile("crawler-data"); |
| - [outputStream, converterOutputStream] = openOutputStream(Storage.dataFile); |
| }; |
| -Storage.write = function(data) |
| +/** |
| + * Return a string of the form "[object ...]" like the built-in types do. |
| + * <p/> |
| + * Mandatory framework function. |
| + */ |
| +Storage_class.prototype.toJSON = function() |
| { |
| - let line = JSON.stringify(data) + "\n"; |
| - converterOutputStream.writeString(line); |
| + throw new Error( "Subclass of Storage_class did not implement 'toJSON()'." ); |
| }; |
| -Storage.finish = function() |
| +/** |
| + * Called when the crawl first begins, before any targets have been loaded. |
| + * <p/> |
| + * Mandatory framework function. |
| + */ |
| +Storage_class.prototype.write = function() |
| { |
| - converterOutputStream.flush(); |
| - FileUtils.closeSafeFileOutputStream(outputStream); |
| + throw new Error( "Subclass of Storage_class did not implement 'write()'." ); |
| }; |
| -Storage.destroy = function() |
| +/** |
| + * Called when the crawl ends, whether normally or abnormally. |
| + */ |
| +Storage_class.prototype.close = function() |
| { |
| - Storage.dataFile.remove(true); |
| }; |
| + |
| +Storage_class.prototype.writer = function() |
| +{ |
| + return this.write.bind( this ); |
| +}; |
| + |
| +//------------------------------------------------------- |
| +// Storage.Local_File |
| +//------------------------------------------------------- |
| +/** |
| + * Storage to the local file system. |
| + * <p> |
| + * This class writes directly to the given file. It does not write to a temporary file first, say, using 'createUnique', |
| + * and then renaming it. |
| + * |
| + * @param {nsIFile} file |
| + * File object to which to write. |
| + * @constructor |
| + */ |
| +var Local_File = function( file ) |
| +{ |
| + /** |
| + * @type {nsIFile} |
| + */ |
| + this.file = file; |
| + |
| + this.output = FileUtils.openSafeFileOutputStream( file ); |
| + this.converter_output = Cc["@mozilla.org/intl/converter-output-stream;1"] |
| + .createInstance( Ci.nsIConverterOutputStream ); |
| + this.converter_output.init( this.output, "UTF-8", 0, 0 ); |
| +}; |
| +Local_File.prototype = new Storage_class(); |
| + |
| +Local_File.prototype.toJSON = function() |
| +{ |
| + return "local file " + this.file.path; |
| +}; |
| + |
| +Local_File.prototype.close = function() |
| +{ |
| + this.converter_output.flush(); |
| + FileUtils.closeSafeFileOutputStream( this.output ); |
| +}; |
| + |
| +Local_File.prototype.write = function( s ) |
| +{ |
| + this.converter_output.writeString( s ); |
| +}; |
| + |
| +//------------------------------------------------------- |
| +// Storage.Bit_Bucket |
| +//------------------------------------------------------- |
| + |
| +var Bit_Bucket = function() |
| +{ |
| +}; |
| +Bit_Bucket.prototype = new Storage_class(); |
| + |
| +/** |
| + * The only way that this differs from the do-nothing base class is that we provide a name. |
| + */ |
| +Bit_Bucket.prototype.toJSON = function() |
| +{ |
| + return "bit bucket"; |
| +}; |
| +Bit_Bucket.prototype.write = function() |
| +{ |
| +}; |
| + |
| +//------------------------------------------------------- |
| +// Storage.Multiple |
| +//------------------------------------------------------- |
| +/** |
| + * Combine one or more Storage_class objects into a single one. This is ordinarily used for logging activity to the |
| + * screen during the run. It also allows enables summary statistics to be gathered simultaneously with a crawl to |
| + * support filter list construction. |
| + * @constructor |
| + * @param {Array} stores |
| + * An array of Storage_class objects. |
| + * @param {boolean} [omit_first] |
| + * Suppress first element in JSON display. |
| + */ |
| +var Multiple = function( stores, omit_first ) |
| +{ |
| + this.stores = stores; |
| + this.omit_first = omit_first; |
| +}; |
| +Multiple.prototype = new Storage_class(); |
| + |
| +/** |
| + * @override |
| + */ |
| +Multiple.prototype.toJSON = function() |
| +{ |
| + if ( this.omit_first && this.stores.length == 2 ) |
| + { |
| + /* |
| + * Special case: Pretend we're not here. |
| + */ |
| + return this.stores[ 1 ].toJSON(); |
| + } |
| + var s = "Multiple["; |
| + var first = (this.omit_first) ? 1 : 0; |
| + if ( this.first < this.stores.length ) |
| + { |
| + for ( let i = first ; i < this.stores.length ; ++i ) |
| + { |
| + if ( i > first ) s += ","; |
| + s += " " + JSON.stringify( this.stores[i] ); |
| + } |
| + s += " "; |
| + } |
| + s += "]"; |
| + return s; |
| +}; |
| + |
| +/** |
| + * @override |
| + */ |
| +Multiple.prototype.write = function( s ) |
| +{ |
| + for ( let i = 0 ; i < this.stores.length ; ++i ) |
| + { |
| + this.stores[i].write( s ); |
| + } |
| +}; |
| + |
| +//------------------------------------------------------- |
| +// Storage.Display_Log |
| +//------------------------------------------------------- |
| +/** |
| + * A display log in the crawler UI, presumably a simple textbox. Used to monitor progress during a crawl, if desired. |
| + * @constructor |
| + * @param [display] |
| + * A display object from the crawler UI. |
| + */ |
| +var Display_Log = function( display ) |
| +{ |
| + this.display = display; |
| +}; |
| +Display_Log.prototype = new Storage_class(); |
| + |
| +/** |
| + * @override |
| + */ |
| +Display_Log.prototype.toJSON = function() |
| +{ |
| + return "Display_Log"; |
| +}; |
| + |
| +/** |
| + * @override |
| + */ |
| +Display_Log.prototype.write = function( s ) |
| +{ |
| + this.display.write( s ); |
| +}; |
| + |
| +//------------------------------------------------------- |
| +// Storage |
| +//------------------------------------------------------- |
| +/** |
| + * Export variable for this module. There's no single class named "Storage" as such. |
| + */ |
| +exports.Storage = { |
| + Local_File: Local_File, |
| + Bit_Bucket: Bit_Bucket, |
| + Multiple: Multiple, |
| + Display_Log: Display_Log |
| +}; |