node-opcua-file-transfer 2.113.0 → 2.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/client_file.js +191 -220
- package/dist/client/client_file.js.map +1 -1
- package/dist/client/read_file.js +31 -44
- package/dist/client/read_file.js.map +1 -1
- package/dist/client/read_max_byte_string_length.js +8 -19
- package/dist/client/read_max_byte_string_length.js.map +1 -1
- package/dist/client/write_file.js +34 -45
- package/dist/client/write_file.js.map +1 -1
- package/dist/server/file_type_helpers.js +262 -292
- package/dist/server/file_type_helpers.js.map +1 -1
- package/package.json +20 -20
|
@@ -25,15 +25,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
__setModuleDefault(result, mod);
|
|
26
26
|
return result;
|
|
27
27
|
};
|
|
28
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
29
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
30
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
31
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
32
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
33
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
34
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
35
|
-
});
|
|
36
|
-
};
|
|
37
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
29
|
exports.installFileType = exports.defaultMaxSize = exports.getFileData = exports.writeFile = exports.FileTypeData = void 0;
|
|
39
30
|
const util_1 = require("util");
|
|
@@ -100,62 +91,54 @@ class FileTypeData {
|
|
|
100
91
|
* is modified externally
|
|
101
92
|
*
|
|
102
93
|
*/
|
|
103
|
-
refresh() {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
self._fileSize = stat.size;
|
|
116
|
-
debugLog("original file size ", self.filename, " size = ", self._fileSize);
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
self._fileSize = 0;
|
|
120
|
-
if (util_1.types.isNativeError(err)) {
|
|
121
|
-
warningLog("Cannot access file ", self.filename, err.message);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
})(this);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
refreshFileContent() {
|
|
129
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
-
if (this.refreshFileContentFunc) {
|
|
131
|
-
yield this.refreshFileContentFunc();
|
|
132
|
-
yield this.refresh();
|
|
94
|
+
async refresh() {
|
|
95
|
+
const abstractFs = this._fs;
|
|
96
|
+
// lauch an async request to update filesize
|
|
97
|
+
await (async function extractFileSize(self) {
|
|
98
|
+
try {
|
|
99
|
+
if (!abstractFs.existsSync(self.filename)) {
|
|
100
|
+
self._fileSize = 0;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const stat = await (0, util_1.promisify)(abstractFs.stat)(self.filename);
|
|
104
|
+
self._fileSize = stat.size;
|
|
105
|
+
debugLog("original file size ", self.filename, " size = ", self._fileSize);
|
|
133
106
|
}
|
|
134
|
-
|
|
107
|
+
catch (err) {
|
|
108
|
+
self._fileSize = 0;
|
|
109
|
+
if (util_1.types.isNativeError(err)) {
|
|
110
|
+
warningLog("Cannot access file ", self.filename, err.message);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
})(this);
|
|
114
|
+
}
|
|
115
|
+
async refreshFileContent() {
|
|
116
|
+
if (this.refreshFileContentFunc) {
|
|
117
|
+
await this.refreshFileContentFunc();
|
|
118
|
+
await this.refresh();
|
|
119
|
+
}
|
|
135
120
|
}
|
|
136
121
|
}
|
|
137
122
|
exports.FileTypeData = FileTypeData;
|
|
138
123
|
FileTypeData.maxChunkSize = 16 * 1024 * 1024; // 16 MB
|
|
139
|
-
function writeFile(fileSystem, filename, content) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
124
|
+
async function writeFile(fileSystem, filename, content) {
|
|
125
|
+
await new Promise((resolve, reject) => {
|
|
126
|
+
fileSystem.open(filename, "w", (err, fd) => {
|
|
127
|
+
// istanbul ignore next
|
|
128
|
+
if (err) {
|
|
129
|
+
return reject(err);
|
|
130
|
+
}
|
|
131
|
+
fileSystem.write(fd, content, 0, content.length, 0, (err) => {
|
|
143
132
|
// istanbul ignore next
|
|
144
133
|
if (err) {
|
|
145
134
|
return reject(err);
|
|
146
135
|
}
|
|
147
|
-
fileSystem.
|
|
136
|
+
fileSystem.close(fd, (err) => {
|
|
148
137
|
// istanbul ignore next
|
|
149
138
|
if (err) {
|
|
150
139
|
return reject(err);
|
|
151
140
|
}
|
|
152
|
-
|
|
153
|
-
// istanbul ignore next
|
|
154
|
-
if (err) {
|
|
155
|
-
return reject(err);
|
|
156
|
-
}
|
|
157
|
-
resolve();
|
|
158
|
-
});
|
|
141
|
+
resolve();
|
|
159
142
|
});
|
|
160
143
|
});
|
|
161
144
|
});
|
|
@@ -179,12 +162,11 @@ function _prepare(addressSpace, context) {
|
|
|
179
162
|
return _context;
|
|
180
163
|
}
|
|
181
164
|
function _getSessionId(context) {
|
|
182
|
-
var _a;
|
|
183
165
|
if (!context.session) {
|
|
184
166
|
return new node_opcua_nodeid_1.NodeId();
|
|
185
167
|
}
|
|
186
168
|
(0, node_opcua_assert_1.assert)(context.session && context.session.getSessionId);
|
|
187
|
-
return
|
|
169
|
+
return context.session?.getSessionId() || new node_opcua_nodeid_1.NodeId();
|
|
188
170
|
}
|
|
189
171
|
function _addFile(addressSpace, context, openMode) {
|
|
190
172
|
const _context = _prepare(addressSpace, context);
|
|
@@ -262,88 +244,86 @@ function toNodeJSMode(opcuaMode) {
|
|
|
262
244
|
*
|
|
263
245
|
* @private
|
|
264
246
|
*/
|
|
265
|
-
function _openFile(inputArguments, context) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
247
|
+
async function _openFile(inputArguments, context) {
|
|
248
|
+
const addressSpace = this.addressSpace;
|
|
249
|
+
const mode = inputArguments[0].value;
|
|
250
|
+
/**
|
|
251
|
+
* mode (Byte) Indicates whether the file should be opened only for read operations
|
|
252
|
+
* or for read and write operations and where the initial position is set.
|
|
253
|
+
* The mode is an 8-bit unsigned integer used as bit mask with the structure
|
|
254
|
+
* defined in the following table:
|
|
255
|
+
* Field Bit Description
|
|
256
|
+
* Read 0 The file is opened for reading. If this bit is not
|
|
257
|
+
* set the Read Method cannot be executed.
|
|
258
|
+
* Write 1 The file is opened for writing. If this bit is not
|
|
259
|
+
* set the Write Method cannot be executed.
|
|
260
|
+
* EraseExisting 2 This bit can only be set if the file is opened for writing
|
|
261
|
+
* (Write bit is set). The existing content of the file is
|
|
262
|
+
* erased and an empty file is provided.
|
|
263
|
+
* Append 3 When the Append bit is set the file is opened at end
|
|
264
|
+
* of the file, otherwise at begin of the file.
|
|
265
|
+
* The SetPosition Method can be used to change the position.
|
|
266
|
+
* Reserved 4:7 Reserved for future use. Shall always be zero.
|
|
267
|
+
*/
|
|
268
|
+
// see https://nodejs.org/api/fs.html#fs_file_system_flags
|
|
269
|
+
const flags = toNodeJSMode(mode);
|
|
270
|
+
if (flags === "?") {
|
|
271
|
+
errorLog("Invalid mode " + open_mode_1.OpenFileMode[mode] + " (" + mode + ")");
|
|
272
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* fileHandle (UInt32) A handle for the file used in other method calls indicating not the
|
|
276
|
+
* file (this is done by the Object of the Method call) but the access
|
|
277
|
+
* request and thus the position in the file. The fileHandle is generated
|
|
278
|
+
* by the server and is unique for the Session. Clients cannot transfer the
|
|
279
|
+
* fileHandle to another Session but need to get a new fileHandle by calling
|
|
280
|
+
* the Open Method.
|
|
281
|
+
*/
|
|
282
|
+
const fileHandle = _addFile(addressSpace, context, mode);
|
|
283
|
+
const _fileInfo = _getFileInfo(addressSpace, context, fileHandle);
|
|
284
|
+
if (!_fileInfo) {
|
|
285
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
286
|
+
}
|
|
287
|
+
const fileData = getFileDataFromContext(context);
|
|
288
|
+
const filename = fileData.filename;
|
|
289
|
+
// make sure file is up to date ... by delegating
|
|
290
|
+
if (mode === open_mode_1.OpenFileMode.Read) {
|
|
291
|
+
await fileData.refreshFileContent();
|
|
292
|
+
}
|
|
293
|
+
const abstractFs = _getFileSystem(context);
|
|
294
|
+
try {
|
|
295
|
+
_fileInfo.fd = await (0, util_1.promisify)(abstractFs.open)(filename, flags);
|
|
296
|
+
// update position
|
|
297
|
+
_fileInfo.position = [0, 0];
|
|
298
|
+
const fileLength = (await (0, util_1.promisify)(abstractFs.stat)(filename)).size;
|
|
299
|
+
_fileInfo.size = fileLength;
|
|
300
|
+
// tslint:disable-next-line:no-bitwise
|
|
301
|
+
if ((mode & open_mode_1.OpenFileModeMask.AppendBit) === open_mode_1.OpenFileModeMask.AppendBit) {
|
|
302
|
+
_fileInfo.position[1] = fileLength;
|
|
305
303
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
// make sure file is up to date ... by delegating
|
|
309
|
-
if (mode === open_mode_1.OpenFileMode.Read) {
|
|
310
|
-
yield fileData.refreshFileContent();
|
|
304
|
+
if ((mode & open_mode_1.OpenFileModeMask.EraseExistingBit) === open_mode_1.OpenFileModeMask.EraseExistingBit) {
|
|
305
|
+
_fileInfo.size = 0;
|
|
311
306
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
_fileInfo.size = fileLength;
|
|
319
|
-
// tslint:disable-next-line:no-bitwise
|
|
320
|
-
if ((mode & open_mode_1.OpenFileModeMask.AppendBit) === open_mode_1.OpenFileModeMask.AppendBit) {
|
|
321
|
-
_fileInfo.position[1] = fileLength;
|
|
322
|
-
}
|
|
323
|
-
if ((mode & open_mode_1.OpenFileModeMask.EraseExistingBit) === open_mode_1.OpenFileModeMask.EraseExistingBit) {
|
|
324
|
-
_fileInfo.size = 0;
|
|
325
|
-
}
|
|
326
|
-
fileData.openCount += 1;
|
|
307
|
+
fileData.openCount += 1;
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
if (util_1.types.isNativeError(err)) {
|
|
311
|
+
errorLog(err.message);
|
|
312
|
+
errorLog(err.stack);
|
|
327
313
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
314
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadUnexpectedError };
|
|
315
|
+
}
|
|
316
|
+
debugLog("Opening file handle ", fileHandle, "filename: ", fileData.filename, "openCount: ", fileData.openCount);
|
|
317
|
+
const callMethodResult = {
|
|
318
|
+
outputArguments: [
|
|
319
|
+
{
|
|
320
|
+
dataType: node_opcua_variant_1.DataType.UInt32,
|
|
321
|
+
value: fileHandle
|
|
332
322
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
outputArguments: [
|
|
338
|
-
{
|
|
339
|
-
dataType: node_opcua_variant_1.DataType.UInt32,
|
|
340
|
-
value: fileHandle
|
|
341
|
-
}
|
|
342
|
-
],
|
|
343
|
-
statusCode: node_opcua_status_code_1.StatusCodes.Good
|
|
344
|
-
};
|
|
345
|
-
return callMethodResult;
|
|
346
|
-
});
|
|
323
|
+
],
|
|
324
|
+
statusCode: node_opcua_status_code_1.StatusCodes.Good
|
|
325
|
+
};
|
|
326
|
+
return callMethodResult;
|
|
347
327
|
}
|
|
348
328
|
function _getFileSystem(context) {
|
|
349
329
|
const fs = getFileDataFromContext(context)._fs;
|
|
@@ -357,24 +337,22 @@ function _getFileSystem(context) {
|
|
|
357
337
|
* @param context
|
|
358
338
|
* @private
|
|
359
339
|
*/
|
|
360
|
-
function _closeFile(inputArguments, context) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
};
|
|
377
|
-
});
|
|
340
|
+
async function _closeFile(inputArguments, context) {
|
|
341
|
+
const abstractFs = _getFileSystem(context);
|
|
342
|
+
const addressSpace = this.addressSpace;
|
|
343
|
+
const fileHandle = inputArguments[0].value;
|
|
344
|
+
const _fileInfo = _getFileInfo(addressSpace, context, fileHandle);
|
|
345
|
+
if (!_fileInfo) {
|
|
346
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
347
|
+
}
|
|
348
|
+
const fileData = getFileDataFromContext(context);
|
|
349
|
+
debugLog("Closing file handle ", fileHandle, "filename: ", fileData.filename, "openCount: ", fileData.openCount);
|
|
350
|
+
await (0, util_1.promisify)(abstractFs.close)(_fileInfo.fd);
|
|
351
|
+
_close(addressSpace, context, _fileInfo);
|
|
352
|
+
fileData.openCount -= 1;
|
|
353
|
+
return {
|
|
354
|
+
statusCode: node_opcua_status_code_1.StatusCodes.Good
|
|
355
|
+
};
|
|
378
356
|
}
|
|
379
357
|
/**
|
|
380
358
|
* Read is used to read a part of the file starting from the current file position.
|
|
@@ -384,156 +362,148 @@ function _closeFile(inputArguments, context) {
|
|
|
384
362
|
* @param context
|
|
385
363
|
* @private
|
|
386
364
|
*/
|
|
387
|
-
function _readFile(inputArguments, context) {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
365
|
+
async function _readFile(inputArguments, context) {
|
|
366
|
+
const addressSpace = this.addressSpace;
|
|
367
|
+
const abstractFs = _getFileSystem(context);
|
|
368
|
+
// fileHandle A handle indicating the access request and thus indirectly the
|
|
369
|
+
// position inside the file.
|
|
370
|
+
const fileHandle = inputArguments[0].value;
|
|
371
|
+
// Length Defines the length in bytes that should be returned in data, starting from the current
|
|
372
|
+
// position of the file handle. If the end of file is reached all data until the end of the file is
|
|
373
|
+
// returned.
|
|
374
|
+
let length = inputArguments[1].value;
|
|
375
|
+
// Only positive values are allowed.
|
|
376
|
+
if (length < 0) {
|
|
377
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
378
|
+
}
|
|
379
|
+
const _fileInfo = _getFileInfo(addressSpace, context, fileHandle);
|
|
380
|
+
if (!_fileInfo) {
|
|
381
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidState };
|
|
382
|
+
}
|
|
383
|
+
// tslint:disable-next-line:no-bitwise
|
|
384
|
+
if ((_fileInfo.openMode & open_mode_1.OpenFileModeMask.ReadBit) === 0x0) {
|
|
385
|
+
// open mode did not specify Read Flag
|
|
386
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidState };
|
|
387
|
+
}
|
|
388
|
+
// Spec says that the the Server is allowed to return less data than specified length.
|
|
389
|
+
//
|
|
390
|
+
// In particular, we have to make sure that the number og bytes returned is not greater than
|
|
391
|
+
// the maxChunkSizeBytes specified in the server configuration.
|
|
392
|
+
// length cannot exceed maxChunkSizeBytes
|
|
393
|
+
const fileData = getFileDataFromContext(context);
|
|
394
|
+
const maxChunkSizeBytes = fileData.maxChunkSizeBytes;
|
|
395
|
+
if (length > maxChunkSizeBytes) {
|
|
396
|
+
length = maxChunkSizeBytes;
|
|
397
|
+
}
|
|
398
|
+
// length cannot either exceed ByteStream.maxChunkSizeBytes
|
|
399
|
+
if (length > node_opcua_binary_stream_1.BinaryStream.maxByteStringLength) {
|
|
400
|
+
length = node_opcua_binary_stream_1.BinaryStream.maxByteStringLength;
|
|
401
|
+
}
|
|
402
|
+
// length cannot either exceed transport OPCUA maxMessageLength - some margin.
|
|
403
|
+
const maxMessageSize = (0, node_opcua_address_space_base_1.getContextMaxMessageSize)(context) - 1024;
|
|
404
|
+
if (maxMessageSize > 0 && length > maxMessageSize) {
|
|
405
|
+
length = maxMessageSize;
|
|
406
|
+
}
|
|
407
|
+
// length cannot either exceed remaining buffer size from current position
|
|
408
|
+
length = Math.min(_fileInfo.size - _fileInfo.position[1], length);
|
|
409
|
+
const data = Buffer.alloc(length);
|
|
410
|
+
let ret = { bytesRead: 0 };
|
|
411
|
+
try {
|
|
412
|
+
// note: we do not util.promise here as it has a wierd behavior...
|
|
413
|
+
ret = await new Promise((resolve, reject) => abstractFs.read(_fileInfo.fd, data, 0, length, _fileInfo.position[1], (err, bytesRead, buff) => {
|
|
414
|
+
if (err) {
|
|
415
|
+
return reject(err);
|
|
416
|
+
}
|
|
417
|
+
return resolve({ bytesRead });
|
|
418
|
+
}));
|
|
419
|
+
_fileInfo.position[1] += ret.bytesRead;
|
|
420
|
+
}
|
|
421
|
+
catch (err) {
|
|
422
|
+
if (util_1.types.isNativeError(err)) {
|
|
423
|
+
errorLog("Read error : ", err.message);
|
|
429
424
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
425
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadUnexpectedError };
|
|
426
|
+
}
|
|
427
|
+
// Data Contains the returned data of the file. If the ByteString is empty it indicates that the end
|
|
428
|
+
// of the file is reached.
|
|
429
|
+
return {
|
|
430
|
+
outputArguments: [{ dataType: node_opcua_variant_1.DataType.ByteString, value: data.subarray(0, ret.bytesRead) }],
|
|
431
|
+
statusCode: node_opcua_status_code_1.StatusCodes.Good
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
async function _writeFile(inputArguments, context) {
|
|
435
|
+
const addressSpace = this.addressSpace;
|
|
436
|
+
const abstractFs = _getFileSystem(context);
|
|
437
|
+
const fileHandle = inputArguments[0].value;
|
|
438
|
+
const _fileInfo = _getFileInfo(addressSpace, context, fileHandle);
|
|
439
|
+
if (!_fileInfo) {
|
|
440
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
441
|
+
}
|
|
442
|
+
// tslint:disable-next-line:no-bitwise
|
|
443
|
+
if ((_fileInfo.openMode & open_mode_1.OpenFileModeMask.WriteBit) === 0x00) {
|
|
444
|
+
// File has not been open with write mode
|
|
445
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidState };
|
|
446
|
+
}
|
|
447
|
+
const data = inputArguments[1].value;
|
|
448
|
+
let ret = { bytesWritten: 0 };
|
|
449
|
+
try {
|
|
450
|
+
// note: we do not util.promise here as it has a wierd behavior...
|
|
451
|
+
ret = await new Promise((resolve, reject) => {
|
|
452
|
+
abstractFs.write(_fileInfo.fd, data, 0, data.length, _fileInfo.position[1], (err, bytesWritten) => {
|
|
437
453
|
if (err) {
|
|
454
|
+
errorLog("Err", err);
|
|
438
455
|
return reject(err);
|
|
439
456
|
}
|
|
440
|
-
return resolve({
|
|
441
|
-
}));
|
|
442
|
-
_fileInfo.position[1] += ret.bytesRead;
|
|
443
|
-
}
|
|
444
|
-
catch (err) {
|
|
445
|
-
if (util_1.types.isNativeError(err)) {
|
|
446
|
-
errorLog("Read error : ", err.message);
|
|
447
|
-
}
|
|
448
|
-
return { statusCode: node_opcua_status_code_1.StatusCodes.BadUnexpectedError };
|
|
449
|
-
}
|
|
450
|
-
// Data Contains the returned data of the file. If the ByteString is empty it indicates that the end
|
|
451
|
-
// of the file is reached.
|
|
452
|
-
return {
|
|
453
|
-
outputArguments: [{ dataType: node_opcua_variant_1.DataType.ByteString, value: data.subarray(0, ret.bytesRead) }],
|
|
454
|
-
statusCode: node_opcua_status_code_1.StatusCodes.Good
|
|
455
|
-
};
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
function _writeFile(inputArguments, context) {
|
|
459
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
460
|
-
const addressSpace = this.addressSpace;
|
|
461
|
-
const abstractFs = _getFileSystem(context);
|
|
462
|
-
const fileHandle = inputArguments[0].value;
|
|
463
|
-
const _fileInfo = _getFileInfo(addressSpace, context, fileHandle);
|
|
464
|
-
if (!_fileInfo) {
|
|
465
|
-
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
466
|
-
}
|
|
467
|
-
// tslint:disable-next-line:no-bitwise
|
|
468
|
-
if ((_fileInfo.openMode & open_mode_1.OpenFileModeMask.WriteBit) === 0x00) {
|
|
469
|
-
// File has not been open with write mode
|
|
470
|
-
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidState };
|
|
471
|
-
}
|
|
472
|
-
const data = inputArguments[1].value;
|
|
473
|
-
let ret = { bytesWritten: 0 };
|
|
474
|
-
try {
|
|
475
|
-
// note: we do not util.promise here as it has a wierd behavior...
|
|
476
|
-
ret = yield new Promise((resolve, reject) => {
|
|
477
|
-
abstractFs.write(_fileInfo.fd, data, 0, data.length, _fileInfo.position[1], (err, bytesWritten) => {
|
|
478
|
-
if (err) {
|
|
479
|
-
errorLog("Err", err);
|
|
480
|
-
return reject(err);
|
|
481
|
-
}
|
|
482
|
-
return resolve({ bytesWritten });
|
|
483
|
-
});
|
|
457
|
+
return resolve({ bytesWritten });
|
|
484
458
|
});
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
return { statusCode: node_opcua_status_code_1.StatusCodes.BadUnexpectedError };
|
|
459
|
+
});
|
|
460
|
+
(0, node_opcua_assert_1.assert)(typeof ret.bytesWritten === "number");
|
|
461
|
+
_fileInfo.position[1] += ret.bytesWritten;
|
|
462
|
+
_fileInfo.size = Math.max(_fileInfo.size, _fileInfo.position[1]);
|
|
463
|
+
const fileData = getFileDataFromContext(context);
|
|
464
|
+
debugLog(fileData.fileSize);
|
|
465
|
+
fileData.fileSize = Math.max(fileData.fileSize, _fileInfo.position[1]);
|
|
466
|
+
debugLog(fileData.fileSize);
|
|
467
|
+
}
|
|
468
|
+
catch (err) {
|
|
469
|
+
if (util_1.types.isNativeError(err)) {
|
|
470
|
+
errorLog("Write error : ", err.message);
|
|
498
471
|
}
|
|
499
|
-
return {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
472
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadUnexpectedError };
|
|
473
|
+
}
|
|
474
|
+
return {
|
|
475
|
+
outputArguments: [],
|
|
476
|
+
statusCode: node_opcua_status_code_1.StatusCodes.Good
|
|
477
|
+
};
|
|
504
478
|
}
|
|
505
|
-
function _setPositionFile(inputArguments, context) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
return { statusCode: node_opcua_status_code_1.StatusCodes.Good };
|
|
516
|
-
});
|
|
479
|
+
async function _setPositionFile(inputArguments, context) {
|
|
480
|
+
const addressSpace = this.addressSpace;
|
|
481
|
+
const fileHandle = inputArguments[0].value;
|
|
482
|
+
const position = inputArguments[1].value;
|
|
483
|
+
const _fileInfo = _getFileInfo(addressSpace, context, fileHandle);
|
|
484
|
+
if (!_fileInfo) {
|
|
485
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
486
|
+
}
|
|
487
|
+
_fileInfo.position = position;
|
|
488
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.Good };
|
|
517
489
|
}
|
|
518
|
-
function _getPositionFile(inputArguments, context) {
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
};
|
|
536
|
-
});
|
|
490
|
+
async function _getPositionFile(inputArguments, context) {
|
|
491
|
+
const addressSpace = this.addressSpace;
|
|
492
|
+
const fileHandle = inputArguments[0].value;
|
|
493
|
+
const _fileInfo = _getFileInfo(addressSpace, context, fileHandle);
|
|
494
|
+
if (!_fileInfo) {
|
|
495
|
+
return { statusCode: node_opcua_status_code_1.StatusCodes.BadInvalidArgument };
|
|
496
|
+
}
|
|
497
|
+
return {
|
|
498
|
+
outputArguments: [
|
|
499
|
+
{
|
|
500
|
+
arrayType: node_opcua_variant_1.VariantArrayType.Scalar,
|
|
501
|
+
dataType: node_opcua_variant_1.DataType.UInt64,
|
|
502
|
+
value: _fileInfo.position
|
|
503
|
+
}
|
|
504
|
+
],
|
|
505
|
+
statusCode: node_opcua_status_code_1.StatusCodes.Good
|
|
506
|
+
};
|
|
537
507
|
}
|
|
538
508
|
exports.defaultMaxSize = 100000000;
|
|
539
509
|
function install_method_handle_on_type(addressSpace) {
|