Browse Source

添加压缩功能

James 5 years ago
parent
commit
8574f52f19
1 changed files with 85 additions and 0 deletions
  1. 85 0
      src/main/java/com/jfinal/template/stat/Compressor.java

+ 85 - 0
src/main/java/com/jfinal/template/stat/Compressor.java

@@ -0,0 +1,85 @@
+package com.jfinal.template.stat;
+
+/**
+ * 对 Text 节点进行压缩
+ * 
+ * 1:为追求性能极致,只压缩 Text 节点,所以压缩结果会存在一部分空白字符
+ * 2:每次读取一行,按行进行压缩
+ * 3:第一行左侧空白不压缩
+ * 4:最后一行右侧空白不压缩(注意:最后一行在以字符 '\n' 结尾时不算最后一行)
+ * 5:第一行、最后一行以外的其它行左右侧都压缩
+ * 6:文本之内的空白不压缩,例如字符串 "abc  def" 中的 "abc" 与 "def" 之间的空格不压缩
+ * 7:压缩后内容的默认分隔字符为 '\n',对 js 语句缺少分号的支持更友好。还可配置为空格 ' ' 等分隔字符
+ */
+public class Compressor {
+	
+	protected char separator = '\n';
+	
+	public Compressor() {}
+	
+	public Compressor(char separator) {
+		if (separator > ' ') {
+			throw new IllegalArgumentException("The parameter separator must be a separator character");
+		}
+		this.separator = separator;
+	}
+	
+	public StringBuilder compress(StringBuilder content) {
+		int len = content.length();
+		StringBuilder result = new StringBuilder(len);
+		
+		int begin = 0;
+		int forward = 0;
+		boolean compressLeft = false;	// 第一行不压缩左侧
+		while (forward < len) {
+			if (content.charAt(forward) == '\n') {
+				compressLine(content, begin, forward - 1, compressLeft, result);
+				result.append(separator);
+				
+				begin = forward + 1;
+				forward = begin;
+				compressLeft = true;
+			} else {
+				forward++;
+			}
+		}
+		
+		for (int i = begin; i < len; i++) {
+			result.append(content.charAt(i));
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * 按行压缩。只压缩文本前后的空白字符,文本内部的空白字符不压缩
+	 * @param content 被处理行文本所在的 StringBuilder 对象
+	 * @param start 被处理行文本的开始下标
+	 * @param end 被处理行文本的结束下标(注意 end 下标所指向的字符被包含在处理的范围之内)
+	 * @param compressLeft 是否压缩左侧
+	 * @param result 存放压缩结果
+	 */
+	protected void compressLine(StringBuilder content, int start, int end, boolean compressLeft, StringBuilder result) {
+		// 压缩右侧空白
+		while (end >= start && content.charAt(end) <= ' ') {
+			end--;
+		}
+		
+		// 压缩左侧空白
+		if (compressLeft) {
+			while (start < end && content.charAt(start) <= ' ') {
+				start++;
+			}
+		}
+		
+		if (start <= end) {
+			for (int i = start; i <= end; i++) {
+				result.append(content.charAt(i));
+			}
+		}
+	}
+}
+
+
+
+