Browse Source

refactor WhoFields to use value receivers

tags/v2.2.0-rc1
Shivaram Lingamneni 4 years ago
parent
commit
97417f4c32
2 changed files with 46 additions and 14 deletions
  1. 30
    0
      irc/client_test.go
  2. 16
    14
      irc/handlers.go

+ 30
- 0
irc/client_test.go View File

@@ -56,3 +56,33 @@ func TestUserMasks(t *testing.T) {
56 56
 		t.Error("failure to match")
57 57
 	}
58 58
 }
59
+
60
+func TestWhoFields(t *testing.T) {
61
+	var w whoxFields
62
+
63
+	if w.Has('a') {
64
+		t.Error("zero value of whoxFields must be empty")
65
+	}
66
+	w = w.Add('a')
67
+	if !w.Has('a') {
68
+		t.Error("failed to set and get")
69
+	}
70
+	if w.Has('A') {
71
+		t.Error("false positive")
72
+	}
73
+	if w.Has('o') {
74
+		t.Error("false positive")
75
+	}
76
+	w = w.Add('🐬')
77
+	if w.Has('🐬') {
78
+		t.Error("should not be able to set invalid who field")
79
+	}
80
+	w = w.Add('o')
81
+	if !w.Has('o') {
82
+		t.Error("failed to set and get")
83
+	}
84
+	w = w.Add('z')
85
+	if !w.Has('z') {
86
+		t.Error("failed to set and get")
87
+	}
88
+}

+ 16
- 14
irc/handlers.go View File

@@ -2794,30 +2794,32 @@ func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
2794 2794
 	return true
2795 2795
 }
2796 2796
 
2797
-const WhoFieldMinimum = int('a') // lowest rune value
2798
-const WhoFieldMaximum = int('z')
2797
+type whoxFields uint32 // bitset to hold the WHOX field values, 'a' through 'z'
2799 2798
 
2800
-type WhoFields [WhoFieldMaximum - WhoFieldMinimum + 1]bool
2799
+func (fields whoxFields) Add(field rune) (result whoxFields) {
2800
+	index := int(field) - int('a')
2801
+	if 0 <= index && index < 26 {
2802
+		return fields | (1 << index)
2803
+	} else {
2804
+		return fields
2805
+	}
2806
+}
2801 2807
 
2802
-func (fields *WhoFields) Set(field rune) bool {
2803
-	index := int(field)
2804
-	if WhoFieldMinimum <= index && index <= WhoFieldMaximum {
2805
-		fields[int(field)-WhoFieldMinimum] = true
2806
-		return true
2808
+func (fields whoxFields) Has(field rune) bool {
2809
+	index := int(field) - int('a')
2810
+	if 0 <= index && index < 26 {
2811
+		return (fields & (1 << index)) != 0
2807 2812
 	} else {
2808 2813
 		return false
2809 2814
 	}
2810 2815
 }
2811
-func (fields *WhoFields) Has(field rune) bool {
2812
-	return fields[int(field)-WhoFieldMinimum]
2813
-}
2814 2816
 
2815 2817
 // rplWhoReply returns the WHO(X) reply between one user and another channel/user.
2816 2818
 // who format:
2817 2819
 // <channel> <user> <host> <server> <nick> <H|G>[*][~|&|@|%|+][B] :<hopcount> <real name>
2818 2820
 // whox format:
2819 2821
 // <type> <channel> <user> <ip> <host> <server> <nick> <H|G>[*][~|&|@|%|+][B] <hops> <idle> <account> <rank> :<real name>
2820
-func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, isWhox bool, fields WhoFields, whoType string) {
2822
+func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, isWhox bool, fields whoxFields, whoType string) {
2821 2823
 	params := []string{client.Nick()}
2822 2824
 
2823 2825
 	details := target.Details()
@@ -2940,9 +2942,9 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
2940 2942
 			sFields = strings.ToLower(sFields[:typeIndex])
2941 2943
 		}
2942 2944
 	}
2943
-	var fields WhoFields
2945
+	var fields whoxFields
2944 2946
 	for _, field := range sFields {
2945
-		fields.Set(field)
2947
+		fields = fields.Add(field)
2946 2948
 	}
2947 2949
 
2948 2950
 	//TODO(dan): is this used and would I put this param in the Modern doc?

Loading…
Cancel
Save