View Javadoc
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 }