|
@@ -27,10 +27,24 @@ export default class Blob {
|
27
|
27
|
_blobCreated:boolean = false;
|
28
|
28
|
_onCreated:Array<any> = [];
|
29
|
29
|
|
30
|
|
- static Instances:any = {}
|
|
30
|
+ /**
|
|
31
|
+ * Static method that remove all files in Blob cache folder.
|
|
32
|
+ * @nonstandard
|
|
33
|
+ * @return {Promise}
|
|
34
|
+ */
|
|
35
|
+ static clearCache() {
|
|
36
|
+ return fs.unlink(blobCacheDir).then(() => fs.mkdir(blobCacheDir))
|
|
37
|
+ }
|
31
|
38
|
|
32
|
|
- // legacy constructor
|
33
|
|
- constructor(data:any, mime:?string) {
|
|
39
|
+ /**
|
|
40
|
+ * RNFetchBlob Blob polyfill, create a Blob directly from file path, BASE64
|
|
41
|
+ * encoded data, and string. The conversion is done implicitly according to
|
|
42
|
+ * given `mime`. However, the blob creation is asynchronously, to register
|
|
43
|
+ * event `onCreated` is need to ensure the Blob is creadted.
|
|
44
|
+ * @param {any} data Content of Blob object
|
|
45
|
+ * @param {string} mime Content type of Blob object, `text/plain` by default
|
|
46
|
+ */
|
|
47
|
+ constructor(data:any, mime='text/plain':?string) {
|
34
|
48
|
|
35
|
49
|
this.cacheName = getBlobName()
|
36
|
50
|
this.isRNFetchBlobPolyfill = true
|
|
@@ -38,22 +52,28 @@ export default class Blob {
|
38
|
52
|
log.verbose('Blob constructor called', 'mime', mime)
|
39
|
53
|
this._ref = blobCacheDir + this.cacheName
|
40
|
54
|
let p = null
|
41
|
|
- // content from file
|
|
55
|
+ // if the data is a string starts with `RNFetchBlob-file://`, append the
|
|
56
|
+ // Blob data from file path
|
42
|
57
|
if(typeof data === 'string' && data.startsWith('RNFetchBlob-file://')) {
|
43
|
58
|
log.verbose('create Blob cache file from file path')
|
44
|
59
|
this._ref = data
|
45
|
|
- p = Promise.resolve()
|
|
60
|
+ p = fs.stat(data.replace('RNFetchBlob-file://'))
|
|
61
|
+ .then((stat) => Promise.resolve(stat.size))
|
46
|
62
|
}
|
47
|
63
|
// content from variable need create file
|
48
|
64
|
else if(typeof data === 'string') {
|
49
|
65
|
log.verbose('create Blob cache file from string')
|
50
|
66
|
let encoding = 'utf8'
|
51
|
|
- if(String(mime).match('application/octet'))
|
|
67
|
+ let mime = String(mime)
|
|
68
|
+ // when content type contains application/octet* or *;base64, RNFetchBlob
|
|
69
|
+ // fs will treat it as BASE64 encoded string binary data
|
|
70
|
+ if(mime.match(/application\/octet/i) || mime.match(/\;base64/i))
|
52
|
71
|
encoding = 'base64'
|
53
|
|
- else if(Array.isArray(data))
|
54
|
|
- encoding = 'ascii'
|
|
72
|
+ else
|
|
73
|
+ data = data.toString()
|
55
|
74
|
// create cache file
|
56
|
75
|
p = fs.writeFile(this._ref, data, encoding)
|
|
76
|
+ .then((size) => Promise.resolve(size))
|
57
|
77
|
|
58
|
78
|
}
|
59
|
79
|
// when input is an array of mixed data types, create a file cache
|
|
@@ -61,21 +81,34 @@ export default class Blob {
|
61
|
81
|
log.verbose('create Blob cache file from mixed array', data)
|
62
|
82
|
p = createMixedBlobData(this._ref, data)
|
63
|
83
|
}
|
64
|
|
- p && p.then(() => {
|
|
84
|
+ else {
|
|
85
|
+ data = data.toString()
|
|
86
|
+ p = Promise.resolve(data.length)
|
|
87
|
+ }
|
|
88
|
+ p && p.then((size) => {
|
|
89
|
+ this.size = size
|
65
|
90
|
this._invokeOnCreateEvent()
|
66
|
91
|
})
|
67
|
92
|
.catch((err) => {
|
68
|
|
- log.error('RNFetchBlob cannot create Blob : '+ this._ref)
|
|
93
|
+ log.error('RNFetchBlob could not create Blob : '+ this._ref, err)
|
69
|
94
|
})
|
70
|
95
|
|
71
|
96
|
}
|
72
|
97
|
|
|
98
|
+ /**
|
|
99
|
+ * Since Blob content will asynchronously write to a file during creation,
|
|
100
|
+ * use this method to register an event handler for Blob initialized event.
|
|
101
|
+ * @nonstandard
|
|
102
|
+ * @param {[type]} fn:( [description]
|
|
103
|
+ * @return {[type]} [description]
|
|
104
|
+ */
|
73
|
105
|
onCreated(fn:() => void) {
|
74
|
106
|
log.verbose('register blob onCreated', this._onCreated.length)
|
75
|
107
|
this._onCreated.push(fn)
|
76
|
108
|
}
|
77
|
109
|
|
78
|
110
|
/**
|
|
111
|
+ * Get file reference of the Blob object.
|
79
|
112
|
* @nonstandard
|
80
|
113
|
* @return {string} Blob file reference which can be consumed by RNFetchBlob fs
|
81
|
114
|
*/
|
|
@@ -92,6 +125,7 @@ export default class Blob {
|
92
|
125
|
*/
|
93
|
126
|
slice(start:?number, end:?number, encoding:?string):Blob {
|
94
|
127
|
log.verbose('slice called')
|
|
128
|
+ // TODO : fs.slice
|
95
|
129
|
// return fs.slice(this.cacheName, getBlobName(), contentType, start, end)
|
96
|
130
|
}
|
97
|
131
|
|
|
@@ -104,10 +138,6 @@ export default class Blob {
|
104
|
138
|
return fs.unlink(this._ref)
|
105
|
139
|
}
|
106
|
140
|
|
107
|
|
- clearCache() {
|
108
|
|
-
|
109
|
|
- }
|
110
|
|
-
|
111
|
141
|
_invokeOnCreateEvent() {
|
112
|
142
|
log.verbose('invoke create event')
|
113
|
143
|
this._blobCreated = true
|
|
@@ -139,6 +169,7 @@ function getBlobName() {
|
139
|
169
|
function createMixedBlobData(ref, dataArray) {
|
140
|
170
|
let p = fs.writeFile(ref, '')
|
141
|
171
|
let args = []
|
|
172
|
+ let size = 0
|
142
|
173
|
for(let i in dataArray) {
|
143
|
174
|
let part = dataArray[i]
|
144
|
175
|
if(part instanceof Blob)
|
|
@@ -152,6 +183,11 @@ function createMixedBlobData(ref, dataArray) {
|
152
|
183
|
let promises = args.map((p) => {
|
153
|
184
|
return fs.appendFile.call(this, ...p)
|
154
|
185
|
})
|
155
|
|
- return Promise.all(promises)
|
|
186
|
+ return Promise.all(promises).then((sizes) => {
|
|
187
|
+ for(let i in sizes) {
|
|
188
|
+ size += sizes[i]
|
|
189
|
+ }
|
|
190
|
+ return Promise.resolve(size)
|
|
191
|
+ })
|
156
|
192
|
})
|
157
|
193
|
}
|