1 package com.github.mygreen.supercsv.cellprocessor.conversion;
2
3 import com.github.mygreen.supercsv.util.Utils;
4
5 /**
6 * パディング処理の抽象クラス。
7 * <p>サロゲートペアを考慮します。</p>
8 *
9 * @since 2.1
10 * @author T.TSUCHIE
11 *
12 */
13 public abstract class AbstractPaddingOperator implements PaddingProcessor {
14
15 @Override
16 public String pad(final String text, final int size, final char padChar, final boolean rightAlign, final boolean chopped) {
17
18 final int currentSize = count(text);
19 final int padCharSize = count(String.valueOf(padChar));
20 final int[] codePointArray = Utils.toCodePointArray(text);
21 final int codePointSize = codePointArray.length;
22
23 if(rightAlign) {
24 // 右詰
25 if(currentSize == size) {
26 return text;
27
28 } else if(currentSize > size) {
29 // 指定した長さを超える場合
30 if(chopped) {
31 // 切り出す場合
32
33 /*
34 * 左端から長さをカウントしていき、オーバした長さ分を切り取る
35 */
36 final int overLength = currentSize - size;
37 for(int i=0, chopLength=0; i < codePointSize; i++) {
38 final int codePoint = codePointArray[i];
39 chopLength += count(codePoint);
40 if(chopLength >= overLength) {
41 // substring(i+1)
42 String chopText = new String(codePointArray, i+1, codePointSize-(i+1));
43
44 // 切り取った後の再調整。
45 // パディング文字が全角の場合は、余分に切り取る場合があるため。
46 return pad(chopText, size, padChar, rightAlign, chopped);
47 }
48
49 }
50
51 // 全て切り出す場合
52 return "";
53
54 } else {
55 // 切り出さない場合
56 return text;
57 }
58 } else {
59 // 指定したサイズより少ない場合
60
61 /*
62 * パディング文字を付与していく
63 * ・パディング文字が全角の時があり、長さが2以上になるので注意する
64 */
65 final int lackLength = size - currentSize;
66 int padCount = lackLength / padCharSize;
67
68 StringBuilder appender = new StringBuilder();
69 for(int i=0; i < padCount; i++) {
70 appender.append(padChar);
71 }
72
73 appender.append(text);
74
75 return appender.toString();
76
77 }
78 } else {
79 // 左詰
80
81 if(currentSize == size) {
82 return text;
83
84 } else if(currentSize > size) {
85 // 指定したサイズを超える場合
86 if(chopped) {
87 // 切り出す場合
88
89 /*
90 * 右端から長さをカウントしていき、オーバした長さ分を切り取る
91 */
92 final int overLength = currentSize - size;
93 for(int i=codePointSize-1, chopLength=0; i >= 0; i--) {
94 final int codePoint = codePointArray[i];
95 chopLength += count(codePoint);
96 if(chopLength >= overLength) {
97 // substring(0, i)
98 String chopText = new String(codePointArray, 0, i);
99
100 // 切り取った後の再調整。
101 // パディング文字が全角の場合は、余分に切り取る場合があるため。
102 return pad(chopText, size, padChar, rightAlign, chopped);
103 }
104
105 }
106
107
108 // 全て切り出す場合
109 return "";
110
111 } else {
112 // 切り出さない場合
113 return text;
114 }
115 } else {
116 // 指定したサイズより少ない場合
117
118 /*
119 * パディング文字を付与していく
120 * ・パディング文字が全角の時があり、長さが2以上になるので注意する
121 */
122 final int lackLength = size - currentSize;
123 int padCount = lackLength / padCharSize;
124
125 StringBuilder appender = new StringBuilder(text);
126 for(int i=0; i < padCount; i++) {
127 appender.append(padChar);
128 }
129
130 return appender.toString();
131 }
132
133 }
134
135 }
136
137 }