×
The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.
Hi Rick,
I think we need to separate this into two distinct possible causes of error.
1) There is a translation problem when reading from the XML/Writing to the
PDF.
Here you seem to be using a bespoke method for opening the XML doc. I also
noted that you are using the literal "codepage=1252" when opening this doc.
PDFDesc = ifsOpen(%TrimR(OutPath) :TxtWrt + ', codepage=1252'); // old = 850
Is it possible to declare the encoding as a CCSID value rather than a
codepage? In this case it may not matter because the ANSI 1252 codepage (I
think) maps to the 1252 CCSID, but personally, I always use CCSID in place
of codepage. In fact, if you're using unicode data (UTF-8, UCS-2, UCS-4) you
need to use CCSID because, by definition, unicode, maps to many codepages
and can't be referenced by one. So, IMHO, it is a good habit to get into
because it makes working with other encodings an easy transition.
I noted that you have created the PDF with a codepage of 1252. You have then
closed and re-opened this file for writing to:
PDFDesc = ifsOpen(%TrimR(OutPath) :TxtWrt + ', codepage=1252');
RtnCd = ifsClose(PDFDesc);
PDFDesc = ifsOpen(%TrimR(OutPath) :TxtWrt);
Again, without knowing the way this bespoke procedure works I can't tell
whether you have definitely defaulted the second open for textdata and
translation to/from the job CCSID. What I can say is that I would rather
explicitly declare the open CCSID on the second open. I have had trouble
before when converting data (other than ASCII - CCSID 819) using an open
that does not declare the "open" CCSID. I usually default it to 0 (zero) for
the current job CCSID.
Here's an example (apologies for the old prototype - it's in copysource and
we all have to use it - so no options(*string) here!):
* Open prototype...
D ExtProc('open')
D Opn_FileName * Value
D Opn_OpenFlags 10I 0 Value
D Opn_Mode 10U 0 Value Options(*NoPass)
D Opn_CodePage 10U 0 Value Options(*NoPass)
* flags...
D O_ReadOnly S 10I 0 INZ(1)
D O_WriteOnly S 10I 0 INZ(2)
D O_ReadWrite S 10I 0 INZ(4)
D O_Create S 10I 0 INZ(8)
D O_Undef1 S 10I 0 INZ(16)
D O_CCSID S 10I 0 INZ(32)
D O_Truncate S 10I 0 INZ(64)
D O_Undef3 S 10I 0 INZ(128)
D O_Undef4 S 10I 0 INZ(256)
D O_IRWXU S 10I 0 INZ(448)
D O_CodePage S 10I 0 INZ(8388608)
D O_TextData S 10I 0 INZ(16777216)
* Open file with file CCSID 1252...
C eval FullName = %TrimR(FileName) + X'00'
C eval FileDesc = IFS_Open(%Addr(FullName):
C O_Create + O_WriteOnly +
C O_Truncate + O_CCSID:
C O_IRWXU + O_ReadWrite:
C 1252)
* Close the file...
C Eval ReturnInt = IFS_Close(FileDesc)
* Re-open file with job CCSID, using special value 0 (zero) ...
C Eval FileDesc = IFS_Open(%Addr(FullName):
C O_TextData + O_ReadWrite +
C + O_CCSID:
C O_IRWXU + O_ReadWrite:
C 0)
In the example above, the file is created (O_Create) with a file CCSID of
1252. This is the CCSID of the "file", not the data. This also truncates
(O_Truncate) the data in the file, if it already exists - it's the IFS
equivalent of doing a CLRPFM, monitor for the file not existing and then do
a CRTDUPOBJ - the result is always an empty file. Note that O_CCSID is
specified in the second argument - this specifies that the value contained
in the fourth argument is a CCSID value, not a codepage.
The file is then closed and re-opened. This time the O_TextData flag is
included (O_Create and O_Truncate is now removed) because we are going to
work with the data within the file. As a result, the CCSID value in the
fouth argument specifies the CCSID of the data you will be working with in
your program. This is known as the "open" CCSID. If you are writing to the
file from variable data within your program then specifying a CCSID of 0
(zero) will ensure that the data is translated from the current job CCSID to
whatever file CCSID was used to create your file. This way all translation
is done during the write - you never need iconv(). Conversely, reading from
your file will convert the data from the file CCSID to whatever CCSID value
you set as the fourth argument when you open with O_TextData. Specifying an
"open" CCSID allows you to read from one file directly to another and all
translation occurs automatically!
As an aside - there are two special values for the fourth argument: 0 (zero)
specifies the job CCSID, 65535 specifies no conversion to be performed. All
other values must be a supported CCSID value.
2) There is a decoding problem when regenerating the PDF binary object.
I would suggest that you perform the data transfer from the XML to the PDF
"without" decoding the data. You can then open both in notepad and compare
them - they should be identical. If the data is not identical then you've
got a translation problem during your open/read/write. This would occur
whether the data was Base64 encoded or not (it's simple text at this point).
If the data is correct then perform the decode and see if you can open the
PDF, if not you must have a problem during the decode.
So, I would strongly suggest that you check that you have specified the
correct parameters during your file opens - they are crucial for data
translation, and the usual suspects when things go awry.
I hope this is of help to you, and good luck.
Cheers
Larry Ducie
As an Amazon Associate we earn from qualifying purchases.