Files
iabtcfv2/segment_core_string.go
2020-04-03 16:38:16 +02:00

191 lines
4.2 KiB
Go

package iabtcf
import (
"encoding/base64"
"time"
)
type CoreString struct {
Version int
Created time.Time
LastUpdated time.Time
CmpId int
CmpVersion int
ConsentScreen int
ConsentLanguage string
VendorListVersion int
TcfPolicyVersion int
IsServiceSpecific bool
UseNonStandardStacks bool
SpecialFeatureOptIns map[int]bool
PurposesConsent map[int]bool
PurposesLITransparency map[int]bool
PurposeOneTreatment bool
PublisherCC string
MaxVendorId int
IsRangeEncoding bool
VendorsConsent map[int]bool
NumEntries int
RangeEntries []*RangeEntry
MaxVendorIdLI int
IsRangeEncodingLI bool
VendorsLITransparency map[int]bool
NumEntriesLI int
RangeEntriesLI []*RangeEntry
NumPubRestrictions int
PubRestrictions []*PubRestriction
}
type PubRestriction struct {
PurposeId int
RestrictionType int
NumEntries int
RangeEntries []*RangeEntry
}
type RangeEntry struct {
StartVendorID int
EndVendorID int
}
func (c *CoreString) IsSpecialFeatureAllowed(id int) bool {
return c.SpecialFeatureOptIns[id]
}
func (c *CoreString) IsPurposeAllowed(id int) bool {
return c.PurposesConsent[id]
}
func (c *CoreString) IsPurposeLIAllowed(id int) bool {
return c.PurposesLITransparency[id]
}
func (c *CoreString) IsVendorAllowed(id int) bool {
if c.IsRangeEncoding {
for _, entry := range c.RangeEntries {
if entry.StartVendorID <= id && id <= entry.EndVendorID {
return true
}
}
return false
}
return c.VendorsConsent[id]
}
func (c *CoreString) IsVendorLIAllowed(id int) bool {
if c.IsRangeEncodingLI {
for _, entry := range c.RangeEntriesLI {
if entry.StartVendorID <= id && id <= entry.EndVendorID {
return true
}
}
return false
}
return c.VendorsLITransparency[id]
}
func (c *CoreString) Encode() string {
bitSize := 230
if c.IsRangeEncoding {
bitSize += 12
entriesSize := len(c.RangeEntries)
for _, entry := range c.RangeEntries {
if entry.EndVendorID > entry.StartVendorID {
entriesSize += 16 * 2
} else {
entriesSize += 16
}
}
bitSize += +entriesSize
} else {
bitSize += c.MaxVendorId
}
bitSize += 16
if c.IsRangeEncodingLI {
bitSize += 12
entriesSize := len(c.RangeEntriesLI)
for _, entry := range c.RangeEntriesLI {
if entry.EndVendorID > entry.StartVendorID {
entriesSize += 16 * 2
} else {
entriesSize += 16
}
}
bitSize += entriesSize
} else {
bitSize += c.MaxVendorIdLI
}
bitSize += 12
for _, res := range c.PubRestrictions {
entriesSize := 20
for _, entry := range res.RangeEntries {
if entry.EndVendorID > entry.StartVendorID {
entriesSize += 16 * 2
} else {
entriesSize += 16
}
}
bitSize += entriesSize
}
var e = NewTCEncoder(make([]byte, bitSize/8))
if bitSize%8 != 0 {
e = NewTCEncoder(make([]byte, bitSize/8+1))
}
e.WriteInt(c.Version, 6)
e.WriteTime(c.Created)
e.WriteTime(c.LastUpdated)
e.WriteInt(c.CmpId, 12)
e.WriteInt(c.CmpVersion, 12)
e.WriteInt(c.ConsentScreen, 6)
e.WriteIsoCode(c.ConsentLanguage)
e.WriteInt(c.VendorListVersion, 12)
e.WriteInt(c.TcfPolicyVersion, 6)
e.WriteBool(c.IsServiceSpecific)
e.WriteBool(c.UseNonStandardStacks)
for i := 0; i < 12; i++ {
e.WriteBool(c.IsSpecialFeatureAllowed(i + 1))
}
for i := 0; i < 24; i++ {
e.WriteBool(c.IsPurposeAllowed(i + 1))
}
for i := 0; i < 24; i++ {
e.WriteBool(c.IsPurposeLIAllowed(i + 1))
}
e.WriteBool(c.PurposeOneTreatment)
e.WriteIsoCode(c.PublisherCC)
e.WriteInt(c.MaxVendorId, 16)
e.WriteBool(c.IsRangeEncoding)
if c.IsRangeEncoding {
e.WriteInt(len(c.RangeEntries), 12)
e.WriteRangeEntries(c.RangeEntries)
} else {
for i := 0; i < c.MaxVendorId; i++ {
e.WriteBool(c.IsVendorAllowed(i + 1))
}
}
e.WriteInt(c.MaxVendorIdLI, 16)
e.WriteBool(c.IsRangeEncodingLI)
if c.IsRangeEncodingLI {
e.WriteInt(len(c.RangeEntriesLI), 12)
e.WriteRangeEntries(c.RangeEntriesLI)
} else {
for i := 0; i < c.MaxVendorIdLI; i++ {
e.WriteBool(c.IsVendorLIAllowed(i + 1))
}
}
e.WriteInt(len(c.PubRestrictions), 12)
e.WritePubRestrictions(c.PubRestrictions)
return base64.RawURLEncoding.EncodeToString(e.bytes)
}