]> Cypherpunks.ru repositories - goredo.git/blobdiff - tai64n.go
Removed hashless mode, small bugfixes, tai64nlocal
[goredo.git] / tai64n.go
index f2b4791f1a58e7d602e6616b9a20379dbebff447..e6dd28e7fd420cc9d3bc7c46b6115823efbe7c39 100644 (file)
--- a/tai64n.go
+++ b/tai64n.go
@@ -1,14 +1,82 @@
+/*
+goredo -- redo implementation on pure Go
+Copyright (C) 2020 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
 package main
 
 import (
+       "bufio"
        "encoding/binary"
+       "encoding/hex"
+       "errors"
+       "io"
+       "strings"
        "time"
 )
 
-type TAI64N [12]byte
+const (
+       TAI64NSize     = 12
+       TAI64NBase     = 0x400000000000000a
+       TAI64NLocalFmt = "2006-01-02 15:04:05.000000000"
+)
+
+type TAI64N [TAI64NSize]byte
 
 func tai64nNow(ts *TAI64N) {
        t := time.Now()
-       binary.BigEndian.PutUint64(ts[:], uint64(0x400000000000000a)+uint64(t.Unix()))
+       binary.BigEndian.PutUint64(ts[:], uint64(TAI64NBase)+uint64(t.Unix()))
        binary.BigEndian.PutUint32(ts[8:], uint32(t.Nanosecond()))
 }
+
+func tai64nLocal(dst io.StringWriter, src io.Reader) error {
+       scanner := bufio.NewScanner(src)
+       var err error
+       var s string
+       var sep int
+       var ts []byte
+       var secs int64
+       var nano int64
+       var t time.Time
+       for {
+               if !scanner.Scan() {
+                       if err = scanner.Err(); err != nil {
+                               return err
+                       }
+                       break
+               }
+               s = scanner.Text()
+
+               if s[0] != '@' {
+                       dst.WriteString(s + "\n")
+               }
+               sep = strings.IndexByte(s, byte(' '))
+               if sep == -1 {
+                       dst.WriteString(s + "\n")
+               }
+               ts, err = hex.DecodeString(s[1:sep])
+               if err != nil {
+                       return err
+               }
+               if len(ts) != TAI64NSize {
+                       return errors.New("invalid ts length")
+               }
+               secs = int64(binary.BigEndian.Uint64(ts[:8]))
+               nano = int64(binary.BigEndian.Uint32(ts[8:]))
+               t = time.Unix(secs-TAI64NBase, nano)
+               dst.WriteString(t.Format(TAI64NLocalFmt) + s[sep:] + "\n")
+       }
+       return nil
+}