return true;
}
+bool FilesystemFile::ReadString(std::vector<char>* data, size_t offset, size_t length) {
+ ScopeLogger();
+ if (!data) {
+ LoggerE("Missing output buffer");
+ return false;
+ }
+
+ data->resize(length);
+ FILE* file = fopen(path.c_str(), "r");
+ if (!file) {
+ LoggerE("Cannot open file %s to read!", path.c_str());
+ return false;
+ }
+ SCOPE_EXIT {
+ int status = fclose(file);
+ if (status) {
+ LoggerE("Cannot close file!");
+ }
+ };
+ int status;
+ status = fseek(file, offset, SEEK_SET);
+ if (status) {
+ LoggerE("Cannot perform seek!");
+ return false;
+ }
+
+ size_t readed = 0;
+ char* data_p = data->data();
+ size_t data_size = length;
+ while (readed < data->size()) {
+ size_t part = fread(data_p, 1, data_size, file);
+
+ readed += part;
+ data_p += part;
+ data_size -= part;
+
+ LoggerD("Readed part %u bytes", readed);
+
+ if (ferror(file)) {
+ LoggerE("Error during file write!");
+ return false;
+ }
+
+ if (feof(file)) {
+ LoggerD("File is at end before buffer is filled. Finish.");
+ break;
+ }
+ }
+ LoggerD("Readed %u bytes", readed);
+ data->resize(readed);
+ return true;
+}
+
bool FilesystemFile::Write(const FilesystemBuffer& data, size_t offset, bool rewrite) {
ScopeLogger();
return true;
}
+
+bool FilesystemFile::WriteString(const std::string& data, size_t offset, bool rewrite) {
+ ScopeLogger();
+
+ FILE* file = nullptr;
+ if (rewrite) {
+ file = fopen(path.c_str(), "w");
+ } else {
+ file = fopen(path.c_str(), "r+");
+ }
+
+ if (!file) {
+ LoggerE("Cannot open file %s to write!", path.c_str());
+ return false;
+ }
+
+ SCOPE_EXIT {
+ int status = fclose(file);
+ if (status) {
+ LoggerE("Cannot close file!");
+ }
+ };
+
+ int status;
+ status = fseek(file, offset, SEEK_SET);
+ LoggerD("Offset is %u, writing %i bytes", offset, data.size());
+ if (status) {
+ LoggerE("Cannot perform seek!");
+ return false;
+ }
+
+ size_t written = 0;
+ uint8_t* data_p = (uint8_t*)(data.c_str());
+ size_t data_size = data.size();
+
+ while (written < data.size()) {
+ size_t part = fwrite(data_p, 1, data_size, file);
+
+ if (ferror(file)) {
+ LoggerE("Error during file write!");
+ return false;
+ }
+
+ written += part;
+ data_p += part;
+ data_size -= part;
+ }
+
+ status = fflush(file);
+ if (status) {
+ LoggerE("Cannot flush file!");
+ return false;
+ }
+
+ status = fsync(fileno(file));
+ if (status) {
+ LoggerE("Cannot sync file!");
+ return false;
+ }
+ LoggerD("Written %u bytes", written);
+
+ return true;
+}
} // namespace filesystem
} // namespace extension
FilesystemFile(const std::string& path_);
bool Read(FilesystemBuffer* data, size_t offset, size_t length);
+ bool ReadString(std::vector<char>* data, size_t offset, size_t length);
bool Write(const FilesystemBuffer& data, size_t offset, bool rewrite);
+ bool WriteString(const std::string& data, size_t offset, bool rewrite);
};
} // namespace filesystem
REGISTER_SYNC("File_createSync", FileCreateSync);
REGISTER_ASYNC("File_readDir", ReadDir);
REGISTER_ASYNC("File_rename", FileRename);
- REGISTER_ASYNC("File_read", FileRead);
REGISTER_SYNC("File_readSync", FileReadSync);
REGISTER_ASYNC("File_write", FileWrite);
REGISTER_SYNC("File_writeSync", FileWriteSync);
std::bind(&FilesystemManager::Rename, &fsm, oldPath, newPath, onSuccess, onError));
}
-void FilesystemInstance::FileRead(const picojson::value& args, picojson::object& out) {
- ScopeLogger();
- CHECK_EXIST(args, "callbackId", out)
- CHECK_EXIST(args, "location", out)
- CHECK_EXIST(args, "offset", out)
- CHECK_EXIST(args, "length", out)
-
- double callback_id = args.get("callbackId").get<double>();
- const std::string& location = args.get("location").get<std::string>();
- size_t offset = static_cast<size_t>(args.get("offset").get<double>());
- size_t length = static_cast<size_t>(args.get("length").get<double>());
-
- auto onSuccess = [this, callback_id](const std::string& data) {
- ScopeLogger("Entered into asynchronous function, onSuccess");
- picojson::value response = picojson::value(picojson::object());
- picojson::object& obj = response.get<picojson::object>();
- obj["callbackId"] = picojson::value(callback_id);
- ReportSuccess(picojson::value(data), obj);
- PostMessage(response.serialize().c_str());
- };
-
- auto onError = [this, callback_id](FilesystemError e) {
- ScopeLogger("Entered into asynchronous function, onError");
- picojson::value response = picojson::value(picojson::object());
- picojson::object& obj = response.get<picojson::object>();
- obj["callbackId"] = picojson::value(callback_id);
- PrepareError(e, obj);
- PostMessage(response.serialize().c_str());
- };
-
- FilesystemManager& fsm = FilesystemManager::GetInstance();
- common::TaskQueue::GetInstance().Async(
- std::bind(&FilesystemManager::FileRead, &fsm, location, offset, length, onSuccess, onError));
-}
-
void FilesystemInstance::FileReadSync(const picojson::value& args, picojson::object& out) {
ScopeLogger();
CHECK_PRIVILEGE_ACCESS(kPrivilegeFilesystemRead, &out);
CHECK_EXIST(args, "location", out)
CHECK_EXIST(args, "offset", out)
CHECK_EXIST(args, "length", out)
+ CHECK_EXIST(args, "isString", out)
const std::string& location = args.get("location").get<std::string>();
size_t offset = static_cast<size_t>(args.get("offset").get<double>());
size_t length = static_cast<size_t>(args.get("length").get<double>());
+ bool is_string = static_cast<bool>(args.get("isString").get<bool>());
auto onSuccess = [this, &out](const std::string& data) {
ScopeLogger("Entered into asynchronous function, onSuccess");
PrepareError(e, out);
};
- FilesystemManager::GetInstance().FileRead(location, offset, length, onSuccess, onError);
+ FilesystemManager::GetInstance().FileRead(location, offset, length, is_string, onSuccess, onError);
}
void FilesystemInstance::FileWrite(const picojson::value& args, picojson::object& out) {
CHECK_EXIST(args, "data", out)
CHECK_EXIST(args, "offset", out)
CHECK_EXIST(args, "rewrite", out)
+ CHECK_EXIST(args, "isString", out)
double callback_id = args.get("callbackId").get<double>();
const std::string& location = args.get("location").get<std::string>();
const std::string& data = args.get("data").get<std::string>();
size_t offset = static_cast<size_t>(args.get("location").get<double>());
- bool rewrite = static_cast<size_t>(args.get("rewrite").get<bool>());
+ bool rewrite = static_cast<bool>(args.get("rewrite").get<bool>());
+ bool is_string = static_cast<bool>(args.get("isString").get<bool>());
auto onSuccess = [this, callback_id]() {
ScopeLogger("Entered into asynchronous function, onSuccess");
FilesystemManager& fsm = FilesystemManager::GetInstance();
common::TaskQueue::GetInstance().Async(std::bind(&FilesystemManager::FileWrite, &fsm, location,
- data, offset, rewrite, onSuccess, onError));
+ data, offset, rewrite, is_string, onSuccess,
+ onError));
}
void FilesystemInstance::FileWriteSync(const picojson::value& args, picojson::object& out) {
CHECK_EXIST(args, "data", out)
CHECK_EXIST(args, "offset", out)
CHECK_EXIST(args, "rewrite", out)
+ CHECK_EXIST(args, "isString", out)
const std::string& location = args.get("location").get<std::string>();
const std::string& data = args.get("data").get<std::string>();
size_t offset = static_cast<size_t>(args.get("offset").get<double>());
- bool rewrite = static_cast<size_t>(args.get("rewrite").get<bool>());
+ bool rewrite = static_cast<bool>(args.get("rewrite").get<bool>());
+ bool is_string = static_cast<bool>(args.get("isString").get<bool>());
auto onSuccess = [this, &out]() {
ScopeLogger("Entered into asynchronous function, onSuccess");
PrepareError(e, out);
};
- FilesystemManager::GetInstance().FileWrite(location, data, offset, rewrite, onSuccess, onError);
+ FilesystemManager::GetInstance().FileWrite(location, data, offset, rewrite, is_string, onSuccess,
+ onError);
}
void FilesystemInstance::FileStat(const picojson::value& args, picojson::object& out) {
}
void FilesystemManager::FileRead(const std::string& path, size_t offset, size_t length,
+ bool is_string,
const std::function<void(const std::string&)>& success_cb,
const std::function<void(FilesystemError)>& error_cb) {
ScopeLogger();
FilesystemFile file(path);
- FilesystemBuffer buffer;
- if (!file.Read(&buffer, offset, length)) {
- LoggerE("Cannot read file %s", path.c_str());
- error_cb(FilesystemError::Other);
- return;
- }
- std::string out_data = buffer.EncodeData();
- success_cb(out_data);
+ // Encode data if its type is not string
+ if (!is_string) {
+ FilesystemBuffer buffer;
+ if (!file.Read(&buffer, offset, length)) {
+ LoggerE("Cannot read file %s", path.c_str());
+ error_cb(FilesystemError::Other);
+ return;
+ }
+ std::string out_data = buffer.EncodeData();
+ success_cb(out_data);
+ } else {
+ std::vector<char> buffer(length);
+ if (!file.ReadString(&buffer, offset, length)) {
+ LoggerE("Cannot read file %s", path.c_str());
+ error_cb(FilesystemError::Other);
+ return;
+ }
+ std::string out_data(buffer.begin(), buffer.end());
+ success_cb(out_data);
+ }
}
void FilesystemManager::FileWrite(const std::string& path, const std::string& data, size_t offset,
- bool rewrite, const std::function<void()>& success_cb,
+ bool rewrite, bool is_string,
+ const std::function<void()>& success_cb,
const std::function<void(FilesystemError)>& error_cb) {
ScopeLogger();
FilesystemFile file(path);
FilesystemBuffer buffer;
- // Decode buffer data
- if (!buffer.DecodeData(data)) {
- LoggerE("Cannot decode file data!");
- error_cb(FilesystemError::Other);
- return;
- }
-
- if (file.Write(buffer, offset, rewrite)) {
+ // Decode buffer data if type is not string
+ if (!is_string) {
+ if (!buffer.DecodeData(data)) {
+ LoggerE("Cannot decode file data!");
+ error_cb(FilesystemError::Other);
+ return;
+ }
+ if (file.Write(buffer, offset, rewrite)) {
+ success_cb();
+ } else {
+ LoggerE("Cannot write to file %s!", path.c_str());
+ error_cb(FilesystemError::Other);
+ }
+ } else if (file.WriteString(data, offset, rewrite)) {
success_cb();
} else {
LoggerE("Cannot write to file %s!", path.c_str());
void RemoveDirectory(const std::string& path, const std::function<void()>& success_cb,
const std::function<void(FilesystemError)>& error_cb);
- void FileRead(const std::string& path, size_t offset, size_t length,
+ void FileRead(const std::string& path, size_t offset, size_t length, bool is_string,
const std::function<void(const std::string&)>& success_cb,
const std::function<void(FilesystemError)>& error_cb);
void FileWrite(const std::string& path, const std::string& data, size_t offset, bool rewrite,
- const std::function<void()>& success_cb,
+ bool is_string, const std::function<void()>& success_cb,
const std::function<void(FilesystemError)>& error_cb);
void CopyTo(const std::string& originFilePath, const std::string& destinationFilePath,
location: commonFS_.toRealPath(this.fullPath),
offset: 0,
length: 65536,
- encoding: args.encoding
+ encoding: args.encoding,
+ isString: true
};
function readFile() {
var result, encoded, buffers = [];
- do {
- result = native_.callSync('File_readSync', data);
- if (native_.isFailure(result)) {
- setTimeout(function() {
- native_.callIfPossible(args.onerror, native_.getErrorObject(result));
- }, 0);
- return;
- }
- encoded = native_.getResultObject(result);
- if (encoded.length) {
- buffers.push( Base64.decode(encoded) );
- data.offset += data.length;
- }
- } while (encoded.length);
-
- var buffer = Array.prototype.concat.apply([], buffers);
+ result = native_.callSync('File_readSync', data);
+ if (native_.isFailure(result)) {
+ setTimeout(function() {
+ native_.callIfPossible(args.onerror, native_.getErrorObject(result));
+ }, 0);
+ return;
+ }
+ result = native_.getResultObject(result);
+ if (result.length) {
+ data.offset += data.length;
+ }
setTimeout(function() {
- native_.callIfPossible(args.onsuccess, Base64._utf8_decode(buffer) );
+ native_.callIfPossible(args.onsuccess, result);
}, 0);
}
var data = {
location: commonFS_.toRealPath(this._file.fullPath),
offset: this.position || 0,
- length: args.charCount > _count ? _count : args.charCount
+ length: args.charCount > _count ? _count : args.charCount,
+ isString: true
};
var result = native_.callSync('File_readSync', data);
if (native_.isFailure(result)) {
throw new WebAPIException(WebAPIException.IO_ERR, 'Could not read');
}
- var decoded = Base64.decodeString(native_.getResultObject(result));
+ var outData = native_.getResultObject(result);
- if (decoded.length) {
+ if (outData.length) {
can_change_size = true;
- this.position += decoded.length;
+ this.position += outData.length;
can_change_size = false;
} else {
this.position += 1; // Set EOF
}
- return decoded;
+ return outData;
};
FileStream.prototype.read = function() {
var data = {
location: commonFS_.toRealPath(this._file.fullPath),
offset: this.position || 0,
- length: args.byteCount > _count ? _count : args.byteCount
+ length: args.byteCount > _count ? _count : args.byteCount,
+ isString: false
};
var result = native_.callSync('File_readSync', data);
var data = {
location: commonFS_.toRealPath(this._file.fullPath),
offset: this.position || 0,
- length: args.byteCount > _count ? _count : args.byteCount
+ length: args.byteCount > _count ? _count : args.byteCount,
+ isString: false
};
var result = native_.callSync('File_readSync', data);
var data = {
location: commonFS_.toRealPath(this._file.fullPath),
offset: this.position,
- data: Base64.encodeString(args.stringData),
- rewrite: this._rewrite
+ data: args.stringData,
+ rewrite: this._rewrite,
+ isString: true
};
var result = native_.callSync('File_writeSync', data);
location: commonFS_.toRealPath(this._file.fullPath),
offset: this.position,
data: Base64.encode(args.byteData),
- rewrite: this._rewrite
+ rewrite: this._rewrite,
+ isString: false
};
var result = native_.callSync('File_writeSync', data);
location: commonFS_.toRealPath(this._file.fullPath),
offset: this.position,
data: args.base64Data,
- rewrite: this._rewrite
+ rewrite: this._rewrite,
+ isString: false
};
var result = native_.callSync('File_writeSync', data);