88 "io/ioutil"
99 "net/url"
1010 "strings"
11+ "encoding/binary"
1112)
1213
1314type FrozenTrie struct {
@@ -32,6 +33,14 @@ type FrozenTrie struct {
3233 usr_bl []string
3334}
3435
36+ func (f * FrozenTrie ) GetData () BS {
37+ return f .data
38+ }
39+
40+ func (f * FrozenTrie ) GetDir () RankDirectory {
41+ return f .directory
42+ }
43+
3544func (FT * FrozenTrie ) Init (trieData []uint16 , rdir RankDirectory , nodeCount int ) {
3645 FT .data = BS {}
3746 FT .data .Init (trieData )
@@ -62,17 +71,17 @@ func (FT *FrozenTrie) Init(trieData []uint16, rdir RankDirectory, nodeCount int)
6271 FT .usr_bl = []string {}
6372}
6473
65- func (FT FrozenTrie ) getNodeByIndex (index int ) FrozenTrieNode {
74+ func (FT * FrozenTrie ) getNodeByIndex (index int ) FrozenTrieNode {
6675 FTN := FrozenTrieNode {}
6776 FTN .Init (FT , index )
6877 return FTN
6978}
7079
71- func (FT FrozenTrie ) getRoot () FrozenTrieNode {
80+ func (FT * FrozenTrie ) getRoot () FrozenTrieNode {
7281 return FT .getNodeByIndex (0 )
7382}
7483
75- func (FT FrozenTrie ) lookup (word []uint8 ) (bool , []uint32 ) {
84+ func (FT * FrozenTrie ) lookup (word []uint8 ) (bool , []uint32 ) {
7685 var node = FT .getRoot ()
7786 var emptyreturn []uint32
7887
@@ -260,7 +269,7 @@ func (FT *FrozenTrie) LoadTag() error {
260269 return nil
261270}
262271
263- func (FT FrozenTrie ) FlagstoTag (flags []uint32 ) []string {
272+ func (FT * FrozenTrie ) FlagstoTag (flags []uint32 ) []string {
264273 // flags has to be an array of 16-bit integers.
265274 header := uint16 (flags [0 ])
266275 tagIndices := []int {}
@@ -309,8 +318,20 @@ func (FT *FrozenTrie) DNlookup(dn string, usr_flag string) (bool, []string) {
309318
310319 if FT .usr_flag == "" || FT .usr_flag != usr_flag {
311320 //fmt.Println("User config saved : ")
321+ var blocklists []string
322+ var err error
323+ s := strings .Split (usr_flag , ":" )
324+ if len (s ) > 1 {
325+ blocklists , err = FT .decode (s [1 ], s [0 ])
326+ } else {
327+ blocklists , err = FT .decode (usr_flag , "0" )
328+ }
329+ if (err != nil ) {
330+ fmt .Println (err , s )
331+ return false , nil
332+ }
333+ FT .usr_bl = blocklists
312334 FT .usr_flag = usr_flag
313- FT .usr_bl = FT .Urlenc_to_flag (FT .usr_flag )
314335 }
315336
316337 dn = strings .TrimSpace (dn )
@@ -362,7 +383,7 @@ func (FT *FrozenTrie) DNlookup(dn string, usr_flag string) (bool, []string) {
362383 }
363384}
364385
365- func (FT FrozenTrie ) CreateUrlEncodedflag (fl []string ) string {
386+ func (FT * FrozenTrie ) CreateUrlEncodedflag (fl []string ) string {
366387 var val = 0
367388 var res = ""
368389 for _ , flag := range fl {
@@ -418,9 +439,118 @@ func (FT FrozenTrie) CreateUrlEncodedflag(fl []string) string {
418439 return url .QueryEscape (b64 .StdEncoding .EncodeToString ([]byte (res )))
419440}
420441
421- func (FT FrozenTrie ) Urlenc_to_flag (str string ) []string {
442+ func (FT * FrozenTrie ) Urlenc_to_flag (str string ) []string {
422443 str , _ = url .QueryUnescape (str )
423444 buf , _ := b64 .StdEncoding .DecodeString (str )
424445 str = string (buf )
425446 return FT .FlagstoTag (Flag_to_uint (str ))
426447}
448+
449+ func (FT * FrozenTrie ) decode (stamp string , ver string ) (tags []string , err error ) {
450+ decoder := b64 .StdEncoding
451+ if (ver == "0" ) {
452+ stamp , err = url .QueryUnescape (stamp )
453+ } else if (ver == "1" ) {
454+ stamp , err = url .PathUnescape (stamp )
455+ decoder = b64 .URLEncoding
456+ } else {
457+ err = fmt .Errorf ("version does not exist" , ver )
458+ }
459+
460+ if err != nil {
461+ return nil , err
462+ }
463+
464+ buf , err := decoder .DecodeString (stamp )
465+ if err != nil {
466+ fmt .Println ("b64" , stamp )
467+ return
468+ }
469+
470+ var u16 []uint16
471+ if ver == "0" {
472+ u16 = stringtouint (string (buf ))
473+ } else if ver == "1" {
474+ u16 = bytestouint (buf )
475+ }
476+ fmt .Println ("%s %v" , ver , u16 )
477+ return FT .flagstotag (u16 )
478+ }
479+
480+ func (ft * FrozenTrie ) flagstotag (flags []uint16 ) ([]string , error ) {
481+ // flags has to be an array of 16-bit integers.
482+
483+ // first index always contains the header
484+ header := uint16 (flags [0 ])
485+ // store of each big-endian position of set bits in header
486+ tagIndices := []int {}
487+ values := []string {}
488+ var mask uint16
489+
490+ // b1000,0000,0000,0000
491+ mask = 0x8000
492+
493+ // read first 16 header bits from msb to lsb
494+ // and capture indices of set bits in tagIndices
495+ for i := 0 ; i < 16 ; i ++ {
496+ if (header << i ) == 0 {
497+ break
498+ }
499+ if (header & mask ) == mask {
500+ tagIndices = append (tagIndices , i )
501+ }
502+ mask = mask >> 1 // shift to read the next msb bit
503+ }
504+ // the number of set bits in header must correspond to total
505+ // blocklist "flags" excluding the header at position 0
506+ if len (tagIndices ) != (len (flags ) - 1 ) {
507+ err := fmt .Errorf ("%v %v flags and header mismatch" , tagIndices , flags )
508+ return nil , err
509+ }
510+
511+ // for all blocklist flags excluding the header
512+ // figure out the blocklist-ids
513+ for i := 1 ; i < len (flags ); i ++ {
514+ // 16 blocklists are represented by one flag
515+ // that is, one bit per blocklist
516+ var flag = uint16 (flags [i ])
517+ // get the index of the current flag in the header
518+ var index = tagIndices [i - 1 ]
519+ mask = 0x8000
520+ // for each of the 16 bits in the flag
521+ // capture the set bits and calculate
522+ // its actual decimal value, the blocklist-id
523+ for j := 0 ; j < 16 ; j ++ {
524+ if (flag << j ) == 0 {
525+ break
526+ }
527+ if (flag & mask ) == mask {
528+ pos := (index * 16 ) + j
529+ // from the decimal value which is its
530+ // blocklist-id, fetch its metadata
531+ values = append (values , FT .rflags [pos ])
532+ }
533+ mask = mask >> 1
534+ }
535+ }
536+ return values , nil
537+ }
538+
539+ func stringtouint (str string ) []uint16 {
540+ runedata := []rune (str )
541+ resp := make ([]uint16 , len (runedata ))
542+ for key , value := range runedata {
543+ resp [key ] = uint16 (value )
544+ }
545+ return resp
546+ }
547+
548+ func bytestouint (b []byte ) []uint16 {
549+ data := make ([]uint16 , len (b )/ 2 )
550+ for i := range data {
551+ // assuming little endian
552+ data [i ] = binary .LittleEndian .Uint16 (b [i * 2 : (i + 1 )* 2 ])
553+ }
554+ return data
555+ }
556+
0 commit comments