github.com/Ptt-official-app/go-bbs@v0.12.0/formosabbs/file.go (about) 1 package bbs 2 3 import ( 4 "github.com/Ptt-official-app/go-bbs" 5 6 "bytes" 7 "encoding/binary" 8 "io" 9 "log" 10 "os" 11 "time" 12 ) 13 14 const ( 15 StrLength = 80 16 17 PosOfFileHeaderFilename = 0 18 PosOfFileHeaderOwner = StrLength 19 PosOfFileHeaderPostno = StrLength - 8 20 PosOfFileHeaderModified = PosOfFileHeaderOwner + StrLength - 8 21 PosOfFileHeaderTitle = PosOfFileHeaderOwner + StrLength 22 ) 23 24 type FileHeader struct { 25 Filename string 26 Modified time.Time 27 Recommend int8 // Important Level 28 Owner string // uid[.] 29 Date string 30 Title string 31 32 Money int 33 AnnoUID int 34 // VoteLimits 35 ReferRef uint // 至底公告? 36 ReferFlag bool // 至底公告? 37 38 Filemode uint8 39 40 Postno int32 // FormosaBBS only 41 } 42 43 func OpenFormosaBBSFileHeaderFile(filename string) ([]*FileHeader, error) { 44 file, err := os.Open(filename) 45 if err != nil { 46 log.Println(err) 47 return nil, err 48 } 49 50 ret := []*FileHeader{} 51 52 for { 53 hdr := make([]byte, 248) 54 _, err := file.Read(hdr) 55 // log.Println(len, err) 56 if err == io.EOF { 57 break 58 } 59 60 f, err := NewFomosaBBSFileHeaderWithByte(hdr) 61 if err != nil { 62 return nil, err 63 } 64 ret = append(ret, f) 65 // log.Println(f.Filename) 66 67 } 68 69 return ret, nil 70 71 } 72 73 func NewFomosaBBSFileHeaderWithByte(data []byte) (*FileHeader, error) { 74 75 ret := FileHeader{} 76 ret.Filename = string(bytes.Trim(data[PosOfFileHeaderFilename:+PosOfFileHeaderFilename+44], "\x00")) 77 78 modifiedInt := binary.LittleEndian.Uint32(data[PosOfFileHeaderModified : PosOfFileHeaderModified+4]) 79 // log.Println("modifiedInt:", modifiedInt, PosOfModified) 80 ret.Modified = time.Unix(int64(modifiedInt), 0) 81 82 // ret.Recommend = int8(data[PosOfRecommend]) 83 ret.Owner = string(bytes.Trim(data[PosOfFileHeaderOwner:PosOfFileHeaderOwner+72], "\x00")) 84 // ret.Date = string(bytes.Trim(data[PosOfDate:PosOfDate+6], "\x00")) 85 ret.Title = bbs.Big5ToUtf8(bytes.Trim(data[PosOfFileHeaderTitle:PosOfFileHeaderTitle+67], "\x00")) 86 // // log.Println("PosOfUnionMulti:", PosOfUnionMulti, data[PosOfUnionMulti]) 87 88 // ret.Money = int(binary.LittleEndian.Uint32(data[PosOfUnionMulti : PosOfUnionMulti+4])) 89 // ret.AnnoUID = int(binary.LittleEndian.Uint32(data[PosOfUnionMulti : PosOfUnionMulti+4])) 90 91 // ret.Filemode = uint8(data[PosOfFilemode]) 92 93 // if ret.IsVotePost() { 94 // ret.VoteLimits.Posts = data[PosOfUnionMulti+0] 95 // ret.VoteLimits.Logins = data[PosOfUnionMulti+1] 96 // ret.VoteLimits.Regtime = data[PosOfUnionMulti+2] 97 // ret.VoteLimits.Badpost = data[PosOfUnionMulti+3] 98 // } 99 100 ret.Postno = int32(binary.LittleEndian.Uint32(data[PosOfFileHeaderPostno : PosOfFileHeaderPostno+4])) 101 // ret.Title = binary.LittleEndian.Uint8(data[FileNameLength+5+PTT_IDLEN+2+6 : FileNameLength+5+PTT_IDLEN+2+6+TitleLength+1]) 102 103 return &ret, nil 104 }