Skip to content

Commit

Permalink
Merge pull request #97 from IBM/support-ascii-no-trailing-blanks
Browse files Browse the repository at this point in the history
Support ascii_no_trailing_blanks
  • Loading branch information
std4lqi authored Jan 9, 2024
2 parents 3366915 + 8187e28 commit 60cdfd2
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 21 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,7 @@ connection.uploadDataset(input, 'HLQ.HOSTS', "LRECL=80 RECFM=FB")
##### Parameter

* dsn - _string_ - Specify a full qualified dataset name, or USS file name. It **CAN NOT** contain any wildcard (*).
* dataType - _string (default: 'ascii')_ - Transfer data type, accepts three options `binary`, `ascii`, `ascii_strip_eol`, `ascii_rdw` or `binary_rdw`. When downloading an ascii dataset, dataType should be either `ascii` or `ascii_strip_eol` so that the FTP server converts `EBCDIC` characters to `ASCII`, `ascii_strip_eol` tells FTP server not the append a CLRF to the end of each record. The `ascii_rdw` or `binary_rdw`
can be used to download variable-length dataset like V, VB, VBS, etc. The 4-byte RDW (Record Descriptor Word) is inserted at the beginning
of each record.
* dataType - _string (default: 'ascii')_ - Transfer data type, accepts the options of `binary`, `ascii`, `ascii_strip_eol`, `ascii_no_trailing_blanks`, `ascii_rdw` or `binary_rdw`. The option `ascii`, or `ascii_strip_eol`, `ascii_no_trailing_blanks`, or `ascii_rdw` tells FTP server convert `EBCDIC` characters to `ASCII`. The option `ascii_strip_eol` tells FTP server not the append a CLRF to the end of each record. The option `ascii_no_trailing_blanks` tells FTP server remove the trailing blanks. The option `ascii_rdw` or `binary_rdw` can be used to download variable-length dataset like V, VB, VBS, etc. The 4-byte RDW (Record Descriptor Word) is inserted at the beginning of each record.
* stream - _boolean (default: false)_ - `true` if you want to obtain a [ReadableStream](https://nodejs.org/api/stream.html#stream_readable_streams) of the data set content, or `false` to read a full dataset into memory (in Buffer).
* params - _string_ - Add extra site parameters, for example, 'sbd=(IBM-1047,ISO8859-1)' for encoding setting.

Expand Down Expand Up @@ -669,7 +667,7 @@ This module adopts the [Module Long Term Support (LTS)](http://github.com/CloudN

| Module Version | Release Date | Minimum EOL | EOL With | Status |
|------------------|--------------|-------------|--------------|---------|
| 1.x.x | Oct 2018 | Dec 2019 | | Current |
| 1.x.x | Oct 2018 | Dec 2019 | | Current |

## License

Expand Down
32 changes: 20 additions & 12 deletions lib/zosAccessor.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/****************************************************************************/
/* */
/* Copyright (c) 2017, 2021 IBM Corp. */
/* Copyright (c) 2017, 2023 IBM Corp. */
/* All rights reserved. This program and the accompanying materials */
/* are made available under the terms of the Eclipse Public License v1.0 */
/* which accompanies this distribution, and is available at */
Expand Down Expand Up @@ -210,43 +210,51 @@ ZosAccessor.prototype.uploadDataset = function(input, destDataset, dataType, all
* Download dataset.
*
* @param {string} dsn - Dataset name
* @param {string} dataType - 'ascii' or 'binary' or 'ascii_strip_eol' or 'ascii_rdw' or 'binary_rdw'
* @param {string} dataType - 'ascii', 'binary', 'ascii_strip_eol', 'ascii_no_trailing_blanks', 'ascii_rdw', or 'binary_rdw'
* @param {boolean} stream - Resolve stream as result or not
* @param {string} params - Add extra site parameters, for example, 'sbd=(IBM-1047,ISO8859-1)' for encoding setting.
*/
ZosAccessor.prototype.getDataset = function (dsn, dataType, stream, params) {
var deferred = Q.defer();
var ftpClient = this.client;
dataType = dataType || 'ascii';
if(dataType !== 'ascii' && dataType !== 'binary' && dataType !== 'ascii_strip_eol' && dataType !== 'ascii_rdw' && dataType !== 'binary_rdw') {
if(dataType !== 'ascii'
&& dataType !== 'binary'
&& dataType !== 'ascii_strip_eol'
&& dataType !== 'ascii_no_trailing_blanks'
&& dataType !== 'ascii_rdw'
&& dataType !== 'binary_rdw') {
throw new Error('Unsupported data type: ' + dataType);
}
var sbsendeol = 'SBSENDEOL=CRLF';
var rdw = '';
var ftpDataType = 'binary';
var trailingBlanks = 'TRAILINGBLANKS';

if (dataType === 'ascii' || dataType === 'ascii_strip_eol' || dataType === 'ascii_no_trailing_blanks' || dataType === 'ascii_rdw') {
ftpDataType = 'ascii';
}
if (dataType === 'ascii_strip_eol') {
sbsendeol = 'SBSENDEOL=NONE';
dataType = 'ascii';
rdw = '';
}
if (dataType === 'ascii_rdw') {
dataType = 'ascii';
rdw = 'rdw';
} else if (dataType === 'binary_rdw') {
dataType = 'binary';
if (dataType === 'ascii_rdw' || dataType === 'binary_rdw') {
rdw = 'rdw';
}
if (dataType === 'ascii_no_trailing_blanks') {
trailingBlanks = '';
}

var siteParams = [];
siteParams.push('FILETYPE=SEQ');
siteParams.push('TRAILINGBLANKS');
siteParams.push(trailingBlanks);
siteParams.push(sbsendeol);
siteParams.push(rdw);

if(params !== undefined && params !== '') {
siteParams.push(params);
}

ftpClient[dataType](function (err) {
ftpClient[ftpDataType](function (err) {
if (err) {
return deferred.reject(err);
}
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zos-node-accessor",
"version": "1.0.15",
"version": "1.0.16",
"description": "Accessing z/OS dataset and interacting with JES in NodeJS way",
"main": "./lib/zosAccessor",
"scripts": {
Expand Down
57 changes: 55 additions & 2 deletions test/zos.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ describe('Integration test cases for z/OS node accessor', function() {
});

// The dataset "<USERNAME>.NODEACC.HELLO" is required on MVS.
it('can get MVS dataset in ASCII mode', function(done) {
it('can get MVS dataset in ascii mode', function(done) {
var text = 'HELLO 00000100\r\n';

_client.getDataset(getDSN('NODEACC.HELLO'), 'ascii')
Expand All @@ -186,7 +186,8 @@ describe('Integration test cases for z/OS node accessor', function() {
});
});

it('can get MVS dataset in ASCII_STRIP_EOL mode', function(done) {
// The dataset "<USERNAME>.NODEACC.HELLO" is required on MVS.
it('can get MVS dataset in ascii_strip_eol mode', function(done) {
var text = 'HELLO 00000100';

_client.getDataset(getDSN('NODEACC.HELLO'), 'ascii_strip_eol')
Expand All @@ -198,6 +199,58 @@ describe('Integration test cases for z/OS node accessor', function() {
});
});

// The dataset "<USERNAME>.NODEACC.HELLO2" with the contents of "HELLO" is required on MVS.
it('can get MVS dataset in ascii_no_trailing_blanks mode', function(done) {
var text = 'HELLO\r\n';

_client.getDataset(getDSN('NODEACC.HELLO2'), 'ascii_no_trailing_blanks')
.then(function(buffer) {
expect(buffer.toString()).toBe(text);
done();
}).catch(function(err) {
done(err);
});
});

// The dataset "<USERNAME>.NODEACC.HELLO2" with the contents of "HELLO" is required on MVS.
it('can get MVS dataset in ascii mode', function(done) {
var text = 'HELLO \r\n';

_client.getDataset(getDSN('NODEACC.HELLO2'), 'ascii')
.then(function(buffer) {
expect(buffer.toString()).toBe(text);
done();
}).catch(function(err) {
done(err);
});
});

// The VB dataset "<USERNAME>.NODEACC.VBHELLO" with the contents of "HELLO" is required on MVS.
it('can get MVS dataset in ascii_rdw mode', function(done) {
var bytes = [0,11,0,0,86,66,72,69,76,76,79,13,10];

_client.getDataset(getDSN('NODEACC.VBHELLO'), 'ascii_rdw')
.then(function(buffer) {
expect(Array.from(buffer.values())).toEqual(bytes);
done();
}).catch(function(err) {
done(err);
});
});

// The VB dataset "<USERNAME>.NODEACC.VBHELLO" with the contents of "HELLO" is required on MVS.
it('can get MVS dataset in binary_rdw mode', function(done) {
var bytes = [0,11,0,0,229,194,200,197,211,211,214];

_client.getDataset(getDSN('NODEACC.VBHELLO'), 'binary_rdw')
.then(function(buffer) {
expect(Array.from(buffer.values())).toEqual(bytes);
done();
}).catch(function(err) {
done(err);
});
});

it('can get MVS dataset in BINARY mode', function(done) {
var text = 'c8c5d3d3d640404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040f0f0f0f0f0f1f0f0';

Expand Down
15 changes: 14 additions & 1 deletion test/zosAccessor.tests.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/****************************************************************************/
/* */
/* Copyright (c) 2017, 2021 IBM Corp. */
/* Copyright (c) 2017, 2023 IBM Corp. */
/* All rights reserved. This program and the accompanying materials */
/* are made available under the terms of the Eclipse Public License v1.0 */
/* which accompanies this distribution, and is available at */
Expand Down Expand Up @@ -497,6 +497,19 @@ describe('Test cases for z/OS node accessor', function() {
}
});

it('can download variable length dataset with no trailing blanks', function() {
if(!TEST_ZOS) {
var bufferStream = new stream.PassThrough();
var stub= sinon.stub(client.client, 'get').callsArgWith(1, null, bufferStream);
return client.getDataset(uploadDSN, 'ascii_no_trailing_blanks', true).then(function () {
site_stub && expect(site_stub.calledWithMatch(/.*TRAILINGBLANKS.*/)).toBeFalsy();
}).finally(function () {
stub && stub.restore();
site_stub && site_stub.restore();
});
}
});

it('can parse LoadLib PDS member list correctly', function() {
var rawLoadLibMemberList = [
' Name Size TTR Alias-of AC --------- Attributes --------- Amode Rmode ',
Expand Down

0 comments on commit 60cdfd2

Please sign in to comment.