| | |
| | |
| | |
| |
|
| | package stringtab |
| |
|
| | import ( |
| | "fmt" |
| | "internal/coverage/slicereader" |
| | "internal/coverage/uleb128" |
| | "io" |
| | ) |
| |
|
| | |
| | |
| | |
| |
|
| | |
| | type Writer struct { |
| | stab map[string]uint32 |
| | strs []string |
| | tmp []byte |
| | frozen bool |
| | } |
| |
|
| | |
| | func (stw *Writer) InitWriter() { |
| | stw.stab = make(map[string]uint32) |
| | stw.tmp = make([]byte, 64) |
| | } |
| |
|
| | |
| | func (stw *Writer) Nentries() uint32 { |
| | return uint32(len(stw.strs)) |
| | } |
| |
|
| | |
| | |
| | func (stw *Writer) Lookup(s string) uint32 { |
| | if idx, ok := stw.stab[s]; ok { |
| | return idx |
| | } |
| | if stw.frozen { |
| | panic("internal error: string table previously frozen") |
| | } |
| | idx := uint32(len(stw.strs)) |
| | stw.stab[s] = idx |
| | stw.strs = append(stw.strs, s) |
| | return idx |
| | } |
| |
|
| | |
| | |
| | func (stw *Writer) Size() uint32 { |
| | rval := uint32(0) |
| | stw.tmp = stw.tmp[:0] |
| | stw.tmp = uleb128.AppendUleb128(stw.tmp, uint(len(stw.strs))) |
| | rval += uint32(len(stw.tmp)) |
| | for _, s := range stw.strs { |
| | stw.tmp = stw.tmp[:0] |
| | slen := uint(len(s)) |
| | stw.tmp = uleb128.AppendUleb128(stw.tmp, slen) |
| | rval += uint32(len(stw.tmp)) + uint32(slen) |
| | } |
| | return rval |
| | } |
| |
|
| | |
| | |
| | func (stw *Writer) Write(w io.Writer) error { |
| | wr128 := func(v uint) error { |
| | stw.tmp = stw.tmp[:0] |
| | stw.tmp = uleb128.AppendUleb128(stw.tmp, v) |
| | if nw, err := w.Write(stw.tmp); err != nil { |
| | return fmt.Errorf("writing string table: %v", err) |
| | } else if nw != len(stw.tmp) { |
| | return fmt.Errorf("short write emitting stringtab uleb") |
| | } |
| | return nil |
| | } |
| | if err := wr128(uint(len(stw.strs))); err != nil { |
| | return err |
| | } |
| | for _, s := range stw.strs { |
| | if err := wr128(uint(len(s))); err != nil { |
| | return err |
| | } |
| | if nw, err := w.Write([]byte(s)); err != nil { |
| | return fmt.Errorf("writing string table: %v", err) |
| | } else if nw != len([]byte(s)) { |
| | return fmt.Errorf("short write emitting stringtab") |
| | } |
| | } |
| | return nil |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | func (stw *Writer) Freeze() { |
| | stw.frozen = true |
| | } |
| |
|
| | |
| | |
| | type Reader struct { |
| | r *slicereader.Reader |
| | strs []string |
| | } |
| |
|
| | |
| | |
| | func NewReader(r *slicereader.Reader) *Reader { |
| | str := &Reader{ |
| | r: r, |
| | } |
| | return str |
| | } |
| |
|
| | |
| | func (str *Reader) Read() { |
| | numEntries := int(str.r.ReadULEB128()) |
| | str.strs = make([]string, 0, numEntries) |
| | for idx := 0; idx < numEntries; idx++ { |
| | slen := str.r.ReadULEB128() |
| | str.strs = append(str.strs, str.r.ReadString(int64(slen))) |
| | } |
| | } |
| |
|
| | |
| | func (str *Reader) Entries() int { |
| | return len(str.strs) |
| | } |
| |
|
| | |
| | func (str *Reader) Get(idx uint32) string { |
| | return str.strs[idx] |
| | } |
| |
|