1

I am trying to perform operations on binary data saved into a macro variable. The datastep below successfully saves the data into the macro variable without any issues:

data _null_;
  infile datalines truncover ;
  attrib x length=$300 informat=$300. format=$300.;
  input x $300.;
  put x=;
  call symput ('str',cats(x));
  datalines4;
‰PNG  >     IHDR   )   )   ëŠZ   sRGB ®Î=é   gAMA  ±^üa    pHYs  ;à  ;ÃÇo¨d   ZIDAT8OåŒ[ À½ÿ¥Ó¼”Ö5Dˆ_v@aw|+¸AnЇ;6<ÞóRÆÒÈeFõU/'“#f™Ù÷&É|&t"<ß}4¯à6†Ë-Œ_È(%<É'™èNß%)˜Î{-    IEND®B`‚
;;;;
run;

When I try and use the contents of the macro variable in any way, the combinations of reserved characters are making it impossible to work with. The following reserved characters are in the value, and are not matched:

&%'"()

I've tried every combination of macro quoting functions I can think of and I can't even get the value to print using a %put():

%put %nrbquote(&str);

Results in:

SYMBOLGEN:  Macro variable STR resolves to ‰PNG  >     IHDR   )   )   ëŠZ   sRGB ®Î=é   gAMA
            ±^üa    pHYs  ;à  ;ÃÇo¨d   ZIDAT8OåŒ[
            À½ÿ¥Ó¼”Ö5Dˆ_v@aw|+¸AnЇ;6<ÞóRÆÒÈeFõU/'“#f™Ù÷&É|&t"<ß}4¯à6†Ë-Œ_È(%<É'™èNß%)˜Î{-
            IEND®B`‚
ERROR: The value É is not a valid SAS name.
ERROR: The SAS Macro Facility has encountered an I/O error.  Canceling submitted statements.

NOTE: The SAS System stopped processing due to receiving a CANCEL request.

Ultimately, what I'd like to do is convert these values to a base64 encoding using the following statement (I've pre-calculated the length of the base64 format for ease-of-debugging):

%let base64_string = %sysfunc(putc(%nrbquote(&str),$base64x244.));
Robert Penridge
  • 8,424
  • 2
  • 34
  • 55

1 Answers1

3

You can use %SUPERQ() to quote a macro variable without having to first expand it. Note that it takes the name of macro variable and not the value as its argument.

%let base64_string = %sysfunc(putc(%superq(str),$base64x244.));

But why not just do the transformation in a DATA STEP and avoid the macro quoting issues?

Tom
  • 47,574
  • 2
  • 16
  • 29
  • I'm reading the value in from a file using `fget()` in a function-style macro, so I don't have that option unfortunately. – Robert Penridge Jan 18 '16 at 15:24
  • Make sure to pad the string with blanks to a multiple of 3 bytes. I saw an issue before with base64 conversion not generating exactly the right value when given string where the last block as less than 3 characters. – Tom Jan 18 '16 at 15:28
  • Thanks for the heads up. I'd tried `superq()` too but forgot it take a var name and not a value... – Robert Penridge Jan 18 '16 at 15:30