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  }