<commit_before>package redis_test

import (
	"fmt"
	"strconv"
	"sync"
	"time"

	"github.com/go-redis/redis"
)

var client *redis.Client

func init() {
	client = redis.NewClient(&redis.Options{
		Addr:         ":6379",
		DialTimeout:  10 * time.Second,
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 30 * time.Second,
		PoolSize:     10,
		PoolTimeout:  30 * time.Second,
	})
	client.FlushDB()
}

func ExampleNewClient() {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	pong, err := client.Ping().Result()
	fmt.Println(pong, err)
	// Output: PONG <nil>
}

func ExampleParseURL() {
	opt, err := redis.ParseURL("redis://:qwerty@localhost:6379/1")
	if err != nil {
		panic(err)
	}
	fmt.Println("addr is", opt.Addr)
	fmt.Println("db is", opt.DB)
	fmt.Println("password is", opt.Password)

	// Create client as usually.
	_ = redis.NewClient(opt)

	// Output: addr is localhost:6379
	// db is 1
	// password is qwerty
}

func ExampleNewFailoverClient() {
	// See http://redis.io/topics/sentinel for instructions how to
	// setup Redis Sentinel.
	client := redis.NewFailoverClient(&redis.FailoverOptions{
		MasterName:    "master",
		SentinelAddrs: []string{":26379"},
	})
	client.Ping()
}

func ExampleNewClusterClient() {
	// See http://redis.io/topics/cluster-tutorial for instructions
	// how to setup Redis Cluster.
	client := redis.NewClusterClient(&redis.ClusterOptions{
		Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
	})
	client.Ping()
}

// Following example creates a cluster from 2 master nodes and 2 slave nodes
// without using cluster mode or Redis Sentinel.
func ExampleNewClusterClient_manualSetup() {
	// clusterSlots returns cluster slots information.
	// It can use service like ZooKeeper to maintain configuration information
	// and Cluster.ReloadState to manually trigger state reloading.
	clusterSlots := func() ([]redis.ClusterSlot, error) {
		slots := []redis.ClusterSlot{
			// First node with 1 master and 1 slave.
			{
				Start: 0,
				End:   8191,
				Nodes: []redis.ClusterNode{{
					Addr: ":7000", // master
				}, {
					Addr: ":8000", // 1st slave
				}},
			},
			// Second node with 1 master and 1 slave.
			{
				Start: 8192,
				End:   16383,
				Nodes: []redis.ClusterNode{{
					Addr: ":7001", // master
				}, {
					Addr: ":8001", // 1st slave
				}},
			},
		}
		return slots, nil
	}

	client := redis.NewClusterClient(&redis.ClusterOptions{
		ClusterSlots:  clusterSlots,
		RouteRandomly: true,
	})
	client.Ping()

	// ReloadState reloads cluster state. It calls ClusterSlots func
	// to get cluster slots information.
	err := client.ReloadState()
	if err != nil {
		panic(err)
	}
}

func ExampleNewRing() {
	client := redis.NewRing(&redis.RingOptions{
		Addrs: map[string]string{
			"shard1": ":7000",
			"shard2": ":7001",
			"shard3": ":7002",
		},
	})
	client.Ping()
}

func ExampleClient() {
	err := client.Set("key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	val, err := client.Get("key").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("key", val)

	val2, err := client.Get("key2").Result()
	if err == redis.Nil {
		fmt.Println("key2 does not exist")
	} else if err != nil {
		panic(err)
	} else {
		fmt.Println("key2", val2)
	}
	// Output: key value
	// key2 does not exist
}

func ExampleClient_Set() {
	// Last argument is expiration. Zero means the key has no
	// expiration time.
	err := client.Set("key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	// key2 will expire in an hour.
	err = client.Set("key2", "value", time.Hour).Err()
	if err != nil {
		panic(err)
	}
}

func ExampleClient_Incr() {
	result, err := client.Incr("counter").Result()
	if err != nil {
		panic(err)
	}

	fmt.Println(result)
	// Output: 1
}

func ExampleClient_BLPop() {
	if err := client.RPush("queue", "message").Err(); err != nil {
		panic(err)
	}

	// use `client.BLPop(0, "queue")` for infinite waiting time
	result, err := client.BLPop(1*time.Second, "queue").Result()
	if err != nil {
		panic(err)
	}

	fmt.Println(result[0], result[1])
	// Output: queue message
}

func ExampleClient_Scan() {
	client.FlushDB()
	for i := 0; i < 33; i++ {
		err := client.Set(fmt.Sprintf("key%d", i), "value", 0).Err()
		if err != nil {
			panic(err)
		}
	}

	var cursor uint64
	var n int
	for {
		var keys []string
		var err error
		keys, cursor, err = client.Scan(cursor, "", 10).Result()
		if err != nil {
			panic(err)
		}
		n += len(keys)
		if cursor == 0 {
			break
		}
	}

	fmt.Printf("found %d keys\n", n)
	// Output: found 33 keys
}

func ExampleClient_Pipelined() {
	var incr *redis.IntCmd
	_, err := client.Pipelined(func(pipe redis.Pipeliner) error {
		incr = pipe.Incr("pipelined_counter")
		pipe.Expire("pipelined_counter", time.Hour)
		return nil
	})
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_Pipeline() {
	pipe := client.Pipeline()

	incr := pipe.Incr("pipeline_counter")
	pipe.Expire("pipeline_counter", time.Hour)

	// Execute
	//
	//     INCR pipeline_counter
	//     EXPIRE pipeline_counts 3600
	//
	// using one client-server roundtrip.
	_, err := pipe.Exec()
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_TxPipelined() {
	var incr *redis.IntCmd
	_, err := client.TxPipelined(func(pipe redis.Pipeliner) error {
		incr = pipe.Incr("tx_pipelined_counter")
		pipe.Expire("tx_pipelined_counter", time.Hour)
		return nil
	})
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_TxPipeline() {
	pipe := client.TxPipeline()

	incr := pipe.Incr("tx_pipeline_counter")
	pipe.Expire("tx_pipeline_counter", time.Hour)

	// Execute
	//
	//     MULTI
	//     INCR pipeline_counter
	//     EXPIRE pipeline_counts 3600
	//     EXEC
	//
	// using one client-server roundtrip.
	_, err := pipe.Exec()
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_Watch() {
	var incr func(string) error

	// Transactionally increments key using GET and SET commands.
	incr = func(key string) error {
		err := client.Watch(func(tx *redis.Tx) error {
			n, err := tx.Get(key).Int64()
			if err != nil && err != redis.Nil {
				return err
			}

			_, err = tx.Pipelined(func(pipe redis.Pipeliner) error {
				pipe.Set(key, strconv.FormatInt(n+1, 10), 0)
				return nil
			})
			return err
		}, key)
		if err == redis.TxFailedErr {
			return incr(key)
		}
		return err
	}

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()

			err := incr("counter3")
			if err != nil {
				panic(err)
			}
		}()
	}
	wg.Wait()

	n, err := client.Get("counter3").Int64()
	fmt.Println(n, err)
	// Output: 100 <nil>
}

func ExamplePubSub() {
	pubsub := client.Subscribe("mychannel1")
	defer pubsub.Close()

	// Wait for confirmation that subscription is created before publishing anything.
	_, err := pubsub.Receive()
	if err != nil {
		panic(err)
	}

	// Go channel which receives messages.
	ch := pubsub.Channel()

	// Publish a message.
	err = client.Publish("mychannel1", "hello").Err()
	if err != nil {
		panic(err)
	}

	msg := <-ch
	fmt.Println(msg.Channel, msg.Payload)
	// Output: mychannel1 hello
}

func ExamplePubSub_Receive() {
	pubsub := client.Subscribe("mychannel2")
	defer pubsub.Close()

	for i := 0; i < 2; i++ {
		// ReceiveTimeout is a low level API. Use ReceiveMessage instead.
		msgi, err := pubsub.ReceiveTimeout(time.Second)
		if err != nil {
			break
		}

		switch msg := msgi.(type) {
		case *redis.Subscription:
			fmt.Println("subscribed to", msg.Channel)

			_, err := client.Publish("mychannel2", "hello").Result()
			if err != nil {
				panic(err)
			}
		case *redis.Message:
			fmt.Println("received", msg.Payload, "from", msg.Channel)
		default:
			panic("unreached")
		}
	}

	// sent message to 1 client
	// received hello from mychannel2
}

func ExampleScript() {
	IncrByXX := redis.NewScript(`
		if redis.call("GET", KEYS[1]) ~= false then
			return redis.call("INCRBY", KEYS[1], ARGV[1])
		end
		return false
	`)

	n, err := IncrByXX.Run(client, []string{"xx_counter"}, 2).Result()
	fmt.Println(n, err)

	err = client.Set("xx_counter", "40", 0).Err()
	if err != nil {
		panic(err)
	}

	n, err = IncrByXX.Run(client, []string{"xx_counter"}, 2).Result()
	fmt.Println(n, err)

	// Output: <nil> redis: nil
	// 42 <nil>
}

func Example_customCommand() {
	Get := func(client *redis.Client, key string) *redis.StringCmd {
		cmd := redis.NewStringCmd("get", key)
		client.Process(cmd)
		return cmd
	}

	v, err := Get(client, "key_does_not_exist").Result()
	fmt.Printf("%q %s", v, err)
	// Output: "" redis: nil
}

func ExampleScanIterator() {
	iter := client.Scan(0, "", 0).Iterator()
	for iter.Next() {
		fmt.Println(iter.Val())
	}
	if err := iter.Err(); err != nil {
		panic(err)
	}
}

func ExampleScanCmd_Iterator() {
	iter := client.Scan(0, "", 0).Iterator()
	for iter.Next() {
		fmt.Println(iter.Val())
	}
	if err := iter.Err(); err != nil {
		panic(err)
	}
}

func ExampleNewUniversalClient_simple() {
	client := redis.NewUniversalClient(&redis.UniversalOptions{
		Addrs: []string{":6379"},
	})
	defer client.Close()

	client.Ping()
}

func ExampleNewUniversalClient_failover() {
	client := redis.NewUniversalClient(&redis.UniversalOptions{
		MasterName: "master",
		Addrs:      []string{":26379"},
	})
	defer client.Close()

	client.Ping()
}

func ExampleNewUniversalClient_cluster() {
	client := redis.NewUniversalClient(&redis.UniversalOptions{
		Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
	})
	defer client.Close()

	client.Ping()
}
<commit_msg>Better PubSub example<commit_after>package redis_test

import (
	"fmt"
	"strconv"
	"sync"
	"time"

	"github.com/go-redis/redis"
)

var client *redis.Client

func init() {
	client = redis.NewClient(&redis.Options{
		Addr:         ":6379",
		DialTimeout:  10 * time.Second,
		ReadTimeout:  30 * time.Second,
		WriteTimeout: 30 * time.Second,
		PoolSize:     10,
		PoolTimeout:  30 * time.Second,
	})
	client.FlushDB()
}

func ExampleNewClient() {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	pong, err := client.Ping().Result()
	fmt.Println(pong, err)
	// Output: PONG <nil>
}

func ExampleParseURL() {
	opt, err := redis.ParseURL("redis://:qwerty@localhost:6379/1")
	if err != nil {
		panic(err)
	}
	fmt.Println("addr is", opt.Addr)
	fmt.Println("db is", opt.DB)
	fmt.Println("password is", opt.Password)

	// Create client as usually.
	_ = redis.NewClient(opt)

	// Output: addr is localhost:6379
	// db is 1
	// password is qwerty
}

func ExampleNewFailoverClient() {
	// See http://redis.io/topics/sentinel for instructions how to
	// setup Redis Sentinel.
	client := redis.NewFailoverClient(&redis.FailoverOptions{
		MasterName:    "master",
		SentinelAddrs: []string{":26379"},
	})
	client.Ping()
}

func ExampleNewClusterClient() {
	// See http://redis.io/topics/cluster-tutorial for instructions
	// how to setup Redis Cluster.
	client := redis.NewClusterClient(&redis.ClusterOptions{
		Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
	})
	client.Ping()
}

// Following example creates a cluster from 2 master nodes and 2 slave nodes
// without using cluster mode or Redis Sentinel.
func ExampleNewClusterClient_manualSetup() {
	// clusterSlots returns cluster slots information.
	// It can use service like ZooKeeper to maintain configuration information
	// and Cluster.ReloadState to manually trigger state reloading.
	clusterSlots := func() ([]redis.ClusterSlot, error) {
		slots := []redis.ClusterSlot{
			// First node with 1 master and 1 slave.
			{
				Start: 0,
				End:   8191,
				Nodes: []redis.ClusterNode{{
					Addr: ":7000", // master
				}, {
					Addr: ":8000", // 1st slave
				}},
			},
			// Second node with 1 master and 1 slave.
			{
				Start: 8192,
				End:   16383,
				Nodes: []redis.ClusterNode{{
					Addr: ":7001", // master
				}, {
					Addr: ":8001", // 1st slave
				}},
			},
		}
		return slots, nil
	}

	client := redis.NewClusterClient(&redis.ClusterOptions{
		ClusterSlots:  clusterSlots,
		RouteRandomly: true,
	})
	client.Ping()

	// ReloadState reloads cluster state. It calls ClusterSlots func
	// to get cluster slots information.
	err := client.ReloadState()
	if err != nil {
		panic(err)
	}
}

func ExampleNewRing() {
	client := redis.NewRing(&redis.RingOptions{
		Addrs: map[string]string{
			"shard1": ":7000",
			"shard2": ":7001",
			"shard3": ":7002",
		},
	})
	client.Ping()
}

func ExampleClient() {
	err := client.Set("key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	val, err := client.Get("key").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("key", val)

	val2, err := client.Get("key2").Result()
	if err == redis.Nil {
		fmt.Println("key2 does not exist")
	} else if err != nil {
		panic(err)
	} else {
		fmt.Println("key2", val2)
	}
	// Output: key value
	// key2 does not exist
}

func ExampleClient_Set() {
	// Last argument is expiration. Zero means the key has no
	// expiration time.
	err := client.Set("key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	// key2 will expire in an hour.
	err = client.Set("key2", "value", time.Hour).Err()
	if err != nil {
		panic(err)
	}
}

func ExampleClient_Incr() {
	result, err := client.Incr("counter").Result()
	if err != nil {
		panic(err)
	}

	fmt.Println(result)
	// Output: 1
}

func ExampleClient_BLPop() {
	if err := client.RPush("queue", "message").Err(); err != nil {
		panic(err)
	}

	// use `client.BLPop(0, "queue")` for infinite waiting time
	result, err := client.BLPop(1*time.Second, "queue").Result()
	if err != nil {
		panic(err)
	}

	fmt.Println(result[0], result[1])
	// Output: queue message
}

func ExampleClient_Scan() {
	client.FlushDB()
	for i := 0; i < 33; i++ {
		err := client.Set(fmt.Sprintf("key%d", i), "value", 0).Err()
		if err != nil {
			panic(err)
		}
	}

	var cursor uint64
	var n int
	for {
		var keys []string
		var err error
		keys, cursor, err = client.Scan(cursor, "", 10).Result()
		if err != nil {
			panic(err)
		}
		n += len(keys)
		if cursor == 0 {
			break
		}
	}

	fmt.Printf("found %d keys\n", n)
	// Output: found 33 keys
}

func ExampleClient_Pipelined() {
	var incr *redis.IntCmd
	_, err := client.Pipelined(func(pipe redis.Pipeliner) error {
		incr = pipe.Incr("pipelined_counter")
		pipe.Expire("pipelined_counter", time.Hour)
		return nil
	})
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_Pipeline() {
	pipe := client.Pipeline()

	incr := pipe.Incr("pipeline_counter")
	pipe.Expire("pipeline_counter", time.Hour)

	// Execute
	//
	//     INCR pipeline_counter
	//     EXPIRE pipeline_counts 3600
	//
	// using one client-server roundtrip.
	_, err := pipe.Exec()
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_TxPipelined() {
	var incr *redis.IntCmd
	_, err := client.TxPipelined(func(pipe redis.Pipeliner) error {
		incr = pipe.Incr("tx_pipelined_counter")
		pipe.Expire("tx_pipelined_counter", time.Hour)
		return nil
	})
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_TxPipeline() {
	pipe := client.TxPipeline()

	incr := pipe.Incr("tx_pipeline_counter")
	pipe.Expire("tx_pipeline_counter", time.Hour)

	// Execute
	//
	//     MULTI
	//     INCR pipeline_counter
	//     EXPIRE pipeline_counts 3600
	//     EXEC
	//
	// using one client-server roundtrip.
	_, err := pipe.Exec()
	fmt.Println(incr.Val(), err)
	// Output: 1 <nil>
}

func ExampleClient_Watch() {
	var incr func(string) error

	// Transactionally increments key using GET and SET commands.
	incr = func(key string) error {
		err := client.Watch(func(tx *redis.Tx) error {
			n, err := tx.Get(key).Int64()
			if err != nil && err != redis.Nil {
				return err
			}

			_, err = tx.Pipelined(func(pipe redis.Pipeliner) error {
				pipe.Set(key, strconv.FormatInt(n+1, 10), 0)
				return nil
			})
			return err
		}, key)
		if err == redis.TxFailedErr {
			return incr(key)
		}
		return err
	}

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()

			err := incr("counter3")
			if err != nil {
				panic(err)
			}
		}()
	}
	wg.Wait()

	n, err := client.Get("counter3").Int64()
	fmt.Println(n, err)
	// Output: 100 <nil>
}

func ExamplePubSub() {
	pubsub := client.Subscribe("mychannel1")

	// Wait for confirmation that subscription is created before publishing anything.
	_, err := pubsub.Receive()
	if err != nil {
		panic(err)
	}

	// Go channel which receives messages.
	ch := pubsub.Channel()

	// Publish a message.
	err = client.Publish("mychannel1", "hello").Err()
	if err != nil {
		panic(err)
	}

	time.AfterFunc(time.Second, func() {
		// When pubsub is closed channel is closed too.
		_ = pubsub.Close()
	})

	// Consume messages.
	for {
		msg, ok := <-ch
		if !ok {
			break
		}
		fmt.Println(msg.Channel, msg.Payload)
	}

	// Output: mychannel1 hello
}

func ExamplePubSub_Receive() {
	pubsub := client.Subscribe("mychannel2")
	defer pubsub.Close()

	for i := 0; i < 2; i++ {
		// ReceiveTimeout is a low level API. Use ReceiveMessage instead.
		msgi, err := pubsub.ReceiveTimeout(time.Second)
		if err != nil {
			break
		}

		switch msg := msgi.(type) {
		case *redis.Subscription:
			fmt.Println("subscribed to", msg.Channel)

			_, err := client.Publish("mychannel2", "hello").Result()
			if err != nil {
				panic(err)
			}
		case *redis.Message:
			fmt.Println("received", msg.Payload, "from", msg.Channel)
		default:
			panic("unreached")
		}
	}

	// sent message to 1 client
	// received hello from mychannel2
}

func ExampleScript() {
	IncrByXX := redis.NewScript(`
		if redis.call("GET", KEYS[1]) ~= false then
			return redis.call("INCRBY", KEYS[1], ARGV[1])
		end
		return false
	`)

	n, err := IncrByXX.Run(client, []string{"xx_counter"}, 2).Result()
	fmt.Println(n, err)

	err = client.Set("xx_counter", "40", 0).Err()
	if err != nil {
		panic(err)
	}

	n, err = IncrByXX.Run(client, []string{"xx_counter"}, 2).Result()
	fmt.Println(n, err)

	// Output: <nil> redis: nil
	// 42 <nil>
}

func Example_customCommand() {
	Get := func(client *redis.Client, key string) *redis.StringCmd {
		cmd := redis.NewStringCmd("get", key)
		client.Process(cmd)
		return cmd
	}

	v, err := Get(client, "key_does_not_exist").Result()
	fmt.Printf("%q %s", v, err)
	// Output: "" redis: nil
}

func ExampleScanIterator() {
	iter := client.Scan(0, "", 0).Iterator()
	for iter.Next() {
		fmt.Println(iter.Val())
	}
	if err := iter.Err(); err != nil {
		panic(err)
	}
}

func ExampleScanCmd_Iterator() {
	iter := client.Scan(0, "", 0).Iterator()
	for iter.Next() {
		fmt.Println(iter.Val())
	}
	if err := iter.Err(); err != nil {
		panic(err)
	}
}

func ExampleNewUniversalClient_simple() {
	client := redis.NewUniversalClient(&redis.UniversalOptions{
		Addrs: []string{":6379"},
	})
	defer client.Close()

	client.Ping()
}

func ExampleNewUniversalClient_failover() {
	client := redis.NewUniversalClient(&redis.UniversalOptions{
		MasterName: "master",
		Addrs:      []string{":26379"},
	})
	defer client.Close()

	client.Ping()
}

func ExampleNewUniversalClient_cluster() {
	client := redis.NewUniversalClient(&redis.UniversalOptions{
		Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
	})
	defer client.Close()

	client.Ping()
}
<|endoftext|>


<commit_before>// Copyright 2016-2020 Olivier Mengué. All rights reserved.
// Use of this source code is governed by the Apache 2.0 license that
// can be found in the LICENSE file.

package jsonptr_test

import (
	"encoding/json"
	"fmt"

	"github.com/dolmen-go/jsonptr"
)

// Example from https://tools.ietf.org/html/rfc6901#section-5
func Example() {
	const JSON = `
{
   "foo": ["bar", "baz"],
   "": 0,
   "a/b": 1,
   "c%d": 2,
   "e^f": 3,
   "g|h": 4,
   "i\\j": 5,
   "k\"l": 6,
   " ": 7,
   "m~n": 8
}`
	var doc interface{}
	_ = json.Unmarshal([]byte(JSON), &doc)

	for _, ptr := range []string{
		"/foo",
		"/foo/0",
		"/",
		"/a~1b",
		"/c%d",
		"/e^f",
		"/g|h",
		"/i\\j",
		"/k\"l",
		"/ ",
		"/m~0n",
	} {
		result, _ := jsonptr.Get(doc, ptr)
		fmt.Printf("%-12q %#v\n", ptr, result)
	}
	// Output:
	// "/foo"       []interface {}{"bar", "baz"}
	// "/foo/0"     "bar"
	// "/"          0
	// "/a~1b"      1
	// "/c%d"       2
	// "/e^f"       3
	// "/g|h"       4
	// "/i\\j"      5
	// "/k\"l"      6
	// "/ "         7
	// "/m~0n"      8
}

func ExampleSet() {

	newArray := []interface{}(nil)
	newObject := map[string]interface{}(nil)

	var doc interface{}

	for _, step := range []struct {
		where string
		what  interface{}
	}{
		{"", newObject},
		{"/arr", newArray},
		{"/arr/-", 3},
		{"/arr/-", 2},
		{"/arr/-", 1},
		{"/obj", newObject},
		{"/obj/str", "hello"},
		{"/obj/bool", true},
		{"/arr/-", 0},
		{"/obj/", nil},
	} {
		err := jsonptr.Set(&doc, step.where, step.what)
		if err != nil {
			panic(err)
		}
		//fmt.Printf("%#v\n", doc)
	}

	fmt.Println(func() string { x, _ := json.Marshal(doc); return string(x) }())
	// Output:
	// {"arr":[3,2,1,0],"obj":{"":null,"bool":true,"str":"hello"}}
}
<commit_msg>Add an example of JSONDecoder usage with Get()<commit_after>// Copyright 2016-2020 Olivier Mengué. All rights reserved.
// Use of this source code is governed by the Apache 2.0 license that
// can be found in the LICENSE file.

package jsonptr_test

import (
	"encoding/json"
	"fmt"
	"strings"
	"testing/iotest"

	"github.com/dolmen-go/jsonptr"
)

// Example from https://tools.ietf.org/html/rfc6901#section-5
func Example() {
	const JSON = `
{
   "foo": ["bar", "baz"],
   "": 0,
   "a/b": 1,
   "c%d": 2,
   "e^f": 3,
   "g|h": 4,
   "i\\j": 5,
   "k\"l": 6,
   " ": 7,
   "m~n": 8
}`
	var doc interface{}
	_ = json.Unmarshal([]byte(JSON), &doc)

	for _, ptr := range []string{
		"/foo",
		"/foo/0",
		"/",
		"/a~1b",
		"/c%d",
		"/e^f",
		"/g|h",
		"/i\\j",
		"/k\"l",
		"/ ",
		"/m~0n",
	} {
		result, _ := jsonptr.Get(doc, ptr)
		fmt.Printf("%-12q %#v\n", ptr, result)
	}
	// Output:
	// "/foo"       []interface {}{"bar", "baz"}
	// "/foo/0"     "bar"
	// "/"          0
	// "/a~1b"      1
	// "/c%d"       2
	// "/e^f"       3
	// "/g|h"       4
	// "/i\\j"      5
	// "/k\"l"      6
	// "/ "         7
	// "/m~0n"      8
}

// ExampleJSONDecoder shows how to extract from a streamed JSON document.
func ExampleJSONDecoder() {
	stream := iotest.OneByteReader(strings.NewReader(`{"a": 42,"b":5}`))
	decoder := json.NewDecoder(stream)

	result, _ := jsonptr.Get(decoder, "/a")
	fmt.Println(result)
	// Output:
	// 42
}

func ExampleSet() {

	newArray := []interface{}(nil)
	newObject := map[string]interface{}(nil)

	var doc interface{}

	for _, step := range []struct {
		where string
		what  interface{}
	}{
		{"", newObject},
		{"/arr", newArray},
		{"/arr/-", 3},
		{"/arr/-", 2},
		{"/arr/-", 1},
		{"/obj", newObject},
		{"/obj/str", "hello"},
		{"/obj/bool", true},
		{"/arr/-", 0},
		{"/obj/", nil},
	} {
		err := jsonptr.Set(&doc, step.where, step.what)
		if err != nil {
			panic(err)
		}
		//fmt.Printf("%#v\n", doc)
	}

	fmt.Println(func() string { x, _ := json.Marshal(doc); return string(x) }())
	// Output:
	// {"arr":[3,2,1,0],"obj":{"":null,"bool":true,"str":"hello"}}
}
<|endoftext|>


<commit_before>package reference

import (
	"regexp"
	"strings"

	// "opencontainers/go-digest" requires us to load the algorithms that we
	// want to use into the binary (it calls .Available).
	_ "crypto/sha256"

	distreference "github.com/docker/distribution/reference"
	"github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
)

const (
	// XDefaultTag defines the default tag used when performing images related actions and no tag or digest is specified
	XDefaultTag = "latest"
	// XDefaultHostname is the default built-in hostname
	XDefaultHostname = "docker.io"
	// XLegacyDefaultHostname is automatically converted to DefaultHostname
	XLegacyDefaultHostname = "index.docker.io"
	// XDefaultRepoPrefix is the prefix used for default repositories in default host
	XDefaultRepoPrefix = "library/"
)

// XNamed is an object with a full name
type XNamed interface {
	// XName returns normalized repository name, like "ubuntu".
	XName() string
	// XString returns full reference, like "ubuntu@sha256:abcdef..."
	XString() string
	// XFullName returns full repository name with hostname, like "docker.io/library/ubuntu"
	XFullName() string
	// XHostname returns hostname for the reference, like "docker.io"
	XHostname() string
	// XRemoteName returns the repository component of the full name, like "library/ubuntu"
	XRemoteName() string
}

// XNamedTagged is an object including a name and tag.
type XNamedTagged interface {
	XNamed
	XTag() string
}

// XCanonical reference is an object with a fully unique
// name including a name with hostname and digest
type XCanonical interface {
	XNamed
	XDigest() digest.Digest
}

// XParseNamed parses s and returns a syntactically valid reference implementing
// the Named interface. The reference must have a name, otherwise an error is
// returned.
// If an error was encountered it is returned, along with a nil Reference.
func XParseNamed(s string) (XNamed, error) {
	named, err := distreference.ParseNormalizedNamed(s)
	if err != nil {
		return nil, errors.Wrapf(err, "Error parsing reference: %q is not a valid repository/tag", s)
	}
	r, err := XWithName(named.Name())
	if err != nil {
		return nil, err
	}
	if canonical, isCanonical := named.(distreference.Canonical); isCanonical {
		// FIXME: depends on XWithName returning a *namedRef.
		r, err := distreference.WithDigest(r.(*namedRef).Named, canonical.Digest())
		if err != nil {
			return nil, err
		}
		return &canonicalRef{namedRef{r}}, nil
	}
	if tagged, isTagged := named.(distreference.NamedTagged); isTagged {
		return XWithTag(r, tagged.Tag())
	}
	return r, nil
}

// XWithName returns a named object representing the given string. If the input
// is invalid ErrReferenceInvalidFormat will be returned.
func XWithName(name string) (XNamed, error) {
	name, err := normalize(name)
	if err != nil {
		return nil, err
	}
	if err := validateName(name); err != nil {
		return nil, err
	}
	r, err := distreference.WithName(name)
	if err != nil {
		return nil, err
	}
	return &namedRef{r}, nil
}

// XWithTag combines the name from "name" and the tag from "tag" to form a
// reference incorporating both the name and the tag.
func XWithTag(name XNamed, tag string) (XNamedTagged, error) {
	// FIXME: depends on XWithName returning a *namedRef, and that this is only called on XNameOnly values.
	r, err := distreference.WithTag(name.(*namedRef).Named, tag)
	if err != nil {
		return nil, err
	}
	return &taggedRef{namedRef{r}}, nil
}

type namedRef struct {
	distreference.Named
}
type taggedRef struct {
	namedRef
}
type canonicalRef struct {
	namedRef
}

func (r *namedRef) XName() string {
	return r.Named.Name()
}
func (r *namedRef) XString() string {
	return r.Named.String()
}
func (r *namedRef) XFullName() string {
	hostname, remoteName := splitHostname(r.XName())
	return hostname + "/" + remoteName
}
func (r *namedRef) XHostname() string {
	hostname, _ := splitHostname(r.XName())
	return hostname
}
func (r *namedRef) XRemoteName() string {
	_, remoteName := splitHostname(r.XName())
	return remoteName
}
func (r *taggedRef) XTag() string {
	return r.namedRef.Named.(distreference.NamedTagged).Tag()
}
func (r *canonicalRef) XDigest() digest.Digest {
	return digest.Digest(r.namedRef.Named.(distreference.Canonical).Digest())
}

// XWithDefaultTag adds a default tag to a reference if it only has a repo name.
func XWithDefaultTag(ref XNamed) XNamed {
	if XIsNameOnly(ref) {
		ref, _ = XWithTag(ref, XDefaultTag)
	}
	return ref
}

// XIsNameOnly returns true if reference only contains a repo name.
func XIsNameOnly(ref XNamed) bool {
	if _, ok := ref.(XNamedTagged); ok {
		return false
	}
	if _, ok := ref.(XCanonical); ok {
		return false
	}
	return true
}

// XParseIDOrReference parses string for an image ID or a reference. ID can be
// without a default prefix.
func XParseIDOrReference(idOrRef string) (digest.Digest, XNamed, error) {
	if err := validateID(idOrRef); err == nil {
		idOrRef = "sha256:" + idOrRef
	}
	if dgst, err := digest.Parse(idOrRef); err == nil {
		return dgst, nil, nil
	}
	ref, err := XParseNamed(idOrRef)
	return "", ref, err
}

// splitHostname splits a repository name to hostname and remotename string.
// If no valid hostname is found, the default hostname is used. Repository name
// needs to be already validated before.
func splitHostname(name string) (hostname, remoteName string) {
	i := strings.IndexRune(name, '/')
	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
		hostname, remoteName = XDefaultHostname, name
	} else {
		hostname, remoteName = name[:i], name[i+1:]
	}
	if hostname == XLegacyDefaultHostname {
		hostname = XDefaultHostname
	}
	if hostname == XDefaultHostname && !strings.ContainsRune(remoteName, '/') {
		remoteName = XDefaultRepoPrefix + remoteName
	}
	return
}

// normalize returns a repository name in its normalized form, meaning it
// will not contain default hostname nor library/ prefix for official images.
func normalize(name string) (string, error) {
	host, remoteName := splitHostname(name)
	if strings.ToLower(remoteName) != remoteName {
		return "", errors.New("invalid reference format: repository name must be lowercase")
	}
	if host == XDefaultHostname {
		if strings.HasPrefix(remoteName, XDefaultRepoPrefix) {
			return strings.TrimPrefix(remoteName, XDefaultRepoPrefix), nil
		}
		return remoteName, nil
	}
	return name, nil
}

var validHex = regexp.MustCompile(`^([a-f0-9]{64})$`)

func validateID(id string) error {
	if ok := validHex.MatchString(id); !ok {
		return errors.Errorf("image ID %q is invalid", id)
	}
	return nil
}

func validateName(name string) error {
	if err := validateID(name); err == nil {
		return errors.Errorf("Invalid repository name (%s), cannot specify 64-byte hexadecimal strings", name)
	}
	return nil
}
<commit_msg>Duplication: Have TWO distreference.Named values in namedRef<commit_after>package reference

import (
	"regexp"
	"strings"

	// "opencontainers/go-digest" requires us to load the algorithms that we
	// want to use into the binary (it calls .Available).
	_ "crypto/sha256"

	distreference "github.com/docker/distribution/reference"
	"github.com/opencontainers/go-digest"
	"github.com/pkg/errors"
)

const (
	// XDefaultTag defines the default tag used when performing images related actions and no tag or digest is specified
	XDefaultTag = "latest"
	// XDefaultHostname is the default built-in hostname
	XDefaultHostname = "docker.io"
	// XLegacyDefaultHostname is automatically converted to DefaultHostname
	XLegacyDefaultHostname = "index.docker.io"
	// XDefaultRepoPrefix is the prefix used for default repositories in default host
	XDefaultRepoPrefix = "library/"
)

// XNamed is an object with a full name
type XNamed interface {
	// XName returns normalized repository name, like "ubuntu".
	XName() string
	// XString returns full reference, like "ubuntu@sha256:abcdef..."
	XString() string
	// XFullName returns full repository name with hostname, like "docker.io/library/ubuntu"
	XFullName() string
	// XHostname returns hostname for the reference, like "docker.io"
	XHostname() string
	// XRemoteName returns the repository component of the full name, like "library/ubuntu"
	XRemoteName() string
}

// XNamedTagged is an object including a name and tag.
type XNamedTagged interface {
	XNamed
	XTag() string
}

// XCanonical reference is an object with a fully unique
// name including a name with hostname and digest
type XCanonical interface {
	XNamed
	XDigest() digest.Digest
}

// XParseNamed parses s and returns a syntactically valid reference implementing
// the Named interface. The reference must have a name, otherwise an error is
// returned.
// If an error was encountered it is returned, along with a nil Reference.
func XParseNamed(s string) (XNamed, error) {
	named, err := distreference.ParseNormalizedNamed(s)
	if err != nil {
		return nil, errors.Wrapf(err, "Error parsing reference: %q is not a valid repository/tag", s)
	}
	r, err := XWithName(named.Name())
	if err != nil {
		return nil, err
	}
	if canonical, isCanonical := named.(distreference.Canonical); isCanonical {
		upstreamR, err := distreference.WithDigest(r.upstream, canonical.Digest())
		if err != nil {
			return nil, err
		}
		ourR, err := distreference.WithDigest(r.our, canonical.Digest())
		if err != nil {
			return nil, err
		}
		return &canonicalRef{namedRef{upstream: upstreamR, our: ourR}}, nil
	}
	if tagged, isTagged := named.(distreference.NamedTagged); isTagged {
		return XWithTag(r, tagged.Tag())
	}
	return r, nil
}

// XWithName returns a named object representing the given string. If the input
// is invalid ErrReferenceInvalidFormat will be returned.
// FIXME: returns *namedRef to expose the upstream/our fields. Should revert to XNamed/Named.
func XWithName(name string) (*namedRef, error) {
	upstreamR, err := distreference.ParseNormalizedNamed(name)
	if err != nil {
		return nil, err
	}
	name, err = normalize(name)
	if err != nil {
		return nil, err
	}
	if err := validateName(name); err != nil {
		return nil, err
	}
	ourR, err := distreference.WithName(name)
	if err != nil {
		return nil, err
	}
	return &namedRef{upstream: upstreamR, our: ourR}, nil
}

// XWithTag combines the name from "name" and the tag from "tag" to form a
// reference incorporating both the name and the tag.
// FIXME: expects *namedRef to expose the upstream/our fields. Should revert to XNamed/Named.
func XWithTag(name *namedRef, tag string) (XNamedTagged, error) {
	upstreamR, err := distreference.WithTag(name.upstream, tag)
	if err != nil {
		return nil, err
	}
	ourR, err := distreference.WithTag(name.our, tag)
	if err != nil {
		return nil, err
	}
	return &taggedRef{namedRef{upstream: upstreamR, our: ourR}}, nil
}

type namedRef struct {
	// TRANSITIONAL state: We want to transition from our semantics (Name(), String() return a minified form)
	// to the upstream ones (Name(), String() return the fully expanded form). In the mean time we still
	// want to call upstream distreference.* methods on the namedRef implementation.
	//
	// As it happens, distreference.WithTag and distreference.WithDigest can both accept
	// minimized input and return minimized output, so we can keep using them even with the minimized
	// values.
	//
	// For the transition,  we keep an "upstream", fully expanded, value, and "our", which we have minimized.
	// We start with "upstream" being essentially write-only, with no users in containers/image.
	// Then we will, bit by bit, eliminate uses of "our".
	//
	// upstream uses the normalization from distreference.ParseNormalizedNamed
	upstream distreference.Named
	// our is what the existing code used to do, via normalize()
	our distreference.Named
}
type taggedRef struct {
	namedRef
}
type canonicalRef struct {
	namedRef
}

func (r *namedRef) XName() string {
	return r.our.Name()
}
func (r *namedRef) XString() string {
	return r.our.String()
}
func (r *namedRef) XFullName() string {
	hostname, remoteName := splitHostname(r.XName())
	return hostname + "/" + remoteName
}
func (r *namedRef) XHostname() string {
	hostname, _ := splitHostname(r.XName())
	return hostname
}
func (r *namedRef) XRemoteName() string {
	_, remoteName := splitHostname(r.XName())
	return remoteName
}
func (r *taggedRef) XTag() string {
	return r.namedRef.our.(distreference.NamedTagged).Tag()
}
func (r *canonicalRef) XDigest() digest.Digest {
	return digest.Digest(r.namedRef.our.(distreference.Canonical).Digest())
}

// XWithDefaultTag adds a default tag to a reference if it only has a repo name.
func XWithDefaultTag(ref XNamed) XNamed {
	if XIsNameOnly(ref) {
		// FIXME: uses *namedRef to expose the upstream/our fields. Should use ref without a cast.
		ref, _ = XWithTag(ref.(*namedRef), XDefaultTag)
	}
	return ref
}

// XIsNameOnly returns true if reference only contains a repo name.
func XIsNameOnly(ref XNamed) bool {
	if _, ok := ref.(XNamedTagged); ok {
		return false
	}
	if _, ok := ref.(XCanonical); ok {
		return false
	}
	return true
}

// XParseIDOrReference parses string for an image ID or a reference. ID can be
// without a default prefix.
func XParseIDOrReference(idOrRef string) (digest.Digest, XNamed, error) {
	if err := validateID(idOrRef); err == nil {
		idOrRef = "sha256:" + idOrRef
	}
	if dgst, err := digest.Parse(idOrRef); err == nil {
		return dgst, nil, nil
	}
	ref, err := XParseNamed(idOrRef)
	return "", ref, err
}

// splitHostname splits a repository name to hostname and remotename string.
// If no valid hostname is found, the default hostname is used. Repository name
// needs to be already validated before.
func splitHostname(name string) (hostname, remoteName string) {
	i := strings.IndexRune(name, '/')
	if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
		hostname, remoteName = XDefaultHostname, name
	} else {
		hostname, remoteName = name[:i], name[i+1:]
	}
	if hostname == XLegacyDefaultHostname {
		hostname = XDefaultHostname
	}
	if hostname == XDefaultHostname && !strings.ContainsRune(remoteName, '/') {
		remoteName = XDefaultRepoPrefix + remoteName
	}
	return
}

// normalize returns a repository name in its normalized form, meaning it
// will not contain default hostname nor library/ prefix for official images.
func normalize(name string) (string, error) {
	host, remoteName := splitHostname(name)
	if strings.ToLower(remoteName) != remoteName {
		return "", errors.New("invalid reference format: repository name must be lowercase")
	}
	if host == XDefaultHostname {
		if strings.HasPrefix(remoteName, XDefaultRepoPrefix) {
			return strings.TrimPrefix(remoteName, XDefaultRepoPrefix), nil
		}
		return remoteName, nil
	}
	return name, nil
}

var validHex = regexp.MustCompile(`^([a-f0-9]{64})$`)

func validateID(id string) error {
	if ok := validHex.MatchString(id); !ok {
		return errors.Errorf("image ID %q is invalid", id)
	}
	return nil
}

func validateName(name string) error {
	if err := validateID(name); err == nil {
		return errors.Errorf("Invalid repository name (%s), cannot specify 64-byte hexadecimal strings", name)
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fuse

import (
	"fmt"
	"log"
	"runtime"
	"strings"

	"golang.org/x/net/context"
)

// Optional configuration accepted by Mount.
type MountConfig struct {
	// The context from which every op read from the connetion by the sever
	// should inherit. If nil, context.Background() will be used.
	OpContext context.Context

	// If non-empty, the name of the file system as displayed by e.g. `mount`.
	// This is important because the `umount` command requires root privileges if
	// it doesn't agree with /etc/fstab.
	FSName string

	// Mount the file system in read-only mode. File modes will appear as normal,
	// but opening a file for writing and metadata operations like chmod,
	// chtimes, etc. will fail.
	ReadOnly bool

	// A logger to use for logging errors. All errors are logged, with the
	// exception of a few blacklisted errors that are expected. If nil, no error
	// logging is performed.
	ErrorLogger *log.Logger

	// A logger to use for logging debug information. If nil, no debug logging is
	// performed.
	DebugLogger *log.Logger

	// Linux only. OS X always behaves as if writeback caching is disabled.
	//
	// By default on Linux we allow the kernel to perform writeback caching
	// (cf. http://goo.gl/LdZzo1):
	//
	// *   When the user calls write(2), the kernel sticks the user's data into
	//     its page cache. Only later does it call through to the file system,
	//     potentially after coalescing multiple small user writes.
	//
	// *   The file system may receive multiple write ops from the kernel
	//     concurrently if there is a lot of page cache data to flush.
	//
	// *   Write performance may be significantly improved due to the user and
	//     the kernel not waiting for serial round trips to the file system. This
	//     is especially true if the user makes tiny writes.
	//
	// *   close(2) (and anything else calling f_op->flush) causes all dirty
	//     pages to be written out before it proceeds to send a FlushFileOp
	//     (cf. https://goo.gl/TMrY6X).
	//
	// *   Similarly, close(2) causes the kernel to send a setattr request
	//     filling in the mtime if any dirty pages were flushed, since the time
	//     at which the pages were written to the file system can't be trusted.
	//
	// *   close(2) (and anything else calling f_op->flush) writes out all dirty
	//     pages, then sends a setattr request with an appropriate mtime for
	//     those writes if there were any, and only then proceeds to send a flush
	//
	//     Code walk:
	//
	//     *   (https://goo.gl/zTIZQ9) fuse_flush calls write_inode_now before
	//         calling the file system. The latter eventually calls into
	//         __writeback_single_inode.
	//
	//     *   (https://goo.gl/L7Z2w5) __writeback_single_inode calls
	//         do_writepages, which writes out any dirty pages.
	//
	//     *   (https://goo.gl/DOPgla) __writeback_single_inode later calls
	//         write_inode, which calls into the superblock op struct's write_inode
	//         member. For fuse, this is fuse_write_inode
	//         (cf. https://goo.gl/eDSKOX).
	//
	//     *   (https://goo.gl/PbkGA1) fuse_write_inode calls fuse_flush_times.
	//
	//     *   (https://goo.gl/ig8x9V) fuse_flush_times sends a setttr request
	//         for setting the inode's mtime.
	//
	// However, this brings along some caveats:
	//
	// *   The file system must handle SetInodeAttributesOp or close(2) will fail,
	//     due to the call chain into fuse_flush_times listed above.
	//
	// *   The kernel caches mtime and ctime regardless of whether the file
	//     system tells it to do so, disregarding the result of further getattr
	//     requests (cf. https://goo.gl/3ZZMUw, https://goo.gl/7WtQUp). It
	//     appears this may be true of the file size, too. Writeback caching may
	//     therefore not be suitable for file systems where these attributes can
	//     spontaneously change for reasons the kernel doesn't observe. See
	//     http://goo.gl/V5WQCN for more discussion.
	//
	// Setting DisableWritebackCaching disables this behavior. Instead the file
	// system is called one or more times for each write(2), and the user's
	// syscall doesn't return until the file system returns.
	DisableWritebackCaching bool

	// OS X only.
	//
	// Normally on OS X we mount with the novncache option
	// (cf. http://goo.gl/1pTjuk), which disables entry caching in the kernel.
	// This is because osxfuse does not honor the entry expiration values we
	// return to it, instead caching potentially forever (cf.
	// http://goo.gl/8yR0Ie), and it is probably better to fail to cache than to
	// cache for too long, since the latter is more likely to hide consistency
	// bugs that are difficult to detect and diagnose.
	//
	// This field disables the use of novncache, restoring entry caching. Beware:
	// the value of ChildInodeEntry.EntryExpiration is ignored by the kernel, and
	// entries will be cached for an arbitrarily long time.
	EnableVnodeCaching bool

	// Additional key=value options to pass unadulterated to the underlying mount
	// command. See `man 8 mount`, the fuse documentation, etc. for
	// system-specific information.
	//
	// For expert use only! May invalidate other guarantees made in the
	// documentation for this package.
	Options map[string]string
}

// Create a map containing all of the key=value mount options to be given to
// the mount helper.
func (c *MountConfig) toMap() (opts map[string]string) {
	isDarwin := runtime.GOOS == "darwin"
	opts = make(map[string]string)

	// Enable permissions checking in the kernel. See the comments on
	// InodeAttributes.Mode.
	opts["default_permissions"] = ""

	// HACK(jacobsa): Work around what appears to be a bug in systemd v219, as
	// shipped in Ubuntu 15.04, where it automatically unmounts any file system
	// that doesn't set an explicit name.
	//
	// When Ubuntu contains systemd v220, this workaround should be removed and
	// the systemd bug reopened if the problem persists.
	//
	// Cf. https://github.com/bazil/fuse/issues/89
	// Cf. https://bugs.freedesktop.org/show_bug.cgi?id=90907
	fsname := c.FSName
	if runtime.GOOS == "linux" && fsname == "" {
		fsname = "some_fuse_file_system"
	}

	// Special file system name?
	if fsname != "" {
		opts["fsname"] = fsname
	}

	// Read only?
	if c.ReadOnly {
		opts["ro"] = ""
	}

	// OS X: set novncache when appropriate.
	if isDarwin && !c.EnableVnodeCaching {
		opts["novncache"] = ""
	}

	// OS X: disable the use of "Apple Double" (._foo and .DS_Store) files, which
	// just add noise to debug output and can have significant cost on
	// network-based file systems.
	//
	// Cf. https://github.com/osxfuse/osxfuse/wiki/Mount-options
	if isDarwin {
		opts["noappledouble"] = ""
	}

	// Last but not least: other user-supplied options.
	for k, v := range c.Options {
		opts[k] = v
	}

	return
}

func escapeOptionsKey(s string) (res string) {
	res = s
	res = strings.Replace(res, `\`, `\\`, -1)
	res = strings.Replace(res, `,`, `\,`, -1)
	return
}

// Create an options string suitable for passing to the mount helper.
func (c *MountConfig) toOptionsString() string {
	var components []string
	for k, v := range c.toMap() {
		k = escapeOptionsKey(k)

		component := k
		if v != "" {
			component = fmt.Sprintf("%s=%s", k, v)
		}

		components = append(components, component)
	}

	return strings.Join(components, ",")
}
<commit_msg>Added a missing full stop.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fuse

import (
	"fmt"
	"log"
	"runtime"
	"strings"

	"golang.org/x/net/context"
)

// Optional configuration accepted by Mount.
type MountConfig struct {
	// The context from which every op read from the connetion by the sever
	// should inherit. If nil, context.Background() will be used.
	OpContext context.Context

	// If non-empty, the name of the file system as displayed by e.g. `mount`.
	// This is important because the `umount` command requires root privileges if
	// it doesn't agree with /etc/fstab.
	FSName string

	// Mount the file system in read-only mode. File modes will appear as normal,
	// but opening a file for writing and metadata operations like chmod,
	// chtimes, etc. will fail.
	ReadOnly bool

	// A logger to use for logging errors. All errors are logged, with the
	// exception of a few blacklisted errors that are expected. If nil, no error
	// logging is performed.
	ErrorLogger *log.Logger

	// A logger to use for logging debug information. If nil, no debug logging is
	// performed.
	DebugLogger *log.Logger

	// Linux only. OS X always behaves as if writeback caching is disabled.
	//
	// By default on Linux we allow the kernel to perform writeback caching
	// (cf. http://goo.gl/LdZzo1):
	//
	// *   When the user calls write(2), the kernel sticks the user's data into
	//     its page cache. Only later does it call through to the file system,
	//     potentially after coalescing multiple small user writes.
	//
	// *   The file system may receive multiple write ops from the kernel
	//     concurrently if there is a lot of page cache data to flush.
	//
	// *   Write performance may be significantly improved due to the user and
	//     the kernel not waiting for serial round trips to the file system. This
	//     is especially true if the user makes tiny writes.
	//
	// *   close(2) (and anything else calling f_op->flush) causes all dirty
	//     pages to be written out before it proceeds to send a FlushFileOp
	//     (cf. https://goo.gl/TMrY6X).
	//
	// *   Similarly, close(2) causes the kernel to send a setattr request
	//     filling in the mtime if any dirty pages were flushed, since the time
	//     at which the pages were written to the file system can't be trusted.
	//
	// *   close(2) (and anything else calling f_op->flush) writes out all dirty
	//     pages, then sends a setattr request with an appropriate mtime for
	//     those writes if there were any, and only then proceeds to send a
	//     flush.
	//
	//     Code walk:
	//
	//     *   (https://goo.gl/zTIZQ9) fuse_flush calls write_inode_now before
	//         calling the file system. The latter eventually calls into
	//         __writeback_single_inode.
	//
	//     *   (https://goo.gl/L7Z2w5) __writeback_single_inode calls
	//         do_writepages, which writes out any dirty pages.
	//
	//     *   (https://goo.gl/DOPgla) __writeback_single_inode later calls
	//         write_inode, which calls into the superblock op struct's write_inode
	//         member. For fuse, this is fuse_write_inode
	//         (cf. https://goo.gl/eDSKOX).
	//
	//     *   (https://goo.gl/PbkGA1) fuse_write_inode calls fuse_flush_times.
	//
	//     *   (https://goo.gl/ig8x9V) fuse_flush_times sends a setttr request
	//         for setting the inode's mtime.
	//
	// However, this brings along some caveats:
	//
	// *   The file system must handle SetInodeAttributesOp or close(2) will fail,
	//     due to the call chain into fuse_flush_times listed above.
	//
	// *   The kernel caches mtime and ctime regardless of whether the file
	//     system tells it to do so, disregarding the result of further getattr
	//     requests (cf. https://goo.gl/3ZZMUw, https://goo.gl/7WtQUp). It
	//     appears this may be true of the file size, too. Writeback caching may
	//     therefore not be suitable for file systems where these attributes can
	//     spontaneously change for reasons the kernel doesn't observe. See
	//     http://goo.gl/V5WQCN for more discussion.
	//
	// Setting DisableWritebackCaching disables this behavior. Instead the file
	// system is called one or more times for each write(2), and the user's
	// syscall doesn't return until the file system returns.
	DisableWritebackCaching bool

	// OS X only.
	//
	// Normally on OS X we mount with the novncache option
	// (cf. http://goo.gl/1pTjuk), which disables entry caching in the kernel.
	// This is because osxfuse does not honor the entry expiration values we
	// return to it, instead caching potentially forever (cf.
	// http://goo.gl/8yR0Ie), and it is probably better to fail to cache than to
	// cache for too long, since the latter is more likely to hide consistency
	// bugs that are difficult to detect and diagnose.
	//
	// This field disables the use of novncache, restoring entry caching. Beware:
	// the value of ChildInodeEntry.EntryExpiration is ignored by the kernel, and
	// entries will be cached for an arbitrarily long time.
	EnableVnodeCaching bool

	// Additional key=value options to pass unadulterated to the underlying mount
	// command. See `man 8 mount`, the fuse documentation, etc. for
	// system-specific information.
	//
	// For expert use only! May invalidate other guarantees made in the
	// documentation for this package.
	Options map[string]string
}

// Create a map containing all of the key=value mount options to be given to
// the mount helper.
func (c *MountConfig) toMap() (opts map[string]string) {
	isDarwin := runtime.GOOS == "darwin"
	opts = make(map[string]string)

	// Enable permissions checking in the kernel. See the comments on
	// InodeAttributes.Mode.
	opts["default_permissions"] = ""

	// HACK(jacobsa): Work around what appears to be a bug in systemd v219, as
	// shipped in Ubuntu 15.04, where it automatically unmounts any file system
	// that doesn't set an explicit name.
	//
	// When Ubuntu contains systemd v220, this workaround should be removed and
	// the systemd bug reopened if the problem persists.
	//
	// Cf. https://github.com/bazil/fuse/issues/89
	// Cf. https://bugs.freedesktop.org/show_bug.cgi?id=90907
	fsname := c.FSName
	if runtime.GOOS == "linux" && fsname == "" {
		fsname = "some_fuse_file_system"
	}

	// Special file system name?
	if fsname != "" {
		opts["fsname"] = fsname
	}

	// Read only?
	if c.ReadOnly {
		opts["ro"] = ""
	}

	// OS X: set novncache when appropriate.
	if isDarwin && !c.EnableVnodeCaching {
		opts["novncache"] = ""
	}

	// OS X: disable the use of "Apple Double" (._foo and .DS_Store) files, which
	// just add noise to debug output and can have significant cost on
	// network-based file systems.
	//
	// Cf. https://github.com/osxfuse/osxfuse/wiki/Mount-options
	if isDarwin {
		opts["noappledouble"] = ""
	}

	// Last but not least: other user-supplied options.
	for k, v := range c.Options {
		opts[k] = v
	}

	return
}

func escapeOptionsKey(s string) (res string) {
	res = s
	res = strings.Replace(res, `\`, `\\`, -1)
	res = strings.Replace(res, `,`, `\,`, -1)
	return
}

// Create an options string suitable for passing to the mount helper.
func (c *MountConfig) toOptionsString() string {
	var components []string
	for k, v := range c.toMap() {
		k = escapeOptionsKey(k)

		component := k
		if v != "" {
			component = fmt.Sprintf("%s=%s", k, v)
		}

		components = append(components, component)
	}

	return strings.Join(components, ",")
}
<|endoftext|>


<commit_before>// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2012 The Go Authors.  All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Verify that the compiler output for test.proto is unchanged.

package testdata

import (
	"crypto/sha1"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"testing"
)

// sum returns in string form (for easy comparison) the SHA-1 hash of the named file.
func sum(t *testing.T, name string) string {
	data, err := ioutil.ReadFile(name)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("sum(%q): length is %d", name, len(data))
	hash := sha1.New()
	_, err = hash.Write(data)
	if err != nil {
		t.Fatal(err)
	}
	return fmt.Sprintf("% x", hash.Sum(nil))
}

func run(t *testing.T, name string, args ...string) {
	cmd := exec.Command(name, args...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		t.Fatal(err)
	}
}

func TestGolden(t *testing.T) {
	// Compute the original checksum.
	goldenSum := sum(t, "my_test/test.pb.go")
	// Run the proto compiler.
	run(t, "protoc", "--go_out=Mmulti/multi1.proto=github.com/golang/protobuf/protoc-gen-go/testdata/multi:"+os.TempDir(), "my_test/test.proto")
	newFile := filepath.Join(os.TempDir(), "my_test/test.pb.go")
	defer os.Remove(newFile)
	// Compute the new checksum.
	newSum := sum(t, newFile)
	// Verify
	if newSum != goldenSum {
		run(t, "diff", "-u", "my_test/test.pb.go", newFile)
		t.Fatal("Code generated by protoc-gen-go has changed; update test.pb.go")
	}
}
<commit_msg>Remove a test that has outlived its usefulness.<commit_after><|endoftext|>


<commit_before>package reflector

import (
	"fmt"
	"reflect"
	"strings"
	"time"
)

func (m *Reflector) ComponentsScan(components ...interface{}) error {
	for _, component := range components {
		value := reflect.ValueOf(component)
		valueType := value.Type()

		// set current model
		m.currentModel = &Model{ModelType: valueType, Name: valueType.Name(), printNesting: 0}

		// before visiting, marking it as visiting, so circular references are avoided
		visitingModels.set(valueType, m.currentModel)

		if value.Kind() == reflect.Interface {
			if printDebug {
				fmt.Printf("Yes, it's an interface from the very beginning\n")
			}
		}

		m.visit(value)
	}
	return nil
}

func (m *Reflector) inspectMap(value reflect.Value) error {

	if err := m.InspectMap(value); err != nil {
		return err
	}

	for _, key := range value.MapKeys() {
		keyValue := value.MapIndex(key)

		if err := m.inspectMapKeyValue(value, key, keyValue); err != nil {
			return err
		}

		if err := m.inspect(key); err != nil {
			return err
		}

		if err := m.inspect(keyValue); err != nil {
			return err
		}

	}

	return nil
}

func (m *Reflector) inspectSlice(value reflect.Value) error {

	if err := m.InspectSlice(value); err != nil {
		return err
	}

	for i := 0; i < value.Len(); i++ {
		elem := value.Index(i)

		if err := m.inspectSliceElem(i, elem); err != nil {
			return err
		}

		if err := m.inspect(elem); err != nil {
			return err
		}

	}

	return nil
}

func (m *Reflector) inspectArray(value reflect.Value) error {

	if err := m.InspectArray(value); err != nil {
		return err
	}

	for i := 0; i < value.Len(); i++ {
		elem := value.Index(i)

		if err := m.InspectArrayElem(i, elem); err != nil {
			return err
		}

		if err := m.inspect(elem); err != nil {
			return err
		}

	}

	return nil
}

func (m *Reflector) InspectMap(theMap reflect.Value) error {
	//fmt.Printf("Map %v\n", theMap)
	return nil
}

func (m *Reflector) inspectMapKeyValue(theMap, key, value reflect.Value) error {
	//fmt.Printf("MapElem %v %v\n", key, value)
	return nil
}

func (m *Reflector) InspectSlice(value reflect.Value) error {

	if value.Len() == 0 {

		var pointedElement reflect.Type
		var pointedStruct reflect.Value
		if m.currentField.Type.Elem().Kind() == reflect.Ptr {
			pointedElement = m.currentField.Type.Elem().Elem()
		} else {
			pointedElement = m.currentField.Type.Elem()
		}
		pointedStruct = reflect.New(pointedElement).Elem()

		// check already visiting
		if cachedValue := visitingModels.get(pointedStruct.Type()); cachedValue == nil {
			if printDebug {
				fmt.Printf("%s[Slice] field name %q of a struct %q\n", strings.Repeat("\t", m.currentModel.printNesting), m.currentField.Name, pointedStruct.Type().Name())
			}

			newReflector := &Reflector{}
			// set current model
			newReflector.currentModel = &Model{ModelType: pointedStruct.Type(), Name: pointedStruct.Type().Name()}
			newReflector.currentModel.printNesting = m.currentModel.printNesting + 1
			// before visiting, marking it as visiting, so circular references are avoided
			visitingModels.set(pointedStruct.Type(), newReflector.currentModel)
			newReflector.visit(pointedStruct)
			// set the relationship
			m.currentField.Relation = newReflector.currentModel
			// set the flag
			m.currentField.flags = m.currentField.flags | (1 << ff_is_relation)
		}
	}

	return nil

}
func (m *Reflector) inspectSliceElem(index int, value reflect.Value) error {
	fmt.Printf("SliceElem : #%d %v\n", index, value)
	return nil
}

func (m *Reflector) InspectArray(value reflect.Value) error {
	//fmt.Printf("Array %v\n", value)
	return nil
}

func (m *Reflector) InspectArrayElem(index int, value reflect.Value) error {
	//fmt.Printf("ArrayElem: #%d %v\n", index, value)
	return nil
}

func (m *Reflector) inspect(value reflect.Value) error {
	// Determine if we're receiving a pointer and if so notify the
	// The logic here is convoluted but very important (tests will fail if
	// almost any part is changed).
	//
	// First, we check if the value is an interface, if so, we really need
	// to check the interface's value to see whether it is a pointer.
	//
	// Check whether the value is then a pointer. If so, then set pointer
	// to true to notify the
	//
	// If we still have a pointer or an interface after the indirections, then
	// we unwrap another level
	//
	// At this time, we also set "value" to be the de-referenced value. This is
	// because once we've unwrapped the pointer we want to use that value.
	var err error
	valuePtr := value
	isPointer := false
	tabs := strings.Repeat("\t", m.currentModel.printNesting)

	for {
		switch valuePtr.Kind() {
		case reflect.Interface:
			valuePtr = valuePtr.Elem()
			// fallthrough, since it can be an interface
			fallthrough
		case reflect.Ptr:
			value = reflect.Indirect(valuePtr)
			valuePtr = value
			isPointer = true
		}

		// If we still have a pointer or interface we have to indirect another level.
		switch valuePtr.Kind() {
		case reflect.Ptr, reflect.Interface:
			continue
		}
		break
	}

	if value.Kind() == reflect.Interface {
		value = value.Elem()
	}

	kind := value.Kind()
	if kind >= reflect.Int && kind <= reflect.Complex128 {
		kind = reflect.Int
	}

	if printDebug {
		fmt.Printf("%s[level #%d] Current model type : %q\n", tabs, m.currentModel.printNesting, m.currentModel.ModelType)
	}

	switch kind {
	case reflect.Bool, reflect.Chan, reflect.Func, reflect.Int, reflect.String, reflect.Invalid:
		// Primitives
		return nil
	case reflect.Map:
		if printDebug {
			fmt.Printf("yes, it's a map : %v\n", value)
		}
		err = m.inspectMap(value)
		return err
	case reflect.Slice:
		if printDebug {
			err = m.inspectSlice(value)
		}
		return err
	case reflect.Array:
		if printDebug {
			fmt.Printf("yes, it's an array : %v\n", value)
		}
		err = m.inspectArray(value)
		return err
	case reflect.Struct:
		if isPointer {
			valueType := value.Type()

			newReflector := &Reflector{}
			// set current model
			newReflector.currentModel = &Model{ModelType: valueType, Name: valueType.Name()}
			newReflector.currentModel.printNesting = m.currentModel.printNesting + 1

			if m.currentField != nil {
				if printDebug {
					fmt.Printf("%s[Visiting] %q -> %q\n", tabs, m.currentField.Name, newReflector.currentModel.ModelType)
				}
				m.currentField.Relation = newReflector.currentModel
				m.currentField.flags = m.currentField.flags | (1 << ff_is_relation)
			} else {
				if printDebug {
					fmt.Printf("%s[level #%d] Visiting NO CURRENT FIELD -> %q over %q\n", tabs, m.currentModel.printNesting, m.currentModel.ModelType, newReflector.currentModel.ModelType)
				}
			}

			newReflector.visit(value)
			// was a pointer, transfer model to the parent
			if m.currentField == nil {
				m.currentModel = newReflector.currentModel
			}

		} else {
			if m.currentField != nil {
				if printDebug {
					fmt.Printf("%s[Inspecting] field struct %q (%q)= `%v`\n", tabs, m.currentField.Name, m.currentField.Type, value)
				}
			} else {
				if printDebug {
					fmt.Printf("%s[Inspecting] NO CURRENT FIELD `%v`\n", tabs, value)
				}
			}
			err = m.inspectStruct(value)
		}
		return err
	default:
		return fmt.Errorf("Inspector : unsupported type %q ", kind.String())
	}
	return err
}

func (m *Reflector) inspectStruct(value reflect.Value) error {

	valueType := value.Type()
	tabs := strings.Repeat("\t", m.currentModel.printNesting)
	for i := 0; i < valueType.NumField(); i++ {
		structField := valueType.Field(i)
		field := value.FieldByIndex([]int{i})
		if structField.Type.Kind() == reflect.Ptr {
			fmt.Printf("%s[Field] %q (valid = %t , nil = %t) `%v`\n", tabs, structField.Name, field.IsValid(), field.IsNil(), field)
			fmt.Printf("%s[StructField] %v\n", tabs, structField)
		}
		if structField.Anonymous {
			if printDebug {
				fmt.Printf("Skipping Anonymous field %q %s\n", structField.Name, structField.Type)
			}
			continue
		}

		// set current field as a new field
		m.currentField = &Field{
			Type: structField.Type,
			Name: structField.Name,
		}

		if field.Kind() == reflect.Invalid {
			if printDebug {
				fmt.Printf("%sINVALID FIELD : %q = %q\n", tabs, structField.Name, structField.Type)
			}
			continue
		}

		switch structField.Type.Kind() {
		case reflect.Ptr:
			// set flag to pointer
			m.currentField.flags = m.currentField.flags | (1 << ff_is_pointer)
			// fallthrough, since it can be a pointer to a struct, slice, whatever
			fallthrough
		case reflect.Struct:
			// set flag to struct
			m.currentField.flags = m.currentField.flags | (1 << ff_is_struct)
			if printDebug {
				fmt.Printf("%sSTRUCT %q : %q = `%v`\n", tabs, m.currentField.Name, m.currentModel.ModelType, field)
			}
			// if it's not a pointer
			if m.currentField.flags&(1<<ff_is_pointer) == 0 {
				// TODO : add Scanner, Valuer, Marshaller, Unmarshaller
				_, isTime := field.Interface().(time.Time)
				if isTime {
					// set flag to time
					m.currentField.flags = m.currentField.flags | (1 << ff_is_time)
				}

				valueType := field.Type()
				// check already visiting
				if cachedValue := visitingModels.get(valueType); cachedValue != nil {
					return nil
				}

				if printDebug {
					fmt.Printf("%sINSPECT STRUCT %q : %q\n", tabs, m.currentField.Name, m.currentModel.ModelType)
				}
				// field has values : visit it
				err := m.inspect(field)
				if err != nil {
					return err
				}

			} else {
				if field.IsNil() {
					if printDebug {
						fmt.Printf("%sNIL STRUCT %q : %q\n", tabs, m.currentField.Name, m.currentModel.ModelType)
					}
				}
				// field is nil, we build one to visit it
				// it's a pointer. dereferencing it

				pointedElement := m.currentField.Type.Elem()
				pointedStruct := reflect.New(pointedElement).Elem()

				valueType := pointedStruct.Type()
				// check already visiting
				if cachedValue := visitingModels.get(valueType); cachedValue != nil {
					return nil
				}

				if printDebug {
					fmt.Printf("%s[Pointer] %q to a struct %q\n", tabs, m.currentField.Name, valueType.Name())
				}

				newReflector := &Reflector{}
				// set current model
				newReflector.currentModel = &Model{ModelType: valueType, Name: valueType.Name()}
				newReflector.currentModel.printNesting = m.currentModel.printNesting + 1
				// before visiting, marking it as visiting, so circular references are avoided
				visitingModels.set(valueType, newReflector.currentModel)
				newReflector.visit(pointedStruct)
				// set the relationship
				m.currentField.Relation = newReflector.currentModel
				// set the flag
				m.currentField.flags = m.currentField.flags | (1 << ff_is_relation)

			}
			//fmt.Printf("%s - %t, %t\n", tabs, field.IsNil(), field.IsValid())

		case reflect.Slice:
			// set flag to slice
			m.currentField.flags = m.currentField.flags | (1 << ff_is_slice)
			// inspect it
			err := m.inspect(field)
			if err != nil {
				return err
			}
		default:
			m.currentField.Value = field
			// by default, we inspect
			err := m.inspect(field)
			if err != nil {
				return err
			}
		}

		// add the field to current model
		m.currentModel.Fields = append(m.currentModel.Fields, m.currentField)

		if printDebug {
			fmt.Printf("%s[ADD] %q (%q) = `%v` to %q\n", tabs, m.currentField.Name, m.currentField.Type, m.currentField.Value, m.currentModel.ModelType)
		}
	}

	return nil
}

func (m *Reflector) visit(value reflect.Value) error {
	valueType := value.Type()

	// Get cached Model
	if cachedValue := cachedModels.get(valueType); cachedValue != nil {
		return nil
	}

	// inspect the value
	err := m.inspect(value)

	switch value.Kind() {
	case
		reflect.Invalid,
		reflect.Bool,
		reflect.Int,
		reflect.Int8,
		reflect.Int16,
		reflect.Int32,
		reflect.Int64,
		reflect.Uint,
		reflect.Uint8,
		reflect.Uint16,
		reflect.Uint32,
		reflect.Uint64,
		reflect.Uintptr,
		reflect.Float32,
		reflect.Float64,
		reflect.Complex64,
		reflect.Complex128,
		reflect.Array,
		reflect.Chan,
		reflect.Func,
		reflect.Interface,
		reflect.Map,
		reflect.Ptr,
		reflect.Slice,
		reflect.String:
		// do nothing, it's primitive
	default:
		// Set cached model
		cachedModels.set(valueType, m.currentModel)

	}

	return err
}
<commit_msg>Initial commit<commit_after>package reflector

import (
	"fmt"
	"reflect"
	"strings"
	"time"
)

func (m *Reflector) ComponentsScan(components ...interface{}) error {
	for _, component := range components {
		value := reflect.ValueOf(component)
		valueType := value.Type()

		// set current model
		m.currentModel = &Model{ModelType: valueType, Name: valueType.Name(), printNesting: 0}

		// before visiting, marking it as visiting, so circular references are avoided
		visitingModels.set(valueType, m.currentModel)

		if value.Kind() == reflect.Interface {
			if printDebug {
				fmt.Printf("Yes, it's an interface from the very beginning\n")
			}
		}

		m.visit(value)
	}
	return nil
}

func (m *Reflector) inspectMap(value reflect.Value) error {

	if err := m.InspectMap(value); err != nil {
		return err
	}

	for _, key := range value.MapKeys() {
		keyValue := value.MapIndex(key)

		if err := m.inspectMapKeyValue(value, key, keyValue); err != nil {
			return err
		}

		if err := m.inspect(key); err != nil {
			return err
		}

		if err := m.inspect(keyValue); err != nil {
			return err
		}

	}

	return nil
}

func (m *Reflector) inspectSlice(value reflect.Value) error {

	if err := m.InspectSlice(value); err != nil {
		return err
	}

	for i := 0; i < value.Len(); i++ {
		elem := value.Index(i)

		if err := m.inspectSliceElem(i, elem); err != nil {
			return err
		}

		if err := m.inspect(elem); err != nil {
			return err
		}

	}

	return nil
}

func (m *Reflector) inspectArray(value reflect.Value) error {

	if err := m.InspectArray(value); err != nil {
		return err
	}

	for i := 0; i < value.Len(); i++ {
		elem := value.Index(i)

		if err := m.InspectArrayElem(i, elem); err != nil {
			return err
		}

		if err := m.inspect(elem); err != nil {
			return err
		}

	}

	return nil
}

func (m *Reflector) InspectMap(theMap reflect.Value) error {
	//fmt.Printf("Map %v\n", theMap)
	return nil
}

func (m *Reflector) inspectMapKeyValue(theMap, key, value reflect.Value) error {
	//fmt.Printf("MapElem %v %v\n", key, value)
	return nil
}

func (m *Reflector) InspectSlice(value reflect.Value) error {

	if value.Len() == 0 {

		var pointedElement reflect.Type
		var pointedStruct reflect.Value
		if m.currentField.Type.Elem().Kind() == reflect.Ptr {
			pointedElement = m.currentField.Type.Elem().Elem()
		} else {
			pointedElement = m.currentField.Type.Elem()
		}
		pointedStruct = reflect.New(pointedElement).Elem()

		// check already visiting
		if cachedValue := visitingModels.get(pointedStruct.Type()); cachedValue == nil {
			if printDebug {
				fmt.Printf("%s[Slice] field name %q of a struct %q\n", strings.Repeat("\t", m.currentModel.printNesting), m.currentField.Name, pointedStruct.Type().Name())
			}

			newReflector := &Reflector{}
			// set current model
			newReflector.currentModel = &Model{ModelType: pointedStruct.Type(), Name: pointedStruct.Type().Name()}
			newReflector.currentModel.printNesting = m.currentModel.printNesting + 1
			// before visiting, marking it as visiting, so circular references are avoided
			visitingModels.set(pointedStruct.Type(), newReflector.currentModel)
			newReflector.visit(pointedStruct)
			// set the relationship
			m.currentField.Relation = newReflector.currentModel
			// set the flag
			m.currentField.flags = m.currentField.flags | (1 << ff_is_relation)
		}
	}

	return nil

}
func (m *Reflector) inspectSliceElem(index int, value reflect.Value) error {
	fmt.Printf("SliceElem : #%d %v\n", index, value)
	return nil
}

func (m *Reflector) InspectArray(value reflect.Value) error {
	//fmt.Printf("Array %v\n", value)
	return nil
}

func (m *Reflector) InspectArrayElem(index int, value reflect.Value) error {
	//fmt.Printf("ArrayElem: #%d %v\n", index, value)
	return nil
}

func (m *Reflector) inspect(value reflect.Value) error {
	// Determine if we're receiving a pointer and if so notify the
	// The logic here is convoluted but very important (tests will fail if
	// almost any part is changed).
	//
	// First, we check if the value is an interface, if so, we really need
	// to check the interface's value to see whether it is a pointer.
	//
	// Check whether the value is then a pointer. If so, then set pointer
	// to true to notify the
	//
	// If we still have a pointer or an interface after the indirections, then
	// we unwrap another level
	//
	// At this time, we also set "value" to be the de-referenced value. This is
	// because once we've unwrapped the pointer we want to use that value.
	var err error
	valuePtr := value
	isPointer := false
	tabs := strings.Repeat("\t", m.currentModel.printNesting)

	for {
		switch valuePtr.Kind() {
		case reflect.Interface:
			valuePtr = valuePtr.Elem()
			// fallthrough, since it can be an interface
			fallthrough
		case reflect.Ptr:
			value = reflect.Indirect(valuePtr)
			valuePtr = value
			isPointer = true
		}

		// If we still have a pointer or interface we have to indirect another level.
		switch valuePtr.Kind() {
		case reflect.Ptr, reflect.Interface:
			continue
		}
		break
	}

	if value.Kind() == reflect.Interface {
		value = value.Elem()
	}

	kind := value.Kind()
	if kind >= reflect.Int && kind <= reflect.Complex128 {
		kind = reflect.Int
	}

	if printDebug {
		fmt.Printf("%s[level #%d] Current model type : %q\n", tabs, m.currentModel.printNesting, m.currentModel.ModelType)
	}

	switch kind {
	case reflect.Bool, reflect.Chan, reflect.Func, reflect.Int, reflect.String, reflect.Invalid:
		// Primitives
		return nil
	case reflect.Map:
		if printDebug {
			fmt.Printf("yes, it's a map : %v\n", value)
		}
		err = m.inspectMap(value)
		return err
	case reflect.Slice:
		if printDebug {
			err = m.inspectSlice(value)
		}
		return err
	case reflect.Array:
		if printDebug {
			fmt.Printf("yes, it's an array : %v\n", value)
		}
		err = m.inspectArray(value)
		return err
	case reflect.Struct:
		if isPointer {
			valueType := value.Type()

			newReflector := &Reflector{}
			// set current model
			newReflector.currentModel = &Model{ModelType: valueType, Name: valueType.Name()}
			newReflector.currentModel.printNesting = m.currentModel.printNesting + 1

			if m.currentField != nil {
				if printDebug {
					fmt.Printf("%s[Visiting] %q -> %q\n", tabs, m.currentField.Name, newReflector.currentModel.ModelType)
				}
				m.currentField.Relation = newReflector.currentModel
				m.currentField.flags = m.currentField.flags | (1 << ff_is_relation)
			} else {
				if printDebug {
					fmt.Printf("%s[level #%d] Visiting NO CURRENT FIELD -> %q over %q\n", tabs, m.currentModel.printNesting, m.currentModel.ModelType, newReflector.currentModel.ModelType)
				}
			}

			newReflector.visit(value)
			// was a pointer, transfer model to the parent
			if m.currentField == nil {
				m.currentModel = newReflector.currentModel
			}

		} else {
			if m.currentField != nil {
				if printDebug {
					fmt.Printf("%s[Inspecting] field struct %q (%q)= `%v`\n", tabs, m.currentField.Name, m.currentField.Type, value)
				}
			} else {
				if printDebug {
					fmt.Printf("%s[Inspecting] NO CURRENT FIELD `%v`\n", tabs, value)
				}
			}
			err = m.inspectStruct(value)
		}
		return err
	default:
		return fmt.Errorf("Inspector : unsupported type %q ", kind.String())
	}
	return err
}

func (m *Reflector) inspectStruct(value reflect.Value) error {

	valueType := value.Type()
	tabs := strings.Repeat("\t", m.currentModel.printNesting)
	for i := 0; i < valueType.NumField(); i++ {
		structField := valueType.Field(i)
		field := value.FieldByIndex([]int{i})
		if structField.Type.Kind() == reflect.Ptr {
			fmt.Printf("%s[Field] %q (valid = %t , nil = %t) `%v`\n", tabs, structField.Name, field.IsValid(), field.IsNil(), field)
			fmt.Printf("%s[StructField] %v\n", tabs, structField)
		}
		if structField.Anonymous {
			if printDebug {
				fmt.Printf("Skipping Anonymous field %q %s\n", structField.Name, structField.Type)
			}
			continue
		}

		// set current field as a new field
		m.currentField = &Field{
			Type: structField.Type,
			Name: structField.Name,
		}

		if field.Kind() == reflect.Invalid {
			if printDebug {
				fmt.Printf("%sINVALID FIELD : %q = %q\n", tabs, structField.Name, structField.Type)
			}
			continue
		}

		switch structField.Type.Kind() {
		case reflect.Ptr:
			// set flag to pointer
			m.currentField.flags = m.currentField.flags | (1 << ff_is_pointer)
			// fallthrough, since it can be a pointer to a struct, slice, whatever
			fallthrough
		case reflect.Struct:
			// set flag to struct
			m.currentField.flags = m.currentField.flags | (1 << ff_is_struct)
			if printDebug {
				fmt.Printf("%sSTRUCT %q : %q = `%v`\n", tabs, m.currentField.Name, m.currentModel.ModelType, field)
			}
			// if it's not a pointer
			if m.currentField.flags&(1<<ff_is_pointer) == 0 {
				// TODO : add Scanner, Valuer, Marshaller, Unmarshaller
				_, isTime := field.Interface().(time.Time)
				if isTime {
					// set flag to time
					m.currentField.flags = m.currentField.flags | (1 << ff_is_time)
				}

				valueType := field.Type()
				// check already visiting
				if cachedValue := visitingModels.get(valueType); cachedValue != nil {

					// add the field to current model
					m.currentModel.Fields = append(m.currentModel.Fields, m.currentField)

					if printDebug {
						fmt.Printf("%s[ADD] %q (%q) = `%v` to %q\n", tabs, m.currentField.Name, m.currentField.Type, m.currentField.Value, m.currentModel.ModelType)
					}

					return nil
				}

				if printDebug {
					fmt.Printf("%sINSPECT STRUCT %q : %q\n", tabs, m.currentField.Name, m.currentModel.ModelType)
				}
				// field has values : visit it
				err := m.inspect(field)
				if err != nil {
					return err
				}

			} else {
				if field.IsNil() {
					if printDebug {
						fmt.Printf("%sNIL STRUCT %q : %q\n", tabs, m.currentField.Name, m.currentModel.ModelType)
					}
				}
				// field is nil, we build one to visit it
				// it's a pointer. dereferencing it

				pointedElement := m.currentField.Type.Elem()
				pointedStruct := reflect.New(pointedElement).Elem()

				valueType := pointedStruct.Type()
				// check already visiting
				if cachedValue := visitingModels.get(valueType); cachedValue != nil {

					// add the field to current model
					m.currentModel.Fields = append(m.currentModel.Fields, m.currentField)

					if printDebug {
						fmt.Printf("%s[ADD] %q (%q) = `%v` to %q\n", tabs, m.currentField.Name, m.currentField.Type, m.currentField.Value, m.currentModel.ModelType)
					}

					return nil
				}

				if printDebug {
					fmt.Printf("%s[Pointer] %q to a struct %q\n", tabs, m.currentField.Name, valueType.Name())
				}

				newReflector := &Reflector{}
				// set current model
				newReflector.currentModel = &Model{ModelType: valueType, Name: valueType.Name()}
				newReflector.currentModel.printNesting = m.currentModel.printNesting + 1
				// before visiting, marking it as visiting, so circular references are avoided
				visitingModels.set(valueType, newReflector.currentModel)
				newReflector.visit(pointedStruct)
				// set the relationship
				m.currentField.Relation = newReflector.currentModel
				// set the flag
				m.currentField.flags = m.currentField.flags | (1 << ff_is_relation)

			}
			//fmt.Printf("%s - %t, %t\n", tabs, field.IsNil(), field.IsValid())

		case reflect.Slice:
			// set flag to slice
			m.currentField.flags = m.currentField.flags | (1 << ff_is_slice)
			// inspect it
			err := m.inspect(field)
			if err != nil {
				return err
			}
		default:
			m.currentField.Value = field
			// by default, we inspect
			err := m.inspect(field)
			if err != nil {
				return err
			}
		}

		// add the field to current model
		m.currentModel.Fields = append(m.currentModel.Fields, m.currentField)

		if printDebug {
			fmt.Printf("%s[ADD] %q (%q) = `%v` to %q\n", tabs, m.currentField.Name, m.currentField.Type, m.currentField.Value, m.currentModel.ModelType)
		}
	}

	return nil
}

func (m *Reflector) visit(value reflect.Value) error {
	valueType := value.Type()

	// Get cached Model
	if cachedValue := cachedModels.get(valueType); cachedValue != nil {
		return nil
	}

	// inspect the value
	err := m.inspect(value)

	switch value.Kind() {
	case
		reflect.Invalid,
		reflect.Bool,
		reflect.Int,
		reflect.Int8,
		reflect.Int16,
		reflect.Int32,
		reflect.Int64,
		reflect.Uint,
		reflect.Uint8,
		reflect.Uint16,
		reflect.Uint32,
		reflect.Uint64,
		reflect.Uintptr,
		reflect.Float32,
		reflect.Float64,
		reflect.Complex64,
		reflect.Complex128,
		reflect.Array,
		reflect.Chan,
		reflect.Func,
		reflect.Interface,
		reflect.Map,
		reflect.Ptr,
		reflect.Slice,
		reflect.String:
		// do nothing, it's primitive
	default:
		// Set cached model
		cachedModels.set(valueType, m.currentModel)

	}

	return err
}
<|endoftext|>


<commit_before>// Copyright 2013 Fredrik Ehnbom
// Use of this source code is governed by a 2-clause
// BSD-style license that can be found in the LICENSE file.

package text

import (
	"reflect"
	"sync"
)

// The RegionSet manages multiple regions,
// merging any regions overlapping.
//
// Note that regions that are right next to each other
// are not merged into a single region. This is because
// otherwise it would not be possible to have multiple
// cursors right next to each other.
type RegionSet struct {
	regions []Region
	lock    sync.Mutex
}

// Adjusts all the regions in the set
func (r *RegionSet) Adjust(position, delta int) {
	r.lock.Lock()
	defer r.lock.Unlock()
	for i := range r.regions {
		r.regions[i].Adjust(position, delta)
	}
	r.flush()
}

// TODO(q): There should be a on modified callback on the RegionSet
func (r *RegionSet) flush() {
	var reg []Region
	for ; !reflect.DeepEqual(r.regions, reg); {
		reg = make([]Region, len(r.regions))
		copy(reg, r.regions)
		for i := 0; i < len(r.regions); i++ {
			for j := i + 1; j < len(r.regions); {
				if r.regions[i] == r.regions[j] || r.regions[i].Intersects(r.regions[j]) || r.regions[j].Covers(r.regions[i]) {
					r.regions[i] = r.regions[i].Cover(r.regions[j])
					copy(r.regions[j:], r.regions[j + 1:])
					r.regions = r.regions[:len(r.regions) - 1]
				} else {
					j++
				}
			}
		}
	}
}

// Removes the given region from the set
func (r *RegionSet) Substract(r2 Region) {
	r3 := r.Cut(r2)
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = r3.regions
}

// Adds the given region to the set
func (r *RegionSet) Add(r2 Region) {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = append(r.regions, r2)
	r.flush()
}

// Clears the set
func (r *RegionSet) Clear() {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = r.regions[0:0]
	r.flush()
}

// Gets the region at index i
func (r *RegionSet) Get(i int) Region {
	r.lock.Lock()
	defer r.lock.Unlock()
	return r.regions[i]
}

// Compares two regions given by their indices
func (r *RegionSet) Less(i, j int) bool {
	if bi, bj := r.regions[i].Begin(), r.regions[j].Begin(); bi < bj {
		return true
	} else if bi == bj {
		return r.regions[i].End() < r.regions[j].End()
	}
	return false
}

// Swaps two regions ath the given indices
func (r *RegionSet) Swap(i, j int) {
	r.regions[i], r.regions[j] = r.regions[j], r.regions[i]
}

// Returns the number of regions contained in the set
func (r *RegionSet) Len() int {
	return len(r.regions)
}

// Adds all regions in the array to the set
func (r *RegionSet) AddAll(rs []Region) {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = append(r.regions, rs...)
	r.flush()
}

// Returns whether the specified region is part of the set
func (r *RegionSet) Contains(r2 Region) bool {
	r.lock.Lock()
	defer r.lock.Unlock()

	for i := range r.regions {
		if r.regions[i] == r2 || (r.regions[i].Contains(r2.Begin()) && r.regions[i].Contains(r2.End())) {
			return true
		}
	}
	return false
}

// Returns a copy of the regions in the set
func (r *RegionSet) Regions() (ret []Region) {
	r.lock.Lock()
	defer r.lock.Unlock()
	ret = make([]Region, len(r.regions))
	copy(ret, r.regions)
	return
}

// Returns whether the set contains at least one
// region that isn't empty.
func (r *RegionSet) HasNonEmpty() bool {
	r.lock.Lock()
	defer r.lock.Unlock()
	for _, r := range r.regions {
		if !r.Empty() {
			return true
		}
	}
	return false
}

// Opposite of #HasNonEmpty
func (r *RegionSet) HasEmpty() bool {
	r.lock.Lock()
	defer r.lock.Unlock()
	for _, r := range r.regions {
		if r.Empty() {
			return true
		}
	}
	return false
}

// Cuts away the provided region from the set, and returns
// the new set
func (r *RegionSet) Cut(r2 Region) (ret RegionSet) {
	r.lock.Lock()
	defer r.lock.Unlock()

	for i := 0; i < len(r.regions); i++ {
		for _, xor := range r.regions[i].Cut(r2) {
			if !xor.Empty() {
				ret.Add(xor)
			}
		}
	}
	return
}
<commit_msg>Simplify RegionsSet.flush.<commit_after>// Copyright 2013 Fredrik Ehnbom
// Use of this source code is governed by a 2-clause
// BSD-style license that can be found in the LICENSE file.

package text

import (
	"sync"
)

// The RegionSet manages multiple regions,
// merging any regions overlapping.
//
// Note that regions that are right next to each other
// are not merged into a single region. This is because
// otherwise it would not be possible to have multiple
// cursors right next to each other.
type RegionSet struct {
	regions []Region
	lock    sync.Mutex
}

// Adjusts all the regions in the set
func (r *RegionSet) Adjust(position, delta int) {
	r.lock.Lock()
	defer r.lock.Unlock()
	for i := range r.regions {
		r.regions[i].Adjust(position, delta)
	}
	r.flush()
}

// TODO(q): There should be a on modified callback on the RegionSet
func (r *RegionSet) flush() {
	for i := 0; i < len(r.regions); i++ {
		for j := i + 1; j < len(r.regions); {
			if r.regions[i] == r.regions[j] || r.regions[i].Intersects(r.regions[j]) || r.regions[j].Covers(r.regions[i]) {
				r.regions[i] = r.regions[i].Cover(r.regions[j])
				copy(r.regions[j:], r.regions[j + 1:])
				r.regions = r.regions[:len(r.regions) - 1]
				j = i + 1
			} else {
				j++
			}
		}
	}
}

// Removes the given region from the set
func (r *RegionSet) Substract(r2 Region) {
	r3 := r.Cut(r2)
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = r3.regions
}

// Adds the given region to the set
func (r *RegionSet) Add(r2 Region) {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = append(r.regions, r2)
	r.flush()
}

// Clears the set
func (r *RegionSet) Clear() {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = r.regions[0:0]
	r.flush()
}

// Gets the region at index i
func (r *RegionSet) Get(i int) Region {
	r.lock.Lock()
	defer r.lock.Unlock()
	return r.regions[i]
}

// Compares two regions given by their indices
func (r *RegionSet) Less(i, j int) bool {
	if bi, bj := r.regions[i].Begin(), r.regions[j].Begin(); bi < bj {
		return true
	} else if bi == bj {
		return r.regions[i].End() < r.regions[j].End()
	}
	return false
}

// Swaps two regions ath the given indices
func (r *RegionSet) Swap(i, j int) {
	r.regions[i], r.regions[j] = r.regions[j], r.regions[i]
}

// Returns the number of regions contained in the set
func (r *RegionSet) Len() int {
	return len(r.regions)
}

// Adds all regions in the array to the set
func (r *RegionSet) AddAll(rs []Region) {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.regions = append(r.regions, rs...)
	r.flush()
}

// Returns whether the specified region is part of the set
func (r *RegionSet) Contains(r2 Region) bool {
	r.lock.Lock()
	defer r.lock.Unlock()

	for i := range r.regions {
		if r.regions[i] == r2 || (r.regions[i].Contains(r2.Begin()) && r.regions[i].Contains(r2.End())) {
			return true
		}
	}
	return false
}

// Returns a copy of the regions in the set
func (r *RegionSet) Regions() (ret []Region) {
	r.lock.Lock()
	defer r.lock.Unlock()
	ret = make([]Region, len(r.regions))
	copy(ret, r.regions)
	return
}

// Returns whether the set contains at least one
// region that isn't empty.
func (r *RegionSet) HasNonEmpty() bool {
	r.lock.Lock()
	defer r.lock.Unlock()
	for _, r := range r.regions {
		if !r.Empty() {
			return true
		}
	}
	return false
}

// Opposite of #HasNonEmpty
func (r *RegionSet) HasEmpty() bool {
	r.lock.Lock()
	defer r.lock.Unlock()
	for _, r := range r.regions {
		if r.Empty() {
			return true
		}
	}
	return false
}

// Cuts away the provided region from the set, and returns
// the new set
func (r *RegionSet) Cut(r2 Region) (ret RegionSet) {
	r.lock.Lock()
	defer r.lock.Unlock()

	for i := 0; i < len(r.regions); i++ {
		for _, xor := range r.regions[i].Cut(r2) {
			if !xor.Empty() {
				ret.Add(xor)
			}
		}
	}
	return
}
<|endoftext|>


<commit_before>package hlltc

import (
	"math"
)

type reg uint8
type regs []reg
type rs struct {
	regs
	nz uint32
}

func newRegs(size uint32) *rs {
	return &rs{
		regs: make(regs, size/2, size/2),
		nz:   size,
	}
}

func (r *reg) set(offset, val uint8) bool {
	isZero := false
	if offset == 0 {
		isZero = uint8((*r)>>4) == 0
		tmpVal := uint8((*r) << 4 >> 4)
		*r = reg(uint8(tmpVal) | (val << 4))
	} else {
		isZero = uint8((*r)<<4>>4) == 0
		tmpVal := uint8((*r) >> 4)
		*r = reg(tmpVal<<4 | val)
	}
	return isZero
}

func (r *reg) get(offset uint8) uint8 {
	if offset == 0 {
		return uint8((*r) >> 4)
	}
	return uint8((*r) << 4 >> 4)
}

func (rs *rs) rebase(delta uint8) {
	nz := uint32(len(rs.regs)) * 2
	for i := range rs.regs {
		val := rs.regs[i].get(0)
		if val >= delta {
			rs.regs[i].set(0, val-delta)
			if val-delta > 0 {
				nz--
			}
		}
		val = rs.regs[i].get(1)
		if val >= delta {
			rs.regs[i].set(1, val-delta)
			if val-delta > 0 {
				nz--
			}
		}
	}
	rs.nz = nz
}

func (rs *rs) set(i uint32, val uint8) {
	offset, index := uint8(i%2), i/2
	if rs.regs[index].set(offset, val) {
		rs.nz--
	}
}

func (rs *rs) get(i uint32) uint8 {
	offset, index := uint8(i%2), i/2
	return rs.regs[index].get(offset)
}

func (rs *rs) sum(base uint8) (res float64) {
	for _, r := range rs.regs {
		res += 1.0 / math.Pow(2.0, float64(base+r.get(0)))
		res += 1.0 / math.Pow(2.0, float64(base+r.get(1)))
	}
	return res
}

func (rs *rs) zeros() (res uint64) {
	for _, r := range rs.regs {
		if uint8(r<<4) == 0 {
			res++
		}
		if r < 16 {
			res++
		}
	}
	return res
}

func (rs *rs) min() uint8 {
	if rs.nz > 0 {
		return 0
	}
	min := uint8(math.MaxUint8)
	for _, r := range rs.regs {
		if val := uint8(r << 4 >> 4); val < min {
			min = val
		}
		if val := uint8(r >> 4); val < min {
			min = val
		}
		if min == 0 {
			break
		}
	}
	return min
}
<commit_msg>more simplifying and cleaning up<commit_after>package hlltc

import (
	"math"
)

type reg uint8
type regs []reg
type rs struct {
	regs
	nz uint32
}

func newRegs(size uint32) *rs {
	return &rs{
		regs: make(regs, size/2, size/2),
		nz:   size,
	}
}

func (r *reg) set(offset, val uint8) bool {
	isZero := false
	if offset == 0 {
		isZero = uint8((*r)>>4) == 0
		tmpVal := uint8((*r) << 4 >> 4)
		*r = reg(uint8(tmpVal) | (val << 4))
	} else {
		isZero = uint8((*r)<<4>>4) == 0
		tmpVal := uint8((*r) >> 4)
		*r = reg(tmpVal<<4 | val)
	}
	return isZero
}

func (r *reg) get(offset uint8) uint8 {
	if offset == 0 {
		return uint8((*r) >> 4)
	}
	return uint8((*r) << 4 >> 4)
}

func (rs *rs) rebase(delta uint8) {
	nz := uint32(len(rs.regs)) * 2
	for i := range rs.regs {
		val := rs.regs[i].get(0)
		if val >= delta {
			rs.regs[i].set(0, val-delta)
			if val-delta > 0 {
				nz--
			}
		}
		val = rs.regs[i].get(1)
		if val >= delta {
			rs.regs[i].set(1, val-delta)
			if val-delta > 0 {
				nz--
			}
		}
	}
	rs.nz = nz
}

func (rs *rs) set(i uint32, val uint8) {
	offset, index := uint8(i%2), i/2
	if rs.regs[index].set(offset, val) {
		rs.nz--
	}
}

func (rs *rs) get(i uint32) uint8 {
	offset, index := uint8(i%2), i/2
	return rs.regs[index].get(offset)
}

func (rs *rs) sum(base uint8) (res float64) {
	for _, r := range rs.regs {
		res += 1.0 / math.Pow(2.0, float64(base+r.get(0)))
		res += 1.0 / math.Pow(2.0, float64(base+r.get(1)))
	}
	return res
}

func (rs *rs) zeros() (res uint32) {
	return rs.nz
}

func (rs *rs) min() uint8 {
	if rs.nz > 0 {
		return 0
	}
	min := uint8(math.MaxUint8)
	for _, r := range rs.regs {
		if val := uint8(r << 4 >> 4); val < min {
			min = val
		}
		if val := uint8(r >> 4); val < min {
			min = val
		}
		if min == 0 {
			break
		}
	}
	return min
}
<|endoftext|>


<commit_before>package signer

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"strings"
	"time"
)

type Signer interface {
	GenerateSignedURL(endpoint, prefixedBlobID, verb string, timeStamp time.Time, expiresAfter time.Duration) (string, error)
}

type signer struct {
	secret string
}

func NewSigner(secret string) Signer {
	return &signer{
		secret: secret,
	}
}

func (s *signer) generateSignature(prefixedBlobID, verb string, timeStamp time.Time, expires int) string {
	verb = strings.ToUpper(verb)
	signature := fmt.Sprintf("%s%s%d%d", verb, prefixedBlobID, timeStamp.Unix(), expires)
	hmac := hmac.New(sha256.New, []byte(s.secret))
	hmac.Write([]byte(signature))
	sigBytes := hmac.Sum(nil)
	return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(sigBytes)
}

func (s *signer) GenerateSignedURL(endpoint, prefixedBlobID, verb string, timeStamp time.Time, expiresAfter time.Duration) (string, error) {
	verb = strings.ToUpper(verb)
	if verb != "GET" && verb != "PUT" {
		return "", fmt.Errorf("action not implemented: %s. Available actions are 'GET' and 'PUT'", verb)
	}

	endpoint = strings.TrimSuffix(endpoint, "/")
	expiresAfterSeconds := int(expiresAfter.Seconds())
	signature := s.generateSignature(prefixedBlobID, verb, timeStamp, expiresAfterSeconds)

	return fmt.Sprintf("%s/%s?st=%s&ts=%d&e=%d", endpoint, prefixedBlobID, signature, timeStamp.Unix(), expiresAfterSeconds), nil
}
<commit_msg>Fix signed url pattern<commit_after>package signer

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"net/http"
	"net/url"
	"path"
	"strings"
	"time"
)

type Signer interface {
	GenerateSignedURL(endpoint, prefixedBlobID, verb string, timeStamp time.Time, expiresAfter time.Duration) (string, error)
}

type signer struct {
	secret string
}

func NewSigner(secret string) Signer {
	return &signer{
		secret: secret,
	}
}

func (s *signer) generateSignature(prefixedBlobID, verb string, timeStamp time.Time, expires int) string {
	verb = strings.ToUpper(verb)
	signature := fmt.Sprintf("%s%s%d%d", verb, prefixedBlobID, timeStamp.Unix(), expires)
	hmac := hmac.New(sha256.New, []byte(s.secret))
	hmac.Write([]byte(signature))
	sigBytes := hmac.Sum(nil)
	return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(sigBytes)
}

func (s *signer) GenerateSignedURL(endpoint, prefixedBlobID, verb string, timeStamp time.Time, expiresAfter time.Duration) (string, error) {
	verb = strings.ToUpper(verb)
	if verb != "GET" && verb != "PUT" {
		return "", fmt.Errorf("action not implemented: %s. Available actions are 'GET' and 'PUT'", verb)
	}

	endpoint = strings.TrimSuffix(endpoint, "/")
	expiresAfterSeconds := int(expiresAfter.Seconds())
	signature := s.generateSignature(prefixedBlobID, verb, timeStamp, expiresAfterSeconds)

	blobURL, err := url.Parse(endpoint)
	if err != nil {
		return "", err
	}
	blobURL.Path = path.Join(blobURL.Path, "signed", prefixedBlobID)
	req, err := http.NewRequest(verb, blobURL.String(), nil)
	if err != nil {
		return "", err
	}
	q := req.URL.Query()
	q.Add("st", signature)
	q.Add("ts", fmt.Sprintf("%d", timeStamp.Unix()))
	q.Add("e", fmt.Sprintf("%d", expiresAfterSeconds))
	req.URL.RawQuery = q.Encode()
	return req.URL.String(), nil
}
<|endoftext|>


<commit_before>// This file was auto-generated via go generate.
// DO NOT UPDATE MANUALLY
package main_test

import "testing"
import "os"

import "v.io/core/veyron/lib/testutil"
import "v.io/core/veyron/lib/testutil/v23tests"

func TestMain(m *testing.M) {
	testutil.Init()
	cleanup := v23tests.UseSharedBinDir()
	r := m.Run()
	cleanup()
	os.Exit(r)
}

func TestV23Tunneld(t *testing.T) {
	v23tests.RunTest(t, V23TestTunneld)
}
<commit_msg>TBR: Copyright header added. MultiPart: 5/5<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file was auto-generated via go generate.
// DO NOT UPDATE MANUALLY
package main_test

import "testing"
import "os"

import "v.io/core/veyron/lib/testutil"
import "v.io/core/veyron/lib/testutil/v23tests"

func TestMain(m *testing.M) {
	testutil.Init()
	cleanup := v23tests.UseSharedBinDir()
	r := m.Run()
	cleanup()
	os.Exit(r)
}

func TestV23Tunneld(t *testing.T) {
	v23tests.RunTest(t, V23TestTunneld)
}
<|endoftext|>