Skip to content

Instantly share code, notes, and snippets.

@VillanCh
Created March 11, 2022 10:04
Show Gist options
  • Save VillanCh/e8d0ceae717d022b230b4581f5cc2f7f to your computer and use it in GitHub Desktop.
Save VillanCh/e8d0ceae717d022b230b4581f5cc2f7f to your computer and use it in GitHub Desktop.
解析C风格的字符串 Quote
func UnquoteCStyleString(raw string) (string, error) {
state := ""
results := ""
hexBuffer := ""
scanner := bufio.NewScanner(bytes.NewBufferString(raw))
scanner.Split(bufio.ScanBytes)
index := 0
for scanner.Scan() {
index++
//log.Infof("index: %d", index)
b := scanner.Bytes()[0]
if b == '\\' && state != "charStart" {
state = "charStart"
continue
}
switch state {
case "hex":
if len(hexBuffer) < 2 {
//log.Infof("hex: %s", string(b))
hexBuffer += string(b)
}
if len(hexBuffer) == 2 {
_ret, err := hex.DecodeString(hexBuffer)
if err != nil {
return "", errors.Errorf("parse hex buffer[\\x%s] failed: %s", hexBuffer, err)
}
if len(_ret) != 1 {
return "", errors.Errorf("BUG: \\x%s to %#v", hexBuffer, _ret)
}
results += string(_ret)
state = ""
hexBuffer = ""
} else if len(hexBuffer) > 2 {
return "", errors.Errorf("parse hex failed: \\x%s", hexBuffer)
} else {
state = "hex"
}
case "charStart":
switch b {
case '0':
results += "\x00"
break
case 'a':
results += "\a"
break
case 'b':
results += "\n"
break
case 'f':
results += "\f"
break
case 'n':
results += "\n"
break
case 'r':
results += "\r"
break
case 't':
results += "\t"
break
case 'v':
results += "\v"
break
case 'x':
state = "hex"
continue
}
state = ""
continue
default:
results += string(b)
continue
}
}
return results, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment