View Javadoc

1   /*******************************************************************************
2    *  Copyright (c) 2005, 2006 Imola Informatica.
3    *  All rights reserved. This program and the accompanying materials
4    *  are made available under the terms of the LGPL License v2.1
5    *  which accompanies this distribution, and is available at
6    *  http://www.gnu.org/licenses/lgpl.html
7    *******************************************************************************/
8   package it.imolinfo.jbi4cics.typemapping.cobol;
9   
10  import it.imolinfo.jbi4cics.Logger;
11  import it.imolinfo.jbi4cics.LoggerFactory;
12  import it.imolinfo.jbi4cics.exception.FormatException;
13  import it.imolinfo.jbi4cics.jbi.Messages;
14  
15  import java.math.BigDecimal;
16  
17  
18  public class ZonedMarshaller {  
19    
20    /**
21     * The logger for this class and its instances.
22     */
23    private static final Logger LOG
24            = LoggerFactory.getLogger(ZonedMarshaller.class);
25    
26    /**
27     * The responsible to translate localized messages.
28     */
29    private static final Messages MESSAGES
30            = Messages.getMessages(ZonedMarshaller.class);
31    
32    private final static byte EBCDIC_PLUS = 0x4E;
33    private final static byte EBCDIC_MINUS = 0x60;
34    
35    /**
36     * void constructor.
37     */
38      public ZonedMarshaller(){
39      }
40  
41    
42    public static void marshallZoned(BigDecimal value, byte[] buffer, int startingOffset, int size, boolean signed, int virtualDecimalPoint, int signFormat, String codePage){
43      //log.debug("value before moving point: "+value);
44      value=value.movePointRight(virtualDecimalPoint);
45      value=value.setScale(0);
46      //log.debug("value after moving point: "+value);
47      int signOffset=((signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE)&&(signed))?1:0;
48      int dataSize=size-signOffset;
49      boolean isNegative=false;
50      if (value.compareTo(new BigDecimal(0))==-1){
51        value=value.abs();
52        isNegative=true;
53      }
54      //log.debug("value after abs: "+value);
55      String stringValue=value.toPlainString();
56      StringBuffer stringBufferValue=new StringBuffer(stringValue);
57      //log.debug("stringValue before padding: "+stringBufferValue);
58  //  at this point we don't have scale and comma and sign
59      //log.debug("size: "+size+", signoffset: "+signOffset+",datasize: "+dataSize);
60      for (int i=0;i<(dataSize-stringValue.length());i++){
61        stringBufferValue.insert(0, '0');
62      }
63      // at this point we have the right length
64      LOG.debug("stringValue after padding: "+stringBufferValue);    
65      byte[] valueArray=stringBufferValue.toString().getBytes();
66      //log.debug("valueArray: "+Arrays.toString(valueArray));
67      int dataStartingOffset=startingOffset+signOffset;
68      for (int i=dataSize-1;i>=0;i--){
69        byte currentByte=(byte)(valueArray[i] & 0x0f);
70        //log.debug("signFormat: "+signFormat+", signed: "+signed+", dataSize: "+dataSize+", i: "+i);
71        if ((signFormat==CobolTypeDescriptor.SIGN_FORMAT_TRAILING && signed && i==dataSize-1) || (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING && signed && i==0)){
72          if (isNegative){
73            currentByte=(byte) ((PackedDecimalMarshaller.NEGATIVE_SIGN << 4) | currentByte);
74          }
75          else {
76            currentByte=(byte) ((PackedDecimalMarshaller.POSITIVE_SIGN << 4) | currentByte);
77          }        
78        }
79        else {
80          currentByte=(byte)(0xf0 | currentByte);
81        }
82        buffer[dataStartingOffset+i]=currentByte;
83      }
84      if (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE && signed){
85        if (isNegative){
86          buffer[startingOffset]= EBCDIC_MINUS;
87        }
88        else {
89          buffer[startingOffset]=EBCDIC_PLUS;        
90        }
91      }
92      
93    }
94    public static BigDecimal unmarshallZoned(byte[] buffer, int startingOffset, int size, boolean signed, int virtualDecimalPoint, int signFormat, String codePage) throws FormatException{
95      int signOffset=((signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE)&&(signed))?1:0;
96      int dataStartingOffset=startingOffset+signOffset;
97      int dataSize=size-signOffset;
98      boolean positive=true;
99      if (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE && signed){
100       byte signByte=buffer[startingOffset];
101       switch (signByte) {
102         case EBCDIC_PLUS  : {positive=true;break;}
103         case EBCDIC_MINUS : {positive=false;break;}
104         default : {
105             LOG.error("CIC002119_Sign_not_recognized", signByte);
106             throw new FormatException(MESSAGES.getString(
107                     "CIC002119_Sign_not_recognized", signByte));
108         }
109       }
110     }
111     StringBuffer stringBuffer=new StringBuffer();
112     for (int i=0;i<dataSize;i++){
113       byte currentByte=buffer[dataStartingOffset+i];
114       //log.debug("signFormat: "+signFormat+", signed: "+signed+", dataSize: "+dataSize+", i: "+i);
115       if ((signFormat==CobolTypeDescriptor.SIGN_FORMAT_TRAILING && signed && i==dataSize-1) || (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING && signed && i==0)){
116         byte signByte=(byte) ((currentByte & 0xf0)>>4);
117         //log.debug("signByte: "+String.valueOf(signByte));
118         if (signByte==PackedDecimalMarshaller.NEGATIVE_SIGN){
119           positive=false;
120         }
121       }
122       stringBuffer.append(String.valueOf(currentByte & 0x0f));
123     }
124     BigDecimal result=new BigDecimal(stringBuffer.toString());
125     result=result.movePointLeft(virtualDecimalPoint);
126     if (!positive){
127       result=result.negate();
128     }
129     return result;
130   }
131 
132 }