<commit_before>package main

import (
	"strconv"
	"strings"
)

type Speech struct {
	manualCode string
	manualName string
	name       string
	number     int
	min        int
	max        int
}

func GetSpeech(manualName string, number int) Speech {
	speech := Speech{}
	speech.number = number
	speech.manualCode = manualName

	manualName = strings.ToLower(manualName)
	switch manualName {
	case "cc":
		speech.manualName = "Competent Communicator"

		switch number {
		case 1:
			speech.name = "Ice Breaker"
			speech.min = 4
			speech.max = 6

		case 2:
			speech.name = "Organize Your Speech"
			speech.min = 5
			speech.max = 7

		case 3:
			speech.name = "Get to the Point"
			speech.min = 5
			speech.max = 7

		case 4:
			speech.name = "How to Say It"
			speech.min = 5
			speech.max = 7

		case 5:
			speech.name = "Your Body Speaks"
			speech.min = 5
			speech.max = 7

		case 6:
			speech.name = "Vocal Variety"
			speech.min = 5
			speech.max = 7

		case 7:
			speech.name = "Research Your Topic"
			speech.min = 5
			speech.max = 7

		case 8:
			speech.name = "Visual Aids"
			speech.min = 5
			speech.max = 7

		case 9:
			speech.name = "Persuade with Power"
			speech.min = 5
			speech.max = 7

		case 10:
			speech.name = "Inspire Your Audience"
			speech.min = 8
			speech.max = 10

		}

	case "inform":
		speech.manualName = "Speaking to Inform"
		switch number {
		case 1:
			speech.name = "The Speech to Inform"
			speech.min = 5
			speech.max = 7

		case 2:
			speech.name = "Resources for Informing"
			speech.min = 5
			speech.max = 7

		case 3:
			speech.name = "The Demonstration Tak"
			speech.min = 5
			speech.max = 7

		case 4:
			speech.name = "A Fact Finding Report"
			speech.min = 5
			speech.max = 7

		case 5:
			speech.name = "The Abstract Concept"
			speech.min = 6
			speech.max = 8
		}

	case "interpretive":
		speech.manualName = "Interpretive Reading"
		switch number {
		case 1:
			speech.name = "Read a Story"
			speech.min = 8
			speech.max = 10

		case 2:
			speech.name = "Interpretive Poetry"
			speech.min = 6
			speech.max = 8

		case 3:
			speech.name = "The Monodrama"
			speech.min = 5
			speech.max = 7

		case 4:
			speech.name = "The Play"
			speech.min = 12
			speech.max = 15

		case 5:
			speech.name = "The Oratorical Speech"
			speech.min = 8
			speech.max = 10
		}
	case "mgt":
		speech.manualName = "Speeches by Management "
		switch number {
		case 1:
			speech.name = "The Briefing"
			speech.min = 8
			speech.max = 10

		case 2:
			speech.name = "The Technical Speech"
			speech.min = 8
			speech.max = 10

		case 3:
			speech.name = "Manage and Motivate"
			speech.min = 10
			speech.max = 12

		case 4:
			speech.name = "The Status Report"
			speech.min = 10
			speech.max = 12

		case 5:
			speech.name = "Confrontation"
			speech.min = 5
			speech.max = 15
		}

	case "technical":
		speech.manualName = "Technical Presentations"
		switch number {
		case 1:
			speech.name = "Technical Briefing"
			speech.min = 8
			speech.max = 10

		case 2:
			speech.name = "The Proposal (Add Q&A TIME!!!!)"
			speech.min = 8
			speech.max = 10

		case 3:
			speech.name = "The Nontechnical Audience"
			speech.min = 10
			speech.max = 12

		case 4:
			speech.name = "Presenting a Technical Paper"
			speech.min = 10
			speech.max = 12

		case 5:
			speech.name = "The Team Technical Presentation"
			speech.min = 20
			speech.max = 30
		}
	case "storytelling":
		speech.manualName = "Storytelling"
		switch number {
		case 1:
			speech.name = "The Folk Tale"
			speech.min = 7
			speech.max = 9

		case 2:
			speech.name = "Let's Get Personal"
			speech.min = 6
			speech.max = 8

		case 3:
			speech.name = "The Moral of the Story"
			speech.min = 4
			speech.max = 6

		case 4:
			speech.name = "The Touching Story"
			speech.min = 6
			speech.max = 8

		case 5:
			speech.name = "Bringing History to Life"
			speech.min = 7
			speech.max = 9
		}
	}

	speech.name = "#" + strconv.Itoa(speech.number) + " " + speech.name +
		" " + "(" + strconv.Itoa(speech.min) + "-" + strconv.Itoa(speech.max) + " mins)"
	return speech
}
<commit_msg>Condensed the initialization of Speech.<commit_after>package main

import (
	"strconv"
	"strings"
)

type Speech struct {
	manualCode string
	manualName string
	name       string
	number     int
	min        int
	max        int
}

func GetSpeech(manualName string, number int) Speech {
	speech := Speech{number: number, manualCode: manualName}

	switch strings.ToLower(manualName) {
	case "cc":
		speech.manualName = "Competent Communicator"

		switch number {
		case 1:
			speech.name = "Ice Breaker"
			speech.min = 4
			speech.max = 6

		case 2:
			speech.name = "Organize Your Speech"
			speech.min = 5
			speech.max = 7

		case 3:
			speech.name = "Get to the Point"
			speech.min = 5
			speech.max = 7

		case 4:
			speech.name = "How to Say It"
			speech.min = 5
			speech.max = 7

		case 5:
			speech.name = "Your Body Speaks"
			speech.min = 5
			speech.max = 7

		case 6:
			speech.name = "Vocal Variety"
			speech.min = 5
			speech.max = 7

		case 7:
			speech.name = "Research Your Topic"
			speech.min = 5
			speech.max = 7

		case 8:
			speech.name = "Visual Aids"
			speech.min = 5
			speech.max = 7

		case 9:
			speech.name = "Persuade with Power"
			speech.min = 5
			speech.max = 7

		case 10:
			speech.name = "Inspire Your Audience"
			speech.min = 8
			speech.max = 10

		}

	case "inform":
		speech.manualName = "Speaking to Inform"
		switch number {
		case 1:
			speech.name = "The Speech to Inform"
			speech.min = 5
			speech.max = 7

		case 2:
			speech.name = "Resources for Informing"
			speech.min = 5
			speech.max = 7

		case 3:
			speech.name = "The Demonstration Tak"
			speech.min = 5
			speech.max = 7

		case 4:
			speech.name = "A Fact Finding Report"
			speech.min = 5
			speech.max = 7

		case 5:
			speech.name = "The Abstract Concept"
			speech.min = 6
			speech.max = 8
		}

	case "interpretive":
		speech.manualName = "Interpretive Reading"
		switch number {
		case 1:
			speech.name = "Read a Story"
			speech.min = 8
			speech.max = 10

		case 2:
			speech.name = "Interpretive Poetry"
			speech.min = 6
			speech.max = 8

		case 3:
			speech.name = "The Monodrama"
			speech.min = 5
			speech.max = 7

		case 4:
			speech.name = "The Play"
			speech.min = 12
			speech.max = 15

		case 5:
			speech.name = "The Oratorical Speech"
			speech.min = 8
			speech.max = 10
		}
	case "mgt":
		speech.manualName = "Speeches by Management "
		switch number {
		case 1:
			speech.name = "The Briefing"
			speech.min = 8
			speech.max = 10

		case 2:
			speech.name = "The Technical Speech"
			speech.min = 8
			speech.max = 10

		case 3:
			speech.name = "Manage and Motivate"
			speech.min = 10
			speech.max = 12

		case 4:
			speech.name = "The Status Report"
			speech.min = 10
			speech.max = 12

		case 5:
			speech.name = "Confrontation"
			speech.min = 5
			speech.max = 15
		}

	case "technical":
		speech.manualName = "Technical Presentations"
		switch number {
		case 1:
			speech.name = "Technical Briefing"
			speech.min = 8
			speech.max = 10

		case 2:
			speech.name = "The Proposal (Add Q&A TIME!!!!)"
			speech.min = 8
			speech.max = 10

		case 3:
			speech.name = "The Nontechnical Audience"
			speech.min = 10
			speech.max = 12

		case 4:
			speech.name = "Presenting a Technical Paper"
			speech.min = 10
			speech.max = 12

		case 5:
			speech.name = "The Team Technical Presentation"
			speech.min = 20
			speech.max = 30
		}
	case "storytelling":
		speech.manualName = "Storytelling"
		switch number {
		case 1:
			speech.name = "The Folk Tale"
			speech.min = 7
			speech.max = 9

		case 2:
			speech.name = "Let's Get Personal"
			speech.min = 6
			speech.max = 8

		case 3:
			speech.name = "The Moral of the Story"
			speech.min = 4
			speech.max = 6

		case 4:
			speech.name = "The Touching Story"
			speech.min = 6
			speech.max = 8

		case 5:
			speech.name = "Bringing History to Life"
			speech.min = 7
			speech.max = 9
		}
	}

	speech.name = "#" + strconv.Itoa(speech.number) + " " + speech.name +
		" " + "(" + strconv.Itoa(speech.min) + "-" + strconv.Itoa(speech.max) + " mins)"
	return speech
}
<|endoftext|>


<commit_before>package main

// see http://safecurves.cr.yp.to/
// see https://github.com/vsergeev/btckeygenie
// see https://godoc.org/github.com/decred/dcrd/dcrec/secp256k1

import (
  "github.com/coin-network/curve"

  "golang.org/x/crypto/ripemd160"

  "crypto/rand"
  "crypto/ecdsa"
	"crypto/elliptic"
	//"encoding/base64"
	"fmt"
  "bytes"
  "crypto/sha256"
  "math/big"
  "strings"
)

// TODO: :NOTUSE:
const (
	pubkeyCompressed   byte = 0x2 // y_bit + x coord
	pubkeyUncompressed byte = 0x4 // x coord + y coord
	pubkeyHybrid       byte = 0x6 // y_bit + x coord + y coord
)

type PublicKey ecdsa.PublicKey
type PrivateKey ecdsa.PrivateKey

// GenerateKey generate PublicKey/PrivateKey from KoblitzCurve
func GenerateKey(koblitzcurve curve.KoblitzCurve) (*PrivateKey, error) {

  //privkeyCurve := new(ecdsa.PrivateKey)
  privkeyCurve, err := ecdsa.GenerateKey(koblitzcurve, rand.Reader)

	if err != nil {
		return nil, err
	}
	return (*PrivateKey)(privkeyCurve), nil
}

/* Decompress decompresses coordinate x and ylsb (y's least significant bit)
and returns the value of y
source: https://github.com/btcsuite/btcd/blob/807d344fe97072efdf38ac3df053e07f26187a4f/btcec/pubkey.go#L27 */
func (curve *KoblitzCurve) Decompress(x *big.Int, ybit bool) (*big.Int, error) {
  // TODO: This will probably only work for secp256k1 due to
	// optimizations.

	// Y = +-sqrt(x^3 + B)
	x3 := new(big.Int).Mul(x, x)
	x3.Mul(x3, x)
	x3.Add(x3, curve.Params().B)

	// now calculate sqrt mod p of x2 + B
	// This code used to do a full sqrt based on tonelli/shanks,
	// but this was replaced by the algorithms referenced in
	// https://bitcointalk.org/index.php?topic=162805.msg1712294#msg1712294
	y := new(big.Int).Exp(x3, curve.QPlus1Div4(), curve.Params().P)

	if ybit != isOdd(y) {
		y.Sub(curve.Params().P, y)
	}
	if ybit != isOdd(y) {
		return nil, fmt.Errorf("ybit doesn't match oddness")
	}

  // TODO: It is necessary to verify with IsOnCurve(x, y) or ParsePubKey ?

	return y, nil  // TODO return struct Point (x, y)
}

/* ---------------- */

/* ---- PublicKey ---- */
  // converts a public key to an uncompressed address string.
  func (pub *PublicKey) ToAddressUncompressed() (address string) {

  	/* Convert the public key to bytes */
  	pub_bytes := pub.ToBytesUncompressed()

  	/* SHA256 Hash */
  	sha256_h := sha256.New()
  	sha256_h.Reset()
  	sha256_h.Write(pub_bytes)
  	pub_hash_1 := sha256_h.Sum(nil)

  	/* RIPEMD-160 Hash */
  	ripemd160_h := ripemd160.New()
  	ripemd160_h.Reset()
  	ripemd160_h.Write(pub_hash_1)
  	pub_hash_2 := ripemd160_h.Sum(nil)

  	/* Convert hash bytes to base58 check encoded sequence */
  	address = b58checkencode(0x00, pub_hash_2)

  	return address
  }
  // converts a public key to a compressed address string.
  func (pub *PublicKey) ToAddress() (address string) {
  	/* See https://en.bitcoin.it/w/images/en/9/9b/PubKeyToAddr.png */

  	/* Convert the public key to bytes */
  	pub_bytes := pub.ToBytes()

  	/* SHA256 Hash */
  	sha256_h := sha256.New()
  	sha256_h.Reset()
  	sha256_h.Write(pub_bytes)
  	pub_hash_1 := sha256_h.Sum(nil)

  	/* RIPEMD-160 Hash */
  	ripemd160_h := ripemd160.New()
  	ripemd160_h.Reset()
  	ripemd160_h.Write(pub_hash_1)
  	pub_hash_2 := ripemd160_h.Sum(nil)

  	/* Convert hash bytes to base58 check encoded sequence */
  	address = b58checkencode(0x00, pub_hash_2)

  	return address
  }
  // converts a public key to a 33-byte byte slice with point compression.
  func (pub *PublicKey) ToBytes() (b []byte) {
  	/* See Certicom SEC1 2.3.3, pg. 10 */

  	x := pub.X.Bytes()

  	/* Pad X to 32-bytes */
  	padded_x := append(bytes.Repeat([]byte{0x00}, 32-len(x)), x...)

  	/* Add prefix 0x02 or 0x03 depending on ylsb */
  	if pub.Y.Bit(0) == 0 {
  		return append([]byte{0x02}, padded_x...)
  	}

  	return append([]byte{0x03}, padded_x...)
  }
  // converts a public key to a 65-byte byte slice without point compression.
  func (pub *PublicKey) ToBytesUncompressed() (b []byte) {
  	/* See Certicom SEC1 2.3.3, pg. 10 */

  	x := pub.X.Bytes()
  	y := pub.Y.Bytes()

  	/* Pad X and Y coordinate bytes to 32-bytes */
  	padded_x := append(bytes.Repeat([]byte{0x00}, 32-len(x)), x...)
  	padded_y := append(bytes.Repeat([]byte{0x00}, 32-len(y)), y...)

  	/* Add prefix 0x04 for uncompressed coordinates */
  	return append([]byte{0x04}, append(padded_x, padded_y...)...)
  }
  // TODO: :NOTUSE: converts a byte slice (either with or without point compression) to a public key.
  func (pub *PublicKey) FromBytes(koblitzcurve curve.KoblitzCurve, b []byte) (err error) {
  	/* See Certicom SEC1 2.3.4, pg. 11 */

  	if len(b) < 33 {
  		return fmt.Errorf("Invalid public key bytes length %d, expected at least 33.", len(b))
  	}

  	if b[0] == 0x02 || b[0] == 0x03 {
  		/* Compressed public key */

  		if len(b) != 33 {
  			return fmt.Errorf("Invalid public key bytes length %d, expected 33.", len(b))
  		}

      // TODO: TEST
      pub.X = new(big.Int).SetBytes(b[1:33])

      if uint(b[0]&0x1) == true {
        ybit := true
      }else{
        ybit := false
      }

  		Y, err := koblitzcurve.Decompress(new(big.Int).SetBytes(b[1:33]), ybit)

  		if err != nil {
  			return fmt.Errorf("Invalid compressed public key bytes, decompression error: %v", err)
  		}

  		pub.Y = Y

  	} else if b[0] == 0x04 {
  		/* Uncompressed public key */

  		if len(b) != 65 {
  			return fmt.Errorf("Invalid public key bytes length %d, expected 65.", len(b))
  		}

  		pub.X = new(big.Int).SetBytes(b[1:33])
  		pub.Y = new(big.Int).SetBytes(b[33:65])

  		/* ??? Check that the point is on the curve */
  		if !elliptic.IsOnCurve(pub.X, pub.Y) {
  			return fmt.Errorf("Invalid public key bytes: point not on curve.")
  		}

  	} else {
  		return fmt.Errorf("Invalid public key prefix byte 0x%02x, expected 0x02, 0x03, or 0x04.", b[0])
  	}

  	return nil
  }
/* -------------------- */

/* ---- PrivateKey ---- */

  // converts a Bitcoin private key to a 32-byte byte slice.
  func (priv *PrivateKey) ToBytes() (b []byte) {
    d := priv.D.Bytes()

    /* Pad D to 32 bytes */
    padded_d := append(bytes.Repeat([]byte{0x00}, 32-len(d)), d...)

    return padded_d
  }
  // FIXME converts a 32-byte byte slice to a Bitcoin private key and derives the corresponding public key.
  func (priv *PrivateKey) FromBytes(b []byte) (err error) {

    if len(b) != 32 {
      return fmt.Errorf("Invalid private key bytes length %d, expected 32.", len(b))
    }

    priv.D = new(big.Int).SetBytes(b)

    /* Public returns the public key corresponding to priv.  */
    priv.Public() // TODO: ?? priv.derive() see: https://github.com/vsergeev/btckeygenie/blob/master/btckey/btckey.go#L48

    return nil
  }
  // converts a Bitcoin private key to a Wallet Import Format string.
  func (priv *PrivateKey) ToWIF() (wif string) {
    /* See https://en.bitcoin.it/wiki/Wallet_import_format */

    /* Convert the private key to bytes */
    priv_bytes := priv.ToBytes()

    /* Convert bytes to base-58 check encoded string with version 0x80 */
    wif = b58checkencode(0x80, priv_bytes)

    return wif
  }
  // converts a private key to a Wallet Import Format string with the public key compressed flag.
  func (priv *PrivateKey) ToWIFC() (wifc string) {
    /* See https://en.bitcoin.it/wiki/Wallet_import_format */

    /* Convert the private key to bytes */
    priv_bytes := priv.ToBytes()

    /* Append 0x01 to tell Bitcoin wallet to use compressed public keys */
    priv_bytes = append(priv_bytes, []byte{0x01}...)

    /* Convert bytes to base-58 check encoded string with version 0x80 */
    wifc = b58checkencode(0x80, priv_bytes)

    return wifc
  }
  // FIXME converts a Wallet Import Format string to a Bitcoin private key and derives the corresponding public key.
  func (priv *PrivateKey) FromWIF(wif string) (err error) {
    /* See https://en.bitcoin.it/wiki/Wallet_import_format */

    /* Base58 Check Decode the WIF string */
    ver, priv_bytes, err := b58checkdecode(wif)
    if err != nil {
      return err
    }

    /* Check that the version byte is 0x80 */
    if ver != 0x80 {
      return fmt.Errorf("Invalid WIF version 0x%02x, expected 0x80.", ver)
    }

    /* If the private key bytes length is 33, check that suffix byte is 0x01 (for compression) and strip it off */
    if len(priv_bytes) == 33 {
      if priv_bytes[len(priv_bytes)-1] != 0x01 {
        return fmt.Errorf("Invalid private key, unknown suffix byte 0x%02x.", priv_bytes[len(priv_bytes)-1])
      }
      priv_bytes = priv_bytes[0:32]
    }

    /* Convert from bytes to a private key */
    err = priv.FromBytes(priv_bytes)
    if err != nil {
      return err
    }

    /* Derive public key from private key */
    priv.Public() // TODO: ?? priv.derive() see: https://github.com/vsergeev/btckeygenie/blob/master/btckey/btckey.go#L48

    return nil
  }
/* -------------------- */

/* ---- Function ---- */

func isOdd(a *big.Int) bool {
	return a.Bit(0) == 1
}

// encodes a byte slice b into a base-58 encoded string
func b58encode(b []byte) (s string) {
	/* See https://en.bitcoin.it/wiki/Base58Check_encoding */

	const BASE58_TABLE = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

	/* Convert big endian bytes to big int */
	x := new(big.Int).SetBytes(b)

	/* Initialize */
	r := new(big.Int)
	m := big.NewInt(58)
	zero := big.NewInt(0)
	s = ""

	/* Convert big int to string */
	for x.Cmp(zero) > 0 {
		/* x, r = (x / 58, x % 58) */
		x.QuoRem(x, m, r)
		/* Prepend ASCII character */
		s = string(BASE58_TABLE[r.Int64()]) + s
	}

	return s
}

// decodes a base-58 encoded string into a byte slice b.
func b58decode(s string) (b []byte, err error) {
	/* See https://en.bitcoin.it/wiki/Base58Check_encoding */

	const BASE58_TABLE = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

	/* Initialize */
	x := big.NewInt(0)
	m := big.NewInt(58)

	/* Convert string to big int */
	for i := 0; i < len(s); i++ {
		b58index := strings.IndexByte(BASE58_TABLE, s[i])
		if b58index == -1 {
			return nil, fmt.Errorf("Invalid base-58 character encountered: '%c', index %d.", s[i], i)
		}
		b58value := big.NewInt(int64(b58index))
		x.Mul(x, m)
		x.Add(x, b58value)
	}

	/* Convert big int to big endian bytes */
	b = x.Bytes()

	return b, nil
}

// encodes version ver and byte slice b into a base-58 check encoded string.
func b58checkencode(ver uint8, b []byte) (s string) {
	/* Prepend version */
	bcpy := append([]byte{ver}, b...)

	/* Create a new SHA256 context */
	sha256_h := sha256.New()

	/* SHA256 Hash #1 */
	sha256_h.Reset()
	sha256_h.Write(bcpy)
	hash1 := sha256_h.Sum(nil)

	/* SHA256 Hash #2 */
	sha256_h.Reset()
	sha256_h.Write(hash1)
	hash2 := sha256_h.Sum(nil)

	/* Append first four bytes of hash */
	bcpy = append(bcpy, hash2[0:4]...)

	/* Encode base58 string */
	s = b58encode(bcpy)

	/* For number of leading 0's in bytes, prepend 1 */
	for _, v := range bcpy {
		if v != 0 {
			break
		}
		s = "1" + s
	}

	return s
}

// decodes base-58 check encoded string s into a version ver and byte slice b.
func b58checkdecode(s string) (ver uint8, b []byte, err error) {
	/* Decode base58 string */
	b, err = b58decode(s)
	if err != nil {
		return 0, nil, err
	}

	/* Add leading zero bytes */
	for i := 0; i < len(s); i++ {
		if s[i] != '1' {
			break
		}
		b = append([]byte{0x00}, b...)
	}

	/* Verify checksum */
	if len(b) < 5 {
		return 0, nil, fmt.Errorf("Invalid base-58 check string: missing checksum.")
	}

	/* Create a new SHA256 context */
	sha256_h := sha256.New()

	/* SHA256 Hash #1 */
	sha256_h.Reset()
	sha256_h.Write(b[:len(b)-4])
	hash1 := sha256_h.Sum(nil)

	/* SHA256 Hash #2 */
	sha256_h.Reset()
	sha256_h.Write(hash1)
	hash2 := sha256_h.Sum(nil)

	/* Compare checksum */
	if bytes.Compare(hash2[0:4], b[len(b)-4:]) != 0 {
		return 0, nil, fmt.Errorf("Invalid base-58 check string: invalid checksum.")
	}

	/* Strip checksum bytes */
	b = b[:len(b)-4]

	/* Extract and strip version */
	ver = b[0]
	b = b[1:]

	return ver, b, nil
}

// checks that string wif is a valid Wallet Import Format or Wallet Import Format Compressed string. If it is not, err is populated with the reason.
func CheckWIF(wif string) (valid bool, err error) {
	/* See https://en.bitcoin.it/wiki/Wallet_import_format */

	/* Base58 Check Decode the WIF string */
	ver, priv_bytes, err := b58checkdecode(wif)
	if err != nil {
		return false, err
	}

	/* Check that the version byte is 0x80 */
	if ver != 0x80 {
		return false, fmt.Errorf("Invalid WIF version 0x%02x, expected 0x80.", ver)
	}

	/* Check that private key bytes length is 32 or 33 */
	if len(priv_bytes) != 32 && len(priv_bytes) != 33 {
		return false, fmt.Errorf("Invalid private key bytes length %d, expected 32 or 33.", len(priv_bytes))
	}

	/* If the private key bytes length is 33, check that suffix byte is 0x01 (for compression) */
	if len(priv_bytes) == 33 && priv_bytes[len(priv_bytes)-1] != 0x01 {
		return false, fmt.Errorf("Invalid private key bytes, unknown suffix byte 0x%02x.", priv_bytes[len(priv_bytes)-1])
	}

	return true, nil
}

func main() {

  KoblitzCurve := curve.S256() // see https://godoc.org/github.com/btcsuite/btcd/btcec#S256

  privkey, err := GenerateKey(KoblitzCurve)

  if err != nil {
		panic("Error")
	}

  fmt.Println(" Private Key ")
  fmt.Println(privkey.D)

  fmt.Println(" Public Key ")
  pubkey := (privkey.PublicKey)
  fmt.Println(pubkey.X)
  fmt.Println(pubkey.Y)

  fmt.Println(privkey.ToAddress())

  fmt.Println("-------")
}
<commit_msg>Migrate functions to (github.com/coin-network/curve)<commit_after>package main

// see http://safecurves.cr.yp.to/
// see https://github.com/vsergeev/btckeygenie
// see https://godoc.org/github.com/decred/dcrd/dcrec/secp256k1

import (
  "github.com/coin-network/curve"
  "crypto/rand"
  "crypto/ecdsa"
	"crypto/elliptic"
	"fmt"
)

type PrivateKey ecdsa.PrivateKey

func main() {

  KoblitzCurve := curve.S256() // see https://godoc.org/github.com/btcsuite/btcd/btcec#S256

  privkey, err := curve.NewPrivateKey(KoblitzCurve)

  if err != nil {
		panic("Error")
	}

  fmt.Println(" Private Key ")
  fmt.Println(privkey.D)

  fmt.Println(" Public Key ")
  pubkey := (privkey.PublicKey)
  fmt.Println(pubkey.X)
  fmt.Println(pubkey.Y)

  fmt.Println("-------")
}
<|endoftext|>


<commit_before>// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.

// Package gcfg provides reading, caching and managing for configuration.
package gcfg

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/gogf/gf/os/gcmd"
	"github.com/gogf/gf/text/gstr"

	"github.com/gogf/gf/os/gres"

	"github.com/gogf/gf/container/garray"
	"github.com/gogf/gf/container/gmap"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gfsnotify"
	"github.com/gogf/gf/os/glog"
	"github.com/gogf/gf/os/gspath"
)

const (
	DefaultConfigFile = "config.toml" // The default configuration file name.
	cmdEnvKey         = "gf.gcfg"     // Configuration key for command argument or environment.
)

// Configuration struct.
type Config struct {
	name  string           // Default configuration file name.
	paths *garray.StrArray // Searching path array.
	jsons *gmap.StrAnyMap  // The pared JSON objects for configuration files.
	vc    bool             // Whether do violence check in value index searching. It affects the performance when set true(false in default).
}

var (
	supportedFileTypes = []string{"toml", "yaml", "json", "ini", "xml"}
	resourceTryFiles   = []string{"", "/", "config/", "config", "/config", "/config/"}
)

// New returns a new configuration management object.
// The parameter <file> specifies the default configuration file name for reading.
func New(file ...string) *Config {
	name := DefaultConfigFile
	if len(file) > 0 {
		name = file[0]
	} else {
		// Custom default configuration file name from command line or environment.
		if customFile := gcmd.GetWithEnv(fmt.Sprintf("%s.file", cmdEnvKey)).String(); customFile != "" {
			name = customFile
		}
	}
	c := &Config{
		name:  name,
		paths: garray.NewStrArray(true),
		jsons: gmap.NewStrAnyMap(true),
	}
	// Customized dir path from env/cmd.
	if customPath := gcmd.GetWithEnv(fmt.Sprintf("%s.path", cmdEnvKey)).String(); customPath != "" {
		if gfile.Exists(customPath) {
			_ = c.SetPath(customPath)
		} else {
			if errorPrint() {
				glog.Errorf("Configuration directory path does not exist: %s", customPath)
			}
		}
	} else {
		// Dir path of working dir.
		_ = c.SetPath(gfile.Pwd())
		// Dir path of binary.
		if selfPath := gfile.SelfDir(); selfPath != "" && gfile.Exists(selfPath) {
			_ = c.AddPath(selfPath)
		}
		// Dir path of main package.
		if mainPath := gfile.MainPkgPath(); mainPath != "" && gfile.Exists(mainPath) {
			_ = c.AddPath(mainPath)
		}
	}
	return c
}

// filePath returns the absolute configuration file path for the given filename by <file>.
func (c *Config) filePath(file ...string) (path string) {
	name := c.name
	if len(file) > 0 {
		name = file[0]
	}
	path = c.FilePath(name)
	if path == "" {
		buffer := bytes.NewBuffer(nil)
		if c.paths.Len() > 0 {
			buffer.WriteString(fmt.Sprintf("[gcfg] cannot find config file \"%s\" in following paths:", name))
			c.paths.RLockFunc(func(array []string) {
				index := 1
				for _, v := range array {
					v = gstr.TrimRight(v, `\/`)
					buffer.WriteString(fmt.Sprintf("\n%d. %s", index, v))
					index++
					buffer.WriteString(fmt.Sprintf("\n%d. %s", index, v+gfile.Separator+"config"))
					index++
				}
			})
		} else {
			buffer.WriteString(fmt.Sprintf("[gcfg] cannot find config file \"%s\" with no path set/add", name))
		}
		if errorPrint() {
			glog.Error(buffer.String())
		}
	}
	return path
}

// SetPath sets the configuration directory path for file search.
// The parameter <path> can be absolute or relative path,
// but absolute path is strongly recommended.
func (c *Config) SetPath(path string) error {
	var (
		isDir    = false
		realPath = ""
	)
	if file := gres.Get(path); file != nil {
		realPath = path
		isDir = file.FileInfo().IsDir()
	} else {
		// Absolute path.
		realPath = gfile.RealPath(path)
		if realPath == "" {
			// Relative path.
			c.paths.RLockFunc(func(array []string) {
				for _, v := range array {
					if path, _ := gspath.Search(v, path); path != "" {
						realPath = path
						break
					}
				}
			})
		}
		if realPath != "" {
			isDir = gfile.IsDir(realPath)
		}
	}
	// Path not exist.
	if realPath == "" {
		buffer := bytes.NewBuffer(nil)
		if c.paths.Len() > 0 {
			buffer.WriteString(fmt.Sprintf("[gcfg] SetPath failed: cannot find directory \"%s\" in following paths:", path))
			c.paths.RLockFunc(func(array []string) {
				for k, v := range array {
					buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v))
				}
			})
		} else {
			buffer.WriteString(fmt.Sprintf(`[gcfg] SetPath failed: path "%s" does not exist`, path))
		}
		err := errors.New(buffer.String())
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	// Should be a directory.
	if !isDir {
		err := fmt.Errorf(`[gcfg] SetPath failed: path "%s" should be directory type`, path)
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	// Repeated path check.
	if c.paths.Search(realPath) != -1 {
		return nil
	}
	c.jsons.Clear()
	c.paths.Clear()
	c.paths.Append(realPath)
	return nil
}

// SetViolenceCheck sets whether to perform hierarchical conflict checking.
// This feature needs to be enabled when there is a level symbol in the key name.
// It is off in default.
//
// Note that, turning on this feature is quite expensive, and it is not recommended
// to allow separators in the key names. It is best to avoid this on the application side.
func (c *Config) SetViolenceCheck(check bool) {
	c.vc = check
	c.Clear()
}

// AddPath adds a absolute or relative path to the search paths.
func (c *Config) AddPath(path string) error {
	var (
		isDir    = false
		realPath = ""
	)
	// It firstly checks the resource manager,
	// and then checks the filesystem for the path.
	if file := gres.Get(path); file != nil {
		realPath = path
		isDir = file.FileInfo().IsDir()
	} else {
		// Absolute path.
		realPath = gfile.RealPath(path)
		if realPath == "" {
			// Relative path.
			c.paths.RLockFunc(func(array []string) {
				for _, v := range array {
					if path, _ := gspath.Search(v, path); path != "" {
						realPath = path
						break
					}
				}
			})
		}
		if realPath != "" {
			isDir = gfile.IsDir(realPath)
		}
	}
	if realPath == "" {
		buffer := bytes.NewBuffer(nil)
		if c.paths.Len() > 0 {
			buffer.WriteString(fmt.Sprintf("[gcfg] AddPath failed: cannot find directory \"%s\" in following paths:", path))
			c.paths.RLockFunc(func(array []string) {
				for k, v := range array {
					buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v))
				}
			})
		} else {
			buffer.WriteString(fmt.Sprintf(`[gcfg] AddPath failed: path "%s" does not exist`, path))
		}
		err := errors.New(buffer.String())
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	if !isDir {
		err := fmt.Errorf(`[gcfg] AddPath failed: path "%s" should be directory type`, path)
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	// Repeated path check.
	if c.paths.Search(realPath) != -1 {
		return nil
	}
	c.paths.Append(realPath)
	//glog.Debug("[gcfg] AddPath:", realPath)
	return nil
}

// GetFilePath returns the absolute path of the specified configuration file.
// If <file> is not passed, it returns the configuration file path of the default name.
// If the specified configuration file does not exist,
// an empty string is returned.
func (c *Config) FilePath(file ...string) (path string) {
	name := c.name
	if len(file) > 0 {
		name = file[0]
	}
	// Searching resource manager.
	if !gres.IsEmpty() {
		for _, v := range resourceTryFiles {
			if file := gres.Get(v + name); file != nil {
				path = file.Name()
				return
			}
		}
		c.paths.RLockFunc(func(array []string) {
			for _, prefix := range array {
				for _, v := range resourceTryFiles {
					if file := gres.Get(prefix + v + name); file != nil {
						path = file.Name()
						return
					}
				}
			}
		})
	}
	// Searching the file system.
	c.paths.RLockFunc(func(array []string) {
		for _, prefix := range array {
			prefix = gstr.TrimRight(prefix, `\/`)
			if path, _ = gspath.Search(prefix, name); path != "" {
				return
			}
			if path, _ = gspath.Search(prefix+gfile.Separator+"config", name); path != "" {
				return
			}
		}
	})
	return
}

// SetFileName sets the default configuration file name.
func (c *Config) SetFileName(name string) *Config {
	c.name = name
	return c
}

// GetFileName returns the default configuration file name.
func (c *Config) GetFileName() string {
	return c.name
}

// Available checks and returns whether configuration of given <file> is available.
func (c *Config) Available(file ...string) bool {
	var name string
	if len(file) > 0 && file[0] != "" {
		name = file[0]
	} else {
		name = c.name
	}
	if c.FilePath(name) != "" {
		return true
	}
	if GetContent(name) != "" {
		return true
	}
	return false
}

// getJson returns a *gjson.Json object for the specified <file> content.
// It would print error if file reading fails. It return nil if any error occurs.
func (c *Config) getJson(file ...string) *gjson.Json {
	var name string
	if len(file) > 0 && file[0] != "" {
		name = file[0]
	} else {
		name = c.name
	}
	r := c.jsons.GetOrSetFuncLock(name, func() interface{} {
		var (
			content  = ""
			filePath = ""
		)
		// The configured content can be any kind of data type different from its file type.
		isFromConfigContent := true
		if content = GetContent(name); content == "" {
			isFromConfigContent = false
			filePath = c.filePath(name)
			if filePath == "" {
				return nil
			}
			if file := gres.Get(filePath); file != nil {
				content = string(file.Content())
			} else {
				content = gfile.GetContents(filePath)
			}
		}
		// Note that the underlying configuration json object operations are concurrent safe.
		var (
			j   *gjson.Json
			err error
		)
		dataType := gfile.ExtName(name)
		if gjson.IsValidDataType(dataType) && !isFromConfigContent {
			j, err = gjson.LoadContentType(dataType, content, true)
		} else {
			j, err = gjson.LoadContent(content, true)
		}
		if err == nil {
			j.SetViolenceCheck(c.vc)
			// Add monitor for this configuration file,
			// any changes of this file will refresh its cache in Config object.
			if filePath != "" && !gres.Contains(filePath) {
				_, err = gfsnotify.Add(filePath, func(event *gfsnotify.Event) {
					c.jsons.Remove(name)
				})
				if err != nil && errorPrint() {
					glog.Error(err)
				}
			}
			return j
		} else {
			if errorPrint() {
				if filePath != "" {
					glog.Criticalf(`[gcfg] Load config file "%s" failed: %s`, filePath, err.Error())
				} else {
					glog.Criticalf(`[gcfg] Load configuration failed: %s`, err.Error())
				}
			}
		}
		return nil
	})
	if r != nil {
		return r.(*gjson.Json)
	}
	return nil
}
<commit_msg>fix issue in resource searching for package gcfg<commit_after>// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.

// Package gcfg provides reading, caching and managing for configuration.
package gcfg

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/gogf/gf/os/gcmd"
	"github.com/gogf/gf/text/gstr"

	"github.com/gogf/gf/os/gres"

	"github.com/gogf/gf/container/garray"
	"github.com/gogf/gf/container/gmap"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gfsnotify"
	"github.com/gogf/gf/os/glog"
	"github.com/gogf/gf/os/gspath"
)

const (
	DefaultConfigFile = "config.toml" // The default configuration file name.
	cmdEnvKey         = "gf.gcfg"     // Configuration key for command argument or environment.
)

// Configuration struct.
type Config struct {
	name  string           // Default configuration file name.
	paths *garray.StrArray // Searching path array.
	jsons *gmap.StrAnyMap  // The pared JSON objects for configuration files.
	vc    bool             // Whether do violence check in value index searching. It affects the performance when set true(false in default).
}

var (
	supportedFileTypes = []string{"toml", "yaml", "json", "ini", "xml"}
	resourceTryFiles   = []string{"", "/", "config/", "config", "/config", "/config/"}
)

// New returns a new configuration management object.
// The parameter <file> specifies the default configuration file name for reading.
func New(file ...string) *Config {
	name := DefaultConfigFile
	if len(file) > 0 {
		name = file[0]
	} else {
		// Custom default configuration file name from command line or environment.
		if customFile := gcmd.GetWithEnv(fmt.Sprintf("%s.file", cmdEnvKey)).String(); customFile != "" {
			name = customFile
		}
	}
	c := &Config{
		name:  name,
		paths: garray.NewStrArray(true),
		jsons: gmap.NewStrAnyMap(true),
	}
	// Customized dir path from env/cmd.
	if customPath := gcmd.GetWithEnv(fmt.Sprintf("%s.path", cmdEnvKey)).String(); customPath != "" {
		if gfile.Exists(customPath) {
			_ = c.SetPath(customPath)
		} else {
			if errorPrint() {
				glog.Errorf("Configuration directory path does not exist: %s", customPath)
			}
		}
	} else {
		// Dir path of working dir.
		_ = c.SetPath(gfile.Pwd())
		// Dir path of binary.
		if selfPath := gfile.SelfDir(); selfPath != "" && gfile.Exists(selfPath) {
			_ = c.AddPath(selfPath)
		}
		// Dir path of main package.
		if mainPath := gfile.MainPkgPath(); mainPath != "" && gfile.Exists(mainPath) {
			_ = c.AddPath(mainPath)
		}
	}
	return c
}

// filePath returns the absolute configuration file path for the given filename by <file>.
func (c *Config) filePath(file ...string) (path string) {
	name := c.name
	if len(file) > 0 {
		name = file[0]
	}
	path = c.FilePath(name)
	if path == "" {
		buffer := bytes.NewBuffer(nil)
		if c.paths.Len() > 0 {
			buffer.WriteString(fmt.Sprintf("[gcfg] cannot find config file \"%s\" in following paths:", name))
			c.paths.RLockFunc(func(array []string) {
				index := 1
				for _, v := range array {
					v = gstr.TrimRight(v, `\/`)
					buffer.WriteString(fmt.Sprintf("\n%d. %s", index, v))
					index++
					buffer.WriteString(fmt.Sprintf("\n%d. %s", index, v+gfile.Separator+"config"))
					index++
				}
			})
		} else {
			buffer.WriteString(fmt.Sprintf("[gcfg] cannot find config file \"%s\" with no path set/add", name))
		}
		if errorPrint() {
			glog.Error(buffer.String())
		}
	}
	return path
}

// SetPath sets the configuration directory path for file search.
// The parameter <path> can be absolute or relative path,
// but absolute path is strongly recommended.
func (c *Config) SetPath(path string) error {
	var (
		isDir    = false
		realPath = ""
	)
	if file := gres.Get(path); file != nil {
		realPath = path
		isDir = file.FileInfo().IsDir()
	} else {
		// Absolute path.
		realPath = gfile.RealPath(path)
		if realPath == "" {
			// Relative path.
			c.paths.RLockFunc(func(array []string) {
				for _, v := range array {
					if path, _ := gspath.Search(v, path); path != "" {
						realPath = path
						break
					}
				}
			})
		}
		if realPath != "" {
			isDir = gfile.IsDir(realPath)
		}
	}
	// Path not exist.
	if realPath == "" {
		buffer := bytes.NewBuffer(nil)
		if c.paths.Len() > 0 {
			buffer.WriteString(fmt.Sprintf("[gcfg] SetPath failed: cannot find directory \"%s\" in following paths:", path))
			c.paths.RLockFunc(func(array []string) {
				for k, v := range array {
					buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v))
				}
			})
		} else {
			buffer.WriteString(fmt.Sprintf(`[gcfg] SetPath failed: path "%s" does not exist`, path))
		}
		err := errors.New(buffer.String())
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	// Should be a directory.
	if !isDir {
		err := fmt.Errorf(`[gcfg] SetPath failed: path "%s" should be directory type`, path)
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	// Repeated path check.
	if c.paths.Search(realPath) != -1 {
		return nil
	}
	c.jsons.Clear()
	c.paths.Clear()
	c.paths.Append(realPath)
	return nil
}

// SetViolenceCheck sets whether to perform hierarchical conflict checking.
// This feature needs to be enabled when there is a level symbol in the key name.
// It is off in default.
//
// Note that, turning on this feature is quite expensive, and it is not recommended
// to allow separators in the key names. It is best to avoid this on the application side.
func (c *Config) SetViolenceCheck(check bool) {
	c.vc = check
	c.Clear()
}

// AddPath adds a absolute or relative path to the search paths.
func (c *Config) AddPath(path string) error {
	var (
		isDir    = false
		realPath = ""
	)
	// It firstly checks the resource manager,
	// and then checks the filesystem for the path.
	if file := gres.Get(path); file != nil {
		realPath = path
		isDir = file.FileInfo().IsDir()
	} else {
		// Absolute path.
		realPath = gfile.RealPath(path)
		if realPath == "" {
			// Relative path.
			c.paths.RLockFunc(func(array []string) {
				for _, v := range array {
					if path, _ := gspath.Search(v, path); path != "" {
						realPath = path
						break
					}
				}
			})
		}
		if realPath != "" {
			isDir = gfile.IsDir(realPath)
		}
	}
	if realPath == "" {
		buffer := bytes.NewBuffer(nil)
		if c.paths.Len() > 0 {
			buffer.WriteString(fmt.Sprintf("[gcfg] AddPath failed: cannot find directory \"%s\" in following paths:", path))
			c.paths.RLockFunc(func(array []string) {
				for k, v := range array {
					buffer.WriteString(fmt.Sprintf("\n%d. %s", k+1, v))
				}
			})
		} else {
			buffer.WriteString(fmt.Sprintf(`[gcfg] AddPath failed: path "%s" does not exist`, path))
		}
		err := errors.New(buffer.String())
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	if !isDir {
		err := fmt.Errorf(`[gcfg] AddPath failed: path "%s" should be directory type`, path)
		if errorPrint() {
			glog.Error(err)
		}
		return err
	}
	// Repeated path check.
	if c.paths.Search(realPath) != -1 {
		return nil
	}
	c.paths.Append(realPath)
	//glog.Debug("[gcfg] AddPath:", realPath)
	return nil
}

// GetFilePath returns the absolute path of the specified configuration file.
// If <file> is not passed, it returns the configuration file path of the default name.
// If the specified configuration file does not exist,
// an empty string is returned.
func (c *Config) FilePath(file ...string) (path string) {
	name := c.name
	if len(file) > 0 {
		name = file[0]
	}
	// Searching resource manager.
	if !gres.IsEmpty() {
		for _, v := range resourceTryFiles {
			if file := gres.Get(v + name); file != nil {
				path = file.Name()
				return
			}
		}
		c.paths.RLockFunc(func(array []string) {
			for _, prefix := range array {
				for _, v := range resourceTryFiles {
					if file := gres.Get(prefix + v + name); file != nil {
						path = file.Name()
						return
					}
				}
			}
		})
	}
	// Already found?
	if path != "" {
		return
	}
	// Searching the file system.
	c.paths.RLockFunc(func(array []string) {
		for _, prefix := range array {
			prefix = gstr.TrimRight(prefix, `\/`)
			if path, _ = gspath.Search(prefix, name); path != "" {
				return
			}
			if path, _ = gspath.Search(prefix+gfile.Separator+"config", name); path != "" {
				return
			}
		}
	})
	return
}

// SetFileName sets the default configuration file name.
func (c *Config) SetFileName(name string) *Config {
	c.name = name
	return c
}

// GetFileName returns the default configuration file name.
func (c *Config) GetFileName() string {
	return c.name
}

// Available checks and returns whether configuration of given <file> is available.
func (c *Config) Available(file ...string) bool {
	var name string
	if len(file) > 0 && file[0] != "" {
		name = file[0]
	} else {
		name = c.name
	}
	if c.FilePath(name) != "" {
		return true
	}
	if GetContent(name) != "" {
		return true
	}
	return false
}

// getJson returns a *gjson.Json object for the specified <file> content.
// It would print error if file reading fails. It return nil if any error occurs.
func (c *Config) getJson(file ...string) *gjson.Json {
	var name string
	if len(file) > 0 && file[0] != "" {
		name = file[0]
	} else {
		name = c.name
	}
	r := c.jsons.GetOrSetFuncLock(name, func() interface{} {
		var (
			content  = ""
			filePath = ""
		)
		// The configured content can be any kind of data type different from its file type.
		isFromConfigContent := true
		if content = GetContent(name); content == "" {
			isFromConfigContent = false
			filePath = c.filePath(name)
			if filePath == "" {
				return nil
			}
			if file := gres.Get(filePath); file != nil {
				content = string(file.Content())
			} else {
				content = gfile.GetContents(filePath)
			}
		}
		// Note that the underlying configuration json object operations are concurrent safe.
		var (
			j   *gjson.Json
			err error
		)
		dataType := gfile.ExtName(name)
		if gjson.IsValidDataType(dataType) && !isFromConfigContent {
			j, err = gjson.LoadContentType(dataType, content, true)
		} else {
			j, err = gjson.LoadContent(content, true)
		}
		if err == nil {
			j.SetViolenceCheck(c.vc)
			// Add monitor for this configuration file,
			// any changes of this file will refresh its cache in Config object.
			if filePath != "" && !gres.Contains(filePath) {
				_, err = gfsnotify.Add(filePath, func(event *gfsnotify.Event) {
					c.jsons.Remove(name)
				})
				if err != nil && errorPrint() {
					glog.Error(err)
				}
			}
			return j
		} else {
			if errorPrint() {
				if filePath != "" {
					glog.Criticalf(`[gcfg] Load config file "%s" failed: %s`, filePath, err.Error())
				} else {
					glog.Criticalf(`[gcfg] Load configuration failed: %s`, err.Error())
				}
			}
		}
		return nil
	})
	if r != nil {
		return r.(*gjson.Json)
	}
	return nil
}
<|endoftext|>


<commit_before>package u6

import (
	"bytes"
	"fmt"
	"os/exec"

	"github.com/shurcooL/go/exp/13"
	"github.com/shurcooL/go/pipe_util"
	"github.com/shurcooL/go/vcs"
	"gopkg.in/pipe.v2"

	. "github.com/shurcooL/go/gists/gist5892738"
	. "github.com/shurcooL/go/gists/gist7480523"
)

// Show the difference between the working directory and the most recent commit.
// Precondition is that goPackage.Dir.Repo is not nil, and VcsLocal is updated.
// TODO: Support for non-git.
func GoPackageWorkingDiff(goPackage *GoPackage) string {
	// git diff
	if goPackage.Dir.Repo.VcsLocal.Status != "" {
		switch goPackage.Dir.Repo.Vcs.Type() {
		case vcs.Git:
			newFileDiff := func(line []byte) []byte {
				cmd := exec.Command("git", "diff", "--no-ext-diff", "--", "/dev/null", TrimLastNewline(string(line)))
				cmd.Dir = goPackage.Dir.Repo.Vcs.RootPath()
				out, err := cmd.Output()
				if err != nil && len(out) == 0 {
					return []byte(err.Error())
				}
				return out
			}

			p := pipe.Script(
				pipe.Exec("git", "diff", "--no-ext-diff", "HEAD"),
				pipe.Line(
					pipe.Exec("git", "ls-files", "--others", "--exclude-standard"),
					pipe.Replace(newFileDiff),
				),
			)

			out, err := pipe_util.OutputDir(p, goPackage.Dir.Repo.Vcs.RootPath())
			if err != nil {
				return err.Error()
			}
			return string(out)
		}
	}
	return ""
}

// Branches returns a Markdown table of branches with ahead/behind information relative to master branch.
func Branches(repo *exp13.VcsState) string {
	switch repo.Vcs.Type() {
	case vcs.Git:
		branchInfo := func(line []byte) []byte {
			branch := TrimLastNewline(string(line))

			cmd := exec.Command("git", "rev-list", "--count", "--left-right", "master..."+branch)
			cmd.Dir = repo.Vcs.RootPath()
			out, err := cmd.Output()
			if err != nil && len(out) == 0 {
				return []byte(err.Error())
			}

			behindAhead := bytes.Split(out, []byte("\t"))

			if branch == repo.VcsLocal.LocalBranch {
				return []byte(fmt.Sprintf("**%s** | %s | %s", branch, string(behindAhead[0]), string(behindAhead[1])))
			} else {
				return []byte(fmt.Sprintf("%s | %s | %s", branch, string(behindAhead[0]), string(behindAhead[1])))
			}
		}

		p := pipe.Script(
			pipe.Println("Branch | Behind | Ahead"),
			pipe.Println("-------|-------:|:-----"),
			pipe.Line(
				pipe.Exec("git", "for-each-ref", "--format=%(refname:short)", "refs/heads"),
				pipe.Replace(branchInfo),
			),
		)

		out, err := pipe_util.OutputDir(p, repo.Vcs.RootPath())
		if err != nil {
			return err.Error()
		}
		return string(out)
	default:
		return ""
	}
}
<commit_msg>Add BranchesRemote and improve Branches.<commit_after>package u6

import (
	"fmt"
	"os/exec"
	"strings"

	"github.com/shurcooL/go/exp/13"
	"github.com/shurcooL/go/pipe_util"
	"github.com/shurcooL/go/vcs"
	"gopkg.in/pipe.v2"

	. "github.com/shurcooL/go/gists/gist5892738"
	. "github.com/shurcooL/go/gists/gist7480523"
)

// Show the difference between the working directory and the most recent commit.
// Precondition is that goPackage.Dir.Repo is not nil, and VcsLocal is updated.
// TODO: Support for non-git.
func GoPackageWorkingDiff(goPackage *GoPackage) string {
	// git diff
	if goPackage.Dir.Repo.VcsLocal.Status != "" {
		switch goPackage.Dir.Repo.Vcs.Type() {
		case vcs.Git:
			newFileDiff := func(line []byte) []byte {
				cmd := exec.Command("git", "diff", "--no-ext-diff", "--", "/dev/null", TrimLastNewline(string(line)))
				cmd.Dir = goPackage.Dir.Repo.Vcs.RootPath()
				out, err := cmd.Output()
				if len(out) > 0 {
					// diff exits with a non-zero status when the files don't match.
					// Ignore that failure as long as we get output.
					err = nil
				}
				if err != nil {
					return []byte(err.Error())
				}
				return out
			}

			p := pipe.Script(
				pipe.Exec("git", "diff", "--no-ext-diff", "HEAD"),
				pipe.Line(
					pipe.Exec("git", "ls-files", "--others", "--exclude-standard"),
					pipe.Replace(newFileDiff),
				),
			)

			out, err := pipe_util.OutputDir(p, goPackage.Dir.Repo.Vcs.RootPath())
			if err != nil {
				return err.Error()
			}
			return string(out)
		}
	}
	return ""
}

// Branches returns a Markdown table of branches with ahead/behind information relative to master branch.
func Branches(repo *exp13.VcsState) string {
	switch repo.Vcs.Type() {
	case vcs.Git:
		branchInfo := func(line []byte) []byte {
			branch := TrimLastNewline(string(line))

			cmd := exec.Command("git", "rev-list", "--count", "--left-right", "master..."+branch)
			cmd.Dir = repo.Vcs.RootPath()
			out, err := cmd.Output()
			if err != nil {
				return []byte(err.Error())
			}

			behindAhead := strings.Split(TrimLastNewline(string(out)), "\t")

			if branch == repo.VcsLocal.LocalBranch {
				return []byte(fmt.Sprintf("**%s** | %s | %s\n", branch, behindAhead[0], behindAhead[1]))
			} else {
				return []byte(fmt.Sprintf("%s | %s | %s\n", branch, behindAhead[0], behindAhead[1]))
			}
		}

		p := pipe.Script(
			pipe.Println("Branch | Behind | Ahead"),
			pipe.Println("-------|-------:|:-----"),
			pipe.Line(
				pipe.Exec("git", "for-each-ref", "--format=%(refname:short)", "refs/heads"),
				pipe.Replace(branchInfo),
			),
		)

		out, err := pipe_util.OutputDir(p, repo.Vcs.RootPath())
		if err != nil {
			return err.Error()
		}
		return string(out)
	default:
		return ""
	}
}

// Branches returns a Markdown table of branches with ahead/behind information relative to upstream.
func BranchesRemote(repo *exp13.VcsState) string {
	switch repo.Vcs.Type() {
	case vcs.Git:
		branchInfo := func(line []byte) []byte {
			branchUpstream := strings.Split(TrimLastNewline(string(line)), "\t")
			if len(branchUpstream) != 2 {
				return []byte("error: len(branchUpstream) != 2")
			}

			branch := branchUpstream[0]
			upstream := branchUpstream[1]
			if upstream == "" {
				return []byte(fmt.Sprintf("%s | | | \n", branch))
			}

			cmd := exec.Command("git", "rev-list", "--count", "--left-right", upstream+"..."+branch)
			cmd.Dir = repo.Vcs.RootPath()
			out, err := cmd.Output()
			if err != nil {
				return []byte(err.Error())
			}

			behindAhead := strings.Split(TrimLastNewline(string(out)), "\t")

			if branch == repo.VcsLocal.LocalBranch {
				return []byte(fmt.Sprintf("**%s** | %s | %s | %s\n", branch, upstream, behindAhead[0], behindAhead[1]))
			} else {
				return []byte(fmt.Sprintf("%s | %s | %s | %s\n", branch, upstream, behindAhead[0], behindAhead[1]))
			}
		}

		p := pipe.Script(
			pipe.Println("Branch | Upstream | Behind | Ahead"),
			pipe.Println("-------|----------|-------:|:-----"),
			pipe.Line(
				pipe.Exec("git", "for-each-ref", "--format=%(refname:short)\t%(upstream:short)", "refs/heads"),
				pipe.Replace(branchInfo),
			),
		)

		out, err := pipe_util.OutputDir(p, repo.Vcs.RootPath())
		if err != nil {
			return err.Error()
		}
		return string(out)
	default:
		return ""
	}
}
<|endoftext|>


<commit_before>package gameboy

import (
	"fmt"
	"io"
	"sdl"
	"os"
	"os/signal"
)

type Config struct {
	SaveDir string
	Verbose bool
	Debug   bool
}

func Start(path string, cfg Config, quit chan int) (err interface{}) {
	var rom romImage
	rom, err = loadROM(path)
	if err != nil {
		return
	}

	if cfg.Verbose {
		rom.printInfo()
	}

	if sdl.Init(sdl.INIT_VIDEO) != 0 {
		err = sdl.GetError()
		return
	}

	var mem *memory
	mem, err = newMemory(rom)
	if err != nil {
		return
	}

	if e := mem.load(cfg.SaveDir); e != nil {
		fmt.Fprintf(os.Stderr, "load failed: %v\n", e)
	}

	sys := newCPU(mem)
	lcd := newDisplay(mem)

	go func() {
		run(&cfg, sys, lcd)
		if e := mem.save(cfg.SaveDir); e != nil {
			fmt.Fprintf(os.Stderr, "save failed: %v\n", e)
		}
		quit <- 1
	}()
	return
}

func run(cfg *Config, sys *cpu, lcd *display) {
	defer sdl.Quit()
	defer func() {
		if e := recover(); e != nil {
			if cfg.Debug {
				fmt.Fprintf(os.Stderr, "panic: %v\n\n", e)
				sys.dump(os.Stderr)
				fmt.Fprint(os.Stderr, "RUNTIME TRACE\n\n")
			}
			panic(e)
		}
	}()

	t := 0
	for {
		if sig, ok := <-signal.Incoming; ok {
			if cfg.Verbose {
				fmt.Printf("\nReceived %v, cleaning up\n", sig)
			}
			break
		}
		var s int
		for s = 0; s < 10; s += sys.step() {
		}
		lcd.step(s)
		t += s
	}
	if cfg.Debug {
		sys.dump(os.Stderr)
		fmt.Printf("total ticks: %d\n", t)
		fmt.Printf("%v\n", sys)
	}
}

func (rom romImage) printInfo() {
	fmt.Printf("Loaded ROM image '%s'\n", rom.title())
	fmt.Printf("Logo match: %t\n", rom.checkLogo())
	fmt.Printf("Header checksum: %t\n", rom.doHeaderChecksum())
	fmt.Printf("Global checksum: %t\n", rom.doGlobalChecksum())
	fmt.Printf("ERAM: %d bytes\n", rom.ramSize())
	if mbc, err := rom.mbcType(); err == nil {
		fmt.Printf("MBC: %d\n", mbc)
	}
}

func (sys *cpu) dump(w io.Writer) {
	fmt.Fprintf(w,
		"LAST INSTRUCTION\n"+
			"%04X\t%s\n\n"+
			"CPU STATE\n"+
			"%v\n\n",
		sys.mar, sys.disasm(sys.mar), sys)
	sys.dumpStack(w)
	sys.traceback(w)
	sys.memory.dump(w)
}
<commit_msg>Do not dump state at normal exit<commit_after>package gameboy

import (
	"fmt"
	"io"
	"sdl"
	"os"
	"os/signal"
)

type Config struct {
	SaveDir string
	Verbose bool
	Debug   bool
}

func Start(path string, cfg Config, quit chan int) (err interface{}) {
	var rom romImage
	rom, err = loadROM(path)
	if err != nil {
		return
	}

	if cfg.Verbose {
		rom.printInfo()
	}

	if sdl.Init(sdl.INIT_VIDEO) != 0 {
		err = sdl.GetError()
		return
	}

	var mem *memory
	mem, err = newMemory(rom)
	if err != nil {
		return
	}

	if e := mem.load(cfg.SaveDir); e != nil {
		fmt.Fprintf(os.Stderr, "load failed: %v\n", e)
	}

	sys := newCPU(mem)
	lcd := newDisplay(mem)

	go func() {
		run(&cfg, sys, lcd)
		if e := mem.save(cfg.SaveDir); e != nil {
			fmt.Fprintf(os.Stderr, "save failed: %v\n", e)
		}
		quit <- 1
	}()
	return
}

func run(cfg *Config, sys *cpu, lcd *display) {
	defer sdl.Quit()
	defer func() {
		if e := recover(); e != nil {
			if cfg.Debug {
				fmt.Fprintf(os.Stderr, "panic: %v\n\n", e)
				sys.dump(os.Stderr)
				fmt.Fprint(os.Stderr, "RUNTIME TRACE\n\n")
			}
			panic(e)
		}
	}()

	t := 0
	for {
		if sig, ok := <-signal.Incoming; ok {
			if cfg.Verbose {
				fmt.Printf("\nReceived %v, cleaning up\n", sig)
			}
			break
		}
		var s int
		for s = 0; s < 10; s += sys.step() {
		}
		lcd.step(s)
		t += s
	}
	if cfg.Debug {
		fmt.Printf("total ticks: %d\n", t)
		fmt.Printf("%v\n", sys)
	}
}

func (rom romImage) printInfo() {
	fmt.Printf("Loaded ROM image '%s'\n", rom.title())
	fmt.Printf("Logo match: %t\n", rom.checkLogo())
	fmt.Printf("Header checksum: %t\n", rom.doHeaderChecksum())
	fmt.Printf("Global checksum: %t\n", rom.doGlobalChecksum())
	fmt.Printf("ERAM: %d bytes\n", rom.ramSize())
	if mbc, err := rom.mbcType(); err == nil {
		fmt.Printf("MBC: %d\n", mbc)
	}
}

func (sys *cpu) dump(w io.Writer) {
	fmt.Fprintf(w,
		"LAST INSTRUCTION\n"+
			"%04X\t%s\n\n"+
			"CPU STATE\n"+
			"%v\n\n",
		sys.mar, sys.disasm(sys.mar), sys)
	sys.dumpStack(w)
	sys.traceback(w)
	sys.memory.dump(w)
}
<|endoftext|>


<commit_before><commit_msg>Change snake body<commit_after><|endoftext|>


<commit_before>// +build darwin freebsd dragonfly netbsd openbsd linux

package reuseport

import (
	"net"
	"os"
	"strconv"
	"syscall"
	"time"

	sockaddrnet "github.com/jbenet/go-sockaddr/net"
)

const (
	filePrefix = "port."
)

// Wrapper around the socket system call that marks the returned file
// descriptor as nonblocking and close-on-exec.
func socket(family, socktype, protocol int) (fd int, err error) {
	syscall.ForkLock.RLock()
	fd, err = syscall.Socket(family, socktype, protocol)
	if err == nil {
		syscall.CloseOnExec(fd)
	}
	syscall.ForkLock.RUnlock()

	if err != nil {
		return -1, err
	}

	// set non-blocking until after connect, because we cant poll using runtime :(
	// if err = syscall.SetNonblock(fd, true); err != nil {
	// 	syscall.Close(fd)
	// 	return -1, err
	// }

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReuseAddr, 1); err != nil {
		// fmt.Println("reuse addr failed")
		syscall.Close(fd)
		return -1, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReusePort, 1); err != nil {
		// fmt.Println("reuse port failed")
		syscall.Close(fd)
		return -1, err
	}

	// set setLinger to 5 as reusing exact same (srcip:srcport, dstip:dstport)
	// will otherwise fail on connect.
	if err = setLinger(fd, 5); err != nil {
		// fmt.Println("linger failed")
		syscall.Close(fd)
		return -1, err
	}

	return fd, nil
}

func dial(dialer net.Dialer, netw, addr string) (c net.Conn, err error) {
	var (
		fd             int
		lfamily        int
		rfamily        int
		socktype       int
		lprotocol      int
		rprotocol      int
		file           *os.File
		remoteSockaddr syscall.Sockaddr
		localSockaddr  syscall.Sockaddr
	)

	netAddr, err := ResolveAddr(netw, addr)
	if err != nil {
		// fmt.Println("resolve addr failed")
		return nil, err
	}

	switch netAddr.(type) {
	case *net.TCPAddr, *net.UDPAddr:
	default:
		return nil, ErrUnsupportedProtocol
	}

	localSockaddr = sockaddrnet.NetAddrToSockaddr(dialer.LocalAddr)
	remoteSockaddr = sockaddrnet.NetAddrToSockaddr(netAddr)

	rfamily = sockaddrnet.NetAddrAF(netAddr)
	rprotocol = sockaddrnet.NetAddrIPPROTO(netAddr)
	socktype = sockaddrnet.NetAddrSOCK(netAddr)

	if dialer.LocalAddr != nil {
		switch dialer.LocalAddr.(type) {
		case *net.TCPAddr, *net.UDPAddr:
		default:
			return nil, ErrUnsupportedProtocol
		}

		// check family and protocols match.
		lfamily = sockaddrnet.NetAddrAF(dialer.LocalAddr)
		lprotocol = sockaddrnet.NetAddrIPPROTO(dialer.LocalAddr)
		if lfamily != rfamily && lprotocol != rfamily {
			return nil, &net.AddrError{Err: "unexpected address type", Addr: netAddr.String()}
		}
	}

	// look at dialTCP in http://golang.org/src/net/tcpsock_posix.go  .... !
	// here we just try again 3 times.
	for i := 0; i < 3; i++ {
		if fd, err = socket(rfamily, socktype, rprotocol); err != nil {
			return nil, err
		}

		if err = syscall.Bind(fd, localSockaddr); err != nil {
			// fmt.Println("bind failed")
			syscall.Close(fd)
			return nil, err
		}
		if err = connect(fd, remoteSockaddr); err != nil {
			syscall.Close(fd)
			// fmt.Println("connect failed", localSockaddr, err)
			continue // try again.
		}

		break
	}
	if err != nil {
		return nil, err
	}

	if rprotocol == syscall.IPPROTO_TCP {
		//  by default golang/net sets TCP no delay to true.
		if err = setNoDelay(fd, true); err != nil {
			// fmt.Println("set no delay failed")
			syscall.Close(fd)
			return nil, err
		}
	}

	if err = syscall.SetNonblock(fd, true); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	switch socktype {
	case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:

		// File Name get be nil
		file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
		if c, err = net.FileConn(file); err != nil {
			// fmt.Println("fileconn failed")
			syscall.Close(fd)
			return nil, err
		}

	case syscall.SOCK_DGRAM:

		// File Name get be nil
		file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
		if c, err = net.FileConn(file); err != nil {
			// fmt.Println("fileconn failed")
			syscall.Close(fd)
			return nil, err
		}
	}

	if err = file.Close(); err != nil {
		// fmt.Println("file close failed")
		syscall.Close(fd)
		return nil, err
	}

	return c, err
}

func listen(netw, addr string) (fd int, err error) {
	var (
		family   int
		socktype int
		protocol int
		sockaddr syscall.Sockaddr
	)

	netAddr, err := ResolveAddr(netw, addr)
	if err != nil {
		// fmt.Println("resolve addr failed")
		return -1, err
	}

	switch netAddr.(type) {
	case *net.TCPAddr, *net.UDPAddr:
	default:
		return -1, ErrUnsupportedProtocol
	}

	family = sockaddrnet.NetAddrAF(netAddr)
	protocol = sockaddrnet.NetAddrIPPROTO(netAddr)
	sockaddr = sockaddrnet.NetAddrToSockaddr(netAddr)
	socktype = sockaddrnet.NetAddrSOCK(netAddr)

	if fd, err = socket(family, socktype, protocol); err != nil {
		return -1, err
	}

	if err = syscall.Bind(fd, sockaddr); err != nil {
		// fmt.Println("bind failed")
		syscall.Close(fd)
		return -1, err
	}

	if protocol == syscall.IPPROTO_TCP {
		//  by default golang/net sets TCP no delay to true.
		if err = setNoDelay(fd, true); err != nil {
			// fmt.Println("set no delay failed")
			syscall.Close(fd)
			return -1, err
		}
	}

	if err = syscall.SetNonblock(fd, true); err != nil {
		syscall.Close(fd)
		return -1, err
	}

	return fd, nil
}

func listenStream(netw, addr string) (l net.Listener, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	// Set backlog size to the maximum
	if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
		// fmt.Println("listen failed")
		syscall.Close(fd)
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if l, err = net.FileListener(file); err != nil {
		// fmt.Println("filelistener failed")
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		// fmt.Println("file close failed")
		syscall.Close(fd)
		return nil, err
	}

	return l, err
}

func listenPacket(netw, addr string) (p net.PacketConn, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if p, err = net.FilePacketConn(file); err != nil {
		// fmt.Println("filelistener failed")
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		// fmt.Println("file close failed")
		syscall.Close(fd)
		return nil, err
	}

	return p, err
}

func listenUDP(netw, addr string) (c net.Conn, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if c, err = net.FileConn(file); err != nil {
		// fmt.Println("filelistener failed")
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		// fmt.Println("file close failed")
		syscall.Close(fd)
		return nil, err
	}

	return c, err
}

// this is close to the connect() function inside stdlib/net
func connect(fd int, ra syscall.Sockaddr) error {
	switch err := syscall.Connect(fd, ra); err {
	case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
	case nil, syscall.EISCONN:
		return nil
	default:
		return err
	}

	var err error
	start := time.Now()
	for {
		// if err := fd.pd.WaitWrite(); err != nil {
		// 	return err
		// }
		// i'd use the above fd.pd.WaitWrite to poll io correctly, just like net sockets...
		// but of course, it uses the damn runtime_* functions that _cannot_ be used by
		// non-go-stdlib source... seriously guys, this is not nice.
		// we're relegated to using syscall.Select (what nightmare that is) or using
		// a simple but totally bogus time-based wait. garbage.
		var nerr int
		nerr, err = syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ERROR)
		if err != nil {
			return err
		}
		switch err = syscall.Errno(nerr); err {
		case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
			if time.Now().Sub(start) > time.Second {
				return err
			}
			<-time.After(20 * time.Microsecond)
		case syscall.Errno(0), syscall.EISCONN:
			return nil
		default:
			return err
		}
	}
}
<commit_msg>removing extra logs<commit_after>// +build darwin freebsd dragonfly netbsd openbsd linux

package reuseport

import (
	"net"
	"os"
	"strconv"
	"syscall"
	"time"

	sockaddrnet "github.com/jbenet/go-sockaddr/net"
)

const (
	filePrefix = "port."
)

// Wrapper around the socket system call that marks the returned file
// descriptor as nonblocking and close-on-exec.
func socket(family, socktype, protocol int) (fd int, err error) {
	syscall.ForkLock.RLock()
	fd, err = syscall.Socket(family, socktype, protocol)
	if err == nil {
		syscall.CloseOnExec(fd)
	}
	syscall.ForkLock.RUnlock()

	if err != nil {
		return -1, err
	}

	// set non-blocking until after connect, because we cant poll using runtime :(
	// if err = syscall.SetNonblock(fd, true); err != nil {
	// 	syscall.Close(fd)
	// 	return -1, err
	// }

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReuseAddr, 1); err != nil {
		syscall.Close(fd)
		return -1, err
	}

	if err = syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, soReusePort, 1); err != nil {
		syscall.Close(fd)
		return -1, err
	}

	// set setLinger to 5 as reusing exact same (srcip:srcport, dstip:dstport)
	// will otherwise fail on connect.
	if err = setLinger(fd, 5); err != nil {
		syscall.Close(fd)
		return -1, err
	}

	return fd, nil
}

func dial(dialer net.Dialer, netw, addr string) (c net.Conn, err error) {
	var (
		fd             int
		lfamily        int
		rfamily        int
		socktype       int
		lprotocol      int
		rprotocol      int
		file           *os.File
		remoteSockaddr syscall.Sockaddr
		localSockaddr  syscall.Sockaddr
	)

	netAddr, err := ResolveAddr(netw, addr)
	if err != nil {
		return nil, err
	}

	switch netAddr.(type) {
	case *net.TCPAddr, *net.UDPAddr:
	default:
		return nil, ErrUnsupportedProtocol
	}

	localSockaddr = sockaddrnet.NetAddrToSockaddr(dialer.LocalAddr)
	remoteSockaddr = sockaddrnet.NetAddrToSockaddr(netAddr)

	rfamily = sockaddrnet.NetAddrAF(netAddr)
	rprotocol = sockaddrnet.NetAddrIPPROTO(netAddr)
	socktype = sockaddrnet.NetAddrSOCK(netAddr)

	if dialer.LocalAddr != nil {
		switch dialer.LocalAddr.(type) {
		case *net.TCPAddr, *net.UDPAddr:
		default:
			return nil, ErrUnsupportedProtocol
		}

		// check family and protocols match.
		lfamily = sockaddrnet.NetAddrAF(dialer.LocalAddr)
		lprotocol = sockaddrnet.NetAddrIPPROTO(dialer.LocalAddr)
		if lfamily != rfamily && lprotocol != rfamily {
			return nil, &net.AddrError{Err: "unexpected address type", Addr: netAddr.String()}
		}
	}

	// look at dialTCP in http://golang.org/src/net/tcpsock_posix.go  .... !
	// here we just try again 3 times.
	for i := 0; i < 3; i++ {
		if fd, err = socket(rfamily, socktype, rprotocol); err != nil {
			return nil, err
		}

		if err = syscall.Bind(fd, localSockaddr); err != nil {
			// fmt.Println("bind failed")
			syscall.Close(fd)
			return nil, err
		}
		if err = connect(fd, remoteSockaddr); err != nil {
			syscall.Close(fd)
			continue // try again.
		}

		break
	}
	if err != nil {
		return nil, err
	}

	if rprotocol == syscall.IPPROTO_TCP {
		//  by default golang/net sets TCP no delay to true.
		if err = setNoDelay(fd, true); err != nil {
			syscall.Close(fd)
			return nil, err
		}
	}

	if err = syscall.SetNonblock(fd, true); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	switch socktype {
	case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:

		// File Name get be nil
		file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
		if c, err = net.FileConn(file); err != nil {
			syscall.Close(fd)
			return nil, err
		}

	case syscall.SOCK_DGRAM:

		// File Name get be nil
		file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
		if c, err = net.FileConn(file); err != nil {
			syscall.Close(fd)
			return nil, err
		}
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	return c, err
}

func listen(netw, addr string) (fd int, err error) {
	var (
		family   int
		socktype int
		protocol int
		sockaddr syscall.Sockaddr
	)

	netAddr, err := ResolveAddr(netw, addr)
	if err != nil {
		return -1, err
	}

	switch netAddr.(type) {
	case *net.TCPAddr, *net.UDPAddr:
	default:
		return -1, ErrUnsupportedProtocol
	}

	family = sockaddrnet.NetAddrAF(netAddr)
	protocol = sockaddrnet.NetAddrIPPROTO(netAddr)
	sockaddr = sockaddrnet.NetAddrToSockaddr(netAddr)
	socktype = sockaddrnet.NetAddrSOCK(netAddr)

	if fd, err = socket(family, socktype, protocol); err != nil {
		return -1, err
	}

	if err = syscall.Bind(fd, sockaddr); err != nil {
		syscall.Close(fd)
		return -1, err
	}

	if protocol == syscall.IPPROTO_TCP {
		//  by default golang/net sets TCP no delay to true.
		if err = setNoDelay(fd, true); err != nil {
			syscall.Close(fd)
			return -1, err
		}
	}

	if err = syscall.SetNonblock(fd, true); err != nil {
		syscall.Close(fd)
		return -1, err
	}

	return fd, nil
}

func listenStream(netw, addr string) (l net.Listener, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	// Set backlog size to the maximum
	if err = syscall.Listen(fd, syscall.SOMAXCONN); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if l, err = net.FileListener(file); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	return l, err
}

func listenPacket(netw, addr string) (p net.PacketConn, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if p, err = net.FilePacketConn(file); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	return p, err
}

func listenUDP(netw, addr string) (c net.Conn, err error) {
	var (
		file *os.File
	)

	fd, err := listen(netw, addr)
	if err != nil {
		return nil, err
	}

	file = os.NewFile(uintptr(fd), filePrefix+strconv.Itoa(os.Getpid()))
	if c, err = net.FileConn(file); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	if err = file.Close(); err != nil {
		syscall.Close(fd)
		return nil, err
	}

	return c, err
}

// this is close to the connect() function inside stdlib/net
func connect(fd int, ra syscall.Sockaddr) error {
	switch err := syscall.Connect(fd, ra); err {
	case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
	case nil, syscall.EISCONN:
		return nil
	default:
		return err
	}

	var err error
	start := time.Now()
	for {
		// if err := fd.pd.WaitWrite(); err != nil {
		// 	return err
		// }
		// i'd use the above fd.pd.WaitWrite to poll io correctly, just like net sockets...
		// but of course, it uses the damn runtime_* functions that _cannot_ be used by
		// non-go-stdlib source... seriously guys, this is not nice.
		// we're relegated to using syscall.Select (what nightmare that is) or using
		// a simple but totally bogus time-based wait. garbage.
		var nerr int
		nerr, err = syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_ERROR)
		if err != nil {
			return err
		}
		switch err = syscall.Errno(nerr); err {
		case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
			if time.Now().Sub(start) > time.Second {
				return err
			}
			<-time.After(20 * time.Microsecond)
		case syscall.Errno(0), syscall.EISCONN:
			return nil
		default:
			return err
		}
	}
}
<|endoftext|>


<commit_before>package youtubeapi

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"time"
)

// Youtube ...
type Youtube struct {
	Key string
}

// New Returns a Youtube struct with the supplied key
//		key: Google API key
func New(key string) *Youtube {
	return &Youtube{
		Key: key,
	}
}

// SearchResult is the json data retrieved from the youtube api search endpoint.
type SearchResult struct {
	Kind          string `json:"kind"`
	Etag          string `json:"etag"`
	NextPageToken string `json:"nextPageToken"`
	RegionCode    string `json:"regionCode"`
	PageInfo      struct {
		TotalResults   int `json:"totalResults"`
		ResultsPerPage int `json:"resultsPerPage"`
	} `json:"pageInfo"`
	Items []Item `json:"items"`
}

// Item stores information about videos
type Item struct {
	Kind string `json:"kind"`
	Etag string `json:"etag"`
	ID   struct {
		Kind    string `json:"kind"`
		VideoID string `json:"videoId"`
	} `json:"id"`
	Snippet struct {
		PublishedAt time.Time `json:"publishedAt"`
		ChannelID   string    `json:"channelId"`
		Title       string    `json:"title"`
		Description string    `json:"description"`
		Thumbnails  struct {
			Default struct {
				URL    string `json:"url"`
				Width  int    `json:"width"`
				Height int    `json:"height"`
			} `json:"default"`
			Medium struct {
				URL    string `json:"url"`
				Width  int    `json:"width"`
				Height int    `json:"height"`
			} `json:"medium"`
			High struct {
				URL    string `json:"url"`
				Width  int    `json:"width"`
				Height int    `json:"height"`
			} `json:"high"`
		} `json:"thumbnails"`
		ChannelTitle         string `json:"channelTitle"`
		LiveBroadcastContent string `json:"liveBroadcastContent"`
	} `json:"snippet"`
}

// Search searches youtube for videos with the supplied query.
//		query: The query to search for.
//		key:   Your google API key.
func (y *Youtube) Search(query string, maxResults int) (*SearchResult, error) {
	resp, err := http.Get(fmt.Sprintf("https://www.googleapis.com/youtube/v3/search?part=snippet&q=%s&key=%s&maxResults=%d", url.QueryEscape(query), y.Key, maxResults))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, errors.New(http.StatusText(resp.StatusCode))
	}

	var searchRes SearchResult
	err = json.NewDecoder(resp.Body).Decode(&searchRes)
	if err != nil {
		return nil, err
	}

	return &searchRes, nil
}
<commit_msg>Remove undeeded parameter comment<commit_after>package youtubeapi

import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"time"
)

// Youtube ...
type Youtube struct {
	Key string
}

// New Returns a Youtube struct with the supplied key
//		key: Google API key
func New(key string) *Youtube {
	return &Youtube{
		Key: key,
	}
}

// SearchResult is the json data retrieved from the youtube api search endpoint.
type SearchResult struct {
	Kind          string `json:"kind"`
	Etag          string `json:"etag"`
	NextPageToken string `json:"nextPageToken"`
	RegionCode    string `json:"regionCode"`
	PageInfo      struct {
		TotalResults   int `json:"totalResults"`
		ResultsPerPage int `json:"resultsPerPage"`
	} `json:"pageInfo"`
	Items []Item `json:"items"`
}

// Item stores information about videos
type Item struct {
	Kind string `json:"kind"`
	Etag string `json:"etag"`
	ID   struct {
		Kind    string `json:"kind"`
		VideoID string `json:"videoId"`
	} `json:"id"`
	Snippet struct {
		PublishedAt time.Time `json:"publishedAt"`
		ChannelID   string    `json:"channelId"`
		Title       string    `json:"title"`
		Description string    `json:"description"`
		Thumbnails  struct {
			Default struct {
				URL    string `json:"url"`
				Width  int    `json:"width"`
				Height int    `json:"height"`
			} `json:"default"`
			Medium struct {
				URL    string `json:"url"`
				Width  int    `json:"width"`
				Height int    `json:"height"`
			} `json:"medium"`
			High struct {
				URL    string `json:"url"`
				Width  int    `json:"width"`
				Height int    `json:"height"`
			} `json:"high"`
		} `json:"thumbnails"`
		ChannelTitle         string `json:"channelTitle"`
		LiveBroadcastContent string `json:"liveBroadcastContent"`
	} `json:"snippet"`
}

// Search searches youtube for videos with the supplied query.
//		query: The query to search for.
func (y *Youtube) Search(query string, maxResults int) (*SearchResult, error) {
	resp, err := http.Get(fmt.Sprintf("https://www.googleapis.com/youtube/v3/search?part=snippet&q=%s&key=%s&maxResults=%d", url.QueryEscape(query), y.Key, maxResults))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, errors.New(http.StatusText(resp.StatusCode))
	}

	var searchRes SearchResult
	err = json.NewDecoder(resp.Body).Decode(&searchRes)
	if err != nil {
		return nil, err
	}

	return &searchRes, nil
}
<|endoftext|>


<commit_before>package monitor

import (
	"fmt"
)

const (
	DBG_CAPTURE_UNSPEC = iota
	DBG_CAPTURE_FROM_LXC
	DBG_CAPTURE_FROM_NETDEV
	DBG_CAPTURE_FROM_OVERLAY
	DBG_CAPTURE_DELIVERY
)

const (
	DBG_UNSPEC = iota
	DBG_GENERIC
	DBG_LOCAL_DELIVERY
	DBG_ENCAP
	DBG_LXC_FOUND
	DBG_NO_POLICY
	DBG_POLICY_DENIED
)

type DebugMsg struct {
	Type    uint8
	SubType uint8
	Flags   uint16
	Arg1    uint32
	Arg2    uint32
}

func (n *DebugMsg) Dump(data []byte) {
	fmt.Printf("DEBUG: ")
	switch n.SubType {
	case DBG_GENERIC:
		fmt.Printf("No message, arg1=%d (%#x) arg2=%d (%#x)\n", n.Arg1, n.Arg1, n.Arg2, n.Arg2)
	case DBG_LOCAL_DELIVERY:
		fmt.Printf("Attempting local delivery for container id %d from seclabel %d\n", n.Arg1, n.Arg2)
	case DBG_ENCAP:
		fmt.Printf("Encapsulating to node %d (%#x) from seclabel %d\n", n.Arg1, n.Arg1, n.Arg2)
	case DBG_LXC_FOUND:
		fmt.Printf("Local container found ifindex %d seclabel %d\n", n.Arg1, n.Arg2)
	case DBG_NO_POLICY:
		fmt.Printf("No policy program found for id %d (FIXME: resolve), dropping...\n", n.Arg1)
	case DBG_POLICY_DENIED:
		fmt.Printf("Policy denied from %d to %d\n", n.Arg1, n.Arg2)
	default:
		fmt.Printf("Unknown message type=%d arg1=%d arg2=%d\n", n.SubType, n.Arg1, n.Arg2)
	}
}

type DebugCapture struct {
	Type    uint8
	SubType uint8
	Flags   uint16
	Len     uint32
	Arg1    uint32
	// data
}

func (n *DebugCapture) Dump(dissect bool, data []byte) {
	fmt.Printf("DEBUG: ")
	switch n.SubType {
	case DBG_CAPTURE_FROM_LXC:
		fmt.Printf("Incoming packet from container ifindex %d\n", n.Arg1)
	case DBG_CAPTURE_FROM_NETDEV:
		fmt.Printf("Incoming packet from netdev ifindex %d\n", n.Arg1)
	case DBG_CAPTURE_FROM_OVERLAY:
		fmt.Printf("Incoming packet from overlay ifindex %d\n", n.Arg1)
	case DBG_CAPTURE_DELIVERY:
		fmt.Printf("Delivery to ifindex %d\n", n.Arg1)
	default:
		fmt.Printf("Unknown message type=%d arg1=%d\n", n.SubType, n.Arg1)
	}
	Dissect(dissect, data[12:])
}
<commit_msg>monitor: Print length of captured frames in debug mode<commit_after>package monitor

import (
	"fmt"
)

const (
	DBG_CAPTURE_UNSPEC = iota
	DBG_CAPTURE_FROM_LXC
	DBG_CAPTURE_FROM_NETDEV
	DBG_CAPTURE_FROM_OVERLAY
	DBG_CAPTURE_DELIVERY
)

const (
	DBG_UNSPEC = iota
	DBG_GENERIC
	DBG_LOCAL_DELIVERY
	DBG_ENCAP
	DBG_LXC_FOUND
	DBG_NO_POLICY
	DBG_POLICY_DENIED
)

type DebugMsg struct {
	Type    uint8
	SubType uint8
	Flags   uint16
	Arg1    uint32
	Arg2    uint32
}

func (n *DebugMsg) Dump(data []byte) {
	fmt.Printf("DEBUG: ")
	switch n.SubType {
	case DBG_GENERIC:
		fmt.Printf("No message, arg1=%d (%#x) arg2=%d (%#x)\n", n.Arg1, n.Arg1, n.Arg2, n.Arg2)
	case DBG_LOCAL_DELIVERY:
		fmt.Printf("Attempting local delivery for container id %d from seclabel %d\n", n.Arg1, n.Arg2)
	case DBG_ENCAP:
		fmt.Printf("Encapsulating to node %d (%#x) from seclabel %d\n", n.Arg1, n.Arg1, n.Arg2)
	case DBG_LXC_FOUND:
		fmt.Printf("Local container found ifindex %d seclabel %d\n", n.Arg1, n.Arg2)
	case DBG_NO_POLICY:
		fmt.Printf("No policy program found for id %d (FIXME: resolve), dropping...\n", n.Arg1)
	case DBG_POLICY_DENIED:
		fmt.Printf("Policy denied from %d to %d\n", n.Arg1, n.Arg2)
	default:
		fmt.Printf("Unknown message type=%d arg1=%d arg2=%d\n", n.SubType, n.Arg1, n.Arg2)
	}
}

type DebugCapture struct {
	Type    uint8
	SubType uint8
	Flags   uint16
	Len     uint32
	Arg1    uint32
	// data
}

func (n *DebugCapture) Dump(dissect bool, data []byte) {
	fmt.Printf("DEBUG: %d bytes ", n.Len)
	switch n.SubType {
	case DBG_CAPTURE_FROM_LXC:
		fmt.Printf("Incoming packet from container ifindex %d\n", n.Arg1)
	case DBG_CAPTURE_FROM_NETDEV:
		fmt.Printf("Incoming packet from netdev ifindex %d\n", n.Arg1)
	case DBG_CAPTURE_FROM_OVERLAY:
		fmt.Printf("Incoming packet from overlay ifindex %d\n", n.Arg1)
	case DBG_CAPTURE_DELIVERY:
		fmt.Printf("Delivery to ifindex %d\n", n.Arg1)
	default:
		fmt.Printf("Unknown message type=%d arg1=%d\n", n.SubType, n.Arg1)
	}
	Dissect(dissect, data[12:])
}
<|endoftext|>


<commit_before>package data

import (
	"fmt"
	"sort"
	"strings"
)

type Asset struct {
	Currency string `json:"currency"`
	Issuer   string `json:"issuer,omitempty"`
}

func NewAsset(s string) (*Asset, error) {
	if s == "XRP" {
		return &Asset{
			Currency: s,
		}, nil
	}
	parts := strings.Split(s, "/")
	if len(parts) != 2 {
		return nil, fmt.Errorf("bad asset: %s", s)
	}
	return &Asset{
		Currency: parts[0],
		Issuer:   parts[1],
	}, nil
}

func (a *Asset) IsNative() bool {
	return a.Currency == "XRP"
}

func (a Asset) String() string {
	if a.IsNative() {
		return a.Currency
	}
	return fmt.Sprintf("%s/%s", a.Currency, a.Issuer)
}

type OrderBookOffer struct {
	Offer
	OwnerFunds      Value          `json:"owner_funds"`
	Quality         NonNativeValue `json:"quality"`
	TakerGetsFunded *Amount        `json:"taker_gets_funded"`
	TakerPaysFunded *Amount        `json:"taker_pays_funded"`
}

type AccountOffer struct {
	Flags      LedgerEntryFlag `json:"flags"`
	Quality    NonNativeValue  `json:"quality"`
	Sequence   uint32          `json:"seq"`
	TakerGets  Amount          `json:"taker_gets"`
	TakerPays  Amount          `json:"taker_pays"`
	Expiration *uint32         `json:"expiration"`
}

type AccountOfferSlice []AccountOffer

func (s AccountOfferSlice) Len() int           { return len(s) }
func (s AccountOfferSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s AccountOfferSlice) Less(i, j int) bool { return s[i].Sequence > s[j].Sequence }

func (s AccountOfferSlice) GetSequences(pays, gets *Asset) []uint32 {
	// TODO: improve performance
	var sequences []uint32
	for i := range s {
		if s[i].TakerPays.Currency.String() == pays.Currency &&
			s[i].TakerPays.Issuer.String() == pays.Issuer &&
			s[i].TakerGets.Currency.String() == gets.Currency &&
			s[i].TakerGets.Issuer.String() == gets.Issuer {
			sequences = append(sequences, s[i].Sequence)
		}
	}
	return sequences
}

func (s AccountOfferSlice) Find(sequence uint32) int {
	return sort.Search(len(s), func(i int) bool {
		return s[i].Sequence <= sequence
	})
}

func (s AccountOfferSlice) Get(sequence uint32) *AccountOffer {
	if i := s.Find(sequence); i < len(s) && s[i].Sequence == sequence {
		return &s[i]
	}
	return nil
}

func defaultUint32(v *uint32) uint32 {
	if v == nil {
		return 0
	}
	return *v
}

func (s *AccountOfferSlice) Add(offer *Offer) bool {
	quality, err := offer.TakerPays.Divide(offer.TakerGets)
	if err != nil {
		panic(fmt.Sprintf("impossible quality: %s %s", offer.TakerPays, offer.TakerGets))
	}
	o := AccountOffer{
		Flags:      LedgerEntryFlag(defaultUint32((*uint32)(offer.Flags))),
		Sequence:   *offer.Sequence,
		TakerGets:  *offer.TakerGets,
		TakerPays:  *offer.TakerPays,
		Quality:    NonNativeValue{*quality.Value},
		Expiration: offer.Expiration,
	}
	i := s.Find(*offer.Sequence)
	switch {
	case i == len(*s):
		*s = append(*s, o)
		return true
	case (*s)[i].Sequence != *offer.Sequence:
		*s = append(*s, AccountOffer{})
		copy((*s)[i+1:], (*s)[i:])
		(*s)[i] = o
		return true
	default:
		return false
	}
}

func (s AccountOfferSlice) Update(offer *Offer) bool {
	if existing := s.Get(*offer.Sequence); existing != nil {
		existing.TakerGets = *offer.TakerGets
		existing.TakerPays = *offer.TakerPays
		return true
	}
	return false
}

func (s *AccountOfferSlice) Delete(offer *Offer) bool {
	if i := s.Find(*offer.Sequence); i < len(*s) && (*s)[i].Sequence == *offer.Sequence {
		*s = append((*s)[:i], (*s)[i+1:]...)
		return true
	}
	return false
}

type AccountLine struct {
	Account      Account        `json:"account"`
	Balance      NonNativeValue `json:"balance"`
	Currency     Currency       `json:"currency"`
	Limit        NonNativeValue `json:"limit"`
	LimitPeer    NonNativeValue `json:"limit_peer"`
	NoRipple     bool           `json:"no_ripple"`
	NoRipplePeer bool           `json:"no_ripple_peer"`
	QualityIn    uint32         `json:"quality_in"`
	QualityOut   uint32         `json:"quality_out"`
}

func (l *AccountLine) Asset() *Asset {
	return &Asset{
		Currency: l.Currency.String(),
		Issuer:   l.Account.String(),
	}
}

func (l *AccountLine) CompareByCurrencyAccount(other *AccountLine) int {
	if cmp := l.Currency.Compare(other.Currency); cmp != 0 {
		return cmp
	}
	return l.Account.Compare(other.Account)
}

func (l *AccountLine) CompareByCurrencyAmount(other *AccountLine) int {
	if cmp := l.Currency.Compare(other.Currency); cmp != 0 {
		return cmp
	}
	return l.Balance.Abs().Compare(*other.Balance.Abs())
}

type AccountLineSlice []AccountLine

type byCurrencyAccount struct {
	AccountLineSlice
}

func (by *byCurrencyAccount) Less(i, j int) bool {
	return by.AccountLineSlice[i].CompareByCurrencyAccount(&by.AccountLineSlice[j]) < 0
}

type byCurrencyAmount struct {
	AccountLineSlice
}

func (by *byCurrencyAmount) Less(i, j int) bool {
	return by.AccountLineSlice[i].CompareByCurrencyAmount(&by.AccountLineSlice[j]) < 0
}

func (s AccountLineSlice) Len() int               { return len(s) }
func (s AccountLineSlice) Swap(i, j int)          { s[i], s[j] = s[j], s[i] }
func (s AccountLineSlice) SortbyCurrencyAccount() { sort.Sort(&byCurrencyAccount{s}) }
func (s AccountLineSlice) SortByCurrencyAmount()  { sort.Sort(&byCurrencyAmount{s}) }

func (s AccountLineSlice) Find(account Account, currency Currency) int {
	return sort.Search(len(s), func(i int) bool {
		switch s[i].Currency.Compare(currency) {
		case 1:
			return true
		case -1:
			return false
		default:
			return s[i].Account.Compare(account) >= 0
		}
	})
}

type highLowFunc func(balance, limit, limitPeer *Amount, noRipple, noRipplePeer bool, qualityIn, qualityOut uint32) bool

func highLow(account Account, rs *RippleState, f highLowFunc) bool {
	high, low := account.Equals(rs.HighLimit.Issuer), account.Equals(rs.LowLimit.Issuer)
	switch {
	case high == low:
		return false
	case high:
		noRipple, noRipplePeer := *rs.Flags&LsHighNoRipple > 0, *rs.Flags&LsLowNoRipple > 0
		return f(rs.Balance.Negate(), rs.HighLimit, rs.LowLimit, noRipple, noRipplePeer, defaultUint32(rs.HighQualityIn), defaultUint32(rs.HighQualityOut))
	default:
		noRipple, noRipplePeer := *rs.Flags&LsLowNoRipple > 0, *rs.Flags&LsHighNoRipple > 0
		return f(rs.Balance, rs.LowLimit, rs.HighLimit, noRipple, noRipplePeer, defaultUint32(rs.LowQualityIn), defaultUint32(rs.LowQualityOut))
	}
}

func (s *AccountLineSlice) Add(account Account, rs *RippleState) bool {
	var add = func(balance, limit, limitPeer *Amount, noRipple, noRipplePeer bool, qualityIn, qualityOut uint32) bool {
		line := AccountLine{
			Account:      limitPeer.Issuer,
			Balance:      NonNativeValue{*balance.Value},
			Currency:     limit.Currency,
			Limit:        NonNativeValue{*limit.Value},
			LimitPeer:    NonNativeValue{*limitPeer.Value},
			NoRipple:     noRipple,
			NoRipplePeer: noRipplePeer,
			QualityIn:    qualityIn,
			QualityOut:   qualityOut,
		}
		i := s.Find(limitPeer.Issuer, limitPeer.Currency)
		switch {
		case i == len(*s):
			*s = append(*s, line)
			return true
		case (*s)[i].Account.Equals(limitPeer.Issuer) && (*s)[i].Currency.Equals(limitPeer.Currency):
			return false
		default:
			*s = append((*s)[:i], append(AccountLineSlice{line}, (*s)[i:]...)...)
			return true
		}
	}
	return highLow(account, rs, add)
}

func (s AccountLineSlice) Update(account Account, rs *RippleState) bool {
	var update = func(balance, limit, limitPeer *Amount, noripple, noRipplePeer bool, qualityIn, qualityOut uint32) bool {
		i := s.Find(limitPeer.Issuer, limitPeer.Currency)
		if i == len(s) || !s[i].Account.Equals(limitPeer.Issuer) || !s[i].Currency.Equals(limitPeer.Currency) {
			return false
		}
		s[i].Balance = NonNativeValue{*balance.Value}
		s[i].Limit = NonNativeValue{*limit.Value}
		s[i].LimitPeer = NonNativeValue{*limitPeer.Value}
		s[i].NoRipple = noripple
		s[i].NoRipplePeer = noRipplePeer
		return true
	}
	return highLow(account, rs, update)
}

func (s *AccountLineSlice) Delete(account Account, rs *RippleState) bool {
	var del = func(balance, limit, limitPeer *Amount, noripple, noRipplePeer bool, qualityIn, qualityOut uint32) bool {
		i := s.Find(limitPeer.Issuer, limitPeer.Currency)
		if i < len(*s) && (*s)[i].Account.Equals(limitPeer.Issuer) && (*s)[i].Currency.Equals(limitPeer.Currency) {
			*s = append((*s)[:i], (*s)[i+1:]...)
			return true
		}
		return false
	}
	return highLow(account, rs, del)
}
<commit_msg>Add Matches() to Asset<commit_after>package data

import (
	"fmt"
	"sort"
	"strings"
)

type Asset struct {
	Currency string `json:"currency"`
	Issuer   string `json:"issuer,omitempty"`
}

func NewAsset(s string) (*Asset, error) {
	if s == "XRP" {
		return &Asset{
			Currency: s,
		}, nil
	}
	parts := strings.Split(s, "/")
	if len(parts) != 2 {
		return nil, fmt.Errorf("bad asset: %s", s)
	}
	return &Asset{
		Currency: parts[0],
		Issuer:   parts[1],
	}, nil
}

func (a *Asset) IsNative() bool {
	return a.Currency == "XRP"
}

func (a *Asset) Matches(amount *Amount) bool {
	return (a.IsNative() && amount.IsNative()) ||
		(a.Currency == amount.Currency.String() && a.Issuer == amount.Issuer.String())
}

func (a Asset) String() string {
	if a.IsNative() {
		return a.Currency
	}
	return fmt.Sprintf("%s/%s", a.Currency, a.Issuer)
}

type OrderBookOffer struct {
	Offer
	OwnerFunds      Value          `json:"owner_funds"`
	Quality         NonNativeValue `json:"quality"`
	TakerGetsFunded *Amount        `json:"taker_gets_funded"`
	TakerPaysFunded *Amount        `json:"taker_pays_funded"`
}

type AccountOffer struct {
	Flags      LedgerEntryFlag `json:"flags"`
	Quality    NonNativeValue  `json:"quality"`
	Sequence   uint32          `json:"seq"`
	TakerGets  Amount          `json:"taker_gets"`
	TakerPays  Amount          `json:"taker_pays"`
	Expiration *uint32         `json:"expiration"`
}

type AccountOfferSlice []AccountOffer

func (s AccountOfferSlice) Len() int           { return len(s) }
func (s AccountOfferSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s AccountOfferSlice) Less(i, j int) bool { return s[i].Sequence > s[j].Sequence }

func (s AccountOfferSlice) GetSequences(pays, gets *Asset) []uint32 {
	// TODO: improve performance
	var sequences []uint32
	for i := range s {
		if pays.Matches(&s[i].TakerPays) && gets.Matches(&s[i].TakerGets) {
			sequences = append(sequences, s[i].Sequence)
		}
	}
	return sequences
}

func (s AccountOfferSlice) Find(sequence uint32) int {
	return sort.Search(len(s), func(i int) bool {
		return s[i].Sequence <= sequence
	})
}

func (s AccountOfferSlice) Get(sequence uint32) *AccountOffer {
	if i := s.Find(sequence); i < len(s) && s[i].Sequence == sequence {
		return &s[i]
	}
	return nil
}

func defaultUint32(v *uint32) uint32 {
	if v == nil {
		return 0
	}
	return *v
}

func (s *AccountOfferSlice) Add(offer *Offer) bool {
	quality, err := offer.TakerPays.Divide(offer.TakerGets)
	if err != nil {
		panic(fmt.Sprintf("impossible quality: %s %s", offer.TakerPays, offer.TakerGets))
	}
	o := AccountOffer{
		Flags:      LedgerEntryFlag(defaultUint32((*uint32)(offer.Flags))),
		Sequence:   *offer.Sequence,
		TakerGets:  *offer.TakerGets,
		TakerPays:  *offer.TakerPays,
		Quality:    NonNativeValue{*quality.Value},
		Expiration: offer.Expiration,
	}
	i := s.Find(*offer.Sequence)
	switch {
	case i == len(*s):
		*s = append(*s, o)
		return true
	case (*s)[i].Sequence != *offer.Sequence:
		*s = append(*s, AccountOffer{})
		copy((*s)[i+1:], (*s)[i:])
		(*s)[i] = o
		return true
	default:
		return false
	}
}

func (s AccountOfferSlice) Update(offer *Offer) bool {
	if existing := s.Get(*offer.Sequence); existing != nil {
		existing.TakerGets = *offer.TakerGets
		existing.TakerPays = *offer.TakerPays
		return true
	}
	return false
}

func (s *AccountOfferSlice) Delete(offer *Offer) bool {
	if i := s.Find(*offer.Sequence); i < len(*s) && (*s)[i].Sequence == *offer.Sequence {
		*s = append((*s)[:i], (*s)[i+1:]...)
		return true
	}
	return false
}

type AccountLine struct {
	Account      Account        `json:"account"`
	Balance      NonNativeValue `json:"balance"`
	Currency     Currency       `json:"currency"`
	Limit        NonNativeValue `json:"limit"`
	LimitPeer    NonNativeValue `json:"limit_peer"`
	NoRipple     bool           `json:"no_ripple"`
	NoRipplePeer bool           `json:"no_ripple_peer"`
	QualityIn    uint32         `json:"quality_in"`
	QualityOut   uint32         `json:"quality_out"`
}

func (l *AccountLine) Asset() *Asset {
	return &Asset{
		Currency: l.Currency.String(),
		Issuer:   l.Account.String(),
	}
}

func (l *AccountLine) CompareByCurrencyAccount(other *AccountLine) int {
	if cmp := l.Currency.Compare(other.Currency); cmp != 0 {
		return cmp
	}
	return l.Account.Compare(other.Account)
}

func (l *AccountLine) CompareByCurrencyAmount(other *AccountLine) int {
	if cmp := l.Currency.Compare(other.Currency); cmp != 0 {
		return cmp
	}
	return l.Balance.Abs().Compare(*other.Balance.Abs())
}

type AccountLineSlice []AccountLine

type byCurrencyAccount struct {
	AccountLineSlice
}

func (by *byCurrencyAccount) Less(i, j int) bool {
	return by.AccountLineSlice[i].CompareByCurrencyAccount(&by.AccountLineSlice[j]) < 0
}

type byCurrencyAmount struct {
	AccountLineSlice
}

func (by *byCurrencyAmount) Less(i, j int) bool {
	return by.AccountLineSlice[i].CompareByCurrencyAmount(&by.AccountLineSlice[j]) < 0
}

func (s AccountLineSlice) Len() int               { return len(s) }
func (s AccountLineSlice) Swap(i, j int)          { s[i], s[j] = s[j], s[i] }
func (s AccountLineSlice) SortbyCurrencyAccount() { sort.Sort(&byCurrencyAccount{s}) }
func (s AccountLineSlice) SortByCurrencyAmount()  { sort.Sort(&byCurrencyAmount{s}) }

func (s AccountLineSlice) Find(account Account, currency Currency) int {
	return sort.Search(len(s), func(i int) bool {
		switch s[i].Currency.Compare(currency) {
		case 1:
			return true
		case -1:
			return false
		default:
			return s[i].Account.Compare(account) >= 0
		}
	})
}

func (s AccountLineSlice) Get(account Account, currency Currency) *AccountLine {
	if i := s.Find(account, currency); i < len(s) && s[i].Account.Equals(account) && s[i].Currency.Equals(currency) {
		return &s[i]
	}
	return nil
}

type highLowFunc func(balance, limit, limitPeer *Amount, noRipple, noRipplePeer bool, qualityIn, qualityOut uint32) bool

func highLow(account Account, rs *RippleState, f highLowFunc) bool {
	high, low := account.Equals(rs.HighLimit.Issuer), account.Equals(rs.LowLimit.Issuer)
	switch {
	case high == low:
		return false
	case high:
		noRipple, noRipplePeer := *rs.Flags&LsHighNoRipple > 0, *rs.Flags&LsLowNoRipple > 0
		return f(rs.Balance.Negate(), rs.HighLimit, rs.LowLimit, noRipple, noRipplePeer, defaultUint32(rs.HighQualityIn), defaultUint32(rs.HighQualityOut))
	default:
		noRipple, noRipplePeer := *rs.Flags&LsLowNoRipple > 0, *rs.Flags&LsHighNoRipple > 0
		return f(rs.Balance, rs.LowLimit, rs.HighLimit, noRipple, noRipplePeer, defaultUint32(rs.LowQualityIn), defaultUint32(rs.LowQualityOut))
	}
}

func (s *AccountLineSlice) Add(account Account, rs *RippleState) bool {
	var add = func(balance, limit, limitPeer *Amount, noRipple, noRipplePeer bool, qualityIn, qualityOut uint32) bool {
		line := AccountLine{
			Account:      limitPeer.Issuer,
			Balance:      NonNativeValue{*balance.Value},
			Currency:     limit.Currency,
			Limit:        NonNativeValue{*limit.Value},
			LimitPeer:    NonNativeValue{*limitPeer.Value},
			NoRipple:     noRipple,
			NoRipplePeer: noRipplePeer,
			QualityIn:    qualityIn,
			QualityOut:   qualityOut,
		}
		i := s.Find(limitPeer.Issuer, limitPeer.Currency)
		switch {
		case i == len(*s):
			*s = append(*s, line)
			return true
		case (*s)[i].Account.Equals(limitPeer.Issuer) && (*s)[i].Currency.Equals(limitPeer.Currency):
			return false
		default:
			*s = append((*s)[:i], append(AccountLineSlice{line}, (*s)[i:]...)...)
			return true
		}
	}
	return highLow(account, rs, add)
}

func (s AccountLineSlice) Update(account Account, rs *RippleState) bool {
	var update = func(balance, limit, limitPeer *Amount, noripple, noRipplePeer bool, qualityIn, qualityOut uint32) bool {
		i := s.Find(limitPeer.Issuer, limitPeer.Currency)
		if i == len(s) || !s[i].Account.Equals(limitPeer.Issuer) || !s[i].Currency.Equals(limitPeer.Currency) {
			return false
		}
		s[i].Balance = NonNativeValue{*balance.Value}
		s[i].Limit = NonNativeValue{*limit.Value}
		s[i].LimitPeer = NonNativeValue{*limitPeer.Value}
		s[i].NoRipple = noripple
		s[i].NoRipplePeer = noRipplePeer
		return true
	}
	return highLow(account, rs, update)
}

func (s *AccountLineSlice) Delete(account Account, rs *RippleState) bool {
	var del = func(balance, limit, limitPeer *Amount, noripple, noRipplePeer bool, qualityIn, qualityOut uint32) bool {
		i := s.Find(limitPeer.Issuer, limitPeer.Currency)
		if i < len(*s) && (*s)[i].Account.Equals(limitPeer.Issuer) && (*s)[i].Currency.Equals(limitPeer.Currency) {
			*s = append((*s)[:i], (*s)[i+1:]...)
			return true
		}
		return false
	}
	return highLow(account, rs, del)
}
<|endoftext|>