Changeset 478 in code for trunk/irc.go
- Timestamp:
- Mar 24, 2021, 5:15:52 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/irc.go
r463 r478 122 122 } 123 123 member := arguments[nextArgument] 124 if _, ok := ch.Members[member]; ok { 124 m := ch.Members.Value(member) 125 if m != nil { 125 126 if plusMinus == '+' { 126 ch.Members[member].Add(ch.conn.availableMemberships, membership)127 m.Add(ch.conn.availableMemberships, membership) 127 128 } else { 128 129 // TODO: for upstreams without multi-prefix, query the user modes again 129 ch.Members[member].Remove(membership)130 m.Remove(membership) 130 131 } 131 132 } … … 419 420 return cmd, params, true 420 421 } 422 423 type casemapping func(string) string 424 425 func casemapNone(name string) string { 426 return name 427 } 428 429 // CasemapASCII of name is the canonical representation of name according to the 430 // ascii casemapping. 431 func casemapASCII(name string) string { 432 var sb strings.Builder 433 sb.Grow(len(name)) 434 for _, r := range name { 435 if 'A' <= r && r <= 'Z' { 436 r += 'a' - 'A' 437 } 438 sb.WriteRune(r) 439 } 440 return sb.String() 441 } 442 443 // casemapRFC1459 of name is the canonical representation of name according to the 444 // rfc1459 casemapping. 445 func casemapRFC1459(name string) string { 446 var sb strings.Builder 447 sb.Grow(len(name)) 448 for _, r := range name { 449 if 'A' <= r && r <= 'Z' { 450 r += 'a' - 'A' 451 } else if r == '{' { 452 r = '[' 453 } else if r == '}' { 454 r = ']' 455 } else if r == '\\' { 456 r = '|' 457 } else if r == '~' { 458 r = '^' 459 } 460 sb.WriteRune(r) 461 } 462 return sb.String() 463 } 464 465 // casemapRFC1459Strict of name is the canonical representation of name 466 // according to the rfc1459-strict casemapping. 467 func casemapRFC1459Strict(name string) string { 468 var sb strings.Builder 469 sb.Grow(len(name)) 470 for _, r := range name { 471 if 'A' <= r && r <= 'Z' { 472 r += 'a' - 'A' 473 } else if r == '{' { 474 r = '[' 475 } else if r == '}' { 476 r = ']' 477 } else if r == '\\' { 478 r = '|' 479 } 480 sb.WriteRune(r) 481 } 482 return sb.String() 483 } 484 485 func parseCasemappingToken(tokenValue string) (casemap casemapping, ok bool) { 486 switch tokenValue { 487 case "ascii": 488 casemap = casemapASCII 489 case "rfc1459": 490 casemap = casemapRFC1459 491 case "rfc1459-strict": 492 casemap = casemapRFC1459Strict 493 default: 494 return nil, false 495 } 496 return casemap, true 497 } 498 499 func partialCasemap(higher casemapping, name string) string { 500 nameFullyCM := higher(name) 501 var sb strings.Builder 502 sb.Grow(len(name)) 503 for i, r := range nameFullyCM { 504 if 'a' <= r && r <= 'z' { 505 r = rune(name[i]) 506 } 507 sb.WriteRune(r) 508 } 509 return sb.String() 510 } 511 512 type casemapMap struct { 513 innerMap map[string]casemapEntry 514 casemap casemapping 515 } 516 517 type casemapEntry struct { 518 originalKey string 519 value interface{} 520 } 521 522 func newCasemapMap(size int) casemapMap { 523 return casemapMap{ 524 innerMap: make(map[string]casemapEntry, size), 525 casemap: casemapNone, 526 } 527 } 528 529 func (cm *casemapMap) OriginalKey(name string) (key string, ok bool) { 530 entry, ok := cm.innerMap[cm.casemap(name)] 531 if !ok { 532 return "", false 533 } 534 return entry.originalKey, true 535 } 536 537 func (cm *casemapMap) Has(name string) bool { 538 _, ok := cm.innerMap[cm.casemap(name)] 539 return ok 540 } 541 542 func (cm *casemapMap) Len() int { 543 return len(cm.innerMap) 544 } 545 546 func (cm *casemapMap) SetValue(name string, value interface{}) { 547 nameCM := cm.casemap(name) 548 entry, ok := cm.innerMap[nameCM] 549 if !ok { 550 cm.innerMap[nameCM] = casemapEntry{ 551 originalKey: name, 552 value: value, 553 } 554 return 555 } 556 entry.value = value 557 cm.innerMap[nameCM] = entry 558 } 559 560 func (cm *casemapMap) Delete(name string) { 561 delete(cm.innerMap, cm.casemap(name)) 562 } 563 564 func (cm *casemapMap) SetCasemapping(newCasemap casemapping) { 565 cm.casemap = newCasemap 566 newInnerMap := make(map[string]casemapEntry, len(cm.innerMap)) 567 for _, entry := range cm.innerMap { 568 newInnerMap[cm.casemap(entry.originalKey)] = entry 569 } 570 cm.innerMap = newInnerMap 571 } 572 573 type upstreamChannelCasemapMap struct{ casemapMap } 574 575 func (cm *upstreamChannelCasemapMap) Value(name string) *upstreamChannel { 576 entry, ok := cm.innerMap[cm.casemap(name)] 577 if !ok { 578 return nil 579 } 580 return entry.value.(*upstreamChannel) 581 } 582 583 type channelCasemapMap struct{ casemapMap } 584 585 func (cm *channelCasemapMap) Value(name string) *Channel { 586 entry, ok := cm.innerMap[cm.casemap(name)] 587 if !ok { 588 return nil 589 } 590 return entry.value.(*Channel) 591 } 592 593 type membershipsCasemapMap struct{ casemapMap } 594 595 func (cm *membershipsCasemapMap) Value(name string) *memberships { 596 entry, ok := cm.innerMap[cm.casemap(name)] 597 if !ok { 598 return nil 599 } 600 return entry.value.(*memberships) 601 } 602 603 type mapStringStringCasemapMap struct{ casemapMap } 604 605 func (cm *mapStringStringCasemapMap) Value(name string) map[string]string { 606 entry, ok := cm.innerMap[cm.casemap(name)] 607 if !ok { 608 return nil 609 } 610 return entry.value.(map[string]string) 611 }
Note:
See TracChangeset
for help on using the changeset viewer.