package fileid import ( "io" "github.com/go-faster/errors" "go.mau.fi/mautrix-telegram/pkg/gotd/bin" ) // FileID represents parsed Telegram Bot API file_id. type FileID struct { Type Type DC int ID int64 AccessHash int64 FileReference []byte URL string PhotoSizeSource PhotoSizeSource } const ( webLocationFlag = 1 << 24 fileReferenceFlag = 1 << 25 ) func (f *FileID) decodeLatestFileID(b *bin.Buffer) error { if len(b.Buf) < 1 { return io.ErrUnexpectedEOF } var subVersion = b.Buf[len(b.Buf)-1] typeID, err := b.Uint32() if err != nil { return errors.Wrap(err, "read type_id") } hasWebLocation := typeID&webLocationFlag != 0 hasReference := typeID&fileReferenceFlag != 0 typeID &^= webLocationFlag typeID &^= fileReferenceFlag if typeID >= uint32(lastType) { return errors.Errorf("unknown type %d", typeID) } f.Type = Type(typeID) { dcID, err := b.Uint32() if err != nil { return errors.Wrap(err, "read dc_id") } f.DC = int(dcID) } if hasReference { reference, err := b.Bytes() if err != nil { return errors.Wrap(err, "read file_reference") } f.FileReference = reference } if hasWebLocation { url, err := b.String() if err != nil { return errors.Wrap(err, "read url") } f.URL = url return nil } { id, err := b.Long() if err != nil { return errors.Wrap(err, "read id") } f.ID = id } { accessHash, err := b.Long() if err != nil { return errors.Wrap(err, "read access_hash") } f.AccessHash = accessHash } switch Type(typeID) { case Thumbnail, Photo, ProfilePhoto: default: return nil } if err := f.PhotoSizeSource.decode(b, subVersion); err != nil { return errors.Wrap(err, "decode photo_size") } return nil } func (f *FileID) encodeLatestFileID(b *bin.Buffer) { hasWebLocation := f.URL != "" hasReference := len(f.FileReference) != 0 { typeID := f.Type if hasWebLocation { typeID |= webLocationFlag } if hasReference { typeID |= fileReferenceFlag } b.PutUint32(uint32(typeID)) } b.PutUint32(uint32(f.DC)) if hasReference { b.PutBytes(f.FileReference) } if hasWebLocation { b.PutString(f.URL) return } b.PutLong(f.ID) b.PutLong(f.AccessHash) switch f.Type { case Thumbnail, Photo, ProfilePhoto: f.PhotoSizeSource.encode(b) } b.Buf = append(b.Buf, latestSubVersion) }