package httphead
import (
"bytes"
"sort"
)
type Option struct {
Name []byte
Parameters Parameters
}
func (opt Option ) Size () int {
return len (opt .Name ) + opt .Parameters .bytes
}
func (opt Option ) Copy (p []byte ) Option {
n := copy (p , opt .Name )
opt .Name = p [:n ]
opt .Parameters , p = opt .Parameters .Copy (p [n :])
return opt
}
func (opt Option ) Clone () Option {
return opt .Copy (make ([]byte , opt .Size ()))
}
func (opt Option ) String () string {
return "{" + string (opt .Name ) + " " + opt .Parameters .String () + "}"
}
func NewOption (name string , params map [string ]string ) Option {
p := Parameters {}
for k , v := range params {
p .Set ([]byte (k ), []byte (v ))
}
return Option {
Name : []byte (name ),
Parameters : p ,
}
}
func (opt Option ) Equal (b Option ) bool {
if bytes .Equal (opt .Name , b .Name ) {
return opt .Parameters .Equal (b .Parameters )
}
return false
}
type Parameters struct {
pos int
bytes int
arr [8 ]pair
dyn []pair
}
func (p Parameters ) Equal (b Parameters ) bool {
switch {
case p .dyn == nil && b .dyn == nil :
case p .dyn != nil && b .dyn != nil :
default :
return false
}
ad , bd := p .data (), b .data ()
if len (ad ) != len (bd ) {
return false
}
sort .Sort (pairs (ad ))
sort .Sort (pairs (bd ))
for i := 0 ; i < len (ad ); i ++ {
av , bv := ad [i ], bd [i ]
if !bytes .Equal (av .key , bv .key ) || !bytes .Equal (av .value , bv .value ) {
return false
}
}
return true
}
func (p *Parameters ) Size () int {
return p .bytes
}
func (p *Parameters ) Copy (dst []byte ) (Parameters , []byte ) {
ret := Parameters {
pos : p .pos ,
bytes : p .bytes ,
}
if p .dyn != nil {
ret .dyn = make ([]pair , len (p .dyn ))
for i , v := range p .dyn {
ret .dyn [i ], dst = v .copy (dst )
}
} else {
for i , p := range p .arr {
ret .arr [i ], dst = p .copy (dst )
}
}
return ret , dst
}
func (p *Parameters ) Get (key string ) (value []byte , ok bool ) {
for _ , v := range p .data () {
if string (v .key ) == key {
return v .value , true
}
}
return nil , false
}
func (p *Parameters ) Set (key , value []byte ) {
p .bytes += len (key ) + len (value )
if p .pos < len (p .arr ) {
p .arr [p .pos ] = pair {key , value }
p .pos ++
return
}
if p .dyn == nil {
p .dyn = make ([]pair , len (p .arr ), len (p .arr )+1 )
copy (p .dyn , p .arr [:])
}
p .dyn = append (p .dyn , pair {key , value })
}
func (p *Parameters ) ForEach (cb func (k , v []byte ) bool ) {
for _ , v := range p .data () {
if !cb (v .key , v .value ) {
break
}
}
}
func (p *Parameters ) String () (ret string ) {
ret = "["
for i , v := range p .data () {
if i > 0 {
ret += " "
}
ret += string (v .key ) + ":" + string (v .value )
}
return ret + "]"
}
func (p *Parameters ) data () []pair {
if p .dyn != nil {
return p .dyn
}
return p .arr [:p .pos ]
}
type pair struct {
key, value []byte
}
func (p pair ) copy (dst []byte ) (pair , []byte ) {
n := copy (dst , p .key )
p .key = dst [:n ]
m := n + copy (dst [n :], p .value )
p .value = dst [n :m ]
dst = dst [m :]
return p , dst
}
type pairs []pair
func (p pairs ) Len () int { return len (p ) }
func (p pairs ) Less (a , b int ) bool { return bytes .Compare (p [a ].key , p [b ].key ) == -1 }
func (p pairs ) Swap (a , b int ) { p [a ], p [b ] = p [b ], p [a ] }
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .