public int read(char ch[],int offset,int length) throws IOException {
  int out=offset;
  if (fSurrogate != -1) {
    ch[offset + 1]=(char)fSurrogate;
    fSurrogate=-1;
    length--;
    out++;
  }
  int count=0;
  if (fOffset == 0) {
    if (length > fBuffer.length) {
      length=fBuffer.length;
    }
    count=fInputStream.read(fBuffer,0,length);
    if (count == -1) {
      return -1;
    }
    count+=out - offset;
  }
 else {
    count=fOffset;
    fOffset=0;
  }
  final int total=count;
  for (int in=0; in < total; in++) {
    int b0=fBuffer[in] & 0x00FF;
    if (b0 < 0x80) {
      ch[out++]=(char)b0;
      continue;
    }
    if ((b0 & 0xE0) == 0xC0) {
      int b1=-1;
      if (++in < total) {
        b1=fBuffer[in] & 0x00FF;
      }
 else {
        b1=fInputStream.read();
        if (b1 == -1) {
          if (out > offset) {
            fBuffer[0]=(byte)b0;
            fOffset=1;
            return out - offset;
          }
          expectedByte(2,2);
        }
        count++;
      }
      if ((b1 & 0xC0) != 0x80) {
        if (out > offset) {
          fBuffer[0]=(byte)b0;
          fBuffer[1]=(byte)b1;
          fOffset=2;
          return out - offset;
        }
        invalidByte(2,2,b1);
      }
      int c=((b0 << 6) & 0x07C0) | (b1 & 0x003F);
      ch[out++]=(char)c;
      count-=1;
      continue;
    }
    if ((b0 & 0xF0) == 0xE0) {
      int b1=-1;
      if (++in < total) {
        b1=fBuffer[in] & 0x00FF;
      }
 else {
        b1=fInputStream.read();
        if (b1 == -1) {
          if (out > offset) {
            fBuffer[0]=(byte)b0;
            fOffset=1;
            return out - offset;
          }
          expectedByte(2,3);
        }
        count++;
      }
      if ((b1 & 0xC0) != 0x80) {
        if (out > offset) {
          fBuffer[0]=(byte)b0;
          fBuffer[1]=(byte)b1;
          fOffset=2;
          return out - offset;
        }
        invalidByte(2,3,b1);
      }
      int b2=-1;
      if (++in < total) {
        b2=fBuffer[in] & 0x00FF;
      }
 else {
        b2=fInputStream.read();
        if (b2 == -1) {
          if (out > offset) {
            fBuffer[0]=(byte)b0;
            fBuffer[1]=(byte)b1;
            fOffset=2;
            return out - offset;
          }
          expectedByte(3,3);
        }
        count++;
      }
      if ((b2 & 0xC0) != 0x80) {
        if (out > offset) {
          fBuffer[0]=(byte)b0;
          fBuffer[1]=(byte)b1;
          fBuffer[2]=(byte)b2;
          fOffset=3;
          return out - offset;
        }
        invalidByte(3,3,b2);
      }
      int c=((b0 << 12) & 0xF000) | ((b1 << 6) & 0x0FC0) | (b2 & 0x003F);
      ch[out++]=(char)c;
      count-=2;
      continue;
    }
    if ((b0 & 0xF8) == 0xF0) {
      int b1=-1;
      if (++in < total) {
        b1=fBuffer[in] & 0x00FF;
      }
 else {
        b1=fInputStream.read();
        if (b1 == -1) {
          if (out > offset) {
            fBuffer[0]=(byte)b0;
            fOffset=1;
            return out - offset;
          }
          expectedByte(2,4);
        }
        count++;
      }
      if ((b1 & 0xC0) != 0x80) {
        if (out > offset) {
          fBuffer[0]=(byte)b0;
          fBuffer[1]=(byte)b1;
          fOffset=2;
          return out - offset;
        }
        invalidByte(2,4,b1);
      }
      int b2=-1;
      if (++in < total) {
        b2=fBuffer[in] & 0x00FF;
      }
 else {
        b2=fInputStream.read();
        if (b2 == -1) {
          if (out > offset) {
            fBuffer[0]=(byte)b0;
            fBuffer[1]=(byte)b1;
            fOffset=2;
            return out - offset;
          }
          expectedByte(3,4);
        }
        count++;
      }
      if ((b2 & 0xC0) != 0x80) {
        if (out > offset) {
          fBuffer[0]=(byte)b0;
          fBuffer[1]=(byte)b1;
          fBuffer[2]=(byte)b2;
          fOffset=3;
          return out - offset;
        }
        invalidByte(3,4,b2);
      }
      int b3=-1;
      if (++in < total) {
        b3=fBuffer[in] & 0x00FF;
      }
 else {
        b3=fInputStream.read();
        if (b3 == -1) {
          if (out > offset) {
            fBuffer[0]=(byte)b0;
            fBuffer[1]=(byte)b1;
            fBuffer[2]=(byte)b2;
            fOffset=3;
            return out - offset;
          }
          expectedByte(4,4);
        }
        count++;
      }
      if ((b3 & 0xC0) != 0x80) {
        if (out > offset) {
          fBuffer[0]=(byte)b0;
          fBuffer[1]=(byte)b1;
          fBuffer[2]=(byte)b2;
          fBuffer[3]=(byte)b3;
          fOffset=4;
          return out - offset;
        }
        invalidByte(4,4,b2);
      }
      int uuuuu=((b0 << 2) & 0x001C) | ((b1 >> 4) & 0x0003);
      if (uuuuu > 0x10) {
        invalidSurrogate(uuuuu);
      }
      int wwww=uuuuu - 1;
      int zzzz=b1 & 0x000F;
      int yyyyyy=b2 & 0x003F;
      int xxxxxx=b3 & 0x003F;
      int hs=0xD800 | ((wwww << 6) & 0x03C0) | (zzzz << 2)| (yyyyyy >> 4);
      int ls=0xDC00 | ((yyyyyy << 6) & 0x03C0) | xxxxxx;
      ch[out++]=(char)hs;
      ch[out++]=(char)ls;
      count-=2;
      continue;
    }
    if (out > offset) {
      fBuffer[0]=(byte)b0;
      fOffset=1;
      return out - offset;
    }
    invalidByte(1,1,b0);
  }
  return count;
}

public int read ( char ch [ ] , int offset , int length ) throws IOException { int out = offset ; if ( fSurrogate != - 1 ) { ch [ offset + 1 ] = ( char ) fSurrogate ; fSurrogate = - 1 ; length -- ; out ++ ; } int count = 0 ; if ( fOffset == 0 ) { if ( length > fBuffer . length ) { length = fBuffer . length ; } count = fInputStream . read ( fBuffer , 0 , length ) ; if ( count == - 1 ) { return - 1 ; } count += out - offset ; } else { count = fOffset ; fOffset = 0 ; } final int total = count ; for ( int in = 0 ; in < total ; in ++ ) { int b0 = fBuffer [ in ] & 0x00FF ; if ( b0 < 0x80 ) { ch [ out ++ ] = ( char ) b0 ; continue ; } if ( ( b0 & 0xE0 ) == 0xC0 ) { int b1 = - 1 ; if ( ++ in < total ) { b1 = fBuffer [ in ] & 0x00FF ; } else { b1 = fInputStream . read ( ) ; if ( b1 == - 1 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fOffset = 1 ; return out - offset ; } expectedByte ( 2 , 2 ) ; } count ++ ; } if ( ( b1 & 0xC0 ) != 0x80 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fOffset = 2 ; return out - offset ; } invalidByte ( 2 , 2 , b1 ) ; } int c = ( ( b0 << 6 ) & 0x07C0 ) | ( b1 & 0x003F ) ; ch [ out ++ ] = ( char ) c ; count -= 1 ; continue ; } if ( ( b0 & 0xF0 ) == 0xE0 ) { int b1 = - 1 ; if ( ++ in < total ) { b1 = fBuffer [ in ] & 0x00FF ; } else { b1 = fInputStream . read ( ) ; if ( b1 == - 1 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fOffset = 1 ; return out - offset ; } expectedByte ( 2 , 3 ) ; } count ++ ; } if ( ( b1 & 0xC0 ) != 0x80 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fOffset = 2 ; return out - offset ; } invalidByte ( 2 , 3 , b1 ) ; } int b2 = - 1 ; if ( ++ in < total ) { b2 = fBuffer [ in ] & 0x00FF ; } else { b2 = fInputStream . read ( ) ; if ( b2 == - 1 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fOffset = 2 ; return out - offset ; } expectedByte ( 3 , 3 ) ; } count ++ ; } if ( ( b2 & 0xC0 ) != 0x80 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fBuffer [ 2 ] = ( byte ) b2 ; fOffset = 3 ; return out - offset ; } invalidByte ( 3 , 3 , b2 ) ; } int c = ( ( b0 << 12 ) & 0xF000 ) | ( ( b1 << 6 ) & 0x0FC0 ) | ( b2 & 0x003F ) ; ch [ out ++ ] = ( char ) c ; count -= 2 ; continue ; } if ( ( b0 & 0xF8 ) == 0xF0 ) { int b1 = - 1 ; if ( ++ in < total ) { b1 = fBuffer [ in ] & 0x00FF ; } else { b1 = fInputStream . read ( ) ; if ( b1 == - 1 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fOffset = 1 ; return out - offset ; } expectedByte ( 2 , 4 ) ; } count ++ ; } if ( ( b1 & 0xC0 ) != 0x80 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fOffset = 2 ; return out - offset ; } invalidByte ( 2 , 4 , b1 ) ; } int b2 = - 1 ; if ( ++ in < total ) { b2 = fBuffer [ in ] & 0x00FF ; } else { b2 = fInputStream . read ( ) ; if ( b2 == - 1 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fOffset = 2 ; return out - offset ; } expectedByte ( 3 , 4 ) ; } count ++ ; } if ( ( b2 & 0xC0 ) != 0x80 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fBuffer [ 2 ] = ( byte ) b2 ; fOffset = 3 ; return out - offset ; } invalidByte ( 3 , 4 , b2 ) ; } int b3 = - 1 ; if ( ++ in < total ) { b3 = fBuffer [ in ] & 0x00FF ; } else { b3 = fInputStream . read ( ) ; if ( b3 == - 1 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fBuffer [ 2 ] = ( byte ) b2 ; fOffset = 3 ; return out - offset ; } expectedByte ( 4 , 4 ) ; } count ++ ; } if ( ( b3 & 0xC0 ) != 0x80 ) { if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fBuffer [ 1 ] = ( byte ) b1 ; fBuffer [ 2 ] = ( byte ) b2 ; fBuffer [ 3 ] = ( byte ) b3 ; fOffset = 4 ; return out - offset ; } invalidByte ( 4 , 4 , b2 ) ; } int uuuuu = ( ( b0 << 2 ) & 0x001C ) | ( ( b1 > > 4 ) & 0x0003 ) ; if ( uuuuu > 0x10 ) { invalidSurrogate ( uuuuu ) ; } int wwww = uuuuu - 1 ; int zzzz = b1 & 0x000F ; int yyyyyy = b2 & 0x003F ; int xxxxxx = b3 & 0x003F ; int hs = 0xD800 | ( ( wwww << 6 ) & 0x03C0 ) | ( zzzz << 2 ) | ( yyyyyy > > 4 ) ; int ls = 0xDC00 | ( ( yyyyyy << 6 ) & 0x03C0 ) | xxxxxx ; ch [ out ++ ] = ( char ) hs ; ch [ out ++ ] = ( char ) ls ; count -= 2 ; continue ; } if ( out > offset ) { fBuffer [ 0 ] = ( byte ) b0 ; fOffset = 1 ; return out - offset ; } invalidByte ( 1 , 1 , b0 ) ; } return count ; }
read characters into a portion of an array . this method will block until some input is available , an i / o error occurs , or the end of the stream is reached .
