Skip to content

Commit

Permalink
Merge pull request #106 from named-data/name-str
Browse files Browse the repository at this point in the history
std: use string builder for Name::String()
  • Loading branch information
zjkmxy authored Jan 14, 2025
2 parents 05d134b + a85153b commit d1c6b28
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 29 deletions.
70 changes: 49 additions & 21 deletions std/encoding/name_component.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,19 @@ const (
DigestShaNameConvention = "sha256digest"
)

var (
HEX_LOWER = []rune("0123456789abcdef")
HEX_UPPER = []rune("0123456789ABCDEF")
)

var hashPool = sync.Pool{
New: func() interface{} {
return xxhash.New()
},
}

type compValFmt interface {
ToString(val []byte) string
WriteTo(val []byte, sb *strings.Builder) int
FromString(s string) ([]byte, error)
ToMatching(val []byte) any
FromMatching(m any) ([]byte, error)
Expand All @@ -50,8 +55,8 @@ type compValFmtText struct{}
type compValFmtDec struct{}
type compValFmtHex struct{}

func (compValFmtInvalid) ToString(val []byte) string {
return ""
func (compValFmtInvalid) WriteTo(val []byte, sb *strings.Builder) int {
return 0
}

func (compValFmtInvalid) FromString(s string) ([]byte, error) {
Expand All @@ -66,16 +71,20 @@ func (compValFmtInvalid) FromMatching(m any) ([]byte, error) {
return nil, ErrFormat{"Invalid component format"}
}

func (compValFmtText) ToString(val []byte) string {
vText := ""
func (compValFmtText) WriteTo(val []byte, sb *strings.Builder) int {
size := 0
for _, b := range val {
if isLegalCompText(b) {
vText = vText + string(b)
sb.WriteByte(b)
size += 1
} else {
vText = vText + fmt.Sprintf("%%%02X", b)
sb.WriteRune('%')
sb.WriteRune(HEX_UPPER[b>>4])
sb.WriteRune(HEX_UPPER[b&0x0F])
size += 3
}
}
return vText
return size
}

func (compValFmtText) FromString(valStr string) ([]byte, error) {
Expand Down Expand Up @@ -128,12 +137,14 @@ func (compValFmtText) FromMatching(m any) ([]byte, error) {
}
}

func (compValFmtDec) ToString(val []byte) string {
func (compValFmtDec) WriteTo(val []byte, sb *strings.Builder) int {
x := uint64(0)
for _, b := range val {
x = (x << 8) | uint64(b)
}
return strconv.FormatUint(x, 10)
vstr := strconv.FormatUint(x, 10)
sb.WriteString(vstr)
return len(vstr)
}

func (compValFmtDec) FromString(s string) ([]byte, error) {
Expand Down Expand Up @@ -164,12 +175,12 @@ func (compValFmtDec) FromMatching(m any) ([]byte, error) {
return ret, nil
}

func (compValFmtHex) ToString(val []byte) string {
vText := ""
func (compValFmtHex) WriteTo(val []byte, sb *strings.Builder) int {
for _, b := range val {
vText = vText + fmt.Sprintf("%02x", b)
sb.WriteRune(HEX_LOWER[b>>4])
sb.WriteRune(HEX_LOWER[b&0x0F])
}
return vText
return len(val) * 2
}

func (compValFmtHex) FromString(s string) ([]byte, error) {
Expand Down Expand Up @@ -342,23 +353,40 @@ func isLegalCompText(b byte) bool {
}

func (c Component) String() string {
sb := strings.Builder{}
c.WriteTo(&sb)
return sb.String()
}

func (c Component) WriteTo(sb *strings.Builder) int {
size := 0

vFmt := compValFmt(compValFmtText{})
tName := ""
if conv, ok := compConvByType[c.Typ]; ok {
vFmt = conv.vFmt
tName = conv.name + "="
typ := conv.name
sb.WriteString(typ)
sb.WriteRune('=')
size += len(typ) + 1
} else if c.Typ != TypeGenericNameComponent {
tName = strconv.FormatUint(uint64(c.Typ), 10) + "="
typ := strconv.FormatUint(uint64(c.Typ), 10)
sb.WriteString(typ)
sb.WriteRune('=')
size += len(typ) + 1
}
return tName + vFmt.ToString(c.Val)

size += vFmt.WriteTo(c.Val, sb)
return size
}

func (c Component) CanonicalString() string {
tName := ""
sb := strings.Builder{}
if c.Typ != TypeGenericNameComponent {
tName = strconv.FormatUint(uint64(c.Typ), 10) + "="
sb.WriteString(strconv.FormatUint(uint64(c.Typ), 10))
sb.WriteRune('=')
}
return tName + compValFmtText{}.ToString(c.Val)
compValFmtText{}.WriteTo(c.Val, &sb)
return sb.String()
}

func (c Component) Append(rest ...Component) Name {
Expand Down
18 changes: 10 additions & 8 deletions std/encoding/name_pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ type NamePattern []ComponentPattern
const TypeName TLNum = 0x07

func (n Name) String() string {
ret := ""
for _, c := range n {
ret += "/" + c.String()
sb := strings.Builder{}
for i, c := range n {
sb.WriteRune('/')
sz := c.WriteTo(&sb)
if i == len(n)-1 && sz == 0 {
sb.WriteRune('/')
}
}
if len(ret) == 0 {
ret = "/"
} else if n[len(n)-1].Typ == TypeGenericNameComponent && len(n[len(n)-1].Val) == 0 {
ret += "/"
if sb.Len() == 0 {
return "/"
}
return ret
return sb.String()
}

func (n NamePattern) String() string {
Expand Down

0 comments on commit d1c6b28

Please sign in to comment.