use of cn.hutool.core.text.StrBuilder in project hutool by looly.
the class CsvParser method readLine.
/**
* 读取一行数据
*
* @return 一行数据
* @throws IORuntimeException IO异常
*/
private List<String> readLine() throws IORuntimeException {
final List<String> currentFields = new ArrayList<>(maxFieldCount > 0 ? maxFieldCount : DEFAULT_ROW_CAPACITY);
final StrBuilder localCurrentField = currentField;
final char[] localBuf = this.buf;
// 当前位置
int localBufPos = bufPos;
// 前一个特殊分界字符
int localPreChar = preChar;
// 拷贝起始位置
int localCopyStart = copyStart;
// 拷贝长度
int copyLen = 0;
while (true) {
if (bufLen == localBufPos) {
if (copyLen > 0) {
localCurrentField.append(localBuf, localCopyStart, copyLen);
}
try {
bufLen = reader.read(localBuf);
} catch (IOException e) {
throw new IORuntimeException(e);
}
if (bufLen < 0) {
// CSV读取结束
finished = true;
if (localPreChar == config.fieldSeparator || localCurrentField.hasContent()) {
// 剩余部分作为一个字段
currentFields.add(localCurrentField.toStringAndReset());
}
break;
}
// 重置
localCopyStart = localBufPos = copyLen = 0;
}
final char c = localBuf[localBufPos++];
if (inQuotes) {
// 引号内,做为内容,直到引号结束
if (c == config.textDelimiter) {
// End of quoted text
inQuotes = false;
} else {
if ((c == CharUtil.CR || c == CharUtil.LF) && localPreChar != CharUtil.CR) {
lineNo++;
}
}
copyLen++;
} else {
if (c == config.fieldSeparator) {
// 一个字段结束
if (copyLen > 0) {
localCurrentField.append(localBuf, localCopyStart, copyLen);
copyLen = 0;
}
currentFields.add(StrUtil.unWrap(localCurrentField.toStringAndReset(), config.textDelimiter));
localCopyStart = localBufPos;
} else if (c == config.textDelimiter) {
// 引号开始
inQuotes = true;
copyLen++;
} else if (c == CharUtil.CR) {
if (copyLen > 0) {
localCurrentField.append(localBuf, localCopyStart, copyLen);
}
currentFields.add(StrUtil.unWrap(localCurrentField.toStringAndReset(), config.textDelimiter));
localPreChar = c;
localCopyStart = localBufPos;
break;
} else if (c == CharUtil.LF) {
if (localPreChar != CharUtil.CR) {
if (copyLen > 0) {
localCurrentField.append(localBuf, localCopyStart, copyLen);
}
currentFields.add(StrUtil.unWrap(localCurrentField.toStringAndReset(), config.textDelimiter));
localPreChar = c;
localCopyStart = localBufPos;
break;
}
localCopyStart = localBufPos;
} else {
copyLen++;
}
}
localPreChar = c;
}
// restore fields
bufPos = localBufPos;
preChar = localPreChar;
copyStart = localCopyStart;
return currentFields;
}
use of cn.hutool.core.text.StrBuilder in project hutool by looly.
the class HttpUtil method encodeParams.
/**
* 对URL参数做编码,只编码键和值<br>
* 提供的值可以是url附带编码,但是不能只是url
*
* @param paramsStr url参数,可以包含url本身
* @param charset 编码
* @return 编码后的url和参数
* @since 4.0.1
*/
public static String encodeParams(final String paramsStr, Charset charset) {
if (StrUtil.isBlank(paramsStr)) {
return StrUtil.EMPTY;
}
// url部分,不包括问号
String urlPart = null;
// 参数部分
String paramPart;
int pathEndPos = paramsStr.indexOf('?');
if (pathEndPos > -1) {
// url + 参数
urlPart = StrUtil.subPre(paramsStr, pathEndPos);
paramPart = StrUtil.subSuf(paramsStr, pathEndPos + 1);
if (StrUtil.isBlank(paramPart)) {
// 无参数,返回url
return urlPart;
}
} else {
// 无URL
paramPart = paramsStr;
}
final StrBuilder builder = StrBuilder.create(paramPart.length() + 16);
final int len = paramPart.length();
String name = null;
// 未处理字符开始位置
int pos = 0;
// 当前字符
char c;
// 当前字符位置
int i;
for (i = 0; i < len; i++) {
c = paramPart.charAt(i);
if (c == '=') {
// 键值对的分界点
if (null == name) {
// 只有=前未定义name时被当作键值分界符,否则做为普通字符
name = (pos == i) ? StrUtil.EMPTY : paramPart.substring(pos, i);
pos = i + 1;
}
} else if (c == '&') {
// 参数对的分界点
if (pos != i) {
if (null == name) {
// 对于像&a&这类无参数值的字符串,我们将name为a的值设为""
name = paramPart.substring(pos, i);
builder.append(encode(name, charset)).append('=');
} else {
builder.append(encode(name, charset)).append('=').append(encode(paramPart.substring(pos, i), charset)).append('&');
}
name = null;
}
pos = i + 1;
}
}
// 结尾处理
if (null != name) {
builder.append(encode(name, charset)).append('=');
}
if (pos != i) {
if (null == name) {
builder.append('=');
}
builder.append(encode(paramPart.substring(pos, i), charset));
}
int lastIndex = builder.length() - 1;
if ('&' == builder.charAt(lastIndex)) {
builder.delTo(lastIndex);
}
return StrUtil.isBlank(urlPart) ? builder.toString() : urlPart + "?" + builder.toString();
}
use of cn.hutool.core.text.StrBuilder in project hutool by looly.
the class HttpUtil method urlWithForm.
/**
* 将表单数据字符串加到URL中(用于GET表单提交)
*
* @param url URL
* @param queryString 表单数据字符串
* @param charset 编码
* @param isEncode 是否对键和值做转义处理
* @return 拼接后的字符串
*/
public static String urlWithForm(String url, String queryString, Charset charset, boolean isEncode) {
if (StrUtil.isBlank(queryString)) {
// 无额外参数
if (StrUtil.contains(url, '?')) {
// url中包含参数
return isEncode ? encodeParams(url, charset) : url;
}
return url;
}
// 始终有参数
final StrBuilder urlBuilder = StrBuilder.create(url.length() + queryString.length() + 16);
int qmIndex = url.indexOf('?');
if (qmIndex > 0) {
// 原URL带参数,则对这部分参数单独编码(如果选项为进行编码)
urlBuilder.append(isEncode ? encodeParams(url, charset) : url);
if (false == StrUtil.endWith(url, '&')) {
// 已经带参数的情况下追加参数
urlBuilder.append('&');
}
} else {
// 原url无参数,则不做编码
urlBuilder.append(url);
if (qmIndex < 0) {
// 无 '?' 追加之
urlBuilder.append('?');
}
}
urlBuilder.append(isEncode ? encodeParams(queryString, charset) : queryString);
return urlBuilder.toString();
}
use of cn.hutool.core.text.StrBuilder in project hutool by looly.
the class BeanPath method init.
/**
* 初始化
*
* @param expression 表达式
*/
private void init(String expression) {
List<String> localPatternParts = new ArrayList<>();
int length = expression.length();
final StrBuilder builder = StrUtil.strBuilder();
char c;
// 下标标识符开始
boolean isNumStart = false;
for (int i = 0; i < length; i++) {
c = expression.charAt(i);
if (0 == i && '$' == c) {
// 忽略开头的$符,表示当前对象
isStartWith$ = true;
continue;
}
if (ArrayUtil.contains(expChars, c)) {
// 处理边界符号
if (CharUtil.BRACKET_END == c) {
// 中括号(数字下标)结束
if (false == isNumStart) {
throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find ']' but no '[' !", expression, i));
}
isNumStart = false;
// 中括号结束加入下标
if (builder.length() > 0) {
localPatternParts.add(unWrapIfPossible(builder));
}
builder.reset();
} else {
if (isNumStart) {
// 非结束中括号情况下发现起始中括号报错(中括号未关闭)
throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, i));
} else if (CharUtil.BRACKET_START == c) {
// 数字下标开始
isNumStart = true;
}
// 每一个边界符之前的表达式是一个完整的KEY,开始处理KEY
if (builder.length() > 0) {
localPatternParts.add(unWrapIfPossible(builder));
}
builder.reset();
}
} else {
// 非边界符号,追加字符
builder.append(c);
}
}
// 末尾边界符检查
if (isNumStart) {
throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, length - 1));
} else {
if (builder.length() > 0) {
localPatternParts.add(unWrapIfPossible(builder));
}
}
// 不可变List
this.patternParts = Collections.unmodifiableList(localPatternParts);
}
use of cn.hutool.core.text.StrBuilder in project hutool by looly.
the class PinyinUtil method getAllFirstLetter.
/**
* 获取所给中文的每个汉字首字母组成首字母字符串
* @param chinese 汉字字符串
* @return 首字母字符串
*/
public static String getAllFirstLetter(String chinese) {
if (StrUtil.isBlank(chinese)) {
return StrUtil.EMPTY;
}
int len = chinese.length();
final StrBuilder strBuilder = new StrBuilder(len);
for (int i = 0; i < len; i++) {
strBuilder.append(getFirstLetter(chinese.charAt(i)));
}
return strBuilder.toString();
}
Aggregations