From 756f00d88d08e59062c8a12ca2924e9add61bc2f Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Sat, 25 Jun 2022 21:30:15 +0000 Subject: [PATCH 1/4] chore: reduce blankspace in compiled streaming apps --- all.sas | 11 +++++------ meta/mm_createfolder.sas | 2 +- meta/mm_createwebservice.sas | 9 ++++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/all.sas b/all.sas index bb48e05..50cc9b2 100644 --- a/all.sas +++ b/all.sas @@ -14066,7 +14066,7 @@ run; %mm_createfolder(path=/some/meta/folder) @param [in] path= Name of the folder to create. - @param [in] mdebug= set DBG to 1 to disable DEBUG messages + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages @version 9.4 @@ -14932,7 +14932,8 @@ run; @file mm_createwebservice.sas @brief Create a Web Ready Stored Process @details This macro creates a Type 2 Stored Process with the mm_webout macro - included as pre-code. + (and dependencies) included as pre-code. + Usage: %* compile macros ; @@ -15424,7 +15425,7 @@ run; %if &x>1 %then %let mod=mod; %let fref=%scan(&freflist,&x); - %put &sysmacroname: adding &fref; + %&mD.put &sysmacroname: adding &fref; data _null_; file "&work/&tmpfile" lrecl=3000 &mod; infile &fref; @@ -15460,13 +15461,11 @@ data _null_; if rc=0 then call symputx('url',url,'l'); run; -%put ;%put ;%put ;%put ;%put ;%put ; %put &sysmacroname: STP &name successfully created in &path; -%put ;%put ;%put ; %put Check it out here:; %put ;%put ;%put ; %put &url?_PROGRAM=&path/&name; -%put ;%put ;%put ;%put ;%put ;%put ; +%put ;%put ;%put ; %mend mm_createwebservice; /** diff --git a/meta/mm_createfolder.sas b/meta/mm_createfolder.sas index 21892f4..5922d80 100644 --- a/meta/mm_createfolder.sas +++ b/meta/mm_createfolder.sas @@ -17,7 +17,7 @@ %mm_createfolder(path=/some/meta/folder) @param [in] path= Name of the folder to create. - @param [in] mdebug= set DBG to 1 to disable DEBUG messages + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages @version 9.4 diff --git a/meta/mm_createwebservice.sas b/meta/mm_createwebservice.sas index 2c7e212..a2d8700 100644 --- a/meta/mm_createwebservice.sas +++ b/meta/mm_createwebservice.sas @@ -2,7 +2,8 @@ @file mm_createwebservice.sas @brief Create a Web Ready Stored Process @details This macro creates a Type 2 Stored Process with the mm_webout macro - included as pre-code. + (and dependencies) included as pre-code. + Usage: %* compile macros ; @@ -494,7 +495,7 @@ run; %if &x>1 %then %let mod=mod; %let fref=%scan(&freflist,&x); - %put &sysmacroname: adding &fref; + %&mD.put &sysmacroname: adding &fref; data _null_; file "&work/&tmpfile" lrecl=3000 &mod; infile &fref; @@ -530,12 +531,10 @@ data _null_; if rc=0 then call symputx('url',url,'l'); run; -%put ;%put ;%put ;%put ;%put ;%put ; %put &sysmacroname: STP &name successfully created in &path; -%put ;%put ;%put ; %put Check it out here:; %put ;%put ;%put ; %put &url?_PROGRAM=&path/&name; -%put ;%put ;%put ;%put ;%put ;%put ; +%put ;%put ;%put ; %mend mm_createwebservice; From e1afbc02c41fd9443c86faa2df527cc58fe35cb2 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Sat, 25 Jun 2022 21:32:21 +0000 Subject: [PATCH 2/4] fix: enabling binary copy of files with encoding that does not match session encoding --- all.sas | 17 ++++++----------- base/mp_binarycopy.sas | 17 ++++++----------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/all.sas b/all.sas index 50cc9b2..7a5d2cf 100644 --- a/all.sas +++ b/all.sas @@ -3529,18 +3529,13 @@ run; /* copy the file byte-for-byte */ data _null_; - length filein 8 fileid 8; - filein = fopen("&inref",'I',1,'B'); - fileid = fopen("&outref",&outmode,1,'B'); - rec = '20'x; - do while(fread(filein)=0); - rc = fget(filein,rec,1); - rc = fput(fileid, rec); - rc =fwrite(fileid); - end; - rc = fclose(filein); - rc = fclose(fileid); + infile &inref; + file &outref; + input sourcechar $char1. @@; + format sourcechar hex2.; + put sourcechar char1. @@; run; + %if &inref = ____in %then %do; filename &inref clear; %end; diff --git a/base/mp_binarycopy.sas b/base/mp_binarycopy.sas index abc7e91..57377d8 100755 --- a/base/mp_binarycopy.sas +++ b/base/mp_binarycopy.sas @@ -63,18 +63,13 @@ /* copy the file byte-for-byte */ data _null_; - length filein 8 fileid 8; - filein = fopen("&inref",'I',1,'B'); - fileid = fopen("&outref",&outmode,1,'B'); - rec = '20'x; - do while(fread(filein)=0); - rc = fget(filein,rec,1); - rc = fput(fileid, rec); - rc =fwrite(fileid); - end; - rc = fclose(filein); - rc = fclose(fileid); + infile &inref; + file &outref; + input sourcechar $char1. @@; + format sourcechar hex2.; + put sourcechar char1. @@; run; + %if &inref = ____in %then %do; filename &inref clear; %end; From 532bf84e069f4da8e3be03bfe7ea7911397c6ce7 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Sat, 25 Jun 2022 21:38:05 +0000 Subject: [PATCH 3/4] fix: mp_jsonout --- all.sas | 96 ++++++++++++++-------------------- base/mp_jsonout.sas | 24 ++++----- meta/mm_createwebservice.sas | 24 ++++----- server/ms_createwebservice.sas | 24 ++++----- viya/mv_createwebservice.sas | 24 ++++----- 5 files changed, 80 insertions(+), 112 deletions(-) diff --git a/all.sas b/all.sas index 7a5d2cf..4b9e42a 100644 --- a/all.sas +++ b/all.sas @@ -8814,20 +8814,16 @@ options %if &action=ARR %then "]" ; %else "}" ; ; /* now write the long strings to _webout 1 byte at a time */ data _null_; - length filein 8 fileid 8; - filein=fopen("_sjs",'I',1,'B'); - fileid=fopen("&jref",'A',1,'B'); - rec='20'x; - do while(fread(filein)=0); - rc=fget(filein,rec,1); - rc=fput(fileid, rec); - rc=fwrite(fileid); - end; - /* close out the table */ - rc=fput(fileid, "]"); - rc=fwrite(fileid); - rc=fclose(filein); - rc=fclose(fileid); + infile _sjs; + file &jref mod; + input sourcechar $char1. @@; + format sourcechar hex2.; + put sourcechar char1. @@; + run; + /* close out the table */ + data _null_; + file &jref mod; + put ']'; run; filename _sjs clear; %end; @@ -15195,20 +15191,16 @@ data _null_; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; put ' /* now write the long strings to _webout 1 byte at a time */ '; put ' data _null_; '; - put ' length filein 8 fileid 8; '; - put ' filein=fopen("_sjs",''I'',1,''B''); '; - put ' fileid=fopen("&jref",''A'',1,''B''); '; - put ' rec=''20''x; '; - put ' do while(fread(filein)=0); '; - put ' rc=fget(filein,rec,1); '; - put ' rc=fput(fileid, rec); '; - put ' rc=fwrite(fileid); '; - put ' end; '; - put ' /* close out the table */ '; - put ' rc=fput(fileid, "]"); '; - put ' rc=fwrite(fileid); '; - put ' rc=fclose(filein); '; - put ' rc=fclose(fileid); '; + put ' infile _sjs; '; + put ' file &jref mod; '; + put ' input sourcechar $char1. @@; '; + put ' format sourcechar hex2.; '; + put ' put sourcechar char1. @@; '; + put ' run; '; + put ' /* close out the table */ '; + put ' data _null_; '; + put ' file &jref mod; '; + put ' put '']''; '; put ' run; '; put ' filename _sjs clear; '; put ' %end; '; @@ -19932,20 +19924,16 @@ data _null_; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; put ' /* now write the long strings to _webout 1 byte at a time */ '; put ' data _null_; '; - put ' length filein 8 fileid 8; '; - put ' filein=fopen("_sjs",''I'',1,''B''); '; - put ' fileid=fopen("&jref",''A'',1,''B''); '; - put ' rec=''20''x; '; - put ' do while(fread(filein)=0); '; - put ' rc=fget(filein,rec,1); '; - put ' rc=fput(fileid, rec); '; - put ' rc=fwrite(fileid); '; - put ' end; '; - put ' /* close out the table */ '; - put ' rc=fput(fileid, "]"); '; - put ' rc=fwrite(fileid); '; - put ' rc=fclose(filein); '; - put ' rc=fclose(fileid); '; + put ' infile _sjs; '; + put ' file &jref mod; '; + put ' input sourcechar $char1. @@; '; + put ' format sourcechar hex2.; '; + put ' put sourcechar char1. @@; '; + put ' run; '; + put ' /* close out the table */ '; + put ' data _null_; '; + put ' file &jref mod; '; + put ' put '']''; '; put ' run; '; put ' filename _sjs clear; '; put ' %end; '; @@ -22277,20 +22265,16 @@ data _null_; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; put ' /* now write the long strings to _webout 1 byte at a time */ '; put ' data _null_; '; - put ' length filein 8 fileid 8; '; - put ' filein=fopen("_sjs",''I'',1,''B''); '; - put ' fileid=fopen("&jref",''A'',1,''B''); '; - put ' rec=''20''x; '; - put ' do while(fread(filein)=0); '; - put ' rc=fget(filein,rec,1); '; - put ' rc=fput(fileid, rec); '; - put ' rc=fwrite(fileid); '; - put ' end; '; - put ' /* close out the table */ '; - put ' rc=fput(fileid, "]"); '; - put ' rc=fwrite(fileid); '; - put ' rc=fclose(filein); '; - put ' rc=fclose(fileid); '; + put ' infile _sjs; '; + put ' file &jref mod; '; + put ' input sourcechar $char1. @@; '; + put ' format sourcechar hex2.; '; + put ' put sourcechar char1. @@; '; + put ' run; '; + put ' /* close out the table */ '; + put ' data _null_; '; + put ' file &jref mod; '; + put ' put '']''; '; put ' run; '; put ' filename _sjs clear; '; put ' %end; '; diff --git a/base/mp_jsonout.sas b/base/mp_jsonout.sas index 5760613..4caee28 100644 --- a/base/mp_jsonout.sas +++ b/base/mp_jsonout.sas @@ -236,20 +236,16 @@ %if &action=ARR %then "]" ; %else "}" ; ; /* now write the long strings to _webout 1 byte at a time */ data _null_; - length filein 8 fileid 8; - filein=fopen("_sjs",'I',1,'B'); - fileid=fopen("&jref",'A',1,'B'); - rec='20'x; - do while(fread(filein)=0); - rc=fget(filein,rec,1); - rc=fput(fileid, rec); - rc=fwrite(fileid); - end; - /* close out the table */ - rc=fput(fileid, "]"); - rc=fwrite(fileid); - rc=fclose(filein); - rc=fclose(fileid); + infile _sjs; + file &jref mod; + input sourcechar $char1. @@; + format sourcechar hex2.; + put sourcechar char1. @@; + run; + /* close out the table */ + data _null_; + file &jref mod; + put ']'; run; filename _sjs clear; %end; diff --git a/meta/mm_createwebservice.sas b/meta/mm_createwebservice.sas index a2d8700..d4f6220 100644 --- a/meta/mm_createwebservice.sas +++ b/meta/mm_createwebservice.sas @@ -270,20 +270,16 @@ data _null_; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; put ' /* now write the long strings to _webout 1 byte at a time */ '; put ' data _null_; '; - put ' length filein 8 fileid 8; '; - put ' filein=fopen("_sjs",''I'',1,''B''); '; - put ' fileid=fopen("&jref",''A'',1,''B''); '; - put ' rec=''20''x; '; - put ' do while(fread(filein)=0); '; - put ' rc=fget(filein,rec,1); '; - put ' rc=fput(fileid, rec); '; - put ' rc=fwrite(fileid); '; - put ' end; '; - put ' /* close out the table */ '; - put ' rc=fput(fileid, "]"); '; - put ' rc=fwrite(fileid); '; - put ' rc=fclose(filein); '; - put ' rc=fclose(fileid); '; + put ' infile _sjs; '; + put ' file &jref mod; '; + put ' input sourcechar $char1. @@; '; + put ' format sourcechar hex2.; '; + put ' put sourcechar char1. @@; '; + put ' run; '; + put ' /* close out the table */ '; + put ' data _null_; '; + put ' file &jref mod; '; + put ' put '']''; '; put ' run; '; put ' filename _sjs clear; '; put ' %end; '; diff --git a/server/ms_createwebservice.sas b/server/ms_createwebservice.sas index 79a8a56..cd7ca4d 100644 --- a/server/ms_createwebservice.sas +++ b/server/ms_createwebservice.sas @@ -271,20 +271,16 @@ data _null_; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; put ' /* now write the long strings to _webout 1 byte at a time */ '; put ' data _null_; '; - put ' length filein 8 fileid 8; '; - put ' filein=fopen("_sjs",''I'',1,''B''); '; - put ' fileid=fopen("&jref",''A'',1,''B''); '; - put ' rec=''20''x; '; - put ' do while(fread(filein)=0); '; - put ' rc=fget(filein,rec,1); '; - put ' rc=fput(fileid, rec); '; - put ' rc=fwrite(fileid); '; - put ' end; '; - put ' /* close out the table */ '; - put ' rc=fput(fileid, "]"); '; - put ' rc=fwrite(fileid); '; - put ' rc=fclose(filein); '; - put ' rc=fclose(fileid); '; + put ' infile _sjs; '; + put ' file &jref mod; '; + put ' input sourcechar $char1. @@; '; + put ' format sourcechar hex2.; '; + put ' put sourcechar char1. @@; '; + put ' run; '; + put ' /* close out the table */ '; + put ' data _null_; '; + put ' file &jref mod; '; + put ' put '']''; '; put ' run; '; put ' filename _sjs clear; '; put ' %end; '; diff --git a/viya/mv_createwebservice.sas b/viya/mv_createwebservice.sas index 22f7796..56e2929 100644 --- a/viya/mv_createwebservice.sas +++ b/viya/mv_createwebservice.sas @@ -413,20 +413,16 @@ data _null_; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; put ' /* now write the long strings to _webout 1 byte at a time */ '; put ' data _null_; '; - put ' length filein 8 fileid 8; '; - put ' filein=fopen("_sjs",''I'',1,''B''); '; - put ' fileid=fopen("&jref",''A'',1,''B''); '; - put ' rec=''20''x; '; - put ' do while(fread(filein)=0); '; - put ' rc=fget(filein,rec,1); '; - put ' rc=fput(fileid, rec); '; - put ' rc=fwrite(fileid); '; - put ' end; '; - put ' /* close out the table */ '; - put ' rc=fput(fileid, "]"); '; - put ' rc=fwrite(fileid); '; - put ' rc=fclose(filein); '; - put ' rc=fclose(fileid); '; + put ' infile _sjs; '; + put ' file &jref mod; '; + put ' input sourcechar $char1. @@; '; + put ' format sourcechar hex2.; '; + put ' put sourcechar char1. @@; '; + put ' run; '; + put ' /* close out the table */ '; + put ' data _null_; '; + put ' file &jref mod; '; + put ' put '']''; '; put ' run; '; put ' filename _sjs clear; '; put ' %end; '; From 7a696981788daa3466ab96728e5020d979686be3 Mon Sep 17 00:00:00 2001 From: munja Date: Sun, 26 Jun 2022 16:12:49 +0100 Subject: [PATCH 4/4] fix: adding fileref options and an additional test for mp_binarycopy --- all.sas | 46 ++++++++++++++----------------- base/mp_binarycopy.sas | 21 ++++++-------- base/mp_jsonout.sas | 6 ++-- meta/mm_createwebservice.sas | 6 ++-- sasjs/sasjsconfig.json | 3 +- server/ms_createwebservice.sas | 6 ++-- tests/base/mp_binarycopy.test.sas | 39 +++++++++++++++++++++++++- viya/mv_createwebservice.sas | 6 ++-- 8 files changed, 81 insertions(+), 52 deletions(-) diff --git a/all.sas b/all.sas index 4b9e42a..f3bb790 100644 --- a/all.sas +++ b/all.sas @@ -3470,8 +3470,8 @@ run; @details Reads in a file byte by byte and writes it back out. Is an os-independent method to copy files. In case of naming collision, the default filerefs can be modified. - Based on: - https://stackoverflow.com/questions/13046116/using-sas-to-copy-a-text-file + Note that if you have a new enough version of SAS, and you don't need features + such as APPEND, you may be better of using the fcopy() function instead. %mp_binarycopy(inloc="/home/me/blah.txt", outref=_webout) @@ -3511,14 +3511,9 @@ run; ,outref=____out /* override default to use own filerefs */ ,mode=CREATE )/*/STORE SOURCE*/; - %local mod outmode; - %if &mode=APPEND %then %do; - %let mod=mod; - %let outmode='a'; - %end; - %else %do; - %let outmode='o'; - %end; + %local mod; + %if &mode=APPEND %then %let mod=mod; + /* these IN and OUT filerefs can point to anything */ %if &inref = ____in %then %do; filename &inref &inloc lrecl=1048576 ; @@ -3529,8 +3524,8 @@ run; /* copy the file byte-for-byte */ data _null_; - infile &inref; - file &outref; + infile &inref lrecl=1 recfm=n; + file &outref &mod recfm=n; input sourcechar $char1. @@; format sourcechar hex2.; put sourcechar char1. @@; @@ -3542,7 +3537,8 @@ run; %if &outref=____out %then %do; filename &outref clear; %end; -%mend mp_binarycopy;/** +%mend mp_binarycopy; +/** @file @brief Splits a file of ANY SIZE by reference to a search string. @details Provide a fileref and a search string to chop off part of a file. @@ -8812,10 +8808,10 @@ options "&&name&i"n /* name literal for reserved variable names */ %end; %if &action=ARR %then "]" ; %else "}" ; ; - /* now write the long strings to _webout 1 byte at a time */ + /* now write the long strings to _webout 1 char at a time */ data _null_; - infile _sjs; - file &jref mod; + infile _sjs lrecl=1 recfm=n; + file &jref mod lrecl=1 recfm=n; input sourcechar $char1. @@; format sourcechar hex2.; put sourcechar char1. @@; @@ -15189,10 +15185,10 @@ data _null_; put ' "&&name&i"n /* name literal for reserved variable names */ '; put ' %end; '; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; - put ' /* now write the long strings to _webout 1 byte at a time */ '; + put ' /* now write the long strings to _webout 1 char at a time */ '; put ' data _null_; '; - put ' infile _sjs; '; - put ' file &jref mod; '; + put ' infile _sjs lrecl=1 recfm=n; '; + put ' file &jref mod lrecl=1 recfm=n; '; put ' input sourcechar $char1. @@; '; put ' format sourcechar hex2.; '; put ' put sourcechar char1. @@; '; @@ -19922,10 +19918,10 @@ data _null_; put ' "&&name&i"n /* name literal for reserved variable names */ '; put ' %end; '; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; - put ' /* now write the long strings to _webout 1 byte at a time */ '; + put ' /* now write the long strings to _webout 1 char at a time */ '; put ' data _null_; '; - put ' infile _sjs; '; - put ' file &jref mod; '; + put ' infile _sjs lrecl=1 recfm=n; '; + put ' file &jref mod lrecl=1 recfm=n; '; put ' input sourcechar $char1. @@; '; put ' format sourcechar hex2.; '; put ' put sourcechar char1. @@; '; @@ -22263,10 +22259,10 @@ data _null_; put ' "&&name&i"n /* name literal for reserved variable names */ '; put ' %end; '; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; - put ' /* now write the long strings to _webout 1 byte at a time */ '; + put ' /* now write the long strings to _webout 1 char at a time */ '; put ' data _null_; '; - put ' infile _sjs; '; - put ' file &jref mod; '; + put ' infile _sjs lrecl=1 recfm=n; '; + put ' file &jref mod lrecl=1 recfm=n; '; put ' input sourcechar $char1. @@; '; put ' format sourcechar hex2.; '; put ' put sourcechar char1. @@; '; diff --git a/base/mp_binarycopy.sas b/base/mp_binarycopy.sas index 57377d8..b6b3d04 100755 --- a/base/mp_binarycopy.sas +++ b/base/mp_binarycopy.sas @@ -4,8 +4,8 @@ @details Reads in a file byte by byte and writes it back out. Is an os-independent method to copy files. In case of naming collision, the default filerefs can be modified. - Based on: - https://stackoverflow.com/questions/13046116/using-sas-to-copy-a-text-file + Note that if you have a new enough version of SAS, and you don't need features + such as APPEND, you may be better of using the fcopy() function instead. %mp_binarycopy(inloc="/home/me/blah.txt", outref=_webout) @@ -45,14 +45,9 @@ ,outref=____out /* override default to use own filerefs */ ,mode=CREATE )/*/STORE SOURCE*/; - %local mod outmode; - %if &mode=APPEND %then %do; - %let mod=mod; - %let outmode='a'; - %end; - %else %do; - %let outmode='o'; - %end; + %local mod; + %if &mode=APPEND %then %let mod=mod; + /* these IN and OUT filerefs can point to anything */ %if &inref = ____in %then %do; filename &inref &inloc lrecl=1048576 ; @@ -63,8 +58,8 @@ /* copy the file byte-for-byte */ data _null_; - infile &inref; - file &outref; + infile &inref lrecl=1 recfm=n; + file &outref &mod recfm=n; input sourcechar $char1. @@; format sourcechar hex2.; put sourcechar char1. @@; @@ -76,4 +71,4 @@ %if &outref=____out %then %do; filename &outref clear; %end; -%mend mp_binarycopy; \ No newline at end of file +%mend mp_binarycopy; diff --git a/base/mp_jsonout.sas b/base/mp_jsonout.sas index 4caee28..924f333 100644 --- a/base/mp_jsonout.sas +++ b/base/mp_jsonout.sas @@ -234,10 +234,10 @@ "&&name&i"n /* name literal for reserved variable names */ %end; %if &action=ARR %then "]" ; %else "}" ; ; - /* now write the long strings to _webout 1 byte at a time */ + /* now write the long strings to _webout 1 char at a time */ data _null_; - infile _sjs; - file &jref mod; + infile _sjs lrecl=1 recfm=n; + file &jref mod lrecl=1 recfm=n; input sourcechar $char1. @@; format sourcechar hex2.; put sourcechar char1. @@; diff --git a/meta/mm_createwebservice.sas b/meta/mm_createwebservice.sas index d4f6220..9285e5c 100644 --- a/meta/mm_createwebservice.sas +++ b/meta/mm_createwebservice.sas @@ -268,10 +268,10 @@ data _null_; put ' "&&name&i"n /* name literal for reserved variable names */ '; put ' %end; '; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; - put ' /* now write the long strings to _webout 1 byte at a time */ '; + put ' /* now write the long strings to _webout 1 char at a time */ '; put ' data _null_; '; - put ' infile _sjs; '; - put ' file &jref mod; '; + put ' infile _sjs lrecl=1 recfm=n; '; + put ' file &jref mod lrecl=1 recfm=n; '; put ' input sourcechar $char1. @@; '; put ' format sourcechar hex2.; '; put ' put sourcechar char1. @@; '; diff --git a/sasjs/sasjsconfig.json b/sasjs/sasjsconfig.json index d1218ca..e900f79 100644 --- a/sasjs/sasjsconfig.json +++ b/sasjs/sasjsconfig.json @@ -67,6 +67,7 @@ }, { "name": "server", + "serverUrl": "", "serverType": "SASJS", "httpsAgentOptions": { "allowInsecureRequests": false @@ -106,4 +107,4 @@ "contextName": "SAS Job Execution compute context" } ] -} \ No newline at end of file +} diff --git a/server/ms_createwebservice.sas b/server/ms_createwebservice.sas index cd7ca4d..e3d392e 100644 --- a/server/ms_createwebservice.sas +++ b/server/ms_createwebservice.sas @@ -269,10 +269,10 @@ data _null_; put ' "&&name&i"n /* name literal for reserved variable names */ '; put ' %end; '; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; - put ' /* now write the long strings to _webout 1 byte at a time */ '; + put ' /* now write the long strings to _webout 1 char at a time */ '; put ' data _null_; '; - put ' infile _sjs; '; - put ' file &jref mod; '; + put ' infile _sjs lrecl=1 recfm=n; '; + put ' file &jref mod lrecl=1 recfm=n; '; put ' input sourcechar $char1. @@; '; put ' format sourcechar hex2.; '; put ' put sourcechar char1. @@; '; diff --git a/tests/base/mp_binarycopy.test.sas b/tests/base/mp_binarycopy.test.sas index b456c21..7ce3f37 100644 --- a/tests/base/mp_binarycopy.test.sas +++ b/tests/base/mp_binarycopy.test.sas @@ -5,6 +5,7 @@

SAS Macros

@li mp_binarycopy.sas @li mp_assert.sas + @li mp_hashdataset.sas **/ @@ -96,4 +97,40 @@ run; iftrue=("&string4"="&string4_check"), desc=Append Check (ref to file), outds=work.test_results -) \ No newline at end of file +) + +/* test 5 - ensure copy works for binary characters */ +/* do this backwards to avoid null chars in JSON preview */ +data work.test5; +do i=255 to 1 by -1; + str=byte(i); + output; +end; +run; +/* get an md5 hash of the ds */ +%mp_hashdataset(work.test5,outds=myhash) + +/* copy it */ +%mp_binarycopy(inloc="%sysfunc(pathname(work))/test5.sas7bdat", + outloc="%sysfunc(pathname(work))/test5copy.sas7bdat" +) + +/* get an md5 hash of the copied ds */ +%mp_hashdataset(work.test5copy,outds=myhash2) + +/* compare hashes */ +%let test5a=0; +%let test5b=1; +data _null_; + set myhash; + call symputx('test5a',hashkey); +run; +data _null_; + set myhash2; + call symputx('test5b',hashkey); +run; +%mp_assert( + iftrue=("&test5a"="&test5b"), + desc=Ensuring binary copy works on binary characters, + outds=work.test_results +) diff --git a/viya/mv_createwebservice.sas b/viya/mv_createwebservice.sas index 56e2929..5b3f18a 100644 --- a/viya/mv_createwebservice.sas +++ b/viya/mv_createwebservice.sas @@ -411,10 +411,10 @@ data _null_; put ' "&&name&i"n /* name literal for reserved variable names */ '; put ' %end; '; put ' %if &action=ARR %then "]" ; %else "}" ; ; '; - put ' /* now write the long strings to _webout 1 byte at a time */ '; + put ' /* now write the long strings to _webout 1 char at a time */ '; put ' data _null_; '; - put ' infile _sjs; '; - put ' file &jref mod; '; + put ' infile _sjs lrecl=1 recfm=n; '; + put ' file &jref mod lrecl=1 recfm=n; '; put ' input sourcechar $char1. @@; '; put ' format sourcechar hex2.; '; put ' put sourcechar char1. @@; ';