其实ByteString没什么好看的。看之前以为有重要内容,看完后发现没有,不过既然已经看了,就记录下来吧。

ByteString封装了以下几点

1、就是把一些输入类型(字符串/字节数组/ByteBuffer/byte)转成字节数组,并封装成新的ByteString返回。

比如ByteString.of(...)

2、封装了对ByteString的比较、加密操作,方便使用

比如ByteString.encode(...)、base64(...)、md5(...)、sha1()、....

ByteString.startWith(...)、endWith(...)

差不多就这些东西。

public class ByteString implements Serializable, Comparable<ByteString> {static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};/** A singleton empty {@code ByteString}. */public static final ByteString EMPTY = ByteString.of();final byte[] data;transient int hashCode; // Lazily computed; 0 if unknown.transient String utf8; // Lazily computed.ByteString(byte[] data) {this.data = data; // Trusted internal constructor doesn't clone data.}/*** Returns a new byte string containing a clone of the bytes of {@code data}.*/public static ByteString of(byte... data) {if (data == null) {throw new IllegalArgumentException("data == null");}return new ByteString(data.clone());}//复制data的缓存中byteCount个字节的内容到新的byte[],返回一个新的ByteStringpublic static ByteString of(byte[] data, int offset, int byteCount) {if (data == null) {throw new IllegalArgumentException("data == null");}checkOffsetAndCount(data.length, offset, byteCount);//校验参数byte[] copy = new byte[byteCount];System.arraycopy(data, offset, copy, 0, byteCount);return new ByteString(copy);}//复制data的缓存中0-data.remaining()的内容到copy数组,返回新的ByteStringpublic static ByteString of(ByteBuffer data) {if (data == null) {throw new IllegalArgumentException("data == null");}byte[] copy = new byte[data.remaining()];//data.get(copy);return new ByteString(copy);}//把string转byte[]存入新建的ByteString返回,byteString.utf8保存了string的原字符串public static ByteString encodeUtf8(String s) {if (s == null) {throw new IllegalArgumentException("s == null");}ByteString byteString = new ByteString(s.getBytes(Util.UTF_8));byteString.utf8 = s;return byteString;}/** Returns a new byte string containing the {@code charset}-encoded bytes of {@code s}. */public static ByteString encodeString(String s, Charset charset) {if (s == null) {throw new IllegalArgumentException("s == null");}if (charset == null) {throw new IllegalArgumentException("charset == null");}return new ByteString(s.getBytes(charset));}//获取data[]对应的UTF8字符串public String utf8() {String result = utf8;// We don't care if we double-allocate in racy code.return result != null ? result : (utf8 = new String(data, Util.UTF_8));}//把data[]转成charset的字符串public String string(Charset charset) {if (charset == null) {throw new IllegalArgumentException("charset == null");}return new String(data, charset);}//把data[]用Base64编码后返回public String base64() {return Base64.encode(data);}//把data[]用md5加密后返回public ByteString md5() {return digest("MD5");}//把data[]用sha1加密后返回public ByteString sha1() {return digest("SHA-1");}//把data用sha256加密后返回public ByteString sha256() {return digest("SHA-256");}//把data用sha512加密后返回public ByteString sha512() {return digest("SHA-512");}//加密的apiprivate ByteString digest(String algorithm) {try {return ByteString.of(MessageDigest.getInstance(algorithm).digest(data));} catch (NoSuchAlgorithmException e) {throw new AssertionError(e);}}/** Returns the 160-bit SHA-1 HMAC of this byte string. */public ByteString hmacSha1(ByteString key) {return hmac("HmacSHA1", key);}/** Returns the 256-bit SHA-256 HMAC of this byte string. */public ByteString hmacSha256(ByteString key) {return hmac("HmacSHA256", key);}/** Returns the 512-bit SHA-512 HMAC of this byte string. */public ByteString hmacSha512(ByteString key) {return hmac("HmacSHA512", key);}private ByteString hmac(String algorithm, ByteString key) {try {Mac mac = Mac.getInstance(algorithm);mac.init(new SecretKeySpec(key.toByteArray(), algorithm));return ByteString.of(mac.doFinal(data));} catch (NoSuchAlgorithmException e) {throw new AssertionError(e);} catch (InvalidKeyException e) {throw new IllegalArgumentException(e);}}//如果data是url的字节数组,用Base64对该url的字节数组编码,返回编码后的字符串public String base64Url() {return Base64.encodeUrl(data);}/*** Decodes the Base64-encoded bytes and returns their value as a byte string.* Returns null if {@code base64} is not a Base64-encoded sequence of bytes.*/public static @NullableByteString decodeBase64(String base64) {if (base64 == null) {throw new IllegalArgumentException("base64 == null");}byte[] decoded = Base64.decode(base64);return decoded != null ? new ByteString(decoded) : null;}/** Returns this byte string encoded in hexadecimal. */public String hex() {char[] result = new char[data.length * 2];int c = 0;for (byte b : data) {result[c++] = HEX_DIGITS[(b >> 4) & 0xf];result[c++] = HEX_DIGITS[b & 0xf];}return new String(result);}/** Decodes the hex-encoded bytes and returns their value a byte string. */public static ByteString decodeHex(String hex) {if (hex == null) {throw new IllegalArgumentException("hex == null");}if (hex.length() % 2 != 0) {throw new IllegalArgumentException("Unexpected hex string: " + hex);}byte[] result = new byte[hex.length() / 2];for (int i = 0; i < result.length; i++) {int d1 = decodeHexDigit(hex.charAt(i * 2)) << 4;int d2 = decodeHexDigit(hex.charAt(i * 2 + 1));result[i] = (byte) (d1 + d2);}return of(result);}private static int decodeHexDigit(char c) {if (c >= '0' && c <= '9') {return c - '0';}if (c >= 'a' && c <= 'f') {return c - 'a' + 10;}if (c >= 'A' && c <= 'F') {return c - 'A' + 10;}throw new IllegalArgumentException("Unexpected hex digit: " + c);}//把输入流in的内容写入字节数组,封装成ByteString返回public static ByteString read(InputStream in, int byteCount) throws IOException {if (in == null) {throw new IllegalArgumentException("in == null");}if (byteCount < 0) {throw new IllegalArgumentException("byteCount < 0: " + byteCount);}byte[] result = new byte[byteCount];for (int offset = 0, read; offset < byteCount; offset += read) {read = in.read(result, offset, byteCount - offset);if (read == -1) {throw new EOFException();}}return new ByteString(result);}//把data[]中A-Z之间的字符大写转小写,生成新的字节数组,封装成新的ByteString返回public ByteString toAsciiLowercase() {for (int i = 0; i < data.length; i++) {byte c = data[i];if (c < 'A' || c > 'Z') {continue;}byte[] lowercase = data.clone();lowercase[i++] = (byte) (c - ('A' - 'a'));for (; i < lowercase.length; i++) {c = lowercase[i];if (c < 'A' || c > 'Z') {continue;}lowercase[i] = (byte) (c - ('A' - 'a'));}return new ByteString(lowercase);}return this;}//把data[]中a-z之间的字符,小写转大写,生成新的字节数组,封装成新的ByteString后返回public ByteString toAsciiUppercase() {for (int i = 0; i < data.length; i++) {byte c = data[i];if (c < 'a' || c > 'z') {continue;}byte[] lowercase = data.clone();lowercase[i++] = (byte) (c - ('a' - 'A'));for (; i < lowercase.length; i++) {c = lowercase[i];if (c < 'a' || c > 'z') {continue;}lowercase[i] = (byte) (c - ('a' - 'A'));}return new ByteString(lowercase);}return this;}/*** Returns a byte string that is a substring of this byte string, beginning at the specified* index until the end of this string. Returns this byte string if {@code beginIndex} is 0.*/public ByteString substring(int beginIndex) {return substring(beginIndex, data.length);}//把data[]中beginIndex到endIndex之间的内容封装成新的字节数组,封装成ByteStirng返回public ByteString substring(int beginIndex, int endIndex) {if (beginIndex < 0) {throw new IllegalArgumentException("beginIndex < 0");}if (endIndex > data.length) {throw new IllegalArgumentException("endIndex > length(" + data.length + ")");}int subLen = endIndex - beginIndex;if (subLen < 0) {throw new IllegalArgumentException("endIndex < beginIndex");}if ((beginIndex == 0) && (endIndex == data.length)) {return this;}byte[] copy = new byte[subLen];System.arraycopy(data, beginIndex, copy, 0, subLen);return new ByteString(copy);}//返回data[]第pos个字节public byte getByte(int pos) {return data[pos];}//返回ByteString中data[]的长度public int size() {return data.length;}//返回data[]的一个副本public byte[] toByteArray() {return data.clone();}//返回data[]本身byte[] internalArray() {return data;}//用data[]封装成一个只读的ByteBuffer视图返回public ByteBuffer asByteBuffer() {return ByteBuffer.wrap(data).asReadOnlyBuffer();}//把当前data[]中的内容写入out输出流中public void write(OutputStream out) throws IOException {if (out == null) {throw new IllegalArgumentException("out == null");}out.write(data);}//把data[]中内容写入buffer中void write(Buffer buffer) {buffer.write(data, 0, data.length);}//比较当前ByteString.data[]的offset~offset+byteCount的内容与otherOffset.data[]的otherOffset~otherOffset+byteCount的内容public boolean rangeEquals(int offset, ByteString other, int otherOffset, int byteCount) {return other.rangeEquals(otherOffset, this.data, offset, byteCount);}/*** Returns true if the bytes of this in {@code [offset..offset+byteCount)} equal the bytes of* {@code other} in {@code [otherOffset..otherOffset+byteCount)}. Returns false if either range is* out of bounds.*/public boolean rangeEquals(int offset, byte[] other, int otherOffset, int byteCount) {return offset >= 0 && offset <= data.length - byteCount&& otherOffset >= 0 && otherOffset <= other.length - byteCount&& arrayRangeEquals(data, offset, other, otherOffset, byteCount);}//判断当前bytestring.data[]前缀public final boolean startsWith(ByteString prefix) {return rangeEquals(0, prefix, 0, prefix.size());}public final boolean startsWith(byte[] prefix) {return rangeEquals(0, prefix, 0, prefix.length);}//判断当前bytestring.data[]后缀public final boolean endsWith(ByteString suffix) {return rangeEquals(size() - suffix.size(), suffix, 0, suffix.size());}public final boolean endsWith(byte[] suffix) {return rangeEquals(size() - suffix.length, suffix, 0, suffix.length);}//判断other在当前ByteString所处的位置索引public final int indexOf(ByteString other) {return indexOf(other.internalArray(), 0);}...@Overridepublic int compareTo(ByteString byteString) {int sizeA = size();int sizeB = byteString.size();for (int i = 0, size = Math.min(sizeA, sizeB); i < size; i++) {int byteA = getByte(i) & 0xff;//&0xff,防止java类型转换补码导致数据发生变化int byteB = byteString.getByte(i) & 0xff;if (byteA == byteB) {continue;}return byteA < byteB ? -1 : 1;}if (sizeA == sizeB) {return 0;}return sizeA < sizeB ? -1 : 1;}...
}

Okio源码阅读笔记(三)ByteString相关推荐

  1. Picasso源码阅读笔记三

    Dispatcher负责分发任务,比如提交请求.取消请求.暂停请求.恢复请求等等. DispatcherThread和DispatcherHandler Dispatcher通过DispatcherT ...

  2. 代码分析:NASM源码阅读笔记

    NASM源码阅读笔记 NASM(Netwide Assembler)的使用文档和代码间的注释相当齐全,这给阅读源码 提供了很大的方便.按作者的说法,这是一个模块化的,可重用的x86汇编器, 而且能够被 ...

  3. 【Flink】Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型

    1.概述 转载:Flink 源码阅读笔记(20)- Flink 基于 Mailbox 的线程模型 相似文章:[Flink]Flink 基于 MailBox 实现的 StreamTask 线程模型 Fl ...

  4. libreCAD源码阅读笔记1

    libreCAD源码阅读笔记1 一 前言: 正如官网(https://www.librecad.org)所说,libreCAD是一个开源的CAD制图软件,可以运行在Windows.Apple.Linu ...

  5. HashMap源码阅读笔记

    HashMap是Java编程中常用的集合框架之一. 利用idea得到的类的继承关系图可以发现,HashMap继承了抽象类AbstractMap,并实现了Map接口(对于Serializable和Clo ...

  6. Live555源码阅读笔记(一):源码介绍文档 及 源码目录结构

    目录 一.Live555介绍 1.Live555项目介绍 2.官网及帮助文档介绍 二.源码目录结构 1.UsageEnvironment 2.BasicUsageEnvironment 3.group ...

  7. dgl源码阅读笔记(3)——DeepWalk

    dgl源码阅读笔记(3)--DeepWalk 图神经网络开源库dgl阅读笔记 文章目录 dgl源码阅读笔记(3)--DeepWalk 图神经网络开源库dgl阅读笔记 @[TOC](文章目录) 前言 一 ...

  8. syzkaller 源码阅读笔记1(syz-extract syz-sysgen)

    文章目录 1. syz-extract 1-0 总结 1-1. `main()` 1-2 `archList()` - `1-1 (3)` 获取架构 name list 1-3 `createArch ...

  9. Go-Excelize API源码阅读(三十一)——ProtectSheet(sheet string, settings *SheetProtectionOptions)

    Go-Excelize API源码阅读(三十一)-- ProtectSheet(sheet string, settings *SheetProtectionOptions) 开源摘星计划(WeOpe ...

最新文章

  1. 报名 | Sven Travis教授设计与人工智能思享会
  2. Mybatis排序无效问题解决
  3. angular 组件通信
  4. wxWidgets:在全局范围内捕捉关键事件
  5. 2020-11-30 OpenCV人工智能图像处理学习笔记 第3章 计算机视觉加强之几何变换 warpAffine
  6. AutoML之锦标赛选择
  7. Android免root字体,字体大师免root
  8. 宋宝华:为了不忘却的纪念,评Linux 5.13内核
  9. matlab基础与实例教程,MATLAB R2018基础与实例教程
  10. ldap 统一认证 java_LDAP统一用户认证
  11. WIN10虚拟机安装教程
  12. FilterSecurityInterceptor详解
  13. pc模式 华为mate30_很实用!华为Mate?30全系支持PC模式,无线充+投屏更方便!
  14. 留美学子安全手册,这个可以有
  15. vue项目使用mand mobile check选择项组点击选中,选中的列表延迟一位问题
  16. 机器学习和NLP面试总结
  17. [Java]Mybatis学习笔记(动力节点老杜)
  18. 最全面试宝典-我的春招总结
  19. 传统方法学习IT已不再适用,快速提升的方法原来是这样
  20. 2011的n次方的后四位

热门文章

  1. html中audio使用src,HTML Audio src用法及代码示例
  2. linux shell chmod,Shell chmod 命令简介
  3. (建议收藏)TCP协议灵魂之问,巩固你的网路底层基础
  4. ShellExecute, WinExec, CreateProcess的使用
  5. MySQL批处理 - executeBatch方法使用
  6. 奇怪问题:stray '\200' in program
  7. Codeforces Round #742 (Div. 2) B、C 题解
  8. EASI 批量转数据格式
  9. Android修改时间同步服务器
  10. 二叉树深度优先广度优先算法