tendermint-go-common-0~20170309~0gitdcb015d/0000755000175000017500000000000013060316665020214 5ustar alessioalessiotendermint-go-common-0~20170309~0gitdcb015d/array.go0000644000175000017500000000011713060316665021660 0ustar alessioalessiopackage common func Arr(items ...interface{}) []interface{} { return items } tendermint-go-common-0~20170309~0gitdcb015d/io.go0000644000175000017500000000270713060316665021160 0ustar alessioalessiopackage common import ( "bytes" "errors" "io" ) type PrefixedReader struct { Prefix []byte reader io.Reader } func NewPrefixedReader(prefix []byte, reader io.Reader) *PrefixedReader { return &PrefixedReader{prefix, reader} } func (pr *PrefixedReader) Read(p []byte) (n int, err error) { if len(pr.Prefix) > 0 { read := copy(p, pr.Prefix) pr.Prefix = pr.Prefix[read:] return read, nil } else { return pr.reader.Read(p) } } // NOTE: Not goroutine safe type BufferCloser struct { bytes.Buffer Closed bool } func NewBufferCloser(buf []byte) *BufferCloser { return &BufferCloser{ *bytes.NewBuffer(buf), false, } } func (bc *BufferCloser) Close() error { if bc.Closed { return errors.New("BufferCloser already closed") } bc.Closed = true return nil } func (bc *BufferCloser) Write(p []byte) (n int, err error) { if bc.Closed { return 0, errors.New("Cannot write to closed BufferCloser") } return bc.Buffer.Write(p) } func (bc *BufferCloser) WriteByte(c byte) error { if bc.Closed { return errors.New("Cannot write to closed BufferCloser") } return bc.Buffer.WriteByte(c) } func (bc *BufferCloser) WriteRune(r rune) (n int, err error) { if bc.Closed { return 0, errors.New("Cannot write to closed BufferCloser") } return bc.Buffer.WriteRune(r) } func (bc *BufferCloser) WriteString(s string) (n int, err error) { if bc.Closed { return 0, errors.New("Cannot write to closed BufferCloser") } return bc.Buffer.WriteString(s) } tendermint-go-common-0~20170309~0gitdcb015d/service.go0000644000175000017500000001011313060316665022177 0ustar alessioalessio/* Classical-inheritance-style service declarations. Services can be started, then stopped, then optionally restarted. Users can override the OnStart/OnStop methods. By default, these methods are guaranteed to be called at most once. A call to Reset will panic, unless OnReset is overwritten, allowing OnStart/OnStop to be called again. Caller must ensure that Start() and Stop() are not called concurrently. It is ok to call Stop() without calling Start() first. Services cannot be re-started unless OnReset is overwritten to allow it. Typical usage: type FooService struct { BaseService // private fields } func NewFooService() *FooService { fs := &FooService{ // init } fs.BaseService = *NewBaseService(log, "FooService", fs) return fs } func (fs *FooService) OnStart() error { fs.BaseService.OnStart() // Always call the overridden method. // initialize private fields // start subroutines, etc. } func (fs *FooService) OnStop() error { fs.BaseService.OnStop() // Always call the overridden method. // close/destroy private fields // stop subroutines, etc. } */ package common import ( "sync/atomic" "github.com/tendermint/log15" ) type Service interface { Start() (bool, error) OnStart() error Stop() bool OnStop() Reset() (bool, error) OnReset() error IsRunning() bool String() string } type BaseService struct { log log15.Logger name string started uint32 // atomic stopped uint32 // atomic Quit chan struct{} // The "subclass" of BaseService impl Service } func NewBaseService(log log15.Logger, name string, impl Service) *BaseService { return &BaseService{ log: log, name: name, Quit: make(chan struct{}), impl: impl, } } // Implements Servce func (bs *BaseService) Start() (bool, error) { if atomic.CompareAndSwapUint32(&bs.started, 0, 1) { if atomic.LoadUint32(&bs.stopped) == 1 { if bs.log != nil { bs.log.Warn(Fmt("Not starting %v -- already stopped", bs.name), "impl", bs.impl) } return false, nil } else { if bs.log != nil { bs.log.Info(Fmt("Starting %v", bs.name), "impl", bs.impl) } } err := bs.impl.OnStart() return true, err } else { if bs.log != nil { bs.log.Debug(Fmt("Not starting %v -- already started", bs.name), "impl", bs.impl) } return false, nil } } // Implements Service // NOTE: Do not put anything in here, // that way users don't need to call BaseService.OnStart() func (bs *BaseService) OnStart() error { return nil } // Implements Service func (bs *BaseService) Stop() bool { if atomic.CompareAndSwapUint32(&bs.stopped, 0, 1) { if bs.log != nil { bs.log.Info(Fmt("Stopping %v", bs.name), "impl", bs.impl) } bs.impl.OnStop() close(bs.Quit) return true } else { if bs.log != nil { bs.log.Debug(Fmt("Stopping %v (ignoring: already stopped)", bs.name), "impl", bs.impl) } return false } } // Implements Service // NOTE: Do not put anything in here, // that way users don't need to call BaseService.OnStop() func (bs *BaseService) OnStop() {} // Implements Service func (bs *BaseService) Reset() (bool, error) { if atomic.CompareAndSwapUint32(&bs.stopped, 1, 0) { // whether or not we've started, we can reset atomic.CompareAndSwapUint32(&bs.started, 1, 0) return true, bs.impl.OnReset() } else { if bs.log != nil { bs.log.Debug(Fmt("Can't reset %v. Not stopped", bs.name), "impl", bs.impl) } return false, nil } // never happens return false, nil } // Implements Service func (bs *BaseService) OnReset() error { PanicSanity("The service cannot be reset") return nil } // Implements Service func (bs *BaseService) IsRunning() bool { return atomic.LoadUint32(&bs.started) == 1 && atomic.LoadUint32(&bs.stopped) == 0 } func (bs *BaseService) Wait() { <-bs.Quit } // Implements Servce func (bs *BaseService) String() string { return bs.name } //---------------------------------------- type QuitService struct { BaseService } func NewQuitService(log log15.Logger, name string, impl Service) *QuitService { if log != nil { log.Warn("QuitService is deprecated, use BaseService instead") } return &QuitService{ BaseService: *NewBaseService(log, name, impl), } } tendermint-go-common-0~20170309~0gitdcb015d/bit_array_test.go0000644000175000017500000000667313060316665023572 0ustar alessioalessiopackage common import ( "bytes" "testing" ) func randBitArray(bits int) (*BitArray, []byte) { src := RandBytes((bits + 7) / 8) bA := NewBitArray(bits) for i := 0; i < len(src); i++ { for j := 0; j < 8; j++ { if i*8+j >= bits { return bA, src } setBit := src[i]&(1< 0 bA.SetIndex(i*8+j, setBit) } } return bA, src } func TestAnd(t *testing.T) { bA1, _ := randBitArray(51) bA2, _ := randBitArray(31) bA3 := bA1.And(bA2) if bA3.Bits != 31 { t.Error("Expected min bits", bA3.Bits) } if len(bA3.Elems) != len(bA2.Elems) { t.Error("Expected min elems length") } for i := 0; i < bA3.Bits; i++ { expected := bA1.GetIndex(i) && bA2.GetIndex(i) if bA3.GetIndex(i) != expected { t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i)) } } } func TestOr(t *testing.T) { bA1, _ := randBitArray(51) bA2, _ := randBitArray(31) bA3 := bA1.Or(bA2) if bA3.Bits != 51 { t.Error("Expected max bits") } if len(bA3.Elems) != len(bA1.Elems) { t.Error("Expected max elems length") } for i := 0; i < bA3.Bits; i++ { expected := bA1.GetIndex(i) || bA2.GetIndex(i) if bA3.GetIndex(i) != expected { t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i)) } } } func TestSub1(t *testing.T) { bA1, _ := randBitArray(31) bA2, _ := randBitArray(51) bA3 := bA1.Sub(bA2) if bA3.Bits != bA1.Bits { t.Error("Expected bA1 bits") } if len(bA3.Elems) != len(bA1.Elems) { t.Error("Expected bA1 elems length") } for i := 0; i < bA3.Bits; i++ { expected := bA1.GetIndex(i) if bA2.GetIndex(i) { expected = false } if bA3.GetIndex(i) != expected { t.Error("Wrong bit from bA3", i, bA1.GetIndex(i), bA2.GetIndex(i), bA3.GetIndex(i)) } } } func TestSub2(t *testing.T) { bA1, _ := randBitArray(51) bA2, _ := randBitArray(31) bA3 := bA1.Sub(bA2) if bA3.Bits != bA1.Bits { t.Error("Expected bA1 bits") } if len(bA3.Elems) != len(bA1.Elems) { t.Error("Expected bA1 elems length") } for i := 0; i < bA3.Bits; i++ { expected := bA1.GetIndex(i) if i < bA2.Bits && bA2.GetIndex(i) { expected = false } if bA3.GetIndex(i) != expected { t.Error("Wrong bit from bA3") } } } func TestPickRandom(t *testing.T) { for idx := 0; idx < 123; idx++ { bA1 := NewBitArray(123) bA1.SetIndex(idx, true) index, ok := bA1.PickRandom() if !ok { t.Fatal("Expected to pick element but got none") } if index != idx { t.Fatalf("Expected to pick element at %v but got wrong index", idx) } } } func TestBytes(t *testing.T) { bA := NewBitArray(4) bA.SetIndex(0, true) check := func(bA *BitArray, bz []byte) { if !bytes.Equal(bA.Bytes(), bz) { panic(Fmt("Expected %X but got %X", bz, bA.Bytes())) } } check(bA, []byte{0x01}) bA.SetIndex(3, true) check(bA, []byte{0x09}) bA = NewBitArray(9) check(bA, []byte{0x00, 0x00}) bA.SetIndex(7, true) check(bA, []byte{0x80, 0x00}) bA.SetIndex(8, true) check(bA, []byte{0x80, 0x01}) bA = NewBitArray(16) check(bA, []byte{0x00, 0x00}) bA.SetIndex(7, true) check(bA, []byte{0x80, 0x00}) bA.SetIndex(8, true) check(bA, []byte{0x80, 0x01}) bA.SetIndex(9, true) check(bA, []byte{0x80, 0x03}) } func TestEmptyFull(t *testing.T) { ns := []int{47, 123} for _, n := range ns { bA := NewBitArray(n) if !bA.IsEmpty() { t.Fatal("Expected bit array to be empty") } for i := 0; i < n; i++ { bA.SetIndex(i, true) } if !bA.IsFull() { t.Fatal("Expected bit array to be full") } } } tendermint-go-common-0~20170309~0gitdcb015d/repeat_timer.go0000644000175000017500000000321213060316665023221 0ustar alessioalessiopackage common import ( "sync" "time" ) /* RepeatTimer repeatedly sends a struct{}{} to .Ch after each "dur" period. It's good for keeping connections alive. A RepeatTimer must be Stop()'d or it will keep a goroutine alive. */ type RepeatTimer struct { Ch chan time.Time mtx sync.Mutex name string ticker *time.Ticker quit chan struct{} wg *sync.WaitGroup dur time.Duration } func NewRepeatTimer(name string, dur time.Duration) *RepeatTimer { var t = &RepeatTimer{ Ch: make(chan time.Time), ticker: time.NewTicker(dur), quit: make(chan struct{}), wg: new(sync.WaitGroup), name: name, dur: dur, } t.wg.Add(1) go t.fireRoutine(t.ticker) return t } func (t *RepeatTimer) fireRoutine(ticker *time.Ticker) { for { select { case t_ := <-ticker.C: t.Ch <- t_ case <-t.quit: // needed so we know when we can reset t.quit t.wg.Done() return } } } // Wait the duration again before firing. func (t *RepeatTimer) Reset() { t.Stop() t.mtx.Lock() // Lock defer t.mtx.Unlock() t.ticker = time.NewTicker(t.dur) t.quit = make(chan struct{}) t.wg.Add(1) go t.fireRoutine(t.ticker) } // For ease of .Stop()'ing services before .Start()'ing them, // we ignore .Stop()'s on nil RepeatTimers. func (t *RepeatTimer) Stop() bool { if t == nil { return false } t.mtx.Lock() // Lock defer t.mtx.Unlock() exists := t.ticker != nil if exists { t.ticker.Stop() // does not close the channel select { case <-t.Ch: // read off channel if there's anything there default: } close(t.quit) t.wg.Wait() // must wait for quit to close else we race Reset t.ticker = nil } return exists } tendermint-go-common-0~20170309~0gitdcb015d/LICENSE0000644000175000017500000002503513060316665021226 0ustar alessioalessioTendermint Go-Common Copyright (C) 2015 Tendermint Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. tendermint-go-common-0~20170309~0gitdcb015d/test/0000755000175000017500000000000013060316665021173 5ustar alessioalessiotendermint-go-common-0~20170309~0gitdcb015d/test/mutate.go0000644000175000017500000000117513060316665023025 0ustar alessioalessiopackage test import ( . "github.com/tendermint/go-common" ) // Contract: !bytes.Equal(input, output) && len(input) >= len(output) func MutateByteSlice(bytez []byte) []byte { // If bytez is empty, panic if len(bytez) == 0 { panic("Cannot mutate an empty bytez") } // Copy bytez mBytez := make([]byte, len(bytez)) copy(mBytez, bytez) bytez = mBytez // Try a random mutation switch RandInt() % 2 { case 0: // Mutate a single byte bytez[RandInt()%len(bytez)] += byte(RandInt()%255 + 1) case 1: // Remove an arbitrary byte pos := RandInt() % len(bytez) bytez = append(bytez[:pos], bytez[pos+1:]...) } return bytez } tendermint-go-common-0~20170309~0gitdcb015d/test/assert.go0000644000175000017500000000033113060316665023020 0ustar alessioalessiopackage test import ( "testing" ) func AssertPanics(t *testing.T, msg string, f func()) { defer func() { if err := recover(); err == nil { t.Errorf("Should have panic'd, but didn't: %v", msg) } }() f() } tendermint-go-common-0~20170309~0gitdcb015d/service_test.go0000644000175000017500000000044613060316665023246 0ustar alessioalessiopackage common import ( "testing" ) func TestBaseServiceWait(t *testing.T) { type TestService struct { BaseService } ts := &TestService{} ts.BaseService = *NewBaseService(nil, "TestService", ts) ts.Start() go func() { ts.Stop() }() for i := 0; i < 10; i++ { ts.Wait() } } tendermint-go-common-0~20170309~0gitdcb015d/net.go0000644000175000017500000000046513060316665021336 0ustar alessioalessiopackage common import ( "net" "strings" ) // protoAddr: e.g. "tcp://127.0.0.1:8080" or "unix:///tmp/test.sock" func Connect(protoAddr string) (net.Conn, error) { parts := strings.SplitN(protoAddr, "://", 2) proto, address := parts[0], parts[1] conn, err := net.Dial(proto, address) return conn, err } tendermint-go-common-0~20170309~0gitdcb015d/random.go0000644000175000017500000000510013060316665022017 0ustar alessioalessiopackage common import ( crand "crypto/rand" "math/rand" "time" ) const ( strChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" // 62 characters ) func init() { b := cRandBytes(8) var seed uint64 for i := 0; i < 8; i++ { seed |= uint64(b[i]) seed <<= 8 } rand.Seed(int64(seed)) } // Constructs an alphanumeric string of given length. func RandStr(length int) string { chars := []byte{} MAIN_LOOP: for { val := rand.Int63() for i := 0; i < 10; i++ { v := int(val & 0x3f) // rightmost 6 bits if v >= 62 { // only 62 characters in strChars val >>= 6 continue } else { chars = append(chars, strChars[v]) if len(chars) == length { break MAIN_LOOP } val >>= 6 } } } return string(chars) } func RandUint16() uint16 { return uint16(rand.Uint32() & (1<<16 - 1)) } func RandUint32() uint32 { return rand.Uint32() } func RandUint64() uint64 { return uint64(rand.Uint32())<<32 + uint64(rand.Uint32()) } func RandUint() uint { return uint(rand.Int()) } func RandInt16() int16 { return int16(rand.Uint32() & (1<<16 - 1)) } func RandInt32() int32 { return int32(rand.Uint32()) } func RandInt64() int64 { return int64(rand.Uint32())<<32 + int64(rand.Uint32()) } func RandInt() int { return rand.Int() } // Distributed pseudo-exponentially to test for various cases func RandUint16Exp() uint16 { bits := rand.Uint32() % 16 if bits == 0 { return 0 } n := uint16(1 << (bits - 1)) n += uint16(rand.Int31()) & ((1 << (bits - 1)) - 1) return n } // Distributed pseudo-exponentially to test for various cases func RandUint32Exp() uint32 { bits := rand.Uint32() % 32 if bits == 0 { return 0 } n := uint32(1 << (bits - 1)) n += uint32(rand.Int31()) & ((1 << (bits - 1)) - 1) return n } // Distributed pseudo-exponentially to test for various cases func RandUint64Exp() uint64 { bits := rand.Uint32() % 64 if bits == 0 { return 0 } n := uint64(1 << (bits - 1)) n += uint64(rand.Int63()) & ((1 << (bits - 1)) - 1) return n } func RandFloat32() float32 { return rand.Float32() } func RandTime() time.Time { return time.Unix(int64(RandUint64Exp()), 0) } func RandBytes(n int) []byte { bs := make([]byte, n) for i := 0; i < n; i++ { bs[i] = byte(rand.Intn(256)) } return bs } // NOTE: This relies on the os's random number generator. // For real security, we should salt that with some seed. // See github.com/tendermint/go-crypto for a more secure reader. func cRandBytes(numBytes int) []byte { b := make([]byte, numBytes) _, err := crand.Read(b) if err != nil { PanicCrisis(err) } return b } tendermint-go-common-0~20170309~0gitdcb015d/os.go0000644000175000017500000000715013060316665021167 0ustar alessioalessiopackage common import ( "bufio" "fmt" "io" "io/ioutil" "os" "os/signal" "strings" ) var ( GoPath = os.Getenv("GOPATH") ) func TrapSignal(cb func()) { c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) signal.Notify(c, os.Kill) go func() { for sig := range c { fmt.Printf("captured %v, exiting...\n", sig) if cb != nil { cb() } os.Exit(1) } }() select {} } func Exit(s string) { fmt.Printf(s + "\n") os.Exit(1) } func EnsureDir(dir string, mode os.FileMode) error { if _, err := os.Stat(dir); os.IsNotExist(err) { err := os.MkdirAll(dir, mode) if err != nil { return fmt.Errorf("Could not create directory %v. %v", dir, err) } } return nil } func IsDirEmpty(name string) (bool, error) { f, err := os.Open(name) if err != nil { return true, err //folder is non-existent } defer f.Close() _, err = f.Readdirnames(1) // Or f.Readdir(1) if err == io.EOF { return true, nil } return false, err // Either not empty or error, suits both cases } func FileExists(filePath string) bool { _, err := os.Stat(filePath) return !os.IsNotExist(err) } func ReadFile(filePath string) ([]byte, error) { return ioutil.ReadFile(filePath) } func MustReadFile(filePath string) []byte { fileBytes, err := ioutil.ReadFile(filePath) if err != nil { Exit(Fmt("MustReadFile failed: %v", err)) return nil } return fileBytes } func WriteFile(filePath string, contents []byte, mode os.FileMode) error { err := ioutil.WriteFile(filePath, contents, mode) if err != nil { return err } // fmt.Printf("File written to %v.\n", filePath) return nil } func MustWriteFile(filePath string, contents []byte, mode os.FileMode) { err := WriteFile(filePath, contents, mode) if err != nil { Exit(Fmt("MustWriteFile failed: %v", err)) } } // Writes to newBytes to filePath. // Guaranteed not to lose *both* oldBytes and newBytes, // (assuming that the OS is perfect) func WriteFileAtomic(filePath string, newBytes []byte, mode os.FileMode) error { // If a file already exists there, copy to filePath+".bak" (overwrite anything) if _, err := os.Stat(filePath); !os.IsNotExist(err) { fileBytes, err := ioutil.ReadFile(filePath) if err != nil { return fmt.Errorf("Could not read file %v. %v", filePath, err) } err = ioutil.WriteFile(filePath+".bak", fileBytes, mode) if err != nil { return fmt.Errorf("Could not write file %v. %v", filePath+".bak", err) } } // Write newBytes to filePath.new err := ioutil.WriteFile(filePath+".new", newBytes, mode) if err != nil { return fmt.Errorf("Could not write file %v. %v", filePath+".new", err) } // Move filePath.new to filePath err = os.Rename(filePath+".new", filePath) return err } //-------------------------------------------------------------------------------- func Tempfile(prefix string) (*os.File, string) { file, err := ioutil.TempFile("", prefix) if err != nil { PanicCrisis(err) } return file, file.Name() } func Tempdir(prefix string) (*os.File, string) { tempDir := os.TempDir() + "/" + prefix + RandStr(12) err := EnsureDir(tempDir, 0700) if err != nil { panic(Fmt("Error creating temp dir: %v", err)) } dir, err := os.Open(tempDir) if err != nil { panic(Fmt("Error opening temp dir: %v", err)) } return dir, tempDir } //-------------------------------------------------------------------------------- func Prompt(prompt string, defaultValue string) (string, error) { fmt.Print(prompt) reader := bufio.NewReader(os.Stdin) line, err := reader.ReadString('\n') if err != nil { return defaultValue, err } else { line = strings.TrimSpace(line) if line == "" { return defaultValue, nil } return line, nil } } tendermint-go-common-0~20170309~0gitdcb015d/throttle_timer.go0000644000175000017500000000262713060316665023617 0ustar alessioalessiopackage common import ( "sync" "time" ) /* ThrottleTimer fires an event at most "dur" after each .Set() call. If a short burst of .Set() calls happens, ThrottleTimer fires once. If a long continuous burst of .Set() calls happens, ThrottleTimer fires at most once every "dur". */ type ThrottleTimer struct { Name string Ch chan struct{} quit chan struct{} dur time.Duration mtx sync.Mutex timer *time.Timer isSet bool } func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer { var ch = make(chan struct{}) var quit = make(chan struct{}) var t = &ThrottleTimer{Name: name, Ch: ch, dur: dur, quit: quit} t.mtx.Lock() t.timer = time.AfterFunc(dur, t.fireRoutine) t.mtx.Unlock() t.timer.Stop() return t } func (t *ThrottleTimer) fireRoutine() { t.mtx.Lock() defer t.mtx.Unlock() select { case t.Ch <- struct{}{}: t.isSet = false case <-t.quit: // do nothing default: t.timer.Reset(t.dur) } } func (t *ThrottleTimer) Set() { t.mtx.Lock() defer t.mtx.Unlock() if !t.isSet { t.isSet = true t.timer.Reset(t.dur) } } func (t *ThrottleTimer) Unset() { t.mtx.Lock() defer t.mtx.Unlock() t.isSet = false t.timer.Stop() } // For ease of .Stop()'ing services before .Start()'ing them, // we ignore .Stop()'s on nil ThrottleTimers func (t *ThrottleTimer) Stop() bool { if t == nil { return false } close(t.quit) t.mtx.Lock() defer t.mtx.Unlock() return t.timer.Stop() } tendermint-go-common-0~20170309~0gitdcb015d/word.go0000644000175000017500000000365013060316665021522 0ustar alessioalessiopackage common import ( "bytes" "sort" ) var ( Zero256 = Word256{0} One256 = Word256{1} ) type Word256 [32]byte func (w Word256) String() string { return string(w[:]) } func (w Word256) TrimmedString() string { return TrimmedString(w.Bytes()) } func (w Word256) Copy() Word256 { return w } func (w Word256) Bytes() []byte { return w[:] } // copied. func (w Word256) Prefix(n int) []byte { return w[:n] } func (w Word256) Postfix(n int) []byte { return w[32-n:] } func (w Word256) IsZero() bool { accum := byte(0) for _, byt := range w { accum |= byt } return accum == 0 } func (w Word256) Compare(other Word256) int { return bytes.Compare(w[:], other[:]) } func Uint64ToWord256(i uint64) Word256 { buf := [8]byte{} PutUint64BE(buf[:], i) return LeftPadWord256(buf[:]) } func Int64ToWord256(i int64) Word256 { buf := [8]byte{} PutInt64BE(buf[:], i) return LeftPadWord256(buf[:]) } func RightPadWord256(bz []byte) (word Word256) { copy(word[:], bz) return } func LeftPadWord256(bz []byte) (word Word256) { copy(word[32-len(bz):], bz) return } func Uint64FromWord256(word Word256) uint64 { buf := word.Postfix(8) return GetUint64BE(buf) } func Int64FromWord256(word Word256) int64 { buf := word.Postfix(8) return GetInt64BE(buf) } //------------------------------------- type Tuple256 struct { First Word256 Second Word256 } func (tuple Tuple256) Compare(other Tuple256) int { firstCompare := tuple.First.Compare(other.First) if firstCompare == 0 { return tuple.Second.Compare(other.Second) } else { return firstCompare } } func Tuple256Split(t Tuple256) (Word256, Word256) { return t.First, t.Second } type Tuple256Slice []Tuple256 func (p Tuple256Slice) Len() int { return len(p) } func (p Tuple256Slice) Less(i, j int) bool { return p[i].Compare(p[j]) < 0 } func (p Tuple256Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p Tuple256Slice) Sort() { sort.Sort(p) } tendermint-go-common-0~20170309~0gitdcb015d/errors.go0000644000175000017500000000241213060316665022056 0ustar alessioalessiopackage common import ( "fmt" ) type StackError struct { Err interface{} Stack []byte } func (se StackError) String() string { return fmt.Sprintf("Error: %v\nStack: %s", se.Err, se.Stack) } func (se StackError) Error() string { return se.String() } //-------------------------------------------------------------------------------------------------- // panic wrappers // A panic resulting from a sanity check means there is a programmer error // and some gaurantee is not satisfied. func PanicSanity(v interface{}) { panic(Fmt("Paniced on a Sanity Check: %v", v)) } // A panic here means something has gone horribly wrong, in the form of data corruption or // failure of the operating system. In a correct/healthy system, these should never fire. // If they do, it's indicative of a much more serious problem. func PanicCrisis(v interface{}) { panic(Fmt("Paniced on a Crisis: %v", v)) } // Indicates a failure of consensus. Someone was malicious or something has // gone horribly wrong. These should really boot us into an "emergency-recover" mode func PanicConsensus(v interface{}) { panic(Fmt("Paniced on a Consensus Failure: %v", v)) } // For those times when we're not sure if we should panic func PanicQ(v interface{}) { panic(Fmt("Paniced questionably: %v", v)) } tendermint-go-common-0~20170309~0gitdcb015d/async.go0000644000175000017500000000032313060316665021656 0ustar alessioalessiopackage common import "sync" func Parallel(tasks ...func()) { var wg sync.WaitGroup wg.Add(len(tasks)) for _, task := range tasks { go func(task func()) { task() wg.Done() }(task) } wg.Wait() } tendermint-go-common-0~20170309~0gitdcb015d/math.go0000644000175000017500000000335613060316665021503 0ustar alessioalessiopackage common func MaxInt8(a, b int8) int8 { if a > b { return a } return b } func MaxUint8(a, b uint8) uint8 { if a > b { return a } return b } func MaxInt16(a, b int16) int16 { if a > b { return a } return b } func MaxUint16(a, b uint16) uint16 { if a > b { return a } return b } func MaxInt32(a, b int32) int32 { if a > b { return a } return b } func MaxUint32(a, b uint32) uint32 { if a > b { return a } return b } func MaxInt64(a, b int64) int64 { if a > b { return a } return b } func MaxUint64(a, b uint64) uint64 { if a > b { return a } return b } func MaxInt(a, b int) int { if a > b { return a } return b } func MaxUint(a, b uint) uint { if a > b { return a } return b } //----------------------------------------------------------------------------- func MinInt8(a, b int8) int8 { if a < b { return a } return b } func MinUint8(a, b uint8) uint8 { if a < b { return a } return b } func MinInt16(a, b int16) int16 { if a < b { return a } return b } func MinUint16(a, b uint16) uint16 { if a < b { return a } return b } func MinInt32(a, b int32) int32 { if a < b { return a } return b } func MinUint32(a, b uint32) uint32 { if a < b { return a } return b } func MinInt64(a, b int64) int64 { if a < b { return a } return b } func MinUint64(a, b uint64) uint64 { if a < b { return a } return b } func MinInt(a, b int) int { if a < b { return a } return b } func MinUint(a, b uint) uint { if a < b { return a } return b } //----------------------------------------------------------------------------- func ExpUint64(a, b uint64) uint64 { accum := uint64(1) for b > 0 { if b&1 == 1 { accum *= a } a *= a b >>= 1 } return accum } tendermint-go-common-0~20170309~0gitdcb015d/heap.go0000644000175000017500000000362513060316665021466 0ustar alessioalessiopackage common import ( "container/heap" ) type Comparable interface { Less(o interface{}) bool } //----------------------------------------------------------------------------- /* Example usage: h := NewHeap() h.Push(String("msg1"), 1) h.Push(String("msg3"), 3) h.Push(String("msg2"), 2) fmt.Println(h.Pop()) fmt.Println(h.Pop()) fmt.Println(h.Pop()) */ type Heap struct { pq priorityQueue } func NewHeap() *Heap { return &Heap{pq: make([]*pqItem, 0)} } func (h *Heap) Len() int64 { return int64(len(h.pq)) } func (h *Heap) Push(value interface{}, priority Comparable) { heap.Push(&h.pq, &pqItem{value: value, priority: priority}) } func (h *Heap) Peek() interface{} { if len(h.pq) == 0 { return nil } return h.pq[0].value } func (h *Heap) Update(value interface{}, priority Comparable) { h.pq.Update(h.pq[0], value, priority) } func (h *Heap) Pop() interface{} { item := heap.Pop(&h.pq).(*pqItem) return item.value } //----------------------------------------------------------------------------- /////////////////////// // From: http://golang.org/pkg/container/heap/#example__priorityQueue type pqItem struct { value interface{} priority Comparable index int } type priorityQueue []*pqItem func (pq priorityQueue) Len() int { return len(pq) } func (pq priorityQueue) Less(i, j int) bool { return pq[i].priority.Less(pq[j].priority) } func (pq priorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] pq[i].index = i pq[j].index = j } func (pq *priorityQueue) Push(x interface{}) { n := len(*pq) item := x.(*pqItem) item.index = n *pq = append(*pq, item) } func (pq *priorityQueue) Pop() interface{} { old := *pq n := len(old) item := old[n-1] item.index = -1 // for safety *pq = old[0 : n-1] return item } func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority Comparable) { item.value = value item.priority = priority heap.Fix(pq, item.index) } tendermint-go-common-0~20170309~0gitdcb015d/byteslice.go0000644000175000017500000000133413060316665022527 0ustar alessioalessiopackage common import ( "bytes" ) func Fingerprint(slice []byte) []byte { fingerprint := make([]byte, 6) copy(fingerprint, slice) return fingerprint } func IsZeros(slice []byte) bool { for _, byt := range slice { if byt != byte(0) { return false } } return true } func RightPadBytes(slice []byte, l int) []byte { if l < len(slice) { return slice } padded := make([]byte, l) copy(padded[0:len(slice)], slice) return padded } func LeftPadBytes(slice []byte, l int) []byte { if l < len(slice) { return slice } padded := make([]byte, l) copy(padded[l-len(slice):], slice) return padded } func TrimmedString(b []byte) string { trimSet := string([]byte{0}) return string(bytes.TrimLeft(b, trimSet)) } tendermint-go-common-0~20170309~0gitdcb015d/cmap.go0000644000175000017500000000172113060316665021464 0ustar alessioalessiopackage common import "sync" // CMap is a goroutine-safe map type CMap struct { m map[string]interface{} l sync.Mutex } func NewCMap() *CMap { return &CMap{ m: make(map[string]interface{}, 0), } } func (cm *CMap) Set(key string, value interface{}) { cm.l.Lock() defer cm.l.Unlock() cm.m[key] = value } func (cm *CMap) Get(key string) interface{} { cm.l.Lock() defer cm.l.Unlock() return cm.m[key] } func (cm *CMap) Has(key string) bool { cm.l.Lock() defer cm.l.Unlock() _, ok := cm.m[key] return ok } func (cm *CMap) Delete(key string) { cm.l.Lock() defer cm.l.Unlock() delete(cm.m, key) } func (cm *CMap) Size() int { cm.l.Lock() defer cm.l.Unlock() return len(cm.m) } func (cm *CMap) Clear() { cm.l.Lock() defer cm.l.Unlock() cm.m = make(map[string]interface{}, 0) } func (cm *CMap) Values() []interface{} { cm.l.Lock() defer cm.l.Unlock() items := []interface{}{} for _, v := range cm.m { items = append(items, v) } return items } tendermint-go-common-0~20170309~0gitdcb015d/bit_array.go0000644000175000017500000001411013060316665022514 0ustar alessioalessiopackage common import ( "encoding/binary" "fmt" "math/rand" "strings" "sync" ) type BitArray struct { mtx sync.Mutex Bits int `json:"bits"` // NOTE: persisted via reflect, must be exported Elems []uint64 `json:"elems"` // NOTE: persisted via reflect, must be exported } // There is no BitArray whose Size is 0. Use nil instead. func NewBitArray(bits int) *BitArray { if bits == 0 { return nil } return &BitArray{ Bits: bits, Elems: make([]uint64, (bits+63)/64), } } func (bA *BitArray) Size() int { if bA == nil { return 0 } return bA.Bits } // NOTE: behavior is undefined if i >= bA.Bits func (bA *BitArray) GetIndex(i int) bool { if bA == nil { return false } bA.mtx.Lock() defer bA.mtx.Unlock() return bA.getIndex(i) } func (bA *BitArray) getIndex(i int) bool { if i >= bA.Bits { return false } return bA.Elems[i/64]&(uint64(1)< 0 } // NOTE: behavior is undefined if i >= bA.Bits func (bA *BitArray) SetIndex(i int, v bool) bool { if bA == nil { return false } bA.mtx.Lock() defer bA.mtx.Unlock() return bA.setIndex(i, v) } func (bA *BitArray) setIndex(i int, v bool) bool { if i >= bA.Bits { return false } if v { bA.Elems[i/64] |= (uint64(1) << uint(i%64)) } else { bA.Elems[i/64] &= ^(uint64(1) << uint(i%64)) } return true } func (bA *BitArray) Copy() *BitArray { if bA == nil { return nil } bA.mtx.Lock() defer bA.mtx.Unlock() return bA.copy() } func (bA *BitArray) copy() *BitArray { c := make([]uint64, len(bA.Elems)) copy(c, bA.Elems) return &BitArray{ Bits: bA.Bits, Elems: c, } } func (bA *BitArray) copyBits(bits int) *BitArray { c := make([]uint64, (bits+63)/64) copy(c, bA.Elems) return &BitArray{ Bits: bits, Elems: c, } } // Returns a BitArray of larger bits size. func (bA *BitArray) Or(o *BitArray) *BitArray { if bA == nil { o.Copy() } bA.mtx.Lock() defer bA.mtx.Unlock() c := bA.copyBits(MaxInt(bA.Bits, o.Bits)) for i := 0; i < len(c.Elems); i++ { c.Elems[i] |= o.Elems[i] } return c } // Returns a BitArray of smaller bit size. func (bA *BitArray) And(o *BitArray) *BitArray { if bA == nil { return nil } bA.mtx.Lock() defer bA.mtx.Unlock() return bA.and(o) } func (bA *BitArray) and(o *BitArray) *BitArray { c := bA.copyBits(MinInt(bA.Bits, o.Bits)) for i := 0; i < len(c.Elems); i++ { c.Elems[i] &= o.Elems[i] } return c } func (bA *BitArray) Not() *BitArray { if bA == nil { return nil // Degenerate } bA.mtx.Lock() defer bA.mtx.Unlock() c := bA.copy() for i := 0; i < len(c.Elems); i++ { c.Elems[i] = ^c.Elems[i] } return c } func (bA *BitArray) Sub(o *BitArray) *BitArray { if bA == nil { return nil } bA.mtx.Lock() defer bA.mtx.Unlock() if bA.Bits > o.Bits { c := bA.copy() for i := 0; i < len(o.Elems)-1; i++ { c.Elems[i] &= ^c.Elems[i] } i := len(o.Elems) - 1 if i >= 0 { for idx := i * 64; idx < o.Bits; idx++ { // NOTE: each individual GetIndex() call to o is safe. c.setIndex(idx, c.getIndex(idx) && !o.GetIndex(idx)) } } return c } else { return bA.and(o.Not()) // Note degenerate case where o == nil } } func (bA *BitArray) IsEmpty() bool { if bA == nil { return true // should this be opposite? } bA.mtx.Lock() defer bA.mtx.Unlock() for _, e := range bA.Elems { if e > 0 { return false } } return true } func (bA *BitArray) IsFull() bool { if bA == nil { return true } bA.mtx.Lock() defer bA.mtx.Unlock() // Check all elements except the last for _, elem := range bA.Elems[:len(bA.Elems)-1] { if (^elem) != 0 { return false } } // Check that the last element has (lastElemBits) 1's lastElemBits := (bA.Bits+63)%64 + 1 lastElem := bA.Elems[len(bA.Elems)-1] return (lastElem+1)&((uint64(1)< 0 { randBitStart := rand.Intn(64) for j := 0; j < 64; j++ { bitIdx := ((j + randBitStart) % 64) if (bA.Elems[elemIdx] & (uint64(1) << uint(bitIdx))) > 0 { return 64*elemIdx + bitIdx, true } } PanicSanity("should not happen") } } else { // Special case for last elem, to ignore straggler bits elemBits := bA.Bits % 64 if elemBits == 0 { elemBits = 64 } randBitStart := rand.Intn(elemBits) for j := 0; j < elemBits; j++ { bitIdx := ((j + randBitStart) % elemBits) if (bA.Elems[elemIdx] & (uint64(1) << uint(bitIdx))) > 0 { return 64*elemIdx + bitIdx, true } } } } return 0, false } func (bA *BitArray) String() string { if bA == nil { return "nil-BitArray" } bA.mtx.Lock() defer bA.mtx.Unlock() return bA.stringIndented("") } func (bA *BitArray) StringIndented(indent string) string { if bA == nil { return "nil-BitArray" } bA.mtx.Lock() defer bA.mtx.Unlock() return bA.stringIndented(indent) } func (bA *BitArray) stringIndented(indent string) string { lines := []string{} bits := "" for i := 0; i < bA.Bits; i++ { if bA.getIndex(i) { bits += "X" } else { bits += "_" } if i%100 == 99 { lines = append(lines, bits) bits = "" } if i%10 == 9 { bits += " " } if i%50 == 49 { bits += " " } } if len(bits) > 0 { lines = append(lines, bits) } return fmt.Sprintf("BA{%v:%v}", bA.Bits, strings.Join(lines, indent)) } func (bA *BitArray) Bytes() []byte { bA.mtx.Lock() defer bA.mtx.Unlock() numBytes := (bA.Bits + 7) / 8 bytes := make([]byte, numBytes) for i := 0; i < len(bA.Elems); i++ { elemBytes := [8]byte{} binary.LittleEndian.PutUint64(elemBytes[:], bA.Elems[i]) copy(bytes[i*8:], elemBytes[:]) } return bytes } // NOTE: other bitarray o is not locked when reading, // so if necessary, caller must copy or lock o prior to calling Update. // If bA is nil, does nothing. func (bA *BitArray) Update(o *BitArray) { if bA == nil { return } bA.mtx.Lock() defer bA.mtx.Unlock() copy(bA.Elems, o.Elems) } tendermint-go-common-0~20170309~0gitdcb015d/colors.go0000644000175000017500000000336513060316665022053 0ustar alessioalessiopackage common import ( "fmt" "strings" ) const ( ANSIReset = "\x1b[0m" ANSIBright = "\x1b[1m" ANSIDim = "\x1b[2m" ANSIUnderscore = "\x1b[4m" ANSIBlink = "\x1b[5m" ANSIReverse = "\x1b[7m" ANSIHidden = "\x1b[8m" ANSIFgBlack = "\x1b[30m" ANSIFgRed = "\x1b[31m" ANSIFgGreen = "\x1b[32m" ANSIFgYellow = "\x1b[33m" ANSIFgBlue = "\x1b[34m" ANSIFgMagenta = "\x1b[35m" ANSIFgCyan = "\x1b[36m" ANSIFgWhite = "\x1b[37m" ANSIBgBlack = "\x1b[40m" ANSIBgRed = "\x1b[41m" ANSIBgGreen = "\x1b[42m" ANSIBgYellow = "\x1b[43m" ANSIBgBlue = "\x1b[44m" ANSIBgMagenta = "\x1b[45m" ANSIBgCyan = "\x1b[46m" ANSIBgWhite = "\x1b[47m" ) // color the string s with color 'color' // unless s is already colored func treat(s string, color string) string { if len(s) > 2 && s[:2] == "\x1b[" { return s } else { return color + s + ANSIReset } } func treatAll(color string, args ...interface{}) string { var parts []string for _, arg := range args { parts = append(parts, treat(fmt.Sprintf("%v", arg), color)) } return strings.Join(parts, "") } func Black(args ...interface{}) string { return treatAll(ANSIFgBlack, args...) } func Red(args ...interface{}) string { return treatAll(ANSIFgRed, args...) } func Green(args ...interface{}) string { return treatAll(ANSIFgGreen, args...) } func Yellow(args ...interface{}) string { return treatAll(ANSIFgYellow, args...) } func Blue(args ...interface{}) string { return treatAll(ANSIFgBlue, args...) } func Magenta(args ...interface{}) string { return treatAll(ANSIFgMagenta, args...) } func Cyan(args ...interface{}) string { return treatAll(ANSIFgCyan, args...) } func White(args ...interface{}) string { return treatAll(ANSIFgWhite, args...) } tendermint-go-common-0~20170309~0gitdcb015d/int.go0000644000175000017500000000242713060316665021342 0ustar alessioalessiopackage common import ( "encoding/binary" "sort" ) // Sort for []uint64 type Uint64Slice []uint64 func (p Uint64Slice) Len() int { return len(p) } func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] } func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p Uint64Slice) Sort() { sort.Sort(p) } func SearchUint64s(a []uint64, x uint64) int { return sort.Search(len(a), func(i int) bool { return a[i] >= x }) } func (p Uint64Slice) Search(x uint64) int { return SearchUint64s(p, x) } //-------------------------------------------------------------------------------- func PutUint64LE(dest []byte, i uint64) { binary.LittleEndian.PutUint64(dest, i) } func GetUint64LE(src []byte) uint64 { return binary.LittleEndian.Uint64(src) } func PutUint64BE(dest []byte, i uint64) { binary.BigEndian.PutUint64(dest, i) } func GetUint64BE(src []byte) uint64 { return binary.BigEndian.Uint64(src) } func PutInt64LE(dest []byte, i int64) { binary.LittleEndian.PutUint64(dest, uint64(i)) } func GetInt64LE(src []byte) int64 { return int64(binary.LittleEndian.Uint64(src)) } func PutInt64BE(dest []byte, i int64) { binary.BigEndian.PutUint64(dest, uint64(i)) } func GetInt64BE(src []byte) int64 { return int64(binary.BigEndian.Uint64(src)) } tendermint-go-common-0~20170309~0gitdcb015d/string.go0000644000175000017500000000062313060316665022052 0ustar alessioalessiopackage common import ( "fmt" "strings" ) var Fmt = fmt.Sprintf func RightPadString(s string, totalLength int) string { remaining := totalLength - len(s) if remaining > 0 { s = s + strings.Repeat(" ", remaining) } return s } func LeftPadString(s string, totalLength int) string { remaining := totalLength - len(s) if remaining > 0 { s = strings.Repeat(" ", remaining) + s } return s }