diff options
| author | jet2tlf <jet2tlf@gmail.com> | 2024-06-03 17:36:39 +0000 |
|---|---|---|
| committer | jet2tlf <jet2tlf@gmail.com> | 2024-06-03 17:36:39 +0000 |
| commit | 7cff8936edbdc7ce7c0ca41eab2f8d5470cad2e6 (patch) | |
| tree | 931ab66c1d6be7adc37fbe810687e00297d5911f /cmd/mybittorrent/file.go | |
| parent | a312577297526cfd3a51f68d8c112229f3c4185a (diff) | |
| download | bittorrent-go-7cff8936edbdc7ce7c0ca41eab2f8d5470cad2e6.tar.gz bittorrent-go-7cff8936edbdc7ce7c0ca41eab2f8d5470cad2e6.zip | |
codecrafters submit [skip ci]
Diffstat (limited to 'cmd/mybittorrent/file.go')
| -rw-r--r-- | cmd/mybittorrent/file.go | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/cmd/mybittorrent/file.go b/cmd/mybittorrent/file.go new file mode 100644 index 0000000..2302976 --- /dev/null +++ b/cmd/mybittorrent/file.go @@ -0,0 +1,85 @@ +package main + +import ( + "bytes" + "fmt" + "io" +) + +type File struct { + Announce string `bencode:"announce"` + Info FileInfo `bencode:"info"` +} + +type FileInfo struct { + Length int `bencode:"length"` + Name string `bencode:"name"` + PieceLength int `bencode:"piece length"` + Pieces string `bencode:"pieces"` +} + +func NewFile() *File { + return &File{} +} + +func (f *File) ReadFrom(r io.ReadCloser) error { + buf := new(bytes.Buffer) + + _, err := buf.ReadFrom(r) + if err != nil { + return err + } + + defer func(r io.ReadCloser) { + err := r.Close() + if err != nil { + fmt.Printf("failed to close: %v+\n", err) + } + }(r) + + if err != nil { + return err + } + + decoded, err := NewDecoder(buf.String()).Decode() + if err != nil { + return err + } + + content, ok := decoded.(map[string]any) + if !ok { + return fmt.Errorf("invalid contents") + } + + f.Announce, ok = content["announce"].(string) + if !ok { + return fmt.Errorf("invalid announce field") + } + + info, ok := content["info"].(map[string]any) + if !ok { + return fmt.Errorf("invalid info field") + } + + f.Info.Length, ok = info["length"].(int) + if !ok { + return fmt.Errorf("invalid info.length field") + } + + f.Info.Name, ok = info["name"].(string) + if !ok { + return fmt.Errorf("invalid info.name field") + } + + f.Info.PieceLength, ok = info["piece length"].(int) + if !ok { + return fmt.Errorf("invalid info.piece length field") + } + + f.Info.Pieces, ok = info["pieces"].(string) + if !ok { + return fmt.Errorf("invalid info.pieces field") + } + + return nil +} |