ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Emulating -- eval-corr using a record format from a file -- the solution

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Emulating -- eval-corr using a record format from a file -- the solution

    4 years ago I started the RFE 89289 about "eval-corr using a record format from a file".

    Unfortunately it was declined recently.

    What I wanted to do was this (from the RFE):
    Description and use case
    Many times I need to move the contents of the fields in a record into a data structure or vice versa.
    because that very often the fields from the file are defined in other data structures or referred to
    in the program it is not possible to use PREFIX with a data structure name. Therefore it would be nice
    if it is possible to use EVAL-CORR instead using a record format name as either the result or the expression.


    Code:
    FMyFileP1  IF   E           K DISK    include(MyFileR1)        
    D MyFileRec       ds                  likerec(MyFileR1 : *INPUT)
    
        read Myfile;                                               
    
        eval-corr MyFileRec = MyFileR1;                            
    
        eval-corr MyFileR1  = MyFileRec;                           
    
        *inlr = '1';                                               
        return;
    - - - - - - - - - - - - - - - - - -- - - - - - - - -- - - - - - - - -- - - - - - - - -- - - - - - - - -- - - - - - - - -- - - - - - - - -- - - - - - - - -

    The solution.

    I have thought a long time how to solve this. All I needed was to get access to the I/O-buffer of the file.
    And suddenly I found the answer. OPEN ACCESS was the solution.

    It only needed the implementation of an Open Access file defined by the handler keyword.
    The fields in MyFileP1 and MyFileP1_h share the same storage. Normal RPG behaviour.
    This means that after reading MyFileP1 I only need to write to MyFileP1_h thus calling the handler.

    In the handler I have made it so that when writing to MyFileP1_h the outputbuffer is saved in the data
    structure MyFileRec. And when reading from it the data in MyFileRec are returned in the inputbuffer or
    more correctly - it acts as the inputbuffer. And all the fields in MyFileP1_h and MyFileP1 are then populated
    with the content of MyFileRec.

    Code:
    FMyFileP1  IF   E           K DISK    include(MyFileR1)  
    FMyFileP1_hIF A E           K DISK    block(*no)                 
    F                                     extdesc('MYFILEP1')        
    F                                     RENAME(MYFILER1:MYFILER1_h)
    F                                     HANDLER(MYFILE_handle)     
    F                                     usropn       
    
    D MyFileRec       ds                  likerec(MyFileR1 : *INPUT)
    
    D* Standard IBM supplied Open Access definitions 
    D/copy qoar/qrpglesrc,qrnopenacc                 
    
        open MyFileP1_h;
    
        read Myfile;                                               
    
        write MyFileP1_h;       //  eval-corr MyFileRec = MyFileR1;  
    
        read  MyFileP1_h;       //  eval-corr MyFileR1  = MyFileRec;                     
    
        *inlr = '1';                                               
        return;
    
    C********************************************************************    
    P MYFILE_handle   B                                           
    D MYFILE_handle   PI                                          
    D   info                              likeds(QrnOpenAccess_T) 
    D*                                                            
    D*                                                            
    D outBuffer       s          32767    based(pOutBuffer)       
    
        select;                                                   
        when info.rpgOperation = QrnOperation_WRITE;              
            pOutBuffer = info.outputBuffer;                       
            MyFileRec  = outBuffer;                             
    
        when info.rpgOperation = QrnOperation_READ;               
            info.inputBuffer    = %addr(MyFileRec);            
            info.inputBufferLen = %size(MyFileRec);               
        endsl;         
    
        return;          
    
    P MYFILE_handle   E

  • #2
    That's clever!

    Comment


    • JonBoy
      JonBoy commented
      Editing a comment
      Agreed. I thought I was good at coming up with things that OA could be used for - but had never thought of this one.

  • #3
    Thank you very much.

    First I thought about if it was possible to get the address of the I/O buffer for the file MyFileP1
    but as far as I know it is not possible. Then I suddenly remembered that Open Access could give
    me the necessary information and flexibility.

    Comment


    • #4
      Why not?
      Code:
      read Myfile myFileDs;
      Eval-corr myFileP1Ds = myFileDs;
      write MyFileP1_h myFileP1Ds;

      Comment


      • #5
        I believe that Peder said earlier that this was not an option as some of the fields are already in other DS. So using this approach would force additional copying.

        Comment

        Working...
        X