-
Notifications
You must be signed in to change notification settings - Fork 4
/
type_jet_payload.go
125 lines (100 loc) · 3.56 KB
/
type_jet_payload.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package reftypes
import (
"encoding/binary"
"github.com/insolar/assured-ledger/ledger-core/ledger/jet"
"github.com/insolar/assured-ledger/ledger-core/pulse"
"github.com/insolar/assured-ledger/ledger-core/reference"
"github.com/insolar/assured-ledger/ledger-core/vanilla/throw"
)
func RecordPayloadRef(id jet.ID, recordRef reference.LocalHolder, offset, length, extID uint32) reference.Global {
local := recordRef.GetLocal()
if !pulseZeroScope(local.GetHeader()).IsTimePulse() {
panic(throw.IllegalValue())
}
var data reference.LocalHash
EncodeJetData(&data, 0, jet.NoLengthExactID(id))
EncodeJetPayloadPosition(&data, offset, length, extID)
return reference.New(reference.NewLocal(pulse.Jet, 0, data), local)
}
func RecordPayloadRefByDrop(id jet.DropID, recordRef reference.LocalHolder, offset, length, extID uint32) reference.Global {
pn := id.CreatedAt()
if !pn.IsTimePulse() {
panic(throw.IllegalValue())
}
local := recordRef.GetLocal()
if pn != local.Pulse() {
panic(throw.IllegalValue())
}
var data reference.LocalHash
EncodeJetData(&data, 0, jet.NoLengthExactID(id.ID()))
EncodeJetPayloadPosition(&data, offset, length, extID)
return reference.New(reference.NewLocal(pulse.Jet, 0, data), local)
}
func UnpackRecordPayloadRef(ref reference.Holder) (id jet.ID, local reference.Local, offset, length, extID uint32, err error) {
base := ref.GetBase()
local = ref.GetLocal()
id, err = PartialUnpackJetLocalRef(base)
switch {
case err == nil:
offset, length, extID, err = DecodeJetPayloadPosition(base.IdentityHash(), true)
case !pulseZeroScope(local.GetHeader()).IsTimePulse():
err = throw.W(ErrIllegalRefValue,"invalid local")
}
if err != nil {
err = newRefTypeErr(err, RecordPayload, base, local)
}
return
}
func DecodeJetPayloadPosition(b reference.LocalHash, checkTailingZeros bool) (offset, length, extID uint32, err error) {
encoder := binary.LittleEndian
length = encoder.Uint32(b[jetDataLength:jetDataLength+4])
if length == 0 {
err = throw.W(ErrIllegalRefValue,"empty jet payload")
return
}
offset = encoder.Uint32(b[jetDataLength+4:jetDataLength+8])
extID = encoder.Uint32(b[jetDataLength+8:jetDataLength+12])
if checkTailingZeros {
for _, bi := range b[jetDataLength+12:] {
if bi != 0 {
err = throw.W(ErrIllegalRefValue,"unexpected data in payload ref")
return
}
}
}
return
}
func EncodeJetPayloadPosition(b *reference.LocalHash, offset, length, extID uint32) {
if length == 0 {
panic(throw.IllegalValue())
}
encoder := binary.LittleEndian
encoder.PutUint32(b[jetDataLength:jetDataLength+4], length)
encoder.PutUint32(b[jetDataLength+4:jetDataLength+8], offset)
encoder.PutUint32(b[jetDataLength+8:jetDataLength+12], extID)
}
/*****************************************************/
var _ RefTypeDef = typeDefRecPayload{}
type typeDefRecPayload struct {}
func (typeDefRecPayload) CanBeDerivedWith(pulse.Number, reference.Local) bool {
return false
}
func (typeDefRecPayload) Usage() Usage {
return UseAsBase
}
func (v typeDefRecPayload) RefFrom(base, local reference.Local) (reference.Global, error) {
if err := v.VerifyGlobalRef(base, local); err != nil {
return reference.Global{}, err
}
return reference.New(base, local), nil
}
func (typeDefRecPayload) VerifyGlobalRef(base, local reference.Local) error {
_, _, _, _, _, err := UnpackRecordPayloadRef(reference.New(base, local))
return err
}
func (typeDefRecPayload) VerifyLocalRef(ref reference.Local) error {
panic(throw.Unsupported())
}
func (typeDefRecPayload) DetectSubType(_, _ reference.Local) RefType {
panic(throw.Unsupported()) // it is a sub type
}