package pkgbits
import (
)
const currentVersion uint32 = 1
type PkgEncoder struct {
elems [numRelocs][]string
stringsIdx map[string]Index
syncFrames int
}
func ( *PkgEncoder) () bool { return .syncFrames >= 0 }
func ( int) PkgEncoder {
return PkgEncoder{
stringsIdx: make(map[string]Index),
syncFrames: ,
}
}
func ( *PkgEncoder) ( io.Writer) ( [8]byte) {
:= md5.New()
:= io.MultiWriter(, )
:= func( uint32) {
assert(binary.Write(, binary.LittleEndian, ) == nil)
}
(currentVersion)
var uint32
if .SyncMarkers() {
|= flagSyncMarkers
}
()
var uint32
for , := range &.elems {
+= uint32(len())
()
}
= 0
for , := range &.elems {
for , := range {
+= uint32(len())
()
}
}
for , := range &.elems {
for , := range {
, := io.WriteString(, )
assert( == nil)
}
}
copy([:], .Sum(nil))
, := .Write([:])
assert( == nil)
return
}
func ( *PkgEncoder) ( string) Index {
if , := .stringsIdx[]; {
assert(.elems[RelocString][] == )
return
}
:= Index(len(.elems[RelocString]))
.elems[RelocString] = append(.elems[RelocString], )
.stringsIdx[] =
return
}
func ( *PkgEncoder) ( RelocKind, SyncMarker) Encoder {
:= .NewEncoderRaw()
.Sync()
return
}
func ( *PkgEncoder) ( RelocKind) Encoder {
:= Index(len(.elems[]))
.elems[] = append(.elems[], "")
return Encoder{
p: ,
k: ,
Idx: ,
}
}
type Encoder struct {
p *PkgEncoder
Relocs []RelocEnt
RelocMap map[RelocEnt]uint32
Data bytes.Buffer
encodingRelocHeader bool
k RelocKind
Idx Index
}
func ( *Encoder) () Index {
var bytes.Buffer
var bytes.Buffer
io.Copy(&, &.Data)
if .encodingRelocHeader {
panic("encodingRelocHeader already true; recursive flush?")
}
.encodingRelocHeader = true
.Sync(SyncRelocs)
.Len(len(.Relocs))
for , := range .Relocs {
.Sync(SyncReloc)
.Len(int(.Kind))
.Len(int(.Idx))
}
io.Copy(&, &.Data)
io.Copy(&, &)
.p.elems[.k][.Idx] = .String()
return .Idx
}
func ( *Encoder) ( error) {
if != nil {
errorf("unexpected encoding error: %v", )
}
}
func ( *Encoder) ( uint64) {
var [binary.MaxVarintLen64]byte
:= binary.PutUvarint([:], )
, := .Data.Write([:])
.checkErr()
}
func ( *Encoder) ( int64) {
:= uint64() << 1
if < 0 {
= ^
}
.rawUvarint()
}
func ( *Encoder) ( RelocKind, Index) int {
:= RelocEnt{, }
if .RelocMap != nil {
if , := .RelocMap[]; {
return int()
}
} else {
.RelocMap = make(map[RelocEnt]uint32)
}
:= len(.Relocs)
.RelocMap[] = uint32()
.Relocs = append(.Relocs, )
return
}
func ( *Encoder) ( SyncMarker) {
if !.p.SyncMarkers() {
return
}
var []string
if !.encodingRelocHeader && .p.syncFrames > 0 {
:= make([]uintptr, .p.syncFrames)
:= runtime.Callers(2, )
= fmtFrames([:]...)
}
.rawUvarint(uint64())
.rawUvarint(uint64(len()))
for , := range {
.rawUvarint(uint64(.rawReloc(RelocString, .p.StringIdx())))
}
}
func ( *Encoder) ( bool) bool {
.Sync(SyncBool)
var byte
if {
= 1
}
:= .Data.WriteByte()
.checkErr()
return
}
func ( *Encoder) ( int64) {
.Sync(SyncInt64)
.rawVarint()
}
func ( *Encoder) ( uint64) {
.Sync(SyncUint64)
.rawUvarint()
}
func ( *Encoder) ( int) { assert( >= 0); .Uint64(uint64()) }
func ( *Encoder) ( int) { .Int64(int64()) }
func ( *Encoder) ( uint) { .Uint64(uint64()) }
func ( *Encoder) ( RelocKind, Index) {
.Sync(SyncUseReloc)
.Len(.rawReloc(, ))
}
func ( *Encoder) ( Code) {
.Sync(.Marker())
.Len(.Value())
}
func ( *Encoder) ( string) {
.Sync(SyncString)
.Reloc(RelocString, .p.StringIdx())
}
func ( *Encoder) ( []string) {
.Len(len())
for , := range {
.String()
}
}
func ( *Encoder) ( constant.Value) {
.Sync(SyncValue)
if .Bool(.Kind() == constant.Complex) {
.scalar(constant.Real())
.scalar(constant.Imag())
} else {
.scalar()
}
}
func ( *Encoder) ( constant.Value) {
switch v := constant.Val().(type) {
default:
errorf("unhandled %v (%v)", , .Kind())
case bool:
.Code(ValBool)
.Bool()
case string:
.Code(ValString)
.String()
case int64:
.Code(ValInt64)
.Int64()
case *big.Int:
.Code(ValBigInt)
.bigInt()
case *big.Rat:
.Code(ValBigRat)
.bigInt(.Num())
.bigInt(.Denom())
case *big.Float:
.Code(ValBigFloat)
.bigFloat()
}
}
func ( *Encoder) ( *big.Int) {
:= .Bytes()
.String(string())
.Bool(.Sign() < 0)
}
func ( *Encoder) ( *big.Float) {
:= .Append(nil, 'p', -1)
.String(string())
}