記憶にないコード


何をしようとしたかは覚えてるが、結局使われなかったコード。
WebAPI側を用意して、ファイルをスライスして送り付けるためのJQurery Plugin
今一つ昔に書いたコードは記憶が薄れるのでメモ。

使う側


$(document).ready(function () {
  $('#files').setSliceDataFunc(function (data) {
    //--post--post--post--post--post--post--
    $.ajax({
      type: "POST",
      contentType: "application/json; charset=utf-8",
      //data: bytes,
      //data : evt.target.result,
      data: JSON.stringify({
        name: data.file.name,
        //file: bytes, file: raw,
        file: data.base64,
        size: data.file.size,
        start:data.start,
        stop: data.stop
      }),
      url: "api/test",
    }).done(function (data) {
      alert('success!!');

      console.log('POST:');
      console.log(data);

    }).fail(function (data) {
      alert('error!!!');
      console.log(data);
    });
    //--post--post--post--post--post--post--
  });
});


Plugin


//前提 lib:JQuery

;(function ($) {


  // Converts an ArrayBuffer directly to base64, without any intermediate 'convert to string then
  // use window.btoa' step. According to my tests, this appears to be a faster approach:
  // http://jsperf.com/encoding-xhr-image-data/5
 
  function base64ArrayBuffer(arrayBuffer) {
    var base64    = ''
    var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
 
    var bytes         = new Uint8Array(arrayBuffer)
    var byteLength    = bytes.byteLength
    var byteRemainder = byteLength % 3
    var mainLength    = byteLength - byteRemainder
 
    var a, b, c, d
    var chunk
 
    // Main loop deals with bytes in chunks of 3
    for (var i = 0; i < mainLength; i = i + 3) {
      // Combine the three bytes into a single integer
      chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
 
      // Use bitmasks to extract 6-bit segments from the triplet
      a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18
      b = (chunk & 258048)   >> 12 // 258048   = (2^6 - 1) << 12
      c = (chunk & 4032)     >>  6 // 4032     = (2^6 - 1) << 6
      d = chunk & 63               // 63       = 2^6 - 1
 
      // Convert the raw binary segments to the appropriate ASCII encoding
      base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
    }
 
    // Deal with the remaining bytes and padding
    if (byteRemainder == 1) {
      chunk = bytes[mainLength]
 
      a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2
 
      // Set the 4 least significant bits to zero
      b = (chunk & 3)   << 4 // 3   = 2^2 - 1
 
      base64 += encodings[a] + encodings[b] + '=='
    } else if (byteRemainder == 2) {
      chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]
 
      a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10
      b = (chunk & 1008)  >>  4 // 1008  = (2^6 - 1) << 4
 
      // Set the 2 least significant bits to zero
      c = (chunk & 15)    <<  2 // 15    = 2^4 - 1
 
      base64 += encodings[a] + encodings[b] + encodings[c] + '='
    }
  
    return base64
  }
  ////////////


  function changeFile(data, callback, opts) {

    if (data.index == 1 && data.leng == 1) {
      console.log('一括読込');
    } else if (data.index >= data.leng) {
      //終了
      return;
    }
    var sliceLeng = opts.slice_size;
    var f = data.file;
    var start = sliceLeng * (data.index - 1);
    var stop = data.index >= data.leng - 1 ? f.size : sliceLeng * data.index;
    data.start = start;
    data.stop = stop;

    //読込準備
    var reader = new FileReader();
    reader.onloadend = function (evt) {
      //読込完了
      if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        //console.log(evt.target.result);

        var raw = new Uint8Array(evt.target.result);
        //var b64encoded = window.btoa(String.fromCharCode.apply(null, raw));
        var b64encoded = base64ArrayBuffer(raw);

        data.base64 = b64encoded;
        callback(data);

        //インデックスを進めて再帰呼び出し
        data.index++;
        changeFile(data, callback, opts);
      } else {
        throw '読込異常?';
      }//end if
    };//onload end

    //sliceする
    var blob = null;
    if (data.index == 1 && data.leng == 1) {
      blob = null;
    } else if (f.slice) {
      blob = f.slice(start, stop);
    } else if (f.webkitSlice) {
      blob = f.webkitSlice(start, stop);
    } else if (f.mozSlice) {
      blob = f.mozSlice(start, stop);
    }//end if
    
    //reader.readAsBinaryString(blob);
    if (blob) {
      reader.readAsArrayBuffer(blob);
    } else {
      reader.readAsArrayBuffer(f);
    }//end if
  }//end func

  //インプットエレメントに変更時挙動を割り付ける
  function setInputFile($obj, callback, opts) {
    //http://api.jquery.com/file-selector/

    //Input FIleでない場合は何もしない。
    var tag = $obj.tagName;
    if (tag != 'INPUT' || $obj.type != 'file')
      return;

    var sliceLeng = opts.slice_size;
    //ファイル変更時
    $($obj).on('change', function () {
      var files = this.files;
      if (!files || files.length < 1)
        return;
      for (var i = 0; i < files.length; i++) {
        var f = files[i];
        console.log(f.name + ':' + f.size);

        var leng = parseInt(f.size / sliceLeng) + 1;
        var index = 1;
        var data = {
          file: f,
          leng: leng,
          index: index
        };
        changeFile(data, callback, opts);
      }//end file

    });
  }//end func


  //データ分割メソッドをセット
  $.fn.setSliceDataFunc = function (callback, opts) {

    // 要素を退避
    var elements = this;

    // 要素を1つずつ処理
    elements.each(function () {

      // 渡されたオプションおよび独自データ属性をデフォルトにマージする
      var opts = $.extend({}, $.fn.setSliceDataFunc.defaults, opts, $(this).data());
      //要素取得の実行
      setInputFile(this, callback, opts);

    });//end loop

    // method chain用に要素を返す
    return elements;
  };//end func

  //既定の設定
  $.fn.setSliceDataFunc.defaults = {
    slice_size: 1048576
  };

})(jQuery);
カテゴリー: 開発 タグ: パーマリンク