2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 var can_change_size = false;
19 function FileStream(data, mode, encoding) {
20 var _totalBytes = data.fileSize || 0;
21 var _position = mode === 'a' ? _totalBytes : 0;
23 Object.defineProperties(this, {
26 return _totalBytes < _position;
36 _position = Math.max(0, v);
37 if (can_change_size) {
38 _totalBytes = Math.max(_position, _totalBytes);
45 return this.eof ? -1 : Math.max(0, _totalBytes - _position);
71 value: mode === 'w' ? true : false,
78 function _checkClosed(stream) {
80 throw new WebAPIException(WebAPIException.IO_ERR, 'Stream is closed.');
84 function closeFileStream() {
88 FileStream.prototype.close = function() {
89 closeFileStream.apply(this, arguments);
92 function _checkReadAccess(mode) {
93 if (mode !== 'r' && mode !== 'rw') {
94 throw new WebAPIException(WebAPIException.IO_ERR, 'Stream is not in read mode.');
98 function _checkWriteAccess(mode) {
99 if (mode !== 'a' && mode !== 'w' && mode !== 'rw') {
100 throw new WebAPIException(WebAPIException.IO_ERR, 'Stream is not in write mode.');
104 /* returns array of numbers */
105 function string_to_binary(str) {
107 var len = str.length;
109 for (var i = 0; i < len; i++) {
110 // decode unicode codepoint U+0100 as zero byte
111 c = str.charCodeAt(i);
112 output.push(c == 0x100 ? 0 : c);
117 /* receives array of numbers, returns string */
118 function binary_to_string(data) {
120 var len = data.length;
121 // endecode zero byte as unicode codepoint U+0100
122 var zero = String.fromCharCode(0x100);
124 for (var i = 0; i < len; i++) {
125 b = data[i] & 0xff; // conversion to octet
126 output += b == 0 ? zero : String.fromCharCode(b);
132 var args = validator_.validateArgs(arguments, [
140 _checkReadAccess(this._mode);
142 if (!arguments.length) {
143 throw new WebAPIException(
144 WebAPIException.INVALID_VALUES_ERR,
145 'Argument "charCount" missing'
148 if (!type_.isNumber(args.charCount)) {
149 throw new WebAPIException(
150 WebAPIException.TYPE_MISMATCH_ERR,
151 'Argument "charCount" must be a number'
154 if (args.charCount <= 0) {
155 throw new WebAPIException(
156 WebAPIException.INVALID_VALUES_ERR,
157 'Argument "charCount" must be greater than 0'
161 throw new WebAPIException(WebAPIException.IO_ERR, 'Stream is marked as EOF.');
164 var _count = this.bytesAvailable;
167 location: commonFS_.toRealPath(this._file.fullPath),
168 encoding: this._encoding,
169 offset: this.position || 0,
170 length: args.charCount > _count ? _count : args.charCount
173 var result = native_.callSync('File_readString', data);
174 if (native_.isFailure(result)) {
175 throw new WebAPIException(WebAPIException.IO_ERR, 'Could not read');
177 var outData = native_.getResultObject(result);
179 if (outData.length) {
180 can_change_size = true;
181 this.position += outData.length;
182 can_change_size = false;
184 this.position += 1; // Set EOF
190 FileStream.prototype.read = function() {
191 return read.apply(this, arguments);
194 function readBytes() {
195 var args = validator_.validateArgs(arguments, [
203 _checkReadAccess(this._mode);
205 if (args.byteCount <= 0) {
206 throw new WebAPIException(
207 WebAPIException.INVALID_VALUES_ERR,
208 'Argument "byteCount" must be greater than 0'
212 var _count = this.bytesAvailable;
215 location: commonFS_.toRealPath(this._file.fullPath),
216 offset: this.position || 0,
217 length: args.byteCount > _count ? _count : args.byteCount
220 var result = native_.callSync('File_readBytes', data);
221 if (native_.isFailure(result)) {
222 throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Could not read');
225 var decoded = string_to_binary(native_.getResultObject(result));
227 if (decoded.length) {
228 can_change_size = true;
229 this.position += decoded.length;
230 can_change_size = false;
232 this.position += 1; // Set EOF
238 FileStream.prototype.readBytes = function() {
239 return readBytes.apply(this, arguments);
242 FileStream.prototype.readBase64 = function() {
243 return base64_encode(readBytes.apply(this, arguments));
247 var args = validator_.validateArgs(arguments, [
255 _checkWriteAccess(this._mode);
257 if (!arguments.length) {
258 throw new WebAPIException(
259 WebAPIException.NOT_FOUND_ERR,
260 'Argument "stringData" missing'
265 location: commonFS_.toRealPath(this._file.fullPath),
266 encoding: this._encoding,
267 offset: this.position,
268 data: args.stringData,
269 rewrite: this._rewrite
272 var result = native_.callSync('File_writeString', data);
274 if (native_.isFailure(result)) {
275 throw new WebAPIException(WebAPIException.IO_ERR, 'Could not write');
277 can_change_size = true;
278 this.position = this.position + args.stringData.length;
279 can_change_size = false;
280 this._rewrite = false;
283 FileStream.prototype.write = function() {
284 write.apply(this, arguments);
287 function writeBytes() {
288 var args = validator_.validateArgs(arguments, [
292 values: undefined /* was types_.OCTET, but checking moved
293 to binary_to_string for performance */
298 _checkWriteAccess(this._mode);
300 if (!arguments.length) {
301 throw new WebAPIException(
302 WebAPIException.TYPE_MISMATCH_ERR,
303 'Argument "byteData" missing'
308 location: commonFS_.toRealPath(this._file.fullPath),
309 offset: this.position,
310 data: binary_to_string(args.byteData),
311 rewrite: this._rewrite
314 var result = native_.callSync('File_writeBytes', data);
316 if (native_.isFailure(result)) {
317 throw new WebAPIException(WebAPIException.IO_ERR, 'Could not write');
319 can_change_size = true;
320 this.position = this.position + args.byteData.length;
321 can_change_size = false;
322 this._rewrite = false;
325 FileStream.prototype.writeBytes = function() {
326 writeBytes.apply(this, arguments);
329 function writeBase64() {
330 var args = validator_.validateArgs(arguments, [
338 _checkWriteAccess(this._mode);
341 location: commonFS_.toRealPath(this._file.fullPath),
342 offset: this.position,
343 data: args.base64Data,
344 rewrite: this._rewrite
347 var result = native_.callSync('File_writeBase64', data);
349 if (native_.isFailure(result)) {
350 throw native_.getErrorObject(result);
353 var written_bytes = native_.getResultObject(result);
355 can_change_size = true;
356 this.position += written_bytes;
357 can_change_size = false;
358 this._rewrite = false;
361 FileStream.prototype.writeBase64 = function() {
362 writeBase64.apply(this, arguments);