package mps import ( "encoding/binary" "io" ) const ( DEBIT = byte(iota) CREDIT STARTAUTOPAY ENDAUTOPAY ) // | 4 byte magic string "MPS7" | 1 byte version | 4 byte (uint32) # of records | // | 1 byte record type enum | 4 byte (uint32) Unix timestamp | 8 byte (uint64) user ID | type Record struct { Type byte Time uint32 UserId uint64 Amount float64 } type TransactionLog struct { Header Header Records []Record } // | 4 byte magic string "MPS7" | 1 byte version | 4 byte (uint32) # of records | type Header struct { Magic [4]byte Version int8 RecordCount uint32 } func parseHeader(r io.Reader, h *Header) error { err := binary.Read(r, binary.BigEndian, h) return err } func parseRecord(r io.Reader, record *Record) error { err := binary.Read(r, binary.BigEndian, &record.Type) if err != nil { return err } err = binary.Read(r, binary.BigEndian, &record.Time) if err != nil { return err } err = binary.Read(r, binary.BigEndian, &record.UserId) if err != nil { return err } if record.Type == CREDIT || record.Type == DEBIT { err = binary.Read(r, binary.BigEndian, &record.Amount) if err != nil { return err } } return nil } func Parse(r io.Reader) (*TransactionLog, error) { var tx TransactionLog err := parseHeader(r, &tx.Header) if err != nil { return nil, err } for i := 0; i < int(tx.Header.RecordCount); i++ { var record Record err := parseRecord(r, &record) if err != nil { return nil, err } tx.Records = append(tx.Records, record) } return &tx, nil }