Domanda

I have many files in the IFS with a wide variety of CCSIDs (0, 37, 819, 1200, 1252, etc.) and I've been tasked with writing a simple RPGLE [1] program that will allow a user to view the contents of any of these files.

Our system (V6R1) CCSID (DSPSYSVAL QCCSID) is 65535 [2] and our jobs have a default CCSID of 37 which means when I try to display CCSID 819 (ASCII) for example, I see garbage – symbols, random colors, etc.

I am familiar with converting data from one CCSID to another via the QtqIconvOpen API so if I know a file has a CCSID that differs from our default CCSID, I can convert it. I wrote code years ago to do that and it works fine.

My problem is finding out the CCSID of the IFS file programmatically. After Googling the only relevant information I found was here on Stackoverflow from JamesA (How to determine the CCSID used in CPYFRMIMPF command?) who points out that you can execute “ls -S” in a QSHELL to get a listing of files showing their CCSID and filename.

So theoretically I could execute ls -S filename, parse the output to get the CCSID and then use that CCSID to perform a conversion of the data if necessary. That's an ugly hack though and I'd much prefer to use an IBM API if possible.

Does anyone know of such an API or a more elegant hack than parsing a listing from ls -S filename?

[1] I use the C API's open(), read() and close() to do the actual reading of data.

[2] I know 65535 is a poor choice but there's nothing I can do about it.

È stato utile?

Soluzione

It looks like the Qp0lGetAttr() "Get Attributes" API will let you specify a set of attributes to retrieve for a particular file, including one called QP0L_ATTR_CCSID.

Here's an example of this API in use from RPG. The example including the GetAttr call is in a ZIP file linked from that page.

Altri suggerimenti

You could use the stat() function from the integrated file system APIs.

The prototype definition looks like this:

D stat            PR            10I 0 ExtProc('stat')                   
D   path                          *   Value Options(*string)            
D   buf                               Likeds(statDS)

Then you also need the stat data structure:

 D statDS          DS                  Qualified Template
 D  st_mode                      10U 0
 D  st_ino                       10U 0
 D  st_nlink                      5U 0
 D  st_reserved2                  5U 0
 D  st_uid                       10U 0
 D  st_gid                       10U 0
 D  st_size                      10I 0
 D  st_atime                     10I 0
 D  st_mtime                     10I 0
 D  st_ctime                     10I 0
 D  st_dev                       10U 0
 D  st_blksize                   10U 0
 D  st_allocsize                 10U 0
 D  st_objtype                   11A
 D  st_reserved3                  1A
 D  st_codepage                   5U 0
 D  st_ccsid                      5U 0
 D  st_rdev                      10U 0
 D  st_nlink32                   10U 0
 D  st_rdev64                    20U 0
 D  st_dev64                     20U 0
 D  st_reserved1                 36A
 D  st_ino_gen_id                10U 0

using it is pretty easy

 D fileStats       DS                  Likeds(statDS)

  /free
     if stat('/path/to/file': fileStats) < 0;
        // error handling
     endif;

     // ccsid now in fileStats.st_ccsid
  /end-free

Is there a reason not to use DSPF for this? IBM's utility does a great job; not sure what eles you might need.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top