001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.internal; 018 019import java.io.*; 020 021/** 022 * Similar to {@link StringReader} except reads from a generic {@link CharSequenceReader}. 023 * 024 * <h5 class='section'>See Also:</h5><ul> 025 026 * </ul> 027 */ 028public class CharSequenceReader extends BufferedReader { 029 030 private final CharSequence cs; 031 private String s; 032 private StringBuffer sb; 033 private StringBuilder sb2; 034 private int length; 035 private int next; 036 037 /** 038 * Constructor. 039 * 040 * @param cs The char sequence to read from. Can be <jk>null</jk>. 041 */ 042 public CharSequenceReader(CharSequence cs) { 043 super(new StringReader(""), 1); // Does not actually use a reader. 044 if (cs == null) 045 cs = ""; 046 this.cs = cs; 047 if (cs instanceof String) 048 s = (String)cs; 049 else if (cs instanceof StringBuffer) 050 sb = (StringBuffer)cs; 051 else if (cs instanceof StringBuilder) 052 sb2 = (StringBuilder)cs; 053 this.length = cs.length(); 054 } 055 056 @Override /* Reader */ 057 public int read() { 058 if (next >= length) 059 return -1; 060 return cs.charAt(next++); 061 } 062 063 @Override /* Reader */ 064 public boolean markSupported() { 065 return false; 066 } 067 068 @Override /* Reader */ 069 public int read(final char[] cbuf, final int off, final int len) { 070 if (next >= length) 071 return -1; 072 int n = Math.min(length - next, len); 073 if (s != null) 074 s.getChars(next, next + n, cbuf, off); 075 else if (sb != null) 076 sb.getChars(next, next + n, cbuf, off); 077 else if (sb2 != null) 078 sb2.getChars(next, next + n, cbuf, off); 079 else { 080 for (int i = 0; i < n; i++) 081 cbuf[off+i] = cs.charAt(next+i); 082 } 083 next += n; 084 return n; 085 } 086 087 @Override /* Reader */ 088 public long skip(long ns) { 089 if (next >= length) 090 return 0; 091 long n = Math.min(length - next, ns); 092 n = Math.max(-next, n); 093 next += n; 094 return n; 095 } 096 097 @Override /* Reader */ 098 public void close() { 099 // no-op 100 } 101 102 @Override /* Object */ 103 public String toString() { 104 return cs.toString(); 105 } 106}