× 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 Jack,

There's a weird quirk to O_TEXTDATA. Basically, if a file DOES NOT exist, O_TEXTDATA assumes that you're trying to create a file from the data that's in your program. Therefore,the code page you've provided is the code page of your program's data, and no translation is needed.

For example, if you create a new IFS file and mark it with CCSID 37, it thinks you're doing this BECAUSE your data is already in CCSID 37. So no conversion is done, the data from your program is simply written to disk, and the file is marked with "37" so that subsequent programs know that it's supposed to be EBCDIC.

Likewise, if you tell it to create a new file and mark it with CCSID 819, it assumes (and this is the problem) that the data coming from your program is ALREADY in CCSID 819 (Apparently, the person at IBM who designed it was thinking that when a new file is created, you're always looking to mark it with the CCSID of the data in your program.) No translation is performed, and the file is marked with 819.

That's why you're getting "garbage" when you mark it as 819. The data in your program is EBCDIC (which might be 37, or might be some other form of EBCDIC, depending on the country you work in). But you've marked the file as 819, which tells the system that it's ASCII. So when you view it, it looks up the hex value of each byte on an ASCII to EBCDIC translation table, and shows you the translated result. (Since the original result was already EBCDIC, you end up with garbage.)

Now... everything I've said up to this point refers to what happens when you create a NEW file. On the other hand, if the file ALREADY EXISTS, it assumes that your data is in the job's CCSID, not in the file's CCSID. In that case, it translates from the job's CCSID to the file's, and vice-versa. (Which is what you want).

For this reason, on pre-V5R2 systems, we typically follow this syntax to create a new file and automatically translate to ASCII:

a) Use the unlink() API to delete an existing file if it exists.

b) Use the open() API with O_WRONLY + O_CREAT + O_CCSID (or O_CODEPAGE if you're on V4R5 or earlier). Give it an ASCII CCSID (819, 1252, whatever..)

c) Call the close() API to close the file from step b. Now you know you have an EXISTING file, and you know that it's marked with an ASCII CCSID.

d) Call the open() API a second time. This time, specify O_WRONLY (or whatever you need) + O_TEXTDATA + O_CCSID. Put a 0 in the "mode" parameter (permissions) since the file isn't going to be created, it'll be ignored. Put the CCSID you want to translate *from* (i.e. the job's CCSID) in the CCSID parameter. You can use a special value of 0 to indicate "the job's current CCSID". You can also leave the O_CCSID and the CCSID parameter off of the command, but this'll only work if the IFS file is a single-byte encoding (it won't work with double-byte or Unicode unless you give O_CCSID and the CCSID parm. I never found out why this was.)

e) At this point, the file is both marked with the correct CCSID, and anything written will be translated to that CCSID. This way, both EDTF and Windows software will be able to read it correctly.

Starting with V5R2, there's an additional flag named O_TEXT_CREAT and an additional parameter that lets you do the whole thing in one call to the open() API. To use that technique, do this:

a) Call unlink() to get rid of an existing file.

b) Call open() with O_CREAT+O_WRONLY+O_TEXTDATA+O_CCSID+O_TEXT_CREAT

c) Specify the CCSID to make the file in the 4th parmeter, and the CCSID of your program's data (or the special value 0 for the job's current CCSID) in the 5th parameter.

Note that O_CCSID became available for IFS objects in V5R1. Prior to that, you had to use O_CODEPAGE, which is similar, but only supports single-byte encodings. O_CODEPAGE does still work in newer releases, but unless you absolutely need to support V4R5 and earlier, I recommend that you use O_CCSID to get the additional flexibility that CCSIDs provide.


Jack Tucky wrote:
If I write file as codepage 37, I can view it using EDTF.

But downloading the files to the PC I see garbage.

I want to FTP the file to some other system as ASCII.

If I add the 819 code page, EDTF shows gibberish and PC download.

I think I need the translation set properly, but maybe I have it wrong? . I
open the file and then close it, and then open it again to begin writing to
it.

Here is my code snippet:

c eval flags = O_WRONLY + O_CREAT + O_TRUNC +
c + O_Codepage + o_TextData
**
c eval mode = S_IRUSR + S_IWUSR
c + S_IRGRP
c + S_IROTH
**
c eval fd = open(%trim(IfsFileName) :
c flags: mode : 819 )
c if fd < 0
c eval Msg = 'open(): failed for writing'
c dsply Msg
c eval *inlr = *on
c return
c endif

Thanks

Jack


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.