Subversion-Projekte lars-tiefland.cienc

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
9 lars 1
/* BlobBuilder.js
2
 * A BlobBuilder implementation.
3
 * 2012-04-21
4
 *
5
 * By Eli Grey, http://eligrey.com
6
 * License: X11/MIT
7
 *   See LICENSE.md
8
 */
9
 
10
/*global self, unescape */
11
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
12
  plusplus: true */
13
 
14
/*! @source http://purl.eligrey.com/github/BlobBuilder.js/blob/master/BlobBuilder.js */
15
 
16
var BlobBuilder = BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder || (function(view) {
17
"use strict";
18
var
19
	  get_class = function(object) {
20
		return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
21
	}
22
	, FakeBlobBuilder = function(){
23
		this.data = [];
24
	}
25
	, FakeBlob = function(data, type, encoding) {
26
		this.data = data;
27
		this.size = data.length;
28
		this.type = type;
29
		this.encoding = encoding;
30
	}
31
	, FBB_proto = FakeBlobBuilder.prototype
32
	, FB_proto = FakeBlob.prototype
33
	, FileReaderSync = view.FileReaderSync
34
	, FileException = function(type) {
35
		this.code = this[this.name = type];
36
	}
37
	, file_ex_codes = (
38
		  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
39
		+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
40
	).split(" ")
41
	, file_ex_code = file_ex_codes.length
42
	, real_URL = view.URL || view.webkitURL || view
43
	, real_create_object_URL = real_URL.createObjectURL
44
	, real_revoke_object_URL = real_URL.revokeObjectURL
45
	, URL = real_URL
46
	, btoa = view.btoa
47
	, atob = view.atob
48
	, can_apply_typed_arrays = false
49
	, can_apply_typed_arrays_test = function(pass) {
50
		can_apply_typed_arrays = !pass;
51
	}
52
 
53
	, ArrayBuffer = view.ArrayBuffer
54
	, Uint8Array = view.Uint8Array
55
;
56
FakeBlobBuilder.fake = FB_proto.fake = true;
57
while (file_ex_code--) {
58
	FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
59
}
60
try {
61
	if (Uint8Array) {
62
		can_apply_typed_arrays_test.apply(0, new Uint8Array(1));
63
	}
64
} catch (ex) {}
65
if (!real_URL.createObjectURL) {
66
	URL = view.URL = {};
67
}
68
URL.createObjectURL = function(blob) {
69
	var
70
		  type = blob.type
71
		, data_URI_header
72
	;
73
	if (type === null) {
74
		type = "application/octet-stream";
75
	}
76
	if (blob instanceof FakeBlob) {
77
		data_URI_header = "data:" + type;
78
		if (blob.encoding === "base64") {
79
			return data_URI_header + ";base64," + blob.data;
80
		} else if (blob.encoding === "URI") {
81
			return data_URI_header + "," + decodeURIComponent(blob.data);
82
		} if (btoa) {
83
			return data_URI_header + ";base64," + btoa(blob.data);
84
		} else {
85
			return data_URI_header + "," + encodeURIComponent(blob.data);
86
		}
87
	} else if (real_create_object_URL) {
88
		return real_create_object_URL.call(real_URL, blob);
89
	}
90
};
91
URL.revokeObjectURL = function(object_URL) {
92
	if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
93
		real_revoke_object_URL.call(real_URL, object_URL);
94
	}
95
};
96
FBB_proto.append = function(data/*, endings*/) {
97
	var bb = this.data;
98
	// decode data to a binary string
99
	if (Uint8Array && data instanceof ArrayBuffer) {
100
		if (can_apply_typed_arrays) {
101
			bb.push(String.fromCharCode.apply(String, new Uint8Array(data)));
102
		} else {
103
			var
104
				  str = ""
105
				, buf = new Uint8Array(data)
106
				, i = 0
107
				, buf_len = buf.length
108
			;
109
			for (; i < buf_len; i++) {
110
				str += String.fromCharCode(buf[i]);
111
			}
112
		}
113
	} else if (get_class(data) === "Blob" || get_class(data) === "File") {
114
		if (FileReaderSync) {
115
			var fr = new FileReaderSync;
116
			bb.push(fr.readAsBinaryString(data));
117
		} else {
118
			// async FileReader won't work as BlobBuilder is sync
119
			throw new FileException("NOT_READABLE_ERR");
120
		}
121
	} else if (data instanceof FakeBlob) {
122
		if (data.encoding === "base64" && atob) {
123
			bb.push(atob(data.data));
124
		} else if (data.encoding === "URI") {
125
			bb.push(decodeURIComponent(data.data));
126
		} else if (data.encoding === "raw") {
127
			bb.push(data.data);
128
		}
129
	} else {
130
		if (typeof data !== "string") {
131
			data += ""; // convert unsupported types to strings
132
		}
133
		// decode UTF-16 to binary string
134
		bb.push(unescape(encodeURIComponent(data)));
135
	}
136
};
137
FBB_proto.getBlob = function(type) {
138
	if (!arguments.length) {
139
		type = null;
140
	}
141
	return new FakeBlob(this.data.join(""), type, "raw");
142
};
143
FBB_proto.toString = function() {
144
	return "[object BlobBuilder]";
145
};
146
FB_proto.slice = function(start, end, type) {
147
	var args = arguments.length;
148
	if (args < 3) {
149
		type = null;
150
	}
151
	return new FakeBlob(
152
		  this.data.slice(start, args > 1 ? end : this.data.length)
153
		, type
154
		, this.encoding
155
	);
156
};
157
FB_proto.toString = function() {
158
	return "[object Blob]";
159
};
160
return FakeBlobBuilder;
161
}(self));