Compare commits
4 Commits
7a579d0d0b
...
7faca878a3
Author | SHA1 | Date |
---|---|---|
Lykin | 7faca878a3 | |
Lykin | 74d789ac8e | |
Lykin | fd58357a04 | |
Lykin | f09ee89a96 |
|
@ -21,6 +21,7 @@ import (
|
|||
"tinyrdm/backend/consts"
|
||||
"tinyrdm/backend/types"
|
||||
"tinyrdm/backend/utils/coll"
|
||||
convutil "tinyrdm/backend/utils/convert"
|
||||
redis2 "tinyrdm/backend/utils/redis"
|
||||
sliceutil "tinyrdm/backend/utils/slice"
|
||||
strutil "tinyrdm/backend/utils/string"
|
||||
|
@ -781,7 +782,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
Value: val,
|
||||
})
|
||||
if doConvert {
|
||||
if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
if dv, _, _ := convutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
items[len(items)-1].DisplayValue = dv
|
||||
}
|
||||
}
|
||||
|
@ -828,7 +829,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
Value: strutil.EncodeRedisKey(loadedVal[i+1]),
|
||||
})
|
||||
if doConvert {
|
||||
if dv, _, _ := strutil.ConvertTo(loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] {
|
||||
if dv, _, _ := convutil.ConvertTo(loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] {
|
||||
items[len(items)-1].DisplayValue = dv
|
||||
}
|
||||
}
|
||||
|
@ -853,7 +854,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
items[i/2].Key = loadedVal[i]
|
||||
items[i/2].Value = strutil.EncodeRedisKey(loadedVal[i+1])
|
||||
if doConvert {
|
||||
if dv, _, _ := strutil.ConvertTo(loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] {
|
||||
if dv, _, _ := convutil.ConvertTo(loadedVal[i+1], param.Decode, param.Format); dv != loadedVal[i+1] {
|
||||
items[i/2].DisplayValue = dv
|
||||
}
|
||||
}
|
||||
|
@ -898,7 +899,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
Value: val,
|
||||
})
|
||||
if doConvert {
|
||||
if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
if dv, _, _ := convutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
items[len(items)-1].DisplayValue = dv
|
||||
}
|
||||
}
|
||||
|
@ -918,7 +919,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
for i, val := range loadedKey {
|
||||
items[i].Value = val
|
||||
if doConvert {
|
||||
if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
if dv, _, _ := convutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
items[i].DisplayValue = dv
|
||||
}
|
||||
}
|
||||
|
@ -966,7 +967,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
Score: score,
|
||||
})
|
||||
if doConvert {
|
||||
if dv, _, _ := strutil.ConvertTo(loadedVal[i], param.Decode, param.Format); dv != loadedVal[i] {
|
||||
if dv, _, _ := convutil.ConvertTo(loadedVal[i], param.Decode, param.Format); dv != loadedVal[i] {
|
||||
items[len(items)-1].DisplayValue = dv
|
||||
}
|
||||
}
|
||||
|
@ -1000,7 +1001,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
Value: val,
|
||||
})
|
||||
if doConvert {
|
||||
if dv, _, _ := strutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
if dv, _, _ := convutil.ConvertTo(val, param.Decode, param.Format); dv != val {
|
||||
items[len(items)-1].DisplayValue = dv
|
||||
}
|
||||
}
|
||||
|
@ -1061,7 +1062,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
if vb, merr := json.Marshal(msg.Values); merr != nil {
|
||||
it.DisplayValue = "{}"
|
||||
} else {
|
||||
it.DisplayValue, _, _ = strutil.ConvertTo(string(vb), types.DECODE_NONE, types.FORMAT_JSON)
|
||||
it.DisplayValue, _, _ = convutil.ConvertTo(string(vb), types.DECODE_NONE, types.FORMAT_JSON)
|
||||
}
|
||||
if doFilter && !strings.Contains(it.DisplayValue, param.MatchPattern) {
|
||||
continue
|
||||
|
@ -1095,7 +1096,7 @@ func (b *browserService) GetKeyDetail(param types.KeyDetailParam) (resp types.JS
|
|||
// blank format indicate auto format
|
||||
func (b *browserService) ConvertValue(value any, decode, format string) (resp types.JSResp) {
|
||||
str := strutil.DecodeRedisKey(value)
|
||||
value, decode, format = strutil.ConvertTo(str, decode, format)
|
||||
value, decode, format = convutil.ConvertTo(str, decode, format)
|
||||
resp.Success = true
|
||||
resp.Data = map[string]any{
|
||||
"value": value,
|
||||
|
@ -1138,7 +1139,7 @@ func (b *browserService) SetKeyValue(param types.SetKeyParam) (resp types.JSResp
|
|||
return
|
||||
} else {
|
||||
var saveStr string
|
||||
if saveStr, err = strutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
if saveStr, err = convutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
resp.Msg = fmt.Sprintf(`save to type "%s" fail: %s`, param.Format, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1249,12 +1250,12 @@ func (b *browserService) SetHashValue(param types.SetHashParam) (resp types.JSRe
|
|||
key := strutil.DecodeRedisKey(param.Key)
|
||||
str := strutil.DecodeRedisKey(param.Value)
|
||||
var saveStr, displayStr string
|
||||
if saveStr, err = strutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
if saveStr, err = convutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
resp.Msg = fmt.Sprintf(`save to type "%s" fail: %s`, param.Format, err.Error())
|
||||
return
|
||||
}
|
||||
if len(param.RetDecode) > 0 && len(param.RetFormat) > 0 {
|
||||
displayStr, _, _ = strutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat)
|
||||
displayStr, _, _ = convutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat)
|
||||
}
|
||||
var updated, added, removed []types.HashEntryItem
|
||||
var replaced []types.HashReplaceItem
|
||||
|
@ -1472,7 +1473,7 @@ func (b *browserService) SetListItem(param types.SetListParam) (resp types.JSRes
|
|||
} else {
|
||||
// replace index value
|
||||
var saveStr string
|
||||
if saveStr, err = strutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
if saveStr, err = convutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
resp.Msg = fmt.Sprintf(`save to type "%s" fail: %s`, param.Format, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1483,7 +1484,7 @@ func (b *browserService) SetListItem(param types.SetListParam) (resp types.JSRes
|
|||
}
|
||||
var displayStr string
|
||||
if len(param.RetDecode) > 0 && len(param.RetFormat) > 0 {
|
||||
displayStr, _, _ = strutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat)
|
||||
displayStr, _, _ = convutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat)
|
||||
}
|
||||
replaced = append(replaced, types.ListReplaceItem{
|
||||
Index: param.Index,
|
||||
|
@ -1574,7 +1575,7 @@ func (b *browserService) UpdateSetItem(param types.SetSetParam) (resp types.JSRe
|
|||
// insert new value
|
||||
str = strutil.DecodeRedisKey(param.NewValue)
|
||||
var saveStr string
|
||||
if saveStr, err = strutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
if saveStr, err = convutil.SaveAs(str, param.Format, param.Decode); err != nil {
|
||||
resp.Msg = fmt.Sprintf(`save to type "%s" fail: %s`, param.Format, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1582,7 +1583,7 @@ func (b *browserService) UpdateSetItem(param types.SetSetParam) (resp types.JSRe
|
|||
// add new item
|
||||
var displayStr string
|
||||
if len(param.RetDecode) > 0 && len(param.RetFormat) > 0 {
|
||||
displayStr, _, _ = strutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat)
|
||||
displayStr, _, _ = convutil.ConvertTo(saveStr, param.RetDecode, param.RetFormat)
|
||||
}
|
||||
added = append(added, types.SetEntryItem{
|
||||
Value: saveStr,
|
||||
|
@ -1629,7 +1630,7 @@ func (b *browserService) UpdateZSetValue(param types.SetZSetParam) (resp types.J
|
|||
}
|
||||
} else {
|
||||
var saveVal string
|
||||
if saveVal, err = strutil.SaveAs(newVal, param.Format, param.Decode); err != nil {
|
||||
if saveVal, err = convutil.SaveAs(newVal, param.Format, param.Decode); err != nil {
|
||||
resp.Msg = fmt.Sprintf(`save to type "%s" fail: %s`, param.Format, err.Error())
|
||||
return
|
||||
}
|
||||
|
@ -1639,7 +1640,7 @@ func (b *browserService) UpdateZSetValue(param types.SetZSetParam) (resp types.J
|
|||
Score: param.Score,
|
||||
Member: saveVal,
|
||||
}).Result()
|
||||
displayValue, _, _ := strutil.ConvertTo(val, param.RetDecode, param.RetFormat)
|
||||
displayValue, _, _ := convutil.ConvertTo(val, param.RetDecode, param.RetFormat)
|
||||
if affect > 0 {
|
||||
// add new item
|
||||
added = append(added, types.ZSetEntryItem{
|
||||
|
@ -1667,7 +1668,7 @@ func (b *browserService) UpdateZSetValue(param types.SetZSetParam) (resp types.J
|
|||
Score: param.Score,
|
||||
Member: saveVal,
|
||||
}).Result()
|
||||
displayValue, _, _ := strutil.ConvertTo(saveVal, param.RetDecode, param.RetFormat)
|
||||
displayValue, _, _ := convutil.ConvertTo(saveVal, param.RetDecode, param.RetFormat)
|
||||
if affect <= 0 {
|
||||
// no new value added, just update exists item
|
||||
removed = append(removed, types.ZSetEntryItem{
|
||||
|
@ -1793,7 +1794,7 @@ func (b *browserService) AddStreamValue(server string, db int, k any, ID string,
|
|||
updateValues[fieldItems[i].(string)] = fieldItems[i+1]
|
||||
}
|
||||
vb, _ := json.Marshal(updateValues)
|
||||
displayValue, _, _ := strutil.ConvertTo(string(vb), types.DECODE_NONE, types.FORMAT_JSON)
|
||||
displayValue, _, _ := convutil.ConvertTo(string(vb), types.DECODE_NONE, types.FORMAT_JSON)
|
||||
|
||||
resp.Success = true
|
||||
resp.Data = struct {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
strutil "tinyrdm/backend/utils/string"
|
||||
)
|
||||
|
||||
type Base64Convert struct{}
|
||||
|
||||
func (Base64Convert) Encode(str string) (string, bool) {
|
||||
return base64.StdEncoding.EncodeToString([]byte(str)), true
|
||||
}
|
||||
|
||||
func (Base64Convert) Decode(str string) (string, bool) {
|
||||
if decodedStr, err := base64.StdEncoding.DecodeString(str); err == nil {
|
||||
if s := string(decodedStr); !strutil.ContainsBinary(s) {
|
||||
return s, true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BinaryConvert struct{}
|
||||
|
||||
func (BinaryConvert) Encode(str string) (string, bool) {
|
||||
var result strings.Builder
|
||||
total := len(str)
|
||||
for i := 0; i < total; i += 8 {
|
||||
b, _ := strconv.ParseInt(str[i:i+8], 2, 8)
|
||||
result.WriteByte(byte(b))
|
||||
}
|
||||
return result.String(), true
|
||||
}
|
||||
|
||||
func (BinaryConvert) Decode(str string) (string, bool) {
|
||||
var binary strings.Builder
|
||||
for _, char := range str {
|
||||
binary.WriteString(fmt.Sprintf("%08b", int(char)))
|
||||
}
|
||||
return binary.String(), true
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/andybalholm/brotli"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BrotliConvert struct{}
|
||||
|
||||
func (BrotliConvert) Encode(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer := brotli.NewWriter(&buf)
|
||||
if _, err := writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
if brotliStr, err := compress([]byte(str)); err == nil {
|
||||
return brotliStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func (BrotliConvert) Decode(str string) (string, bool) {
|
||||
reader := brotli.NewReader(strings.NewReader(str))
|
||||
if decompressed, err := io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
return str, false
|
||||
}
|
|
@ -0,0 +1,302 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"tinyrdm/backend/types"
|
||||
strutil "tinyrdm/backend/utils/string"
|
||||
)
|
||||
|
||||
type DataConvert interface {
|
||||
Encode(string) (string, bool)
|
||||
Decode(string) (string, bool)
|
||||
}
|
||||
|
||||
var (
|
||||
jsonConv JsonConvert
|
||||
yamlConv YamlConvert
|
||||
xmlConv XmlConvert
|
||||
base64Conv Base64Convert
|
||||
binaryConv BinaryConvert
|
||||
hexConv HexConvert
|
||||
gzipConv GZipConvert
|
||||
deflateConv DeflateConvert
|
||||
zstdConv ZStdConvert
|
||||
brotliConv BrotliConvert
|
||||
msgpackConv MsgpackConvert
|
||||
)
|
||||
|
||||
// ConvertTo convert string to specified type
|
||||
// @param decodeType empty string indicates automatic detection
|
||||
// @param formatType empty string indicates automatic detection
|
||||
func ConvertTo(str, decodeType, formatType string) (value, resultDecode, resultFormat string) {
|
||||
if len(str) <= 0 {
|
||||
// empty content
|
||||
if len(formatType) <= 0 {
|
||||
resultFormat = types.FORMAT_RAW
|
||||
} else {
|
||||
resultFormat = formatType
|
||||
}
|
||||
if len(decodeType) <= 0 {
|
||||
resultDecode = types.DECODE_NONE
|
||||
} else {
|
||||
resultDecode = decodeType
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// decode first
|
||||
value, resultDecode = decodeWith(str, decodeType)
|
||||
// then format content
|
||||
value, resultFormat = viewAs(value, formatType)
|
||||
return
|
||||
}
|
||||
|
||||
func decodeWith(str, decodeType string) (value, resultDecode string) {
|
||||
if len(decodeType) > 0 {
|
||||
switch decodeType {
|
||||
case types.DECODE_NONE:
|
||||
value = str
|
||||
|
||||
case types.DECODE_BASE64:
|
||||
if base64Str, ok := base64Conv.Decode(str); ok {
|
||||
value = base64Str
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
|
||||
case types.DECODE_GZIP:
|
||||
if gzipStr, ok := gzipConv.Decode(str); ok {
|
||||
value = gzipStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
|
||||
case types.DECODE_DEFLATE:
|
||||
if falteStr, ok := deflateConv.Decode(str); ok {
|
||||
value = falteStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
|
||||
case types.DECODE_ZSTD:
|
||||
if zstdStr, ok := zstdConv.Decode(str); ok {
|
||||
value = zstdStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
|
||||
case types.DECODE_BROTLI:
|
||||
if brotliStr, ok := brotliConv.Decode(str); ok {
|
||||
value = brotliStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
|
||||
case types.DECODE_MSGPACK:
|
||||
if msgpackStr, ok := msgpackConv.Decode(str); ok {
|
||||
value = msgpackStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
}
|
||||
resultDecode = decodeType
|
||||
return
|
||||
}
|
||||
|
||||
return autoDecode(str)
|
||||
}
|
||||
|
||||
// attempt try possible decode method
|
||||
// if no decode is possible, it will return the origin string value and "none" decode type
|
||||
func autoDecode(str string) (value, resultDecode string) {
|
||||
if len(str) > 0 {
|
||||
// pure digit content may incorrect regard as some encoded type, skip decode
|
||||
if match, _ := regexp.MatchString(`^\d+$`, str); !match {
|
||||
var ok bool
|
||||
if len(str)%4 == 0 && len(str) >= 12 && !strutil.IsSameChar(str) {
|
||||
if value, ok = base64Conv.Decode(str); ok {
|
||||
resultDecode = types.DECODE_BASE64
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if value, ok = gzipConv.Decode(str); ok {
|
||||
resultDecode = types.DECODE_GZIP
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: skip decompress with deflate due to incorrect format checking
|
||||
//if value, ok = decodeDeflate(str); ok {
|
||||
// resultDecode = types.DECODE_DEFLATE
|
||||
// return
|
||||
//}
|
||||
|
||||
if value, ok = zstdConv.Decode(str); ok {
|
||||
resultDecode = types.DECODE_ZSTD
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: skip decompress with brotli due to incorrect format checking
|
||||
//if value, ok = decodeBrotli(str); ok {
|
||||
// resultDecode = types.DECODE_BROTLI
|
||||
// return
|
||||
//}
|
||||
|
||||
if value, ok = msgpackConv.Decode(str); ok {
|
||||
resultDecode = types.DECODE_MSGPACK
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = str
|
||||
resultDecode = types.DECODE_NONE
|
||||
return
|
||||
}
|
||||
|
||||
func viewAs(str, formatType string) (value, resultFormat string) {
|
||||
if len(formatType) > 0 {
|
||||
switch formatType {
|
||||
case types.FORMAT_RAW, types.FORMAT_YAML, types.FORMAT_XML:
|
||||
value = str
|
||||
|
||||
case types.FORMAT_JSON:
|
||||
if jsonStr, ok := jsonConv.Decode(str); ok {
|
||||
value = jsonStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
|
||||
case types.FORMAT_HEX:
|
||||
if hexStr, ok := hexConv.Decode(str); ok {
|
||||
value = hexStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
|
||||
case types.FORMAT_BINARY:
|
||||
if binStr, ok := binaryConv.Decode(str); ok {
|
||||
value = binStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
}
|
||||
resultFormat = formatType
|
||||
return
|
||||
}
|
||||
|
||||
return autoViewAs(str)
|
||||
}
|
||||
|
||||
// attempt automatic convert to possible types
|
||||
// if no conversion is possible, it will return the origin string value and "plain text" type
|
||||
func autoViewAs(str string) (value, resultFormat string) {
|
||||
if len(str) > 0 {
|
||||
var ok bool
|
||||
if value, ok = jsonConv.Decode(str); ok {
|
||||
resultFormat = types.FORMAT_JSON
|
||||
return
|
||||
}
|
||||
|
||||
if value, ok = yamlConv.Decode(str); ok {
|
||||
resultFormat = types.FORMAT_YAML
|
||||
return
|
||||
}
|
||||
|
||||
if value, ok = xmlConv.Decode(str); ok {
|
||||
resultFormat = types.FORMAT_XML
|
||||
return
|
||||
}
|
||||
|
||||
if strutil.ContainsBinary(str) {
|
||||
if value, ok = hexConv.Decode(str); ok {
|
||||
resultFormat = types.FORMAT_HEX
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = str
|
||||
resultFormat = types.FORMAT_RAW
|
||||
return
|
||||
}
|
||||
|
||||
func SaveAs(str, format, decode string) (value string, err error) {
|
||||
value = str
|
||||
switch format {
|
||||
case types.FORMAT_JSON:
|
||||
if jsonStr, ok := jsonConv.Encode(str); ok {
|
||||
value = jsonStr
|
||||
} else {
|
||||
err = errors.New("invalid json data")
|
||||
return
|
||||
}
|
||||
|
||||
case types.FORMAT_HEX:
|
||||
if hexStr, ok := hexConv.Encode(str); ok {
|
||||
value = hexStr
|
||||
} else {
|
||||
err = errors.New("invalid hex data")
|
||||
return
|
||||
}
|
||||
|
||||
case types.FORMAT_BINARY:
|
||||
if binStr, ok := binaryConv.Encode(str); ok {
|
||||
value = binStr
|
||||
} else {
|
||||
err = errors.New("invalid binary data")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch decode {
|
||||
case types.DECODE_NONE:
|
||||
return
|
||||
|
||||
case types.DECODE_BASE64:
|
||||
value, _ = base64Conv.Encode(value)
|
||||
return
|
||||
|
||||
case types.DECODE_GZIP:
|
||||
if gzipStr, ok := gzipConv.Encode(str); ok {
|
||||
value = gzipStr
|
||||
} else {
|
||||
err = errors.New("fail to build gzip")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_DEFLATE:
|
||||
if deflateStr, ok := deflateConv.Encode(str); ok {
|
||||
value = deflateStr
|
||||
} else {
|
||||
err = errors.New("fail to build deflate")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_ZSTD:
|
||||
if zstdStr, ok := zstdConv.Encode(str); ok {
|
||||
value = zstdStr
|
||||
} else {
|
||||
err = errors.New("fail to build zstd")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_BROTLI:
|
||||
if brotliStr, ok := brotliConv.Encode(str); ok {
|
||||
value = brotliStr
|
||||
} else {
|
||||
err = errors.New("fail to build brotli")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_MSGPACK:
|
||||
if msgpackStr, ok := msgpackConv.Encode(str); ok {
|
||||
value = msgpackStr
|
||||
} else {
|
||||
err = errors.New("fail to build msgpack")
|
||||
}
|
||||
return
|
||||
}
|
||||
return str, nil
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/klauspost/compress/flate"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type DeflateConvert struct{}
|
||||
|
||||
func (d DeflateConvert) Encode(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer, err := flate.NewWriter(&buf, flate.DefaultCompression)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err = writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
if deflateStr, err := compress([]byte(str)); err == nil {
|
||||
return deflateStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func (d DeflateConvert) Decode(str string) (string, bool) {
|
||||
reader := flate.NewReader(strings.NewReader(str))
|
||||
defer reader.Close()
|
||||
if decompressed, err := io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
return str, false
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/klauspost/compress/gzip"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type GZipConvert struct{}
|
||||
|
||||
func (GZipConvert) Encode(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer := gzip.NewWriter(&buf)
|
||||
if _, err := writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
|
||||
if gzipStr, err := compress([]byte(str)); err == nil {
|
||||
return gzipStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func (GZipConvert) Decode(str string) (string, bool) {
|
||||
if reader, err := gzip.NewReader(strings.NewReader(str)); err == nil {
|
||||
defer reader.Close()
|
||||
var decompressed []byte
|
||||
if decompressed, err = io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type HexConvert struct{}
|
||||
|
||||
func (HexConvert) Encode(str string) (string, bool) {
|
||||
hexStrArr := strings.Split(str, "\\x")
|
||||
hexStr := strings.Join(hexStrArr, "")
|
||||
if decodeStr, err := hex.DecodeString(hexStr); err == nil {
|
||||
return string(decodeStr), true
|
||||
}
|
||||
|
||||
return str, false
|
||||
}
|
||||
|
||||
func (HexConvert) Decode(str string) (string, bool) {
|
||||
decodeStr := hex.EncodeToString([]byte(str))
|
||||
decodeStr = strings.ToUpper(decodeStr)
|
||||
var resultStr strings.Builder
|
||||
for i := 0; i < len(decodeStr); i += 2 {
|
||||
resultStr.WriteString("\\x")
|
||||
resultStr.WriteString(decodeStr[i : i+2])
|
||||
}
|
||||
return resultStr.String(), true
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type JsonConvert struct{}
|
||||
|
||||
func (JsonConvert) Decode(str string) (string, bool) {
|
||||
trimedStr := strings.TrimSpace(str)
|
||||
if (strings.HasPrefix(trimedStr, "{") && strings.HasSuffix(trimedStr, "}")) ||
|
||||
(strings.HasPrefix(trimedStr, "[") && strings.HasSuffix(trimedStr, "]")) {
|
||||
var out bytes.Buffer
|
||||
if err := json.Indent(&out, []byte(trimedStr), "", " "); err == nil {
|
||||
return out.String(), true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func (JsonConvert) Encode(str string) (string, bool) {
|
||||
var dst bytes.Buffer
|
||||
if err := json.Compact(&dst, []byte(str)); err != nil {
|
||||
return str, false
|
||||
}
|
||||
return dst.String(), true
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
)
|
||||
|
||||
type MsgpackConvert struct{}
|
||||
|
||||
func (MsgpackConvert) Encode(str string) (string, bool) {
|
||||
var obj map[string]any
|
||||
if err := json.Unmarshal([]byte(str), &obj); err == nil {
|
||||
if b, err := msgpack.Marshal(obj); err == nil {
|
||||
return string(b), true
|
||||
}
|
||||
}
|
||||
|
||||
if b, err := msgpack.Marshal(str); err != nil {
|
||||
return string(b), true
|
||||
}
|
||||
|
||||
return str, false
|
||||
}
|
||||
|
||||
func (MsgpackConvert) Decode(str string) (string, bool) {
|
||||
var decodedStr string
|
||||
if err := msgpack.Unmarshal([]byte(str), &decodedStr); err == nil {
|
||||
return decodedStr, true
|
||||
}
|
||||
|
||||
var obj map[string]any
|
||||
if err := msgpack.Unmarshal([]byte(str), &obj); err == nil {
|
||||
if b, err := json.Marshal(obj); err == nil {
|
||||
return string(b), true
|
||||
}
|
||||
}
|
||||
|
||||
return str, false
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type XmlConvert struct{}
|
||||
|
||||
func (XmlConvert) Encode(str string) (string, bool) {
|
||||
return str, true
|
||||
}
|
||||
|
||||
func (XmlConvert) Decode(str string) (string, bool) {
|
||||
trimedStr := strings.TrimSpace(str)
|
||||
if !strings.HasPrefix(trimedStr, "<") && !strings.HasSuffix(trimedStr, ">") {
|
||||
return str, false
|
||||
}
|
||||
var obj any
|
||||
err := xml.Unmarshal([]byte(trimedStr), &obj)
|
||||
return str, err == nil
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
"log"
|
||||
)
|
||||
|
||||
type YamlConvert struct{}
|
||||
|
||||
func (YamlConvert) Encode(str string) (string, bool) {
|
||||
return str, true
|
||||
}
|
||||
|
||||
func (YamlConvert) Decode(str string) (string, bool) {
|
||||
var obj map[string]any
|
||||
err := yaml.Unmarshal([]byte(str), &obj)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
} else {
|
||||
log.Println(obj)
|
||||
}
|
||||
return str, err == nil
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package convutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ZStdConvert struct{}
|
||||
|
||||
func (ZStdConvert) Encode(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer, err := zstd.NewWriter(&buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err = writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
if zstdStr, err := compress([]byte(str)); err == nil {
|
||||
return zstdStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func (ZStdConvert) Decode(str string) (string, bool) {
|
||||
if reader, err := zstd.NewReader(strings.NewReader(str)); err == nil {
|
||||
defer reader.Close()
|
||||
if decompressed, err := io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
|
@ -4,7 +4,7 @@ import (
|
|||
"unicode"
|
||||
)
|
||||
|
||||
func containsBinary(str string) bool {
|
||||
func ContainsBinary(str string) bool {
|
||||
//buf := []byte(str)
|
||||
//size := 0
|
||||
//for start := 0; start < len(buf); start += size {
|
||||
|
@ -25,7 +25,7 @@ func containsBinary(str string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func isSameChar(str string) bool {
|
||||
func IsSameChar(str string) bool {
|
||||
if len(str) <= 0 {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,505 +0,0 @@
|
|||
package strutil
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/andybalholm/brotli"
|
||||
"github.com/klauspost/compress/flate"
|
||||
"github.com/klauspost/compress/gzip"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"github.com/vmihailenco/msgpack/v5"
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"tinyrdm/backend/types"
|
||||
)
|
||||
|
||||
// ConvertTo convert string to specified type
|
||||
// @param decodeType empty string indicates automatic detection
|
||||
// @param formatType empty string indicates automatic detection
|
||||
func ConvertTo(str, decodeType, formatType string) (value, resultDecode, resultFormat string) {
|
||||
if len(str) <= 0 {
|
||||
// empty content
|
||||
if len(formatType) <= 0 {
|
||||
resultFormat = types.FORMAT_RAW
|
||||
} else {
|
||||
resultFormat = formatType
|
||||
}
|
||||
if len(decodeType) <= 0 {
|
||||
resultDecode = types.DECODE_NONE
|
||||
} else {
|
||||
resultDecode = decodeType
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// decode first
|
||||
value, resultDecode = decodeWith(str, decodeType)
|
||||
// then format content
|
||||
value, resultFormat = viewAs(value, formatType)
|
||||
return
|
||||
}
|
||||
|
||||
func decodeWith(str, decodeType string) (value, resultDecode string) {
|
||||
if len(decodeType) > 0 {
|
||||
switch decodeType {
|
||||
case types.DECODE_NONE:
|
||||
value = str
|
||||
resultDecode = decodeType
|
||||
return
|
||||
|
||||
case types.DECODE_BASE64:
|
||||
if base64Str, ok := decodeBase64(str); ok {
|
||||
value = base64Str
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultDecode = decodeType
|
||||
return
|
||||
|
||||
case types.DECODE_GZIP:
|
||||
if gzipStr, ok := decodeGZip(str); ok {
|
||||
value = gzipStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultDecode = decodeType
|
||||
return
|
||||
|
||||
case types.DECODE_DEFLATE:
|
||||
if falteStr, ok := decodeDeflate(str); ok {
|
||||
value = falteStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultDecode = decodeType
|
||||
return
|
||||
|
||||
case types.DECODE_ZSTD:
|
||||
if zstdStr, ok := decodeZStd(str); ok {
|
||||
value = zstdStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultDecode = decodeType
|
||||
return
|
||||
|
||||
case types.DECODE_BROTLI:
|
||||
if brotliStr, ok := decodeBrotli(str); ok {
|
||||
value = brotliStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultDecode = decodeType
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return autoDecode(str)
|
||||
}
|
||||
|
||||
// attempt try possible decode method
|
||||
// if no decode is possible, it will return the origin string value and "none" decode type
|
||||
func autoDecode(str string) (value, resultDecode string) {
|
||||
if len(str) > 0 {
|
||||
// pure digit content may incorrect regard as some encoded type, skip decode
|
||||
if match, _ := regexp.MatchString(`^\d+$`, str); !match {
|
||||
var ok bool
|
||||
if len(str)%4 == 0 && len(str) >= 12 && !isSameChar(str) {
|
||||
if value, ok = decodeBase64(str); ok {
|
||||
resultDecode = types.DECODE_BASE64
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if value, ok = decodeGZip(str); ok {
|
||||
resultDecode = types.DECODE_GZIP
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: skip decompress with deflate due to incorrect format checking
|
||||
//if value, ok = decodeDeflate(str); ok {
|
||||
// resultDecode = types.DECODE_DEFLATE
|
||||
// return
|
||||
//}
|
||||
|
||||
if value, ok = decodeZStd(str); ok {
|
||||
resultDecode = types.DECODE_ZSTD
|
||||
return
|
||||
}
|
||||
|
||||
// FIXME: skip decompress with brotli due to incorrect format checking
|
||||
//if value, ok = decodeBrotli(str); ok {
|
||||
// resultDecode = types.DECODE_BROTLI
|
||||
// return
|
||||
//}
|
||||
|
||||
if value, ok = decodeMsgpack(str); ok {
|
||||
resultDecode = types.DECODE_MSGPACK
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = str
|
||||
resultDecode = types.DECODE_NONE
|
||||
return
|
||||
}
|
||||
|
||||
func viewAs(str, formatType string) (value, resultFormat string) {
|
||||
if len(formatType) > 0 {
|
||||
switch formatType {
|
||||
case types.FORMAT_RAW, types.FORMAT_YAML, types.FORMAT_XML:
|
||||
value = str
|
||||
resultFormat = formatType
|
||||
return
|
||||
|
||||
case types.FORMAT_JSON:
|
||||
if jsonStr, ok := decodeJson(str); ok {
|
||||
value = jsonStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultFormat = formatType
|
||||
return
|
||||
|
||||
case types.FORMAT_HEX:
|
||||
if hexStr, ok := decodeToHex(str); ok {
|
||||
value = hexStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultFormat = formatType
|
||||
return
|
||||
|
||||
case types.FORMAT_BINARY:
|
||||
if binStr, ok := decodeBinary(str); ok {
|
||||
value = binStr
|
||||
} else {
|
||||
value = str
|
||||
}
|
||||
resultFormat = formatType
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return autoViewAs(str)
|
||||
}
|
||||
|
||||
// attempt automatic convert to possible types
|
||||
// if no conversion is possible, it will return the origin string value and "plain text" type
|
||||
func autoViewAs(str string) (value, resultFormat string) {
|
||||
if len(str) > 0 {
|
||||
var ok bool
|
||||
if value, ok = decodeJson(str); ok {
|
||||
resultFormat = types.FORMAT_JSON
|
||||
return
|
||||
}
|
||||
|
||||
if containsBinary(str) {
|
||||
if value, ok = decodeToHex(str); ok {
|
||||
resultFormat = types.FORMAT_HEX
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
value = str
|
||||
resultFormat = types.FORMAT_RAW
|
||||
return
|
||||
}
|
||||
|
||||
func decodeJson(str string) (string, bool) {
|
||||
trimedStr := strings.TrimSpace(str)
|
||||
if (strings.HasPrefix(trimedStr, "{") && strings.HasSuffix(trimedStr, "}")) ||
|
||||
(strings.HasPrefix(trimedStr, "[") && strings.HasSuffix(trimedStr, "]")) {
|
||||
var out bytes.Buffer
|
||||
if err := json.Indent(&out, []byte(trimedStr), "", " "); err == nil {
|
||||
return out.String(), true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func decodeBase64(str string) (string, bool) {
|
||||
if decodedStr, err := base64.StdEncoding.DecodeString(str); err == nil {
|
||||
if s := string(decodedStr); !containsBinary(s) {
|
||||
return s, true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func decodeBinary(str string) (string, bool) {
|
||||
var binary strings.Builder
|
||||
for _, char := range str {
|
||||
binary.WriteString(fmt.Sprintf("%08b", int(char)))
|
||||
}
|
||||
return binary.String(), true
|
||||
}
|
||||
|
||||
func decodeToHex(str string) (string, bool) {
|
||||
decodeStr := hex.EncodeToString([]byte(str))
|
||||
var resultStr strings.Builder
|
||||
for i := 0; i < len(decodeStr); i += 2 {
|
||||
resultStr.WriteString("\\x")
|
||||
resultStr.WriteString(strings.ToUpper(decodeStr[i : i+2]))
|
||||
}
|
||||
return resultStr.String(), true
|
||||
}
|
||||
|
||||
func decodeGZip(str string) (string, bool) {
|
||||
if reader, err := gzip.NewReader(strings.NewReader(str)); err == nil {
|
||||
defer reader.Close()
|
||||
var decompressed []byte
|
||||
if decompressed, err = io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func decodeDeflate(str string) (string, bool) {
|
||||
reader := flate.NewReader(strings.NewReader(str))
|
||||
defer reader.Close()
|
||||
if decompressed, err := io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func decodeZStd(str string) (string, bool) {
|
||||
if reader, err := zstd.NewReader(strings.NewReader(str)); err == nil {
|
||||
defer reader.Close()
|
||||
if decompressed, err := io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func decodeBrotli(str string) (string, bool) {
|
||||
reader := brotli.NewReader(strings.NewReader(str))
|
||||
if decompressed, err := io.ReadAll(reader); err == nil {
|
||||
return string(decompressed), true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func decodeMsgpack(str string) (string, bool) {
|
||||
var decodedStr string
|
||||
if err := msgpack.Unmarshal([]byte(str), &decodedStr); err == nil {
|
||||
return decodedStr, true
|
||||
}
|
||||
|
||||
var decodedObj map[string]any
|
||||
if err := msgpack.Unmarshal([]byte(str), &decodedObj); err == nil {
|
||||
if b, err := json.Marshal(decodedObj); err == nil {
|
||||
return string(b), true
|
||||
}
|
||||
}
|
||||
|
||||
return str, false
|
||||
}
|
||||
|
||||
func SaveAs(str, format, decode string) (value string, err error) {
|
||||
value = str
|
||||
switch format {
|
||||
case types.FORMAT_JSON:
|
||||
if jsonStr, ok := encodeJson(str); ok {
|
||||
value = jsonStr
|
||||
} else {
|
||||
err = errors.New("invalid json data")
|
||||
return
|
||||
}
|
||||
|
||||
case types.FORMAT_HEX:
|
||||
if hexStr, ok := encodeHex(str); ok {
|
||||
value = hexStr
|
||||
} else {
|
||||
err = errors.New("invalid hex data")
|
||||
return
|
||||
}
|
||||
|
||||
case types.FORMAT_BINARY:
|
||||
if binStr, ok := encodeBinary(str); ok {
|
||||
value = binStr
|
||||
} else {
|
||||
err = errors.New("invalid binary data")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
switch decode {
|
||||
case types.DECODE_NONE:
|
||||
return
|
||||
|
||||
case types.DECODE_BASE64:
|
||||
value, _ = encodeBase64(value)
|
||||
return
|
||||
|
||||
case types.DECODE_GZIP:
|
||||
if gzipStr, ok := encodeGZip(str); ok {
|
||||
value = gzipStr
|
||||
} else {
|
||||
err = errors.New("fail to build gzip")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_DEFLATE:
|
||||
if deflateStr, ok := encodeDeflate(str); ok {
|
||||
value = deflateStr
|
||||
} else {
|
||||
err = errors.New("fail to build deflate")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_ZSTD:
|
||||
if zstdStr, ok := encodeZStd(str); ok {
|
||||
value = zstdStr
|
||||
} else {
|
||||
err = errors.New("fail to build zstd")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_BROTLI:
|
||||
if brotliStr, ok := encodeBrotli(str); ok {
|
||||
value = brotliStr
|
||||
} else {
|
||||
err = errors.New("fail to build brotli")
|
||||
}
|
||||
return
|
||||
|
||||
case types.DECODE_MSGPACK:
|
||||
if msgpackStr, ok := encodeMsgpack(str); ok {
|
||||
value = msgpackStr
|
||||
} else {
|
||||
err = errors.New("fail to build msgpack")
|
||||
}
|
||||
return
|
||||
}
|
||||
return str, nil
|
||||
}
|
||||
|
||||
func encodeJson(str string) (string, bool) {
|
||||
var dst bytes.Buffer
|
||||
if err := json.Compact(&dst, []byte(str)); err != nil {
|
||||
return str, false
|
||||
}
|
||||
return dst.String(), true
|
||||
}
|
||||
|
||||
func encodeBase64(str string) (string, bool) {
|
||||
return base64.StdEncoding.EncodeToString([]byte(str)), true
|
||||
}
|
||||
|
||||
func encodeBinary(str string) (string, bool) {
|
||||
var result strings.Builder
|
||||
total := len(str)
|
||||
for i := 0; i < total; i += 8 {
|
||||
b, _ := strconv.ParseInt(str[i:i+8], 2, 8)
|
||||
result.WriteByte(byte(b))
|
||||
}
|
||||
return result.String(), true
|
||||
}
|
||||
|
||||
func encodeHex(str string) (string, bool) {
|
||||
hexStrArr := strings.Split(str, "\\x")
|
||||
hexStr := strings.Join(hexStrArr, "")
|
||||
if decodeStr, err := hex.DecodeString(hexStr); err == nil {
|
||||
return string(decodeStr), true
|
||||
}
|
||||
|
||||
return str, false
|
||||
}
|
||||
|
||||
func encodeGZip(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer := gzip.NewWriter(&buf)
|
||||
if _, err := writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
|
||||
if gzipStr, err := compress([]byte(str)); err == nil {
|
||||
return gzipStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func encodeDeflate(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer, err := flate.NewWriter(&buf, flate.DefaultCompression)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err = writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
if deflateStr, err := compress([]byte(str)); err == nil {
|
||||
return deflateStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func encodeZStd(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer, err := zstd.NewWriter(&buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err = writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
if zstdStr, err := compress([]byte(str)); err == nil {
|
||||
return zstdStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func encodeBrotli(str string) (string, bool) {
|
||||
var compress = func(b []byte) (string, error) {
|
||||
var buf bytes.Buffer
|
||||
writer := brotli.NewWriter(&buf)
|
||||
if _, err := writer.Write([]byte(str)); err != nil {
|
||||
writer.Close()
|
||||
return "", err
|
||||
}
|
||||
writer.Close()
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
if brotliStr, err := compress([]byte(str)); err == nil {
|
||||
return brotliStr, true
|
||||
}
|
||||
return str, false
|
||||
}
|
||||
|
||||
func encodeMsgpack(str string) (string, bool) {
|
||||
var err error
|
||||
var buf bytes.Buffer
|
||||
enc := msgpack.NewEncoder(&buf)
|
||||
if err = enc.EncodeString(str); err == nil {
|
||||
return buf.String(), true
|
||||
}
|
||||
|
||||
return str, false
|
||||
}
|
|
@ -8,7 +8,7 @@ import (
|
|||
// EncodeRedisKey encode the redis key to integer array
|
||||
// if key contains binary which could not display on ui, convert the key to char array
|
||||
func EncodeRedisKey(key string) any {
|
||||
if containsBinary(key) {
|
||||
if ContainsBinary(key) {
|
||||
b := []byte(key)
|
||||
arr := make([]int, len(b))
|
||||
for i, bb := range b {
|
||||
|
|
|
@ -498,6 +498,7 @@ const pasteFromClipboard = async () => {
|
|||
</n-form>
|
||||
</n-tab-pane>
|
||||
|
||||
<!-- Alias pane -->
|
||||
<n-tab-pane :tab="$t('dialogue.connection.alias.title')" display-directive="show:lazy" name="alias">
|
||||
<n-form
|
||||
:model="generalForm.alias"
|
||||
|
|
|
@ -108,6 +108,7 @@ const onClose = () => {
|
|||
<n-select
|
||||
v-model:value="prefStore.general.fontFamily"
|
||||
:options="prefStore.fontOption"
|
||||
:placeholder="$t('preferences.general.font_tip')"
|
||||
:render-label="({ label, value }) => (value === '' ? $t(label) : label)"
|
||||
filterable
|
||||
multiple
|
||||
|
@ -166,6 +167,7 @@ const onClose = () => {
|
|||
<n-select
|
||||
v-model:value="prefStore.editor.fontFamily"
|
||||
:options="prefStore.fontOption"
|
||||
:placeholder="$t('preferences.general.font_tip')"
|
||||
:render-label="({ label, value }) => value || $t(label)"
|
||||
filterable
|
||||
multiple
|
||||
|
@ -206,6 +208,7 @@ const onClose = () => {
|
|||
<n-select
|
||||
v-model:value="prefStore.cli.fontFamily"
|
||||
:options="prefStore.fontOption"
|
||||
:placeholder="$t('preferences.general.font_tip')"
|
||||
:render-label="({ label, value }) => value || $t(label)"
|
||||
filterable
|
||||
multiple
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"language": "Language",
|
||||
"system_lang": "Use System Language",
|
||||
"font": "Font",
|
||||
"font_tip": "Please Select or Input Font Name",
|
||||
"font_size": "Font Size",
|
||||
"scan_size": "Default Size for SCAN Command",
|
||||
"key_icon_style": "Key Icon Style",
|
||||
|
@ -139,6 +140,7 @@
|
|||
"action": "Action",
|
||||
"type": "Type",
|
||||
"cli_welcome": "Welcome to Tiny RDM Redis Console",
|
||||
"retrieving_version": "Retrieving for new version",
|
||||
"sub_tab": {
|
||||
"status": "Status",
|
||||
"key_detail": "Key Detail",
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
"language": "语言",
|
||||
"system_lang": "使用系统语言",
|
||||
"font": "字体",
|
||||
"font_tip": "请选择或手动输入字体名",
|
||||
"font_size": "字体尺寸",
|
||||
"scan_size": "SCAN命令默认数量",
|
||||
"key_icon_style": "键图标样式",
|
||||
|
@ -139,6 +140,7 @@
|
|||
"action": "操作",
|
||||
"type": "类型",
|
||||
"cli_welcome": "欢迎使用Tiny RDM的Redis命令行控制台",
|
||||
"retrieving_version": "正在检索新版本",
|
||||
"sub_tab": {
|
||||
"status": "状态",
|
||||
"key_detail": "键详情",
|
||||
|
@ -153,7 +155,7 @@
|
|||
"browser": "数据浏览",
|
||||
"log": "日志",
|
||||
"wechat_official": "微信公众号",
|
||||
"follow_x": "关注的我\uD835\uDD4F",
|
||||
"follow_x": "关注我的\uD835\uDD4F",
|
||||
"github": "Github"
|
||||
},
|
||||
"dialogue": {
|
||||
|
|
|
@ -338,7 +338,7 @@ const usePreferencesStore = defineStore('preferences', {
|
|||
async checkForUpdate(manual = false) {
|
||||
let msgRef = null
|
||||
if (manual) {
|
||||
msgRef = $message.loading('Retrieving for new version', { duration: 0 })
|
||||
msgRef = $message.loading(i18nGlobal.t('interface.retrieving_version'), { duration: 0 })
|
||||
}
|
||||
try {
|
||||
const { success, data = {} } = await CheckForUpdate()
|
||||
|
|
Loading…
Reference in New Issue