<commit_before>/**
 * Manages file operations
 * @param {File} file - The disk file to be handled
 */
var StorageManager = function (file) {
  var index = 0,
    chunkSize = 16000,
    reader = new FileReader(),
    fileSize = file.size,
    writer = [];

  /**
   * Reads the next specific number of bytes, calling the callback when done
   * @param {Number} size - The number of bytes to be read
   * @param {Function} callback - The callback to be called when done
   */
  var readChunk = function (size, callback) {
    if (index >= fileSize) {
      return false;
    }
    var bSize = size;
    if (index + size > fileSize) {
      bSize = fileSize - index;
    }
    reader.onload = function (e) {
      if (reader.readyState === 2) {
        var block = new Uint8Array(reader.result);
        if (typeof callback === 'function') {
          setTimeout(function () {
            callback(block);
          }, 5);
        }
      }
    };
    reader.readAsArrayBuffer(file.slice(index, index + bSize));
    index += bSize;
    return true;
  };

  /**
   * Reads the next chunk of bytes, calling the callback when done
   * @param {Function} callback - The callback to be called when done
   */
  this.readNext = function (callback) {
    return readChunk(chunkSize, callback);
  };

  /**
   * Reads the next specific number of bytes, calling the callback when done
   * @param {Number} size - The number of bytes to be read
   * @param {Function} callback - The callback to be called when done
   */
  this.readNextLength = function (size, callback) {
    if (!size) {
      throw 'Argument exception: Size zero or not specified.';
    }
    return readChunk(size, callback);
  };

  this.getName = function () {
    return file.name;
  };

  /**
   * Stores the provided data, calling the callback when done
   * @param {Uint8Array} data - The data to be stored
   * @param {Boolean} prepend - The data will be prepended
   * @param {Function} callback - The callback to be called when done
   */
  this.store = function (data, prepend, callback) {
    writer = prepend ? data.concat(writer) : writer.concat(data);

    if (typeof callback === 'function') {
      callback();
    }
  };

  /**
   * Saves the currently stored data to disk
   */
  this.saveToDisk = function (length) {
    var saveAs = saveAs || (typeof navigator !== "undefined" &&
      navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator));

    var blob = new Blob([Utils.toTypedArray(writer, length)], {
      type: 'application/octet-stream'
    });

    saveAs(blob);
  };
};<commit_msg>Abstractising saveas<commit_after>/**
 * Manages file operations
 * @param {File} file - The disk file to be handled
 */
var StorageManager = function (file) {
  var index = 0,
    chunkSize = 16000,
    reader = new FileReader(),
    fileSize = file.size,
    writer = [];

  /**
   * Reads the next specific number of bytes, calling the callback when done
   * @param {Number} size - The number of bytes to be read
   * @param {Function} callback - The callback to be called when done
   */
  var readChunk = function (size, callback) {
    if (index >= fileSize) {
      return false;
    }
    var bSize = size;
    if (index + size > fileSize) {
      bSize = fileSize - index;
    }
    reader.onload = function (e) {
      if (reader.readyState === 2) {
        var block = new Uint8Array(reader.result);
        if (typeof callback === 'function') {
          setTimeout(function () {
            callback(block);
          }, 5);
        }
      }
    };
    reader.readAsArrayBuffer(file.slice(index, index + bSize));
    index += bSize;
    return true;
  };

  /**
   * Reads the next chunk of bytes, calling the callback when done
   * @param {Function} callback - The callback to be called when done
   */
  this.readNext = function (callback) {
    return readChunk(chunkSize, callback);
  };

  /**
   * Reads the next specific number of bytes, calling the callback when done
   * @param {Number} size - The number of bytes to be read
   * @param {Function} callback - The callback to be called when done
   */
  this.readNextLength = function (size, callback) {
    if (!size) {
      throw 'Argument exception: Size zero or not specified.';
    }
    return readChunk(size, callback);
  };

  this.getName = function () {
    return file.name;
  };

  /**
   * Stores the provided data, calling the callback when done
   * @param {Uint8Array} data - The data to be stored
   * @param {Boolean} prepend - The data will be prepended
   * @param {Function} callback - The callback to be called when done
   */
  this.store = function (data, prepend, callback) {
    writer = prepend ? data.concat(writer) : writer.concat(data);

    if (typeof callback === 'function') {
      callback();
    }
  };

  /**
   * Saves the currently stored data to disk
   */
  this.saveToDisk = function (length) {
    var saveAs = saveAs || (typeof navigator !== "undefined" &&
      navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator));

    var blob = new Blob([Utils.toTypedArray(writer, length)], {
      type: 'application/octet-stream'
    });

    window.webkitRequestFileSystem(window.TEMPORARY, length, function (fs) {
      fs.root.getDirectory("saved", {
        create: true
      }, function (dir) {

        var save = function () {
          dir.getFile("file.txt", {
            create: true,
            exclusive: false
          }, function (file) {
            file.createWriter(function (writer) {
              writer.onwriteend = function (event) {
                window.location.href = file.toURL();
              };
              writer.write(blob);
            });
          });
        };

        dir.getFile("file.txt", {
          create: false
        }, function (file) {
          file.remove(save);
        });


      });
    });

    saveAs(blob);

    var objUrl = URL.createObjectURL(blob);
    window.location = objUrl;

  };
};
{'fraction_non_alphanumeric': 0.12062907813284256, 'fraction_numerical': 0.0033461602810774638, 'mean_word_length': 2.4004550625711034, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6148576', 'n_tokens_mistral': 1764, 'n_tokens_neox': 1721, 'n_words': 557}