github.com/suiyunonghen/dxcommonlib@v0.0.0-20190612012041-7f8547a81a67/StringList.go (about) 1 /* 2 仿Delphi的通用类库 3 GStringList类似于TStringList 4 Autor: 不得闲 5 QQ:75492895 6 */ 7 package DxCommonLib 8 9 import ( 10 "fmt" 11 "os" 12 "strings" 13 "io" 14 "bytes" 15 "bufio" 16 ) 17 18 type ( 19 IStrings interface { 20 Count() int 21 Strings(index int) string 22 SetStrings(index int, str string) 23 Text() string 24 SetText(text string) 25 LoadFromFile(fileName string) 26 SaveToFile(fileName string) 27 Add(str string) 28 Insert(Index int, str string) 29 Delete(index int) 30 AddStrings(strs IStrings) 31 AddSlice(strs []string) 32 Clear() 33 IndexOf(str string) int 34 35 AddPair(Name, Value string) 36 IndexOfName(Name string) int 37 ValueFromIndex(index int) string 38 ValueByName(Name string) string 39 Names(Index int) string 40 AsSlice() []string 41 } 42 43 LineBreakMode byte 44 45 GStringList struct { 46 strings []string 47 LineBreak LineBreakMode 48 UnknownCodeUseGbk bool //未知编码的时候采用GBK编码打开 49 } 50 ) 51 52 const ( 53 LBK_CRLF LineBreakMode = iota 54 LBK_CR 55 LBK_LF 56 ) 57 58 func (lst *GStringList) LineBreakStr() string { 59 switch lst.LineBreak { 60 case LBK_CRLF: 61 return "\r\n" 62 case LBK_CR: 63 return "\r" 64 case LBK_LF: 65 return "\n" 66 default: 67 return "\r\n" 68 } 69 } 70 71 func (lst *GStringList) Count() int { 72 if lst.strings == nil { 73 return 0 74 } 75 return len(lst.strings) 76 } 77 78 func (lst *GStringList) Strings(index int) string { 79 if index >= 0 && index < len(lst.strings) { 80 return lst.strings[index] 81 } 82 return "" 83 } 84 85 func (lst *GStringList) SetStrings(index int, str string) { 86 if lst.strings == nil { 87 lst.strings = make([]string, 0, 64) 88 } 89 if index >= 0 && index < len(lst.strings) { 90 lst.strings[index] = str 91 } 92 } 93 94 func (lst *GStringList) Text() string { 95 if lst.Count() == 0 { 96 return "" 97 } 98 buffer := bytes.NewBuffer(make([]byte,0,1024)) 99 count := lst.Count() 100 for i := 0;i<count;i++{ 101 buffer.WriteString(lst.strings[i]) 102 if i < count - 1{ 103 buffer.WriteString(lst.LineBreakStr()) 104 } 105 } 106 return FastByte2String(buffer.Bytes()) 107 } 108 109 func (lst *GStringList) SetText(text string) { 110 lst.strings = strings.Split(text, lst.LineBreakStr()) 111 } 112 113 func (lst *GStringList) LoadFromFile(fileName string) { 114 if finfo, err := os.Stat(fileName); err == nil && !finfo.IsDir() { 115 if file, err := os.Open(fileName); err == nil { 116 //先判定文件格式,是否为utf8或者utf16,去掉BOM 117 if lst.strings == nil{ 118 lst.strings = make([]string,0,100) 119 }else{ 120 lst.strings = lst.strings[:0] 121 } 122 defer file.Close() 123 var bt [3]byte 124 filecodeType := File_Code_Unknown 125 if _,err := file.Read(bt[:3]);err==nil{ 126 if bt[0] == 0xFF && bt[1] == 0xFE { //UTF-16(Little Endian) 127 file.Seek(-1,io.SeekCurrent) 128 filecodeType = File_Code_Utf16LE 129 }else if bt[0] == 0xFE && bt[1] == 0xFF{ //UTF-16(big Endian) 130 file.Seek(-1,io.SeekCurrent) 131 filecodeType = File_Code_Utf16BE 132 }else if bt[0] == 0xEF && bt[1] == 0xBB && bt[2] == 0xBF { //UTF-8 133 filecodeType = File_Code_Utf8 134 }else{ 135 file.Seek(-3,io.SeekCurrent) 136 } 137 } 138 reader := bufio.NewReader(file) 139 for{ 140 line,err := reader.ReadBytes('\n') 141 if filecodeType == File_Code_Utf16LE{ //小端结尾多一个空白的0标记 142 reader.ReadByte() 143 } 144 if err == nil || err == io.EOF{ 145 linelen := len(line) 146 if linelen >= 2{ 147 if line[linelen-2] == '\r'{ 148 line = line[:linelen - 2] 149 }else if line[linelen - 1] == '\n'{ 150 line = line[:linelen-1] 151 } 152 } 153 if linelen>0{ 154 switch filecodeType { 155 case File_Code_Utf8: 156 lst.Add(FastByte2String(line)) 157 case File_Code_Utf16LE,File_Code_Utf16BE: 158 lst.Add(UTF16Byte2string(line,filecodeType == File_Code_Utf16BE)) 159 case File_Code_GBK,File_Code_Unknown: 160 if tmpbytes, err := GBK2Utf8(line); err == nil { 161 lst.Add(FastByte2String(tmpbytes)) 162 }else{ 163 lst.Add(FastByte2String(line)) 164 } 165 } 166 }else{ 167 lst.Add("") 168 } 169 if err != nil{ 170 return 171 } 172 }else{ 173 return 174 } 175 } 176 } 177 } 178 } 179 180 func (lst *GStringList) SaveToFile(fileName string) { 181 //文件要先写入UTF8的BOM 182 if file, err := os.OpenFile(fileName, os.O_CREATE|os.O_TRUNC, 0644); err == nil { 183 count := lst.Count() 184 if count > 0 { 185 file.Write([]byte{0xEF, 0xBB, 0xBF}) 186 //写入内容 187 buffer := bytes.NewBuffer(make([]byte,0,1024)) 188 for i := 0;i<count;i++{ 189 buffer.WriteString(lst.strings[i]) 190 if i < count - 1{ 191 buffer.WriteString(lst.LineBreakStr()) 192 } 193 } 194 file.Write(buffer.Bytes()) 195 } 196 file.Close() 197 } 198 } 199 200 func (lst *GStringList) Add(str string) { 201 if lst.strings == nil { 202 lst.strings = make([]string, 0, 64) 203 } 204 lst.strings = append(lst.strings, str) 205 } 206 207 func (lst *GStringList) Insert(Index int, str string) { 208 if lst.strings == nil { 209 lst.strings = make([]string, 0, 64) 210 } 211 if Index >= 0 && Index < len(lst.strings) { 212 temp := append([]string{}, lst.strings[Index:]...) 213 lst.strings = append(lst.strings[0:Index], str) 214 lst.strings = append(lst.strings, temp...) 215 } else { 216 lst.Add(str) 217 } 218 } 219 func (lst *GStringList) Delete(index int) { 220 if lst.Count() > 0 && index >= 0 && index < len(lst.strings) { 221 lst.strings = append(lst.strings[0:index], lst.strings[index+1:]...) 222 } 223 } 224 225 func (lst *GStringList) AddStrings(strs IStrings) { 226 for idx := 0; idx < strs.Count(); idx++ { 227 lst.Add(strs.Strings(idx)) 228 } 229 } 230 231 func (lst *GStringList) AddSlice(strs []string) { 232 if lst.strings != nil { 233 lst.strings = append(lst.strings, strs...) 234 } else { 235 lst.strings = strs 236 } 237 } 238 func (lst *GStringList) Clear() { 239 if lst.strings != nil { 240 lst.strings = lst.strings[:0] 241 } 242 } 243 func (lst *GStringList) IndexOf(str string) int { 244 if lst.Count() > 0 { 245 for idx, v := range lst.strings { 246 if v == str { 247 return idx 248 } 249 } 250 } 251 return -1 252 } 253 254 func (lst *GStringList) AddPair(Name, Value string) { 255 lst.strings = append(lst.strings, fmt.Sprintf("%s=%s", Name, Value)) 256 } 257 func (lst *GStringList) IndexOfName(Name string) int { 258 if lst.Count() > 0 { 259 for idx, v := range lst.strings { 260 if eidx := strings.IndexByte(v, '='); eidx > 0 { 261 bt := []byte(v) 262 if string(bt[:eidx]) == Name { 263 return idx 264 } 265 } 266 } 267 } 268 return -1 269 } 270 271 func (lst *GStringList) ValueFromIndex(index int) string { 272 if lst.Count() == 0 { 273 return "" 274 } 275 if index >= 0 && index < len(lst.strings) { 276 str := lst.strings[index] 277 if idx := strings.IndexByte(str, '='); idx > 0 { 278 bt := []byte(str) 279 return FastByte2String(bt[idx+1:]) 280 } 281 return "" 282 } 283 return "" 284 } 285 286 func (lst *GStringList) ValueByName(Name string) string { 287 if lst.Count() > 0 { 288 for _, v := range lst.strings { 289 if eidx := strings.IndexByte(v, '='); eidx > 0 { 290 bt := []byte(v) 291 if string(bt[:eidx]) == Name { 292 return FastByte2String(bt[eidx+1:]) 293 } 294 } 295 } 296 } 297 return "" 298 } 299 func (lst *GStringList) Names(Index int) string { 300 if lst.Count() == 0 { 301 return "" 302 } 303 if Index >= 0 && Index < len(lst.strings) { 304 str := lst.strings[Index] 305 if idx := strings.IndexByte(str, '='); idx > 0 { 306 bt := []byte(str) 307 return FastByte2String(bt[:idx]) 308 } 309 return "" 310 } 311 return "" 312 } 313 func (lst *GStringList) AsSlice() []string { 314 return lst.strings 315 }