websocket-based lrcproto server

fix utf16 insert delete

Changed files
+19 -36
+19 -36
server.go
··· 6 6 "github.com/gorilla/websocket" 7 7 "github.com/rachel-mp4/lrcproto/gen/go" 8 8 "google.golang.org/protobuf/proto" 9 + "unicode/utf16" 9 10 "log" 10 11 "net/http" 11 12 "sync" ··· 396 397 397 398 func insertAtUTF16Index(base string, index uint32, insert string) (string, error) { 398 399 runes := []rune(base) 399 - 400 - unitCount := 0 401 - var splitAt int 402 - for i, r := range runes { 403 - units := 1 404 - if r > 0xFFFF { 405 - units = 2 406 - } 407 - if uint32(unitCount+units) > index { 408 - splitAt = i 409 - break 410 - } 411 - unitCount += units 412 - splitAt = i + 1 413 - } 414 - if index > uint32(unitCount) { 400 + baseUTF16Units := utf16.Encode(runes) 401 + if uint32(len(baseUTF16Units)) < index { 415 402 return "", errors.New("index out of range") 416 403 } 417 - return string(runes[:splitAt]) + insert + string(runes[splitAt:]), nil 404 + 405 + insertRunes := []rune(insert) 406 + insertUTF16Units := utf16.Encode(insertRunes) 407 + result := make([]uint16, 0, len(baseUTF16Units) + len(insertUTF16Units)) 408 + result = append(result, baseUTF16Units[:index]...) 409 + result = append(result, insertUTF16Units...) 410 + result = append(result, baseUTF16Units[index:]...) 411 + resultRunes := utf16.Decode(result) 412 + return string(resultRunes), nil 418 413 } 419 414 420 415 func (s *Server) handleDelete(msg *lrcpb.Event_Delete, client *client) { ··· 437 432 return "", errors.New("end must come after start") 438 433 } 439 434 runes := []rune(base) 440 - unitCount := 0 441 - var startAt, endAt *int 442 - for i, r := range runes { 443 - units := 1 444 - if r > 0xFFFF { 445 - units = 2 446 - } 447 - if startAt == nil && uint32(unitCount+units) > start { 448 - startAt = &i 449 - } 450 - if uint32(unitCount) > end { 451 - endAt = &i 452 - break 453 - } 454 - unitCount += units 455 - } 456 - if end > uint32(unitCount) { 435 + baseUTF16Units := utf16.Encode(runes) 436 + if uint32(len(baseUTF16Units)) < end { 457 437 return "", errors.New("index out of range") 458 438 } 459 - return string(runes[:*startAt]) + string(runes[*endAt:]), nil 460 - 439 + result := make([]uint16, 0, uint32(len(baseUTF16Units)) + start - end) 440 + result = append(result, baseUTF16Units[:start]...) 441 + result = append(result, baseUTF16Units[end:]...) 442 + resultRunes := utf16.Decode(result) 443 + return string(resultRunes), nil 461 444 } 462 445 463 446 func (s *Server) broadcast(event *lrcpb.Event, client *client) {