private static void decodeC40Segment(BitSource bits,StringBuilder result) throws FormatException {
  boolean upperShift=false;
  int[] cValues=new int[3];
  int shift=0;
  do {
    if (bits.available() == 8) {
      return;
    }
    int firstByte=bits.readBits(8);
    if (firstByte == 254) {
      return;
    }
    parseTwoBytes(firstByte,bits.readBits(8),cValues);
    for (int i=0; i < 3; i++) {
      int cValue=cValues[i];
switch (shift) {
case 0:
        if (cValue < 3) {
          shift=cValue + 1;
        }
 else         if (cValue < C40_BASIC_SET_CHARS.length) {
          char c40char=C40_BASIC_SET_CHARS[cValue];
          if (upperShift) {
            result.append((char)(c40char + 128));
            upperShift=false;
          }
 else {
            result.append(c40char);
          }
        }
 else {
          throw FormatException.getFormatInstance();
        }
      break;
case 1:
    if (upperShift) {
      result.append((char)(cValue + 128));
      upperShift=false;
    }
 else {
      result.append((char)cValue);
    }
  shift=0;
break;
case 2:
if (cValue < C40_SHIFT2_SET_CHARS.length) {
char c40char=C40_SHIFT2_SET_CHARS[cValue];
if (upperShift) {
  result.append((char)(c40char + 128));
  upperShift=false;
}
 else {
  result.append(c40char);
}
}
 else if (cValue == 27) {
result.append((char)29);
}
 else if (cValue == 30) {
upperShift=true;
}
 else {
throw FormatException.getFormatInstance();
}
shift=0;
break;
case 3:
if (upperShift) {
result.append((char)(cValue + 224));
upperShift=false;
}
 else {
result.append((char)(cValue + 96));
}
shift=0;
break;
default :
throw FormatException.getFormatInstance();
}
}
}
 while (bits.available() > 0);
}

private static void decodeC40Segment ( BitSource bits , StringBuilder result ) throws FormatException { boolean upperShift = false ; int [ ] cValues = new int [ 3 ] ; int shift = 0 ; do { if ( bits . available ( ) == 8 ) { return ; } int firstByte = bits . readBits ( 8 ) ; if ( firstByte == 254 ) { return ; } parseTwoBytes ( firstByte , bits . readBits ( 8 ) , cValues ) ; for ( int i = 0 ; i < 3 ; i ++ ) { int cValue = cValues [ i ] ; switch ( shift ) { case 0 : if ( cValue < 3 ) { shift = cValue + 1 ; } else if ( cValue < C40_BASIC_SET_CHARS . length ) { char c40char = C40_BASIC_SET_CHARS [ cValue ] ; if ( upperShift ) { result . append ( ( char ) ( c40char + 128 ) ) ; upperShift = false ; } else { result . append ( c40char ) ; } } else { throw FormatException . getFormatInstance ( ) ; } break ; case 1 : if ( upperShift ) { result . append ( ( char ) ( cValue + 128 ) ) ; upperShift = false ; } else { result . append ( ( char ) cValue ) ; } shift = 0 ; break ; case 2 : if ( cValue < C40_SHIFT2_SET_CHARS . length ) { char c40char = C40_SHIFT2_SET_CHARS [ cValue ] ; if ( upperShift ) { result . append ( ( char ) ( c40char + 128 ) ) ; upperShift = false ; } else { result . append ( c40char ) ; } } else if ( cValue == 27 ) { result . append ( ( char ) 29 ) ; } else if ( cValue == 30 ) { upperShift = true ; } else { throw FormatException . getFormatInstance ( ) ; } shift = 0 ; break ; case 3 : if ( upperShift ) { result . append ( ( char ) ( cValue + 224 ) ) ; upperShift = false ; } else { result . append ( ( char ) ( cValue + 96 ) ) ; } shift = 0 ; break ; default : throw FormatException . getFormatInstance ( ) ; } } } while ( bits . available ( ) > 0 ) ; }
see iso 16022 : 2006 , 5 . 2 . 5 and annex c , table c . 1
