move gotd fork into repo. (#111)
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"io"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// ComputeLength returns length of s encoded as UTF-16 string.
|
||||
//
|
||||
// While Telegram API docs state that they expect the number of UTF-8
|
||||
// code points, in fact they are talking about UTF-16 code units.
|
||||
func ComputeLength(s string) int {
|
||||
// From utf16 package.
|
||||
n := 0
|
||||
for _, v := range s {
|
||||
n += utf16RuneLen(v)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// ComputeLengthBytes returns length of s encoded as UTF-16 string.
|
||||
//
|
||||
// While Telegram API docs state that they expect the number of UTF-8
|
||||
// code points, in fact they are talking about UTF-16 code units.
|
||||
func ComputeLengthBytes(s []byte) (n int) {
|
||||
// From utf16 package.
|
||||
var i int
|
||||
for i < len(s) {
|
||||
v, size := utf8.DecodeRune(s[i:])
|
||||
i += size
|
||||
n += utf16RuneLen(v)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func utf16RuneLen(v rune) int {
|
||||
const (
|
||||
surrSelf = 0x10000
|
||||
maxRune = '\U0010FFFF' // Maximum valid Unicode code point.
|
||||
)
|
||||
|
||||
if surrSelf <= v && v <= maxRune {
|
||||
return 2
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func (b *Builder) appendMessage(s string, formats ...Formatter) *Builder {
|
||||
if s == "" {
|
||||
return b
|
||||
}
|
||||
|
||||
offset := b.utf16length
|
||||
length := ComputeLength(s)
|
||||
|
||||
b.appendEntities(offset, length, utf8entity{
|
||||
offset: b.message.Len(),
|
||||
length: len(s),
|
||||
}, formats...)
|
||||
_, _ = b.WriteString(s)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Builder) appendEntities(offset, length int, u utf8entity, formats ...Formatter) *Builder {
|
||||
b.lastFormatIndex = len(b.entities)
|
||||
for i := range formats {
|
||||
b.entities = append(b.entities, formats[i](offset, length))
|
||||
b.lengths = append(b.lengths, u)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
var _ = []interface {
|
||||
io.Writer
|
||||
io.StringWriter
|
||||
io.ByteWriter
|
||||
WriteRune(rune) (int, error)
|
||||
}{
|
||||
(*Builder)(nil),
|
||||
}
|
||||
|
||||
// Write implements io.Writer.
|
||||
func (b *Builder) Write(s []byte) (int, error) {
|
||||
n, err := b.message.Write(s)
|
||||
b.utf16length += ComputeLengthBytes(s)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// WriteString implements io.StringWriter.
|
||||
func (b *Builder) WriteString(s string) (int, error) {
|
||||
n, err := b.message.WriteString(s)
|
||||
b.utf16length += ComputeLength(s)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// WriteByte implements io.ByteWriter.
|
||||
func (b *Builder) WriteByte(s byte) error {
|
||||
err := b.message.WriteByte(s)
|
||||
b.utf16length++
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteRune implements rune writer.
|
||||
func (b *Builder) WriteRune(s rune) (int, error) {
|
||||
n, err := b.message.WriteRune(s)
|
||||
b.utf16length += utf16RuneLen(s)
|
||||
return n, err
|
||||
}
|
||||
Reference in New Issue
Block a user