<commit_before>package main

import (
	"github.com/dotcloud/beam"
	"os/exec"
	"log"
	"fmt"
)

func main() {
	if err := RunServer(); err != nil {
		log.Fatal(err)
	}
}

func RunServer() error {
	srv := beam.NewServer()
	srv.RegisterJob("hello", JobHelloWorld)
	srv.RegisterJob("exec", JobExec)
	if err := srv.ListenAndServe("unix", "./beam.sock"); err != nil {
		return err
	}
	return nil
}

func JobHello(name string, args []string, env map[string]string, db beam.DB, streams beam.Streamer) error {
	 // FIXME: can we get away with not returning errors? Maybe the server just kills the handler on error?
	stdout := streams.Open("stdout", beam.O_WRONLY)
	fmt.Fprintf(stdout, "Hello, %s!", strings.Join(args, " "))
	return nil
}

func JobExec(name string, args []string, env map[string]string, db beam.DB, streams beam.Streamer) error {
	var (
		cmdName string
		cmdArgs []string
	)
	if len(args) >= 1 {
		cmdName = args[0]
	} else {
		return fmt.Errorf("Not enough arguments")
	}
	if len(args) > 1 {
		cmdArgs = args[1:]
	}
	p := exec.Command(cmdName, cmdArgs...)
	p.Stdin = streams.OpenRead("stdin")
	p.Stdout = streams.OpenWrite("stdout")
	p.Stderr = streams.OpenWrite("stderr")
<commit_msg>Move db to last argument of job handlers, to group unix-style arguments together.<commit_after>package main

import (
	"github.com/dotcloud/beam"
	"os/exec"
	"log"
	"fmt"
)

func main() {
	if err := RunServer(); err != nil {
		log.Fatal(err)
	}
}

func RunServer() error {
	srv := beam.NewServer()
	srv.RegisterJob("hello", JobHelloWorld)
	srv.RegisterJob("exec", JobExec)
	if err := srv.ListenAndServe("unix", "./beam.sock"); err != nil {
		return err
	}
	return nil
}

func JobHello(name string, args []string, env map[string]string, streams beam.Streamer, db beam.DB) error {
	 // FIXME: can we get away with not returning errors? Maybe the server just kills the handler on error?
	stdout := streams.Open("stdout", beam.O_WRONLY)
	fmt.Fprintf(stdout, "Hello, %s!", strings.Join(args, " "))
	return nil
}

func JobExec(name string, args []string, env map[string]string, streams beam.Streamer, db beam.DB) error {
	var (
		cmdName string
		cmdArgs []string
	)
	if len(args) >= 1 {
		cmdName = args[0]
	} else {
		return fmt.Errorf("Not enough arguments")
	}
	if len(args) > 1 {
		cmdArgs = args[1:]
	}
	p := exec.Command(cmdName, cmdArgs...)
	p.Stdin = streams.OpenRead("stdin")
	p.Stdout = streams.OpenWrite("stdout")
	p.Stderr = streams.OpenWrite("stderr")
<|endoftext|>


<commit_before>// Copyright 2016 Mender Software AS
//
//    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 main

import (
	"bufio"
	"os"
	"strings"
	"time"

	"github.com/mendersoftware/log"
	"github.com/pkg/errors"
)

type Controller interface {
	Bootstrap() error
	GetCurrentImageID() string
	GetUpdatePollInterval() time.Duration
	HasUpgrade() (bool, error)
	CheckUpdate() (*UpdateResponse, error)

	UInstallCommitRebooter
	Updater
	StateRunner
}

const (
	defaultManifestFile = "/etc/build_mender"
	defaultKeyFile      = "mender-agent.pem"
	defaultDataStore    = "/var/lib/mender"
)

type MenderState int

// State transitions:
//
//            unknown
//               |
//               v
//             init
//               |
//               v
//          bootstrapped
//               |
//       +-------+-------------+
//       |                     |
//       v                     v
// fresh update         wait for update
//
// Any state can transition to MenderStateError

const (
	// initial state
	MenderStateInit MenderState = iota
	// client is bootstrapped, i.e. ready to go
	MenderStateBootstrapped
	// wait for new update
	MenderStateUpdateCheckWait
	// check update
	MenderStateUpdateCheck
	// update fetch
	MenderStateUpdateFetch
	// update install
	MenderStateUpdateInstall
	// commit needed
	MenderStateUpdateCommit
	// reboot
	MenderStateReboot
	// error
	MenderStateError
	// exit state
	MenderStateDone
)

type mender struct {
	UInstallCommitRebooter
	Updater
	env            BootEnvReadWriter
	state          State
	config         menderConfig
	manifestFile   string
	deviceKey      *Keystore
	forceBootstrap bool
}

type MenderPieces struct {
	updater Updater
	device  UInstallCommitRebooter
	env     BootEnvReadWriter
	store   Store
}

func NewMender(config menderConfig, pieces MenderPieces) *mender {

	ks := NewKeystore(pieces.store)
	if ks == nil {
		return nil
	}

	m := &mender{
		UInstallCommitRebooter: pieces.device,
		Updater:                pieces.updater,
		env:                    pieces.env,
		manifestFile:           defaultManifestFile,
		deviceKey:              ks,
		state:                  initState,
		config:                 config,
	}

	if err := m.deviceKey.Load(m.config.DeviceKey); err != nil && IsNoKeys(err) == false {
		log.Errorf("failed to load device keys: %s", err)
		return nil
	}

	return m
}

func (m mender) GetCurrentImageID() string {
	// This is where Yocto stores buid information
	manifest, err := os.Open(m.manifestFile)
	if err != nil {
		log.Error("Can not read current image id.")
		return ""
	}

	imageID := ""

	scanner := bufio.NewScanner(manifest)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		log.Debug("Read data from device manifest file: ", line)
		if strings.HasPrefix(line, "IMAGE_ID") {
			log.Debug("Found device id line: ", line)
			lineID := strings.Split(line, "=")
			if len(lineID) != 2 {
				log.Errorf("Broken device manifest file: (%v)", lineID)
				return ""
			}
			log.Debug("Current image id: ", strings.TrimSpace(lineID[1]))
			return strings.TrimSpace(lineID[1])
		}
	}
	if err := scanner.Err(); err != nil {
		log.Error(err)
	}
	return imageID
}

func (m *mender) HasUpgrade() (bool, error) {
	env, err := m.env.ReadEnv("upgrade_available")
	if err != nil {
		return false, err
	}
	upgradeAvailable := env["upgrade_available"]

	// we are after update
	if upgradeAvailable == "1" {
		return true, nil
	}
	return false, nil
}

func (m *mender) ForceBootstrap() {
	m.forceBootstrap = true
}

func (m *mender) needsBootstrap() bool {
	if m.forceBootstrap {
		return true
	}

	if m.deviceKey.Private() == nil {
		log.Debugf("needs keys")
		return true
	}

	return false
}

func (m *mender) Bootstrap() error {
	if !m.needsBootstrap() {
		return nil
	}

	return m.doBootstrap()
}

func (m *mender) doBootstrap() error {
	if m.deviceKey.Private() == nil {
		log.Infof("device keys not present, generating")
		if err := m.deviceKey.Generate(); err != nil {
			return err
		}

		if err := m.deviceKey.Save(m.config.DeviceKey); err != nil {
			log.Errorf("failed to save keys to %s: %s",
				m.config.DeviceKey, err)
			return err
		}
	}

	m.forceBootstrap = false

	return nil
}

// Check if new update is available. In case of errors, returns nil and error
// that occurred. If no update is available *UpdateResponse is nil, otherwise it
// contains update information.
func (m *mender) CheckUpdate() (*UpdateResponse, error) {
	currentImageID := m.GetCurrentImageID()
	//TODO: if currentImageID == "" {
	// 	return errors.New("")
	// }

	haveUpdate, err := m.Updater.GetScheduledUpdate(m.config.ServerURL, m.config.DeviceID)
	if err != nil {
		log.Error("Error receiving scheduled update data: ", err)
		return nil, err
	}

	log.Debug("Received correct response for update request.")

	update, ok := haveUpdate.(UpdateResponse)
	if !ok {
		return nil, errors.Errorf("not an update response?")
	}

	if update.Image.YoctoID == currentImageID {
		return nil, nil
	}
	return &update, nil
}

func (m mender) GetUpdatePollInterval() time.Duration {
	return time.Duration(m.config.PollIntervalSeconds) * time.Second
}

func (m *mender) SetState(s State) {
	log.Infof("Mender state: %v -> %v", m.state.Id(), s.Id())
	m.state = s
}

func (m *mender) GetState() State {
	return m.state
}
<commit_msg>mender: use menderError in Controler interface methods<commit_after>// Copyright 2016 Mender Software AS
//
//    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 main

import (
	"bufio"
	"os"
	"strings"
	"time"

	"github.com/mendersoftware/log"
	"github.com/pkg/errors"
)

type Controller interface {
	Bootstrap() menderError
	GetCurrentImageID() string
	GetUpdatePollInterval() time.Duration
	HasUpgrade() (bool, menderError)
	CheckUpdate() (*UpdateResponse, menderError)

	UInstallCommitRebooter
	Updater
	StateRunner
}

const (
	defaultManifestFile = "/etc/build_mender"
	defaultKeyFile      = "mender-agent.pem"
	defaultDataStore    = "/var/lib/mender"
)

type MenderState int

// State transitions:
//
//            unknown
//               |
//               v
//             init
//               |
//               v
//          bootstrapped
//               |
//       +-------+-------------+
//       |                     |
//       v                     v
// fresh update         wait for update
//
// Any state can transition to MenderStateError

const (
	// initial state
	MenderStateInit MenderState = iota
	// client is bootstrapped, i.e. ready to go
	MenderStateBootstrapped
	// wait for new update
	MenderStateUpdateCheckWait
	// check update
	MenderStateUpdateCheck
	// update fetch
	MenderStateUpdateFetch
	// update install
	MenderStateUpdateInstall
	// commit needed
	MenderStateUpdateCommit
	// reboot
	MenderStateReboot
	// error
	MenderStateError
	// exit state
	MenderStateDone
)

type mender struct {
	UInstallCommitRebooter
	Updater
	env            BootEnvReadWriter
	state          State
	config         menderConfig
	manifestFile   string
	deviceKey      *Keystore
	forceBootstrap bool
}

type MenderPieces struct {
	updater Updater
	device  UInstallCommitRebooter
	env     BootEnvReadWriter
	store   Store
}

func NewMender(config menderConfig, pieces MenderPieces) *mender {

	ks := NewKeystore(pieces.store)
	if ks == nil {
		return nil
	}

	m := &mender{
		UInstallCommitRebooter: pieces.device,
		Updater:                pieces.updater,
		env:                    pieces.env,
		manifestFile:           defaultManifestFile,
		deviceKey:              ks,
		state:                  initState,
		config:                 config,
	}

	if err := m.deviceKey.Load(m.config.DeviceKey); err != nil && IsNoKeys(err) == false {
		log.Errorf("failed to load device keys: %s", err)
		return nil
	}

	return m
}

func (m mender) GetCurrentImageID() string {
	// This is where Yocto stores buid information
	manifest, err := os.Open(m.manifestFile)
	if err != nil {
		log.Error("Can not read current image id.")
		return ""
	}

	imageID := ""

	scanner := bufio.NewScanner(manifest)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		log.Debug("Read data from device manifest file: ", line)
		if strings.HasPrefix(line, "IMAGE_ID") {
			log.Debug("Found device id line: ", line)
			lineID := strings.Split(line, "=")
			if len(lineID) != 2 {
				log.Errorf("Broken device manifest file: (%v)", lineID)
				return ""
			}
			log.Debug("Current image id: ", strings.TrimSpace(lineID[1]))
			return strings.TrimSpace(lineID[1])
		}
	}
	if err := scanner.Err(); err != nil {
		log.Error(err)
	}
	return imageID
}

func (m *mender) HasUpgrade() (bool, menderError) {
	env, err := m.env.ReadEnv("upgrade_available")
	if err != nil {
		return false, NewFatalError(err)
	}
	upgradeAvailable := env["upgrade_available"]

	// we are after update
	if upgradeAvailable == "1" {
		return true, nil
	}
	return false, nil
}

func (m *mender) ForceBootstrap() {
	m.forceBootstrap = true
}

func (m *mender) needsBootstrap() bool {
	if m.forceBootstrap {
		return true
	}

	if m.deviceKey.Private() == nil {
		log.Debugf("needs keys")
		return true
	}

	return false
}

func (m *mender) Bootstrap() menderError {
	if !m.needsBootstrap() {
		return nil
	}

	return m.doBootstrap()
}

func (m *mender) doBootstrap() menderError {
	if m.deviceKey.Private() == nil {
		log.Infof("device keys not present, generating")
		if err := m.deviceKey.Generate(); err != nil {
			return NewFatalError(err)
		}

		if err := m.deviceKey.Save(m.config.DeviceKey); err != nil {
			log.Errorf("failed to save keys to %s: %s",
				m.config.DeviceKey, err)
			return NewFatalError(err)
		}
	}

	m.forceBootstrap = false

	return nil
}

// Check if new update is available. In case of errors, returns nil and error
// that occurred. If no update is available *UpdateResponse is nil, otherwise it
// contains update information.
func (m *mender) CheckUpdate() (*UpdateResponse, menderError) {
	currentImageID := m.GetCurrentImageID()
	//TODO: if currentImageID == "" {
	// 	return errors.New("")
	// }

	haveUpdate, err := m.Updater.GetScheduledUpdate(m.config.ServerURL, m.config.DeviceID)
	if err != nil {
		log.Error("Error receiving scheduled update data: ", err)
		return nil, NewTransientError(err)
	}

	log.Debug("Received correct response for update request.")

	update, ok := haveUpdate.(UpdateResponse)
	if !ok {
		return nil, NewTransientError(errors.Errorf("not an update response?"))
	}

	if update.Image.YoctoID == currentImageID {
		return nil, nil
	}
	return &update, nil
}

func (m mender) GetUpdatePollInterval() time.Duration {
	return time.Duration(m.config.PollIntervalSeconds) * time.Second
}

func (m *mender) SetState(s State) {
	log.Infof("Mender state: %v -> %v", m.state.Id(), s.Id())
	m.state = s
}

func (m *mender) GetState() State {
	return m.state
}
<|endoftext|>


<commit_before>package netns_test

import (
	"errors"
	"fmt"
	"net"
	"os"
	"os/exec"

	"code.cloudfoundry.org/guardian/kawasaki/netns"
	"github.com/vishvananda/netlink"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
)

var _ = Describe("NetnsExecerLinux", func() {
	BeforeEach(func() {
		sess, err := gexec.Start(exec.Command("ip", "netns", "add", fmt.Sprintf("gdn-netnstest-%d", GinkgoParallelNode())), GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
		Eventually(sess).Should(gexec.Exit(0))
	})

	AfterEach(func() {
		sess, err := gexec.Start(exec.Command("ip", "netns", "delete", fmt.Sprintf("gdn-netnstest-%d", GinkgoParallelNode())), GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
		Eventually(sess).Should(gexec.Exit(0))
	})

	Describe("Executing a function inside the network namespace", func() {
		It("should be inside the namespace", func() {
			fd, err := os.Open(fmt.Sprintf("/var/run/netns/gdn-netnstest-%d", GinkgoParallelNode()))
			Expect(err).NotTo(HaveOccurred())

			Expect(netns.Exec(fd, func() error {

				link := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: "banana-iface"}}
				Expect(netlink.LinkAdd(link)).To(Succeed())

				_, err := net.InterfaceByName("banana-iface")
				Expect(err).NotTo(HaveOccurred())
				return nil
			})).To(Succeed())

			_, err = net.InterfaceByName("banana-iface")
			Expect(err).To(HaveOccurred())
		})

		It("bubbles up any errors", func() {
			fd, err := os.Open(fmt.Sprintf("/var/run/netns/gdn-netnstest-%d", GinkgoParallelNode()))
			Expect(err).NotTo(HaveOccurred())

			Expect(
				netns.Exec(fd, func() error { return errors.New("boom") }),
			).To(MatchError("boom"))
		})
	})
})
<commit_msg>Improve NetnsExecerLinux tests<commit_after>package netns_test

import (
	"errors"
	"fmt"
	"net"
	"os"
	"os/exec"

	"code.cloudfoundry.org/guardian/kawasaki/netns"
	"github.com/vishvananda/netlink"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
)

var _ = Describe("NetnsExecerLinux", func() {
	var netnsName string

	BeforeEach(func() {
		netnsName = fmt.Sprintf("gdn-netnstest-%d", GinkgoParallelNode())
	})

	JustBeforeEach(func() {
		sess, err := gexec.Start(exec.Command("ip", "netns", "add", netnsName), GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
		Eventually(sess, "3s").Should(gexec.Exit(0))
	})

	AfterEach(func() {
		sess, err := gexec.Start(exec.Command("ip", "netns", "delete", netnsName), GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
		Eventually(sess, "3s").Should(gexec.Exit(0))
	})

	Describe("Executing a function inside the network namespace", func() {
		It("should be inside the namespace", func() {
			fd, err := os.Open(fmt.Sprintf("/var/run/netns/%s", netnsName))
			Expect(err).NotTo(HaveOccurred())

			Expect(netns.Exec(fd, func() error {
				link := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: "banana-iface"}}
				Expect(netlink.LinkAdd(link)).To(Succeed())

				_, err := net.InterfaceByName("banana-iface")
				Expect(err).NotTo(HaveOccurred())
				return nil
			})).To(Succeed())

			_, err = net.InterfaceByName("banana-iface")
			Expect(err).To(HaveOccurred())
		})

		It("bubbles up any errors", func() {
			fd, err := os.Open(fmt.Sprintf("/var/run/netns/%s", netnsName))
			Expect(err).NotTo(HaveOccurred())

			Expect(
				netns.Exec(fd, func() error { return errors.New("boom") }),
			).To(MatchError("boom"))
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"os"
)

func main() {

	var (
		ClientOV       *ov.OVClient
		new_volume     = "TestVolume"
		name_to_update = "UpdatedName"
	)

	ovc := ClientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		2000,
		"*")

	// Create storage volume with name <new_volume>
	st_pool, _ := ovc.GetStoragePoolByName("CPG-SSD")
	properties := &ov.Properties{
		Name:                new_volume,
		Storagepool:         st_pool.URI,
		Size:                268435456,
		ProvisioningType:    "Thin",
		DataProtectionLevel: "NetworkRaid10Mirror2Way",
	}
	trueVal := true
	storageVolume := ov.StorageVolume{TemplateURI: utils.NewNstring("/rest/storage-volume-templates/5d57f25a-0fb0-4980-84af-ac3001139130"), Properties: properties, IsPermanent: &trueVal}

	err := ovc.CreateStorageVolume(storageVolume)
	if err != nil {
		fmt.Println("Could not create the volume", err)
	}

	// Update the given storage volume
	update_vol, _ := ovc.GetStorageVolumeByName(new_volume)

	updated_storage_volume := ov.StorageVolume{
		ProvisioningTypeForUpdate: update_vol.ProvisioningTypeForUpdate,
		IsPermanent:               update_vol.IsPermanent,
		IsShareable:               update_vol.IsShareable,
		Name:                      name_to_update,
		ProvisionedCapacity:       "107374741824",
		DeviceSpecificAttributes:  update_vol.DeviceSpecificAttributes,
		URI:                       update_vol.URI,
		ETAG:                      update_vol.ETAG,
		Description:               "empty",
		TemplateVersion:           "1.1",
		VolumeTemplateUri:         update_vol.VolumeTemplateUri,
	}

	err = ovc.UpdateStorageVolume(updated_storage_volume)
	if err != nil {
		fmt.Println("Could not update the volume", err)
	}

	// Get All the volumes present
	fmt.Println("\nGetting all the storage volumes present in the system: \n")
	sort := "name:desc"
	vol_list, err := ovc.GetStorageVolumes("", sort)
	if err != nil {
		fmt.Println("Error Getting the storage volumes ", err)
	}
	for i := 0; i < len(vol_list.Members); i++ {
		fmt.Println(vol_list.Members[i].Name)
	}

	// Get volume by name
	fmt.Println("\nGetting details of volume with name: ", name_to_update)
	vol_by_name, _ := ovc.GetStorageVolumeByName(name_to_update)
	fmt.Println(vol_by_name)

	// Delete the created volume
	fmt.Println("\nDeleting the volume with name : UpdatedName")
	err = ovc.DeleteStorageVolume(name_to_update)
	if err != nil {
		fmt.Println("Delete Unsuccessful", err)
	}
}
<commit_msg>update st_vol ex<commit_after>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"os"
)

func main() {

	var (
		ClientOV       *ov.OVClient
		new_volume     = "TestVolume"
		name_to_update = "UpdatedName"
	)

	ovc := ClientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		2000,
		"*")

	// Create storage volume with name <new_volume>
	st_pool, _ := ovc.GetStoragePoolByName("CPG-SSD")
	properties := &ov.Properties{
		Name:                new_volume,
		Storagepool:         st_pool.URI,
		Size:                268435456,
		ProvisioningType:    "Thin",
		DataProtectionLevel: "NetworkRaid10Mirror2Way",
	}
	trueVal := true
        vol_template, err := ovc.GetStorageVolumeTemplateByName("template1")
        if err != nil {
                fmt.Println(err)
	}
	storageVolume := ov.StorageVolume{TemplateURI: vol_template.URI, Properties: properties, IsPermanent: &trueVal}

	err := ovc.CreateStorageVolume(storageVolume)
	if err != nil {
		fmt.Println("Could not create the volume", err)
	}

	// Update the given storage volume
	update_vol, _ := ovc.GetStorageVolumeByName(new_volume)

	updated_storage_volume := ov.StorageVolume{
		ProvisioningTypeForUpdate: update_vol.ProvisioningTypeForUpdate,
		IsPermanent:               update_vol.IsPermanent,
		IsShareable:               update_vol.IsShareable,
		Name:                      name_to_update,
		ProvisionedCapacity:       "107374741824",
		DeviceSpecificAttributes:  update_vol.DeviceSpecificAttributes,
		URI:                       update_vol.URI,
		ETAG:                      update_vol.ETAG,
		Description:               "empty",
		TemplateVersion:           "1.1",
		VolumeTemplateUri:         update_vol.VolumeTemplateUri,
	}

	err = ovc.UpdateStorageVolume(updated_storage_volume)
	if err != nil {
		fmt.Println("Could not update the volume", err)
	}

	// Get All the volumes present
	fmt.Println("\nGetting all the storage volumes present in the system: \n")
	sort := "name:desc"
	vol_list, err := ovc.GetStorageVolumes("", sort)
	if err != nil {
		fmt.Println("Error Getting the storage volumes ", err)
	}
	for i := 0; i < len(vol_list.Members); i++ {
		fmt.Println(vol_list.Members[i].Name)
	}

	// Get volume by name
	fmt.Println("\nGetting details of volume with name: ", name_to_update)
	vol_by_name, _ := ovc.GetStorageVolumeByName(name_to_update)
	fmt.Println(vol_by_name)

	// Delete the created volume
	fmt.Println("\nDeleting the volume with name : UpdatedName")
	err = ovc.DeleteStorageVolume(name_to_update)
	if err != nil {
		fmt.Println("Delete Unsuccessful", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"os"
)

func main() {

	var (
		ClientOV       *ov.OVClient
		new_volume     = "TestVolume"
		name_to_update = "UpdatedName"
	)

	ovc := ClientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		2000,
		"*")

	// Create storage volume with name <new_volume>
	st_pool, _ := ovc.GetStoragePoolByName("CPG-SSD")
	properties := &ov.Properties{
		Name:                new_volume,
		Storagepool:         st_pool.URI,
		Size:                268435456,
		ProvisioningType:    "Thin",
		DataProtectionLevel: "NetworkRaid10Mirror2Way",
	}
	trueVal := true
        vol_template, err := ovc.GetStorageVolumeTemplateByName("template1")
        if err != nil {
                fmt.Println(err)
	}
	storageVolume := ov.StorageVolume{TemplateURI: vol_template.URI, Properties: properties, IsPermanent: &trueVal}

	err := ovc.CreateStorageVolume(storageVolume)
	if err != nil {
		fmt.Println("Could not create the volume", err)
	}

	// Update the given storage volume
	update_vol, _ := ovc.GetStorageVolumeByName(new_volume)

	updated_storage_volume := ov.StorageVolume{
		ProvisioningTypeForUpdate: update_vol.ProvisioningTypeForUpdate,
		IsPermanent:               update_vol.IsPermanent,
		IsShareable:               update_vol.IsShareable,
		Name:                      name_to_update,
		ProvisionedCapacity:       "107374741824",
		DeviceSpecificAttributes:  update_vol.DeviceSpecificAttributes,
		URI:                       update_vol.URI,
		ETAG:                      update_vol.ETAG,
		Description:               "empty",
		TemplateVersion:           "1.1",
		VolumeTemplateUri:         update_vol.VolumeTemplateUri,
	}

	err = ovc.UpdateStorageVolume(updated_storage_volume)
	if err != nil {
		fmt.Println("Could not update the volume", err)
	}

	// Get All the volumes present
	fmt.Println("\nGetting all the storage volumes present in the system: \n")
	sort := "name:desc"
	vol_list, err := ovc.GetStorageVolumes("", sort)
	if err != nil {
		fmt.Println("Error Getting the storage volumes ", err)
	}
	for i := 0; i < len(vol_list.Members); i++ {
		fmt.Println(vol_list.Members[i].Name)
	}

	// Get volume by name
	fmt.Println("\nGetting details of volume with name: ", name_to_update)
	vol_by_name, _ := ovc.GetStorageVolumeByName(name_to_update)
	fmt.Println(vol_by_name)

	// Delete the created volume
	fmt.Println("\nDeleting the volume with name : UpdatedName")
	err = ovc.DeleteStorageVolume(name_to_update)
	if err != nil {
		fmt.Println("Delete Unsuccessful", err)
	}
}
<commit_msg>update st_vol ex<commit_after>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"github.com/HewlettPackard/oneview-golang/utils"
	"os"
)

func main() {

	var (
		ClientOV       *ov.OVClient
		new_volume     = "TestVolume"
		name_to_update = "UpdatedName"
	)

	ovc := ClientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		2000,
		"*")

	// Create storage volume with name <new_volume>
	st_pool, _ := ovc.GetStoragePoolByName("CPG-SSD")
	properties := &ov.Properties{
		Name:                new_volume,
		Storagepool:         st_pool.URI,
		Size:                268435456,
		ProvisioningType:    "Thin",
		DataProtectionLevel: "NetworkRaid10Mirror2Way",
	}
	trueVal := true
	vol_template, err := ovc.GetStorageVolumeTemplateByName("template1")
	if err != nil {
		fmt.Println(err)
	}
	storageVolume := ov.StorageVolume{TemplateURI: vol_template.URI, Properties: properties, IsPermanent: &trueVal}

	err := ovc.CreateStorageVolume(storageVolume)
	if err != nil {
		fmt.Println("Could not create the volume", err)
	}

	// Update the given storage volume
	update_vol, _ := ovc.GetStorageVolumeByName(new_volume)

	updated_storage_volume := ov.StorageVolume{
		ProvisioningTypeForUpdate: update_vol.ProvisioningTypeForUpdate,
		IsPermanent:               update_vol.IsPermanent,
		IsShareable:               update_vol.IsShareable,
		Name:                      name_to_update,
		ProvisionedCapacity:       "107374741824",
		DeviceSpecificAttributes:  update_vol.DeviceSpecificAttributes,
		URI:                       update_vol.URI,
		ETAG:                      update_vol.ETAG,
		Description:               "empty",
		TemplateVersion:           "1.1",
		VolumeTemplateUri:         update_vol.VolumeTemplateUri,
	}

	err = ovc.UpdateStorageVolume(updated_storage_volume)
	if err != nil {
		fmt.Println("Could not update the volume", err)
	}

	// Get All the volumes present
	fmt.Println("\nGetting all the storage volumes present in the system: \n")
	sort := "name:desc"
	vol_list, err := ovc.GetStorageVolumes("", sort)
	if err != nil {
		fmt.Println("Error Getting the storage volumes ", err)
	}
	for i := 0; i < len(vol_list.Members); i++ {
		fmt.Println(vol_list.Members[i].Name)
	}

	// Get volume by name
	fmt.Println("\nGetting details of volume with name: ", name_to_update)
	vol_by_name, _ := ovc.GetStorageVolumeByName(name_to_update)
	fmt.Println(vol_by_name)

	// Delete the created volume
	fmt.Println("\nDeleting the volume with name : UpdatedName")
	err = ovc.DeleteStorageVolume(name_to_update)
	if err != nil {
		fmt.Println("Delete Unsuccessful", err)
	}
}
<|endoftext|>


<commit_before>package profile

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
)

/********
* MODEL *
********/

// Model represents the player model type used by a profile.
type Model int

const (
	Steve Model = iota // Classic player model aka "Steve"
	Alex               // Slim-armed player model aka "Alex"
)

var modelNames = [...]string{
	"Steve",
	"Alex",
}

func (m Model) String() string {

	return modelNames[m]
}

/*********************
* PROFILE PROPERTIES *
*********************/

// ProfileProperties contains additional information associated with a Profile.
type ProfileProperties struct {
	skinURL string
	capeURL string
	model   Model
}

// SkinURL returns a URL to the profile's custom skin texture if such one has been set.
// If a skin has been set, the boolean return value will be true.
// If no skin texture has been set for the profile, this method returns ("", false).
func (pp *ProfileProperties) SkinURL() (url string, ok bool) {

	url = pp.skinURL
	ok = url != ""
	return
}

// CapeURL returns a URL to the profile's cape texture if such one is associated.
// If a cape is associated, the boolean return value will be true.
// If no cape texture is associated with the profile, this method returns ("", false).
func (pp *ProfileProperties) CapeURL() (url string, ok bool) {

	url = pp.capeURL
	ok = url != ""
	return
}

// Model returns the player model type used by the profile.
func (pp *ProfileProperties) Model() Model {

	return pp.model
}

/******************
* PROFILE METHODS *
******************/

// LoadProperties loads and returns profile skin, cape and model information.
// On success, the result will be memoized in a thread safe manner to be returned on future calls to this method.
// A profile which was loaded by LoadWithProperties has this information preloaded.
//
// NB! For each profile, profile properties may only be requested once per minute.
func (p *Profile) LoadProperties() (*ProfileProperties, error) {

	p.mutex.Lock()
	defer p.mutex.Unlock()

	if p.properties == nil {

		loaded, err := LoadWithProperties(p.id)
		if err != nil {

			return nil, err
		}

		p.properties = loaded.properties
	}

	return p.properties, nil
}

// Properties simply returns profile skin, cape and model information if loaded, otherwise nil.
func (p *Profile) Properties() *ProfileProperties {

	p.mutex.Lock()
	defer p.mutex.Unlock()

	return p.properties
}

/************
* INTERNALS *
************/

// Map of property => parser pairs
var propertyPopulators = map[string]func(base64 string, p *ProfileProperties) error{
	"textures": populateTextures,
}

// Constructs and returns a property set based on a JSON array of properties
func buildProperties(ps []interface{}) (*ProfileProperties, error) {

	pp := new(ProfileProperties)

	for _, p := range ps {

		prop := p.(map[string]interface{})
		name := prop["name"].(string)
		value := prop["value"].(string) // base64 encoded

		err := propertyPopulators[name](value, pp)
		if err != nil {

			return nil, err
		}
	}

	return pp, nil
}

// Parses the "textures" property and adds its info to the ProfileProperties struct
func populateTextures(enc string, pp *ProfileProperties) error {

	bs, err := base64.StdEncoding.DecodeString(enc)
	if err != nil {

		return err
	}

	var j interface{}
	err = json.NewDecoder(bytes.NewBuffer(bs)).Decode(&j)
	if err != nil {

		return err
	}

	ts := j.(map[string]interface{})["textures"].(map[string]interface{})

	// Set skin URL and skin Model if present
	if s, set := ts["SKIN"]; set {

		skin := s.(map[string]interface{})

		// Set skin URL
		pp.skinURL = skin["url"].(string)

		// Set model
		if s, set := skin["metadata"]; set {

			skinMeta := s.(map[string]interface{})

			if m, set := skinMeta["model"]; set && m.(string) == "slim" {

				// Default model is Steve
				pp.model = Alex
			}
		}
	}

	// Set cape URL
	if c, ok := ts["CAPE"]; ok {

		cape := c.(map[string]interface{})

		pp.capeURL = cape["url"].(string)
	}

	return nil
}
<commit_msg>Updated documentation for the profile package<commit_after>package profile

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
)

/********
* MODEL *
********/

// Model represents the player model type used by a profile.
type Model int

const (
	Steve Model = iota // Classic player model aka "Steve"
	Alex               // Slim-armed player model aka "Alex"
)

var modelNames = [...]string{
	"Steve",
	"Alex",
}

func (m Model) String() string {

	return modelNames[m]
}

/*********************
* PROFILE PROPERTIES *
*********************/

// ProfileProperties contains additional information associated with a Profile.
type ProfileProperties struct {
	skinURL string
	capeURL string
	model   Model
}

// SkinURL returns a URL to the profile's custom skin texture if such one has been set.
// If a skin has been set, the boolean return value will be true.
// If no skin texture has been set for the profile, this method returns ("", false).
func (pp *ProfileProperties) SkinURL() (url string, ok bool) {

	url = pp.skinURL
	ok = url != ""
	return
}

// CapeURL returns a URL to the profile's cape texture if such one is associated.
// If a cape is associated, the boolean return value will be true.
// If no cape texture is associated with the profile, this method returns ("", false).
func (pp *ProfileProperties) CapeURL() (url string, ok bool) {

	url = pp.capeURL
	ok = url != ""
	return
}

// Model returns the player model type used by the profile.
func (pp *ProfileProperties) Model() Model {

	return pp.model
}

/******************
* PROFILE METHODS *
******************/

// LoadProperties loads and returns the profile's skin, cape and model information.
// On success, the result will be memoized in a thread safe manner to be returned on future calls to this method.
// A profile which was loaded by LoadWithProperties has this information preloaded.
//
// NB! For each profile, profile properties may only be requested once per minute.
func (p *Profile) LoadProperties() (*ProfileProperties, error) {

	p.mutex.Lock()
	defer p.mutex.Unlock()

	if p.properties == nil {

		loaded, err := LoadWithProperties(p.id)
		if err != nil {

			return nil, err
		}

		p.properties = loaded.properties
	}

	return p.properties, nil
}

// Properties returns the profile's skin, cape and model information if loaded, otherwise nil.
func (p *Profile) Properties() *ProfileProperties {

	p.mutex.Lock()
	defer p.mutex.Unlock()

	return p.properties
}

/************
* INTERNALS *
************/

// Map of property => parser pairs
var propertyPopulators = map[string]func(base64 string, p *ProfileProperties) error{
	"textures": populateTextures,
}

// Constructs and returns a property set based on a JSON array of properties
func buildProperties(ps []interface{}) (*ProfileProperties, error) {

	pp := new(ProfileProperties)

	for _, p := range ps {

		prop := p.(map[string]interface{})
		name := prop["name"].(string)
		value := prop["value"].(string) // base64 encoded

		err := propertyPopulators[name](value, pp)
		if err != nil {

			return nil, err
		}
	}

	return pp, nil
}

// Parses the "textures" property and adds its info to the ProfileProperties struct
func populateTextures(enc string, pp *ProfileProperties) error {

	bs, err := base64.StdEncoding.DecodeString(enc)
	if err != nil {

		return err
	}

	var j interface{}
	err = json.NewDecoder(bytes.NewBuffer(bs)).Decode(&j)
	if err != nil {

		return err
	}

	ts := j.(map[string]interface{})["textures"].(map[string]interface{})

	// Set skin URL and skin Model if present
	if s, set := ts["SKIN"]; set {

		skin := s.(map[string]interface{})

		// Set skin URL
		pp.skinURL = skin["url"].(string)

		// Set model
		if s, set := skin["metadata"]; set {

			skinMeta := s.(map[string]interface{})

			if m, set := skinMeta["model"]; set && m.(string) == "slim" {

				// Default model is Steve
				pp.model = Alex
			}
		}
	}

	// Set cape URL
	if c, ok := ts["CAPE"]; ok {

		cape := c.(map[string]interface{})

		pp.capeURL = cape["url"].(string)
	}

	return nil
}
<|endoftext|>


<commit_before>package services

import (
	"github.com/matrix-org/go-neb/database"
	"github.com/matrix-org/go-neb/matrix"
	"github.com/matrix-org/go-neb/plugin"
	"regexp"
	"strings"
)

type githubService struct {
	id     string
	UserID string
	Rooms  []string
}

func (s *githubService) ServiceUserID() string { return s.UserID }
func (s *githubService) ServiceID() string     { return s.id }
func (s *githubService) ServiceType() string   { return "github" }
func (s *githubService) RoomIDs() []string     { return s.Rooms }
func (s *githubService) Plugin(roomID string) plugin.Plugin {
	return plugin.Plugin{
		Commands: []plugin.Command{
			plugin.Command{
				Path: []string{"github"},
				Command: func(roomID, userID string, args []string) (interface{}, error) {
					return &matrix.TextMessage{"m.notice", strings.Join(args, " ")}, nil
				},
			},
		},
		Expansions: []plugin.Expansion{
			plugin.Expansion{
				// E.g. owner/repo#11 (issue/PR numbers)
				Regexp: regexp.MustCompile("[A-z0-9-_]+/[A-z0-9-_]+#[0-9]+"),
				Expand: func(roomID, matchingText string) interface{} {
					// get the issue/PR number
					repoAndNum := strings.Split(matchingText, "#")
					return &matrix.TextMessage{
						"m.notice",
						"Repo: " + repoAndNum[0] + " Num: " + repoAndNum[1],
					}
				},
			},
		},
	}
}

func init() {
	database.RegisterService(func(serviceID string) database.Service {
		return &githubService{id: serviceID}
	})
}
<commit_msg>Add github issue expansion for things that look like owner/repo#11<commit_after>package services

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/google/go-github/github"
	"github.com/matrix-org/go-neb/database"
	"github.com/matrix-org/go-neb/matrix"
	"github.com/matrix-org/go-neb/plugin"
	"golang.org/x/oauth2"
	"regexp"
	"strconv"
	"strings"
)

// Matches alphanumeric then a /, then more alphanumeric then a #, then a number.
// E.g. owner/repo#11 (issue/PR numbers) - Captured groups for owner/repo/number
const ownerRepoIssueRegex = "([A-z0-9-_]+)/([A-z0-9-_]+)#([0-9]+)"

type githubService struct {
	id     string
	UserID string
	Rooms  []string
}

func (s *githubService) ServiceUserID() string { return s.UserID }
func (s *githubService) ServiceID() string     { return s.id }
func (s *githubService) ServiceType() string   { return "github" }
func (s *githubService) RoomIDs() []string     { return s.Rooms }
func (s *githubService) Plugin(roomID string) plugin.Plugin {
	return plugin.Plugin{
		Commands: []plugin.Command{
			plugin.Command{
				Path: []string{"github"},
				Command: func(roomID, userID string, args []string) (interface{}, error) {
					return &matrix.TextMessage{"m.notice", strings.Join(args, " ")}, nil
				},
			},
		},
		Expansions: []plugin.Expansion{
			plugin.Expansion{
				Regexp: regexp.MustCompile(ownerRepoIssueRegex),
				Expand: func(roomID, matchingText string) interface{} {
					cli := githubClient("")
					owner, repo, num, err := ownerRepoNumberFromText(matchingText)
					if err != nil {
						log.WithError(err).WithField("text", matchingText).Print(
							"Failed to extract owner,repo,number from matched string")
						return nil
					}

					i, _, err := cli.Issues.Get(owner, repo, num)
					if err != nil {
						log.WithError(err).WithFields(log.Fields{
							"owner":  owner,
							"repo":   repo,
							"number": num,
						}).Print("Failed to fetch issue")
						return nil
					}

					return &matrix.TextMessage{
						"m.notice",
						fmt.Sprintf("%s : %s", *i.HTMLURL, *i.Title),
					}
				},
			},
		},
	}
}

func githubClient(token string) *github.Client {
	var tokenSource oauth2.TokenSource
	if token != "" {
		tokenSource = oauth2.StaticTokenSource(
			&oauth2.Token{AccessToken: token},
		)
	}
	httpCli := oauth2.NewClient(oauth2.NoContext, tokenSource)
	return github.NewClient(httpCli)
}

// ownerRepoNumberFromText parses a GH issue string that looks like 'owner/repo#11'
// into its constituient parts. Returns: owner, repo, issue#.
func ownerRepoNumberFromText(ownerRepoNumberText string) (string, string, int, error) {
	// TODO: cache this?
	re := regexp.MustCompile(ownerRepoIssueRegex)
	// [full_string, owner, repo, issue_number]
	groups := re.FindStringSubmatch(ownerRepoNumberText)
	if len(groups) != 4 {
		return "", "", 0, fmt.Errorf("No match found for '%s'", ownerRepoNumberText)
	}
	num, err := strconv.Atoi(groups[3])
	if err != nil {
		return "", "", 0, err
	}
	return groups[1], groups[2], num, nil
}

func init() {
	database.RegisterService(func(serviceID string) database.Service {
		return &githubService{id: serviceID}
	})
}
<|endoftext|>


<commit_before>// Copyright (c) Ilia Kravets, 2015. All rights reserved. PROVIDED "AS IS"
// WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. See LICENSE file for details.

package rec

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"

	"my/ev/packet"
	"my/ev/packet/bats"
	"my/ev/packet/nasdaq"
	"my/ev/sim"
)

const (
	EFHM_DEFINITION      = 0
	EFHM_TRADE           = 1
	EFHM_QUOTE           = 2
	EFHM_ORDER           = 3
	EFHM_DEFINITION_NOM  = 4
	EFHM_DEFINITION_BATS = 5
	EFHM_REFRESHED       = 100
	EFHM_STOPPED         = 101

	EFH_ORDER_BID = 1
	EFH_ORDER_ASK = -1

	EFH_SECURITY_PUT  = 0
	EFH_SECURITY_CALL = 1
)

type efhm_header struct {
	Type           uint8
	TickCondition  uint8
	QueuePosition  uint16
	UnderlyingId   uint32
	SecurityId     uint64
	SequenceNumber uint64
	TimeStamp      uint64
}

type efhm_order struct {
	efhm_header
	TradeStatus     uint8
	OrderType       uint8
	OrderSide       int8
	_pad            byte
	Price           uint32
	Size            uint32
	AoNSize         uint32
	CustomerSize    uint32
	CustomerAoNSize uint32
	BDSize          uint32
	BDAoNSize       uint32
}

type efhm_quote struct {
	efhm_header
	TradeStatus        uint8
	_pad               [3]byte
	BidPrice           uint32
	BidSize            uint32
	BidOrderSize       uint32
	BidAoNSize         uint32
	BidCustomerSize    uint32
	BidCustomerAoNSize uint32
	BidBDSize          uint32
	BidBDAoNSize       uint32
	AskPrice           uint32
	AskSize            uint32
	AskOrderSize       uint32
	AskAoNSize         uint32
	AskCustomerSize    uint32
	AskCustomerAoNSize uint32
	AskBDSize          uint32
	AskBDAoNSize       uint32
}

type efhm_trade struct {
	efhm_header
	Price          uint32
	Size           uint32
	TradeCondition uint8
}

type efhm_definition_nom struct {
	efhm_header
	Symbol           [8]byte
	MaturityDate     uint64
	UnderlyingSymbol [16]byte
	StrikePrice      uint32
	PutOrCall        uint8
}

type efhm_definition_bats struct {
	efhm_header
	OsiSymbol [22]byte
}

func (m efhm_header) String() string {
	switch m.Type {
	case EFHM_QUOTE, EFHM_ORDER, EFHM_TRADE, EFHM_DEFINITION_NOM, EFHM_DEFINITION_BATS:
		return fmt.Sprintf("HDR{T:%d, TC:%d, QP:%d, UId:%08x, SId:%016x, SN:%d, TS:%016x}",
			m.Type,
			m.TickCondition,
			m.QueuePosition,
			m.UnderlyingId,
			m.SecurityId,
			m.SequenceNumber,
			m.TimeStamp,
		)
	default:
		return fmt.Sprintf("HDR{T:%d}", m.Type)
	}
}
func (m efhm_order) String() string {
	return fmt.Sprintf("%s ORD{TS:%d, OT:%d, OS:%+d, P:%10d, S:%d, AS:%d, CS:%d, CAS:%d, BS:%d, BAS:%d}",
		m.efhm_header,
		m.TradeStatus,
		m.OrderType,
		m.OrderSide,
		m.Price,
		m.Size,
		m.AoNSize,
		m.CustomerSize,
		m.CustomerAoNSize,
		m.BDSize,
		m.BDAoNSize,
	)
}
func (m efhm_quote) String() string {
	return fmt.Sprintf("%s QUO{TS:%d, "+
		"Bid{P:%10d, S:%d, OS:%d, AS:%d, CS:%d, CAS:%d, BS:%d, BAS:%d}, "+
		"Ask{P:%10d, S:%d, OS:%d, AS:%d, CS:%d, CAS:%d, BS:%d, BAS:%d}"+
		"}",
		m.efhm_header,
		m.TradeStatus,
		m.BidPrice,
		m.BidSize,
		m.BidOrderSize,
		m.BidAoNSize,
		m.BidCustomerSize,
		m.BidCustomerAoNSize,
		m.BidBDSize,
		m.BidBDAoNSize,
		m.AskPrice,
		m.AskSize,
		m.AskOrderSize,
		m.AskAoNSize,
		m.AskCustomerSize,
		m.AskCustomerAoNSize,
		m.AskBDSize,
		m.AskBDAoNSize,
	)
}
func (m efhm_trade) String() string {
	return fmt.Sprintf("%s TRD{P:%10d, S:%d, TC:%d}",
		m.efhm_header,
		m.Price,
		m.Size,
		m.TradeCondition,
	)
}
func (m efhm_definition_nom) String() string {
	return fmt.Sprintf("%s DEF_NOM{S:\"%s\" %016x, MD:%x, US:\"%s\" %016x, SP:%d, PC:%d}",
		m.efhm_header,
		trimAsciiz(m.Symbol[:]),
		binary.LittleEndian.Uint64(m.Symbol[:]),
		m.MaturityDate,
		trimAsciiz(m.UnderlyingSymbol[:]),
		binary.LittleEndian.Uint64(m.UnderlyingSymbol[:]),
		m.StrikePrice,
		m.PutOrCall,
	)
}
func (m efhm_definition_bats) String() string {
	return fmt.Sprintf("%s DEF_BATS{OS:\"%s\"}",
		m.efhm_header,
		trimAsciiz(m.OsiSymbol[:]),
	)
}
func trimAsciiz(b []byte) []byte {
	pos := bytes.IndexByte(b, 0)
	if pos < 0 {
		return b
	}
	return b[:pos]
}

type EfhLoggerPrinter interface {
	PrintOrder(efhm_order)
	PrintQuote(efhm_quote)
	PrintTrade(efhm_trade)
	PrintDefinitionNom(efhm_definition_nom)
	PrintDefinitionBats(efhm_definition_bats)
}

type testefhPrinter struct {
	w io.Writer
}

var _ EfhLoggerPrinter = &testefhPrinter{}

func NewTestefhPrinter(w io.Writer) EfhLoggerPrinter {
	return &testefhPrinter{w: w}
}
func (p *testefhPrinter) PrintOrder(o efhm_order) {
	fmt.Fprintln(p.w, o)
}
func (p *testefhPrinter) PrintQuote(o efhm_quote) {
	fmt.Fprintln(p.w, o)
}
func (p *testefhPrinter) PrintTrade(m efhm_trade) {
	fmt.Fprintln(p.w, m)
}
func (p *testefhPrinter) PrintDefinitionNom(m efhm_definition_nom) {
	fmt.Fprintln(p.w, m)
}
func (p *testefhPrinter) PrintDefinitionBats(m efhm_definition_bats) {
	fmt.Fprintln(p.w, m)
}

type EfhLogger struct {
	TobLogger
	printer EfhLoggerPrinter
	mode    EfhLoggerOutputMode
	stream  Stream
}

var _ sim.Observer = &EfhLogger{}

func NewEfhLogger(p EfhLoggerPrinter) *EfhLogger {
	l := &EfhLogger{
		printer:   p,
		TobLogger: *NewTobLogger(),
		stream:    *NewStream(),
	}
	return l
}

type EfhLoggerOutputMode byte

const (
	EfhLoggerOutputOrders EfhLoggerOutputMode = iota
	EfhLoggerOutputQuotes
)

func (l *EfhLogger) SetOutputMode(mode EfhLoggerOutputMode) {
	l.mode = mode
}

func (l *EfhLogger) MessageArrived(idm *sim.SimMessage) {
	l.stream.MessageArrived(idm)
	l.TobLogger.MessageArrived(idm)
	switch m := l.stream.getExchangeMessage().(type) {
	case packet.TradeMessage:
		l.genUpdateTrades(m)
	case *nasdaq.IttoMessageOptionDirectory:
		l.genUpdateDefinitionsNom(m)
	case *bats.PitchMessageSymbolMapping:
		l.genUpdateDefinitionsBats(m)
	}
}

func (l *EfhLogger) AfterBookUpdate(book sim.Book, operation sim.SimOperation) {
	if l.mode == EfhLoggerOutputOrders {
		if l.TobLogger.AfterBookUpdate(book, operation, TobUpdateNew) {
			l.genUpdateOrders(l.TobLogger.bid)
			l.genUpdateOrders(l.TobLogger.ask)
		}
	} else {
		if l.TobLogger.AfterBookUpdate(book, operation, TobUpdateNewForce) {
			l.genUpdateQuotes()
		}
	}
}

func (l *EfhLogger) genUpdateHeaderForOption(messageType uint8, oid packet.OptionId) efhm_header {
	return efhm_header{
		Type:           messageType,
		SecurityId:     oid.ToUint64(),
		SequenceNumber: l.stream.getSeqNum(),
		TimeStamp:      l.stream.getTimestamp(),
	}
}
func (l *EfhLogger) genUpdateHeader(messageType uint8) efhm_header {
	return l.genUpdateHeaderForOption(messageType, l.TobLogger.lastOptionId)
}
func (l *EfhLogger) genUpdateOrders(tob tob) {
	if !tob.updated() {
		return
	}
	m := efhm_order{
		efhm_header: l.genUpdateHeader(EFHM_ORDER),
		Price:       uint32(tob.New.Price),
		Size:        uint32(tob.New.Size),
		OrderType:   1,
	}
	switch tob.Side {
	case packet.MarketSideBid:
		m.OrderSide = EFH_ORDER_BID
	case packet.MarketSideAsk:
		m.OrderSide = EFH_ORDER_ASK
	}
	l.printer.PrintOrder(m)
}
func (l *EfhLogger) genUpdateQuotes() {
	m := efhm_quote{
		efhm_header: l.genUpdateHeader(EFHM_QUOTE),
		BidPrice:    uint32(l.TobLogger.bid.New.Price),
		BidSize:     uint32(l.TobLogger.bid.New.Size),
		AskPrice:    uint32(l.TobLogger.ask.New.Price),
		AskSize:     uint32(l.TobLogger.ask.New.Size),
	}
	l.printer.PrintQuote(m)
}
func (l *EfhLogger) genUpdateTrades(msg packet.TradeMessage) {
	oid, price, size := msg.TradeInfo()
	m := efhm_trade{
		efhm_header: l.genUpdateHeaderForOption(EFHM_TRADE, oid),
		Price:       uint32(packet.PriceTo4Dec(price)),
		Size:        uint32(size),
	}
	l.printer.PrintTrade(m)
}
func (l *EfhLogger) genUpdateDefinitionsNom(msg *nasdaq.IttoMessageOptionDirectory) {
	m := efhm_definition_nom{
		efhm_header: l.genUpdateHeaderForOption(EFHM_DEFINITION_NOM, msg.OptionId()),
		StrikePrice: uint32(msg.StrikePrice),
	}
	year, month, day := msg.Expiration.Date()
	m.MaturityDate = uint64(year%100<<16 + int(month)<<8 + day)
	copy(m.Symbol[:], msg.Symbol)
	copy(m.UnderlyingSymbol[:], msg.UnderlyingSymbol)
	switch msg.OType {
	case 'C':
		m.PutOrCall = EFH_SECURITY_CALL
	case 'P':
		m.PutOrCall = EFH_SECURITY_PUT
	}
	l.printer.PrintDefinitionNom(m)
}
func (l *EfhLogger) genUpdateDefinitionsBats(msg *bats.PitchMessageSymbolMapping) {
	m := efhm_definition_bats{
		efhm_header: l.genUpdateHeaderForOption(EFHM_DEFINITION_BATS, msg.OptionId()),
	}
	copy(m.OsiSymbol[:], msg.OsiSymbol)
	l.printer.PrintDefinitionBats(m)
}
<commit_msg>rec:EfhLogger: update MaturityDate format<commit_after>// Copyright (c) Ilia Kravets, 2015. All rights reserved. PROVIDED "AS IS"
// WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. See LICENSE file for details.

package rec

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"

	"my/ev/packet"
	"my/ev/packet/bats"
	"my/ev/packet/nasdaq"
	"my/ev/sim"
)

const (
	EFHM_DEFINITION      = 0
	EFHM_TRADE           = 1
	EFHM_QUOTE           = 2
	EFHM_ORDER           = 3
	EFHM_DEFINITION_NOM  = 4
	EFHM_DEFINITION_BATS = 5
	EFHM_REFRESHED       = 100
	EFHM_STOPPED         = 101

	EFH_ORDER_BID = 1
	EFH_ORDER_ASK = -1

	EFH_SECURITY_PUT  = 0
	EFH_SECURITY_CALL = 1
)

type efhm_header struct {
	Type           uint8
	TickCondition  uint8
	QueuePosition  uint16
	UnderlyingId   uint32
	SecurityId     uint64
	SequenceNumber uint64
	TimeStamp      uint64
}

type efhm_order struct {
	efhm_header
	TradeStatus     uint8
	OrderType       uint8
	OrderSide       int8
	_pad            byte
	Price           uint32
	Size            uint32
	AoNSize         uint32
	CustomerSize    uint32
	CustomerAoNSize uint32
	BDSize          uint32
	BDAoNSize       uint32
}

type efhm_quote struct {
	efhm_header
	TradeStatus        uint8
	_pad               [3]byte
	BidPrice           uint32
	BidSize            uint32
	BidOrderSize       uint32
	BidAoNSize         uint32
	BidCustomerSize    uint32
	BidCustomerAoNSize uint32
	BidBDSize          uint32
	BidBDAoNSize       uint32
	AskPrice           uint32
	AskSize            uint32
	AskOrderSize       uint32
	AskAoNSize         uint32
	AskCustomerSize    uint32
	AskCustomerAoNSize uint32
	AskBDSize          uint32
	AskBDAoNSize       uint32
}

type efhm_trade struct {
	efhm_header
	Price          uint32
	Size           uint32
	TradeCondition uint8
}

type efhm_definition_nom struct {
	efhm_header
	Symbol           [8]byte
	MaturityDate     uint64
	UnderlyingSymbol [16]byte
	StrikePrice      uint32
	PutOrCall        uint8
}

type efhm_definition_bats struct {
	efhm_header
	OsiSymbol [22]byte
}

func (m efhm_header) String() string {
	switch m.Type {
	case EFHM_QUOTE, EFHM_ORDER, EFHM_TRADE, EFHM_DEFINITION_NOM, EFHM_DEFINITION_BATS:
		return fmt.Sprintf("HDR{T:%d, TC:%d, QP:%d, UId:%08x, SId:%016x, SN:%d, TS:%016x}",
			m.Type,
			m.TickCondition,
			m.QueuePosition,
			m.UnderlyingId,
			m.SecurityId,
			m.SequenceNumber,
			m.TimeStamp,
		)
	default:
		return fmt.Sprintf("HDR{T:%d}", m.Type)
	}
}
func (m efhm_order) String() string {
	return fmt.Sprintf("%s ORD{TS:%d, OT:%d, OS:%+d, P:%10d, S:%d, AS:%d, CS:%d, CAS:%d, BS:%d, BAS:%d}",
		m.efhm_header,
		m.TradeStatus,
		m.OrderType,
		m.OrderSide,
		m.Price,
		m.Size,
		m.AoNSize,
		m.CustomerSize,
		m.CustomerAoNSize,
		m.BDSize,
		m.BDAoNSize,
	)
}
func (m efhm_quote) String() string {
	return fmt.Sprintf("%s QUO{TS:%d, "+
		"Bid{P:%10d, S:%d, OS:%d, AS:%d, CS:%d, CAS:%d, BS:%d, BAS:%d}, "+
		"Ask{P:%10d, S:%d, OS:%d, AS:%d, CS:%d, CAS:%d, BS:%d, BAS:%d}"+
		"}",
		m.efhm_header,
		m.TradeStatus,
		m.BidPrice,
		m.BidSize,
		m.BidOrderSize,
		m.BidAoNSize,
		m.BidCustomerSize,
		m.BidCustomerAoNSize,
		m.BidBDSize,
		m.BidBDAoNSize,
		m.AskPrice,
		m.AskSize,
		m.AskOrderSize,
		m.AskAoNSize,
		m.AskCustomerSize,
		m.AskCustomerAoNSize,
		m.AskBDSize,
		m.AskBDAoNSize,
	)
}
func (m efhm_trade) String() string {
	return fmt.Sprintf("%s TRD{P:%10d, S:%d, TC:%d}",
		m.efhm_header,
		m.Price,
		m.Size,
		m.TradeCondition,
	)
}
func (m efhm_definition_nom) String() string {
	return fmt.Sprintf("%s DEF_NOM{S:\"%s\" %016x, MD:%x, US:\"%s\" %016x, SP:%d, PC:%d}",
		m.efhm_header,
		trimAsciiz(m.Symbol[:]),
		binary.LittleEndian.Uint64(m.Symbol[:]),
		m.MaturityDate,
		trimAsciiz(m.UnderlyingSymbol[:]),
		binary.LittleEndian.Uint64(m.UnderlyingSymbol[:]),
		m.StrikePrice,
		m.PutOrCall,
	)
}
func (m efhm_definition_bats) String() string {
	return fmt.Sprintf("%s DEF_BATS{OS:\"%s\"}",
		m.efhm_header,
		trimAsciiz(m.OsiSymbol[:]),
	)
}
func trimAsciiz(b []byte) []byte {
	pos := bytes.IndexByte(b, 0)
	if pos < 0 {
		return b
	}
	return b[:pos]
}

type EfhLoggerPrinter interface {
	PrintOrder(efhm_order)
	PrintQuote(efhm_quote)
	PrintTrade(efhm_trade)
	PrintDefinitionNom(efhm_definition_nom)
	PrintDefinitionBats(efhm_definition_bats)
}

type testefhPrinter struct {
	w io.Writer
}

var _ EfhLoggerPrinter = &testefhPrinter{}

func NewTestefhPrinter(w io.Writer) EfhLoggerPrinter {
	return &testefhPrinter{w: w}
}
func (p *testefhPrinter) PrintOrder(o efhm_order) {
	fmt.Fprintln(p.w, o)
}
func (p *testefhPrinter) PrintQuote(o efhm_quote) {
	fmt.Fprintln(p.w, o)
}
func (p *testefhPrinter) PrintTrade(m efhm_trade) {
	fmt.Fprintln(p.w, m)
}
func (p *testefhPrinter) PrintDefinitionNom(m efhm_definition_nom) {
	fmt.Fprintln(p.w, m)
}
func (p *testefhPrinter) PrintDefinitionBats(m efhm_definition_bats) {
	fmt.Fprintln(p.w, m)
}

type EfhLogger struct {
	TobLogger
	printer EfhLoggerPrinter
	mode    EfhLoggerOutputMode
	stream  Stream
}

var _ sim.Observer = &EfhLogger{}

func NewEfhLogger(p EfhLoggerPrinter) *EfhLogger {
	l := &EfhLogger{
		printer:   p,
		TobLogger: *NewTobLogger(),
		stream:    *NewStream(),
	}
	return l
}

type EfhLoggerOutputMode byte

const (
	EfhLoggerOutputOrders EfhLoggerOutputMode = iota
	EfhLoggerOutputQuotes
)

func (l *EfhLogger) SetOutputMode(mode EfhLoggerOutputMode) {
	l.mode = mode
}

func (l *EfhLogger) MessageArrived(idm *sim.SimMessage) {
	l.stream.MessageArrived(idm)
	l.TobLogger.MessageArrived(idm)
	switch m := l.stream.getExchangeMessage().(type) {
	case packet.TradeMessage:
		l.genUpdateTrades(m)
	case *nasdaq.IttoMessageOptionDirectory:
		l.genUpdateDefinitionsNom(m)
	case *bats.PitchMessageSymbolMapping:
		l.genUpdateDefinitionsBats(m)
	}
}

func (l *EfhLogger) AfterBookUpdate(book sim.Book, operation sim.SimOperation) {
	if l.mode == EfhLoggerOutputOrders {
		if l.TobLogger.AfterBookUpdate(book, operation, TobUpdateNew) {
			l.genUpdateOrders(l.TobLogger.bid)
			l.genUpdateOrders(l.TobLogger.ask)
		}
	} else {
		if l.TobLogger.AfterBookUpdate(book, operation, TobUpdateNewForce) {
			l.genUpdateQuotes()
		}
	}
}

func (l *EfhLogger) genUpdateHeaderForOption(messageType uint8, oid packet.OptionId) efhm_header {
	return efhm_header{
		Type:           messageType,
		SecurityId:     oid.ToUint64(),
		SequenceNumber: l.stream.getSeqNum(),
		TimeStamp:      l.stream.getTimestamp(),
	}
}
func (l *EfhLogger) genUpdateHeader(messageType uint8) efhm_header {
	return l.genUpdateHeaderForOption(messageType, l.TobLogger.lastOptionId)
}
func (l *EfhLogger) genUpdateOrders(tob tob) {
	if !tob.updated() {
		return
	}
	m := efhm_order{
		efhm_header: l.genUpdateHeader(EFHM_ORDER),
		Price:       uint32(tob.New.Price),
		Size:        uint32(tob.New.Size),
		OrderType:   1,
	}
	switch tob.Side {
	case packet.MarketSideBid:
		m.OrderSide = EFH_ORDER_BID
	case packet.MarketSideAsk:
		m.OrderSide = EFH_ORDER_ASK
	}
	l.printer.PrintOrder(m)
}
func (l *EfhLogger) genUpdateQuotes() {
	m := efhm_quote{
		efhm_header: l.genUpdateHeader(EFHM_QUOTE),
		BidPrice:    uint32(l.TobLogger.bid.New.Price),
		BidSize:     uint32(l.TobLogger.bid.New.Size),
		AskPrice:    uint32(l.TobLogger.ask.New.Price),
		AskSize:     uint32(l.TobLogger.ask.New.Size),
	}
	l.printer.PrintQuote(m)
}
func (l *EfhLogger) genUpdateTrades(msg packet.TradeMessage) {
	oid, price, size := msg.TradeInfo()
	m := efhm_trade{
		efhm_header: l.genUpdateHeaderForOption(EFHM_TRADE, oid),
		Price:       uint32(packet.PriceTo4Dec(price)),
		Size:        uint32(size),
	}
	l.printer.PrintTrade(m)
}
func (l *EfhLogger) genUpdateDefinitionsNom(msg *nasdaq.IttoMessageOptionDirectory) {
	m := efhm_definition_nom{
		efhm_header: l.genUpdateHeaderForOption(EFHM_DEFINITION_NOM, msg.OptionId()),
		StrikePrice: uint32(msg.StrikePrice),
	}
	year, month, day := msg.Expiration.Date()
	m.MaturityDate = uint64(day<<16 + int(month)<<8 + year%100)
	copy(m.Symbol[:], msg.Symbol)
	copy(m.UnderlyingSymbol[:], msg.UnderlyingSymbol)
	switch msg.OType {
	case 'C':
		m.PutOrCall = EFH_SECURITY_CALL
	case 'P':
		m.PutOrCall = EFH_SECURITY_PUT
	}
	l.printer.PrintDefinitionNom(m)
}
func (l *EfhLogger) genUpdateDefinitionsBats(msg *bats.PitchMessageSymbolMapping) {
	m := efhm_definition_bats{
		efhm_header: l.genUpdateHeaderForOption(EFHM_DEFINITION_BATS, msg.OptionId()),
	}
	copy(m.OsiSymbol[:], msg.OsiSymbol)
	l.printer.PrintDefinitionBats(m)
}
<|endoftext|>


<commit_before>// Copyright (c) Ilia Kravets, 2015. All rights reserved. PROVIDED "AS IS"
// WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. See LICENSE file for details.

package rec

import (
	"log"

	"my/ev/packet"
	"my/ev/sim"
)

type TobLogger struct {
	lastOptionId packet.OptionId
	consumeOps   int
	curOps       int
	hasOldTob    bool
	bid          tob
	ask          tob
}
type tob struct {
	Check bool
	Side  packet.MarketSide
	Old   sim.PriceLevel
	New   sim.PriceLevel
	Flags TobUpdate
}

func NewTobLogger() *TobLogger {
	l := &TobLogger{
		bid: tob{Side: packet.MarketSideBid},
		ask: tob{Side: packet.MarketSideAsk},
	}
	return l
}

func (l *TobLogger) SetUpdateFlags(flags TobUpdate) {
	l.bid.Flags = flags
	l.ask.Flags = flags
}

func (l *TobLogger) MessageArrived(idm *sim.SimMessage) {
	l.consumeOps = idm.BookUpdates()
	if idm.BookSides() == 2 {
		// XXX why do we need this?
		l.bid.Check, l.ask.Check = true, true
	} else {
		l.bid.Check, l.ask.Check = false, false
	}
	l.curOps = 0
	l.hasOldTob = false
}

func (*TobLogger) OperationAppliedToOrders(sim.SimOperation) {}

func (l *TobLogger) BeforeBookUpdate(book sim.Book, operation sim.SimOperation) {
	if l.consumeOps == 0 {
		log.Fatal("book operation is not expected")
	}
	if l.hasOldTob {
		return
	}
	l.lastOptionId = operation.GetOptionId()
	if l.lastOptionId.Invalid() {
		return
	}
	switch operation.GetSide() {
	case packet.MarketSideBid:
		l.bid.Check = true
	case packet.MarketSideAsk:
		l.ask.Check = true
	default:
		log.Fatalln("wrong operation side")
	}
	l.bid.update(book, l.lastOptionId, false)
	l.ask.update(book, l.lastOptionId, false)
	l.hasOldTob = true
}

func (l *TobLogger) AfterBookUpdate(book sim.Book, operation sim.SimOperation) bool {
	if l.consumeOps == 0 {
		log.Fatal("book operation is not expected")
	}
	l.curOps++
	if l.curOps < l.consumeOps {
		return false
	}
	l.curOps = 0
	l.hasOldTob = false
	if l.lastOptionId.Invalid() {
		return false
	}
	l.bid.update(book, l.lastOptionId, true)
	l.ask.update(book, l.lastOptionId, true)

	return l.bid.updated() || l.ask.updated()
}

type TobUpdate byte

const (
	TobUpdateBothSides TobUpdate = 1 << iota
	TobUpdateAssumeUpdated
)

func (tob *tob) update(book sim.Book, oid packet.OptionId, updateNew bool) {
	pl := &tob.Old
	if updateNew {
		pl = &tob.New
	}
	*pl = sim.EmptyPriceLevel
	if tob.Check || tob.Flags&TobUpdateBothSides != 0 && updateNew {
		if pls := book.GetTop(oid, tob.Side, 1); len(pls) > 0 {
			*pl = pls[0].Clone()
		}
	}
}

func (tob *tob) updated() bool {
	return tob.Check && (tob.Flags&TobUpdateAssumeUpdated != 0 || !tob.Old.Equals(tob.New) && (tob.Old.Price() != 0 || tob.New.Price() != 0))
}
<commit_msg>rec:TobLogger: refactor some error checking<commit_after>// Copyright (c) Ilia Kravets, 2014-2016. All rights reserved. PROVIDED "AS IS"
// WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. See LICENSE file for details.

package rec

import (
	"log"

	"github.com/ikravets/errs"

	"my/ev/packet"
	"my/ev/sim"
)

type TobLogger struct {
	lastOptionId packet.OptionId
	consumeOps   int
	curOps       int
	hasOldTob    bool
	bid          tob
	ask          tob
}
type tob struct {
	Check bool
	Side  packet.MarketSide
	Old   sim.PriceLevel
	New   sim.PriceLevel
	Flags TobUpdate
}

func NewTobLogger() *TobLogger {
	l := &TobLogger{
		bid: tob{Side: packet.MarketSideBid},
		ask: tob{Side: packet.MarketSideAsk},
	}
	return l
}

func (l *TobLogger) SetUpdateFlags(flags TobUpdate) {
	l.bid.Flags = flags
	l.ask.Flags = flags
}

func (l *TobLogger) MessageArrived(idm *sim.SimMessage) {
	l.consumeOps = idm.BookUpdates()
	if idm.BookSides() == 2 {
		// XXX why do we need this?
		l.bid.Check, l.ask.Check = true, true
	} else {
		l.bid.Check, l.ask.Check = false, false
	}
	l.curOps = 0
	l.hasOldTob = false
}

func (*TobLogger) OperationAppliedToOrders(sim.SimOperation) {}

func (l *TobLogger) BeforeBookUpdate(book sim.Book, operation sim.SimOperation) {
	errs.Check(l.consumeOps != 0)
	if l.hasOldTob {
		return
	}
	l.lastOptionId = operation.GetOptionId()
	if l.lastOptionId.Invalid() {
		return
	}
	switch operation.GetSide() {
	case packet.MarketSideBid:
		l.bid.Check = true
	case packet.MarketSideAsk:
		l.ask.Check = true
	default:
		log.Fatalln("wrong operation side")
	}
	l.bid.update(book, l.lastOptionId, false)
	l.ask.update(book, l.lastOptionId, false)
	l.hasOldTob = true
}

func (l *TobLogger) AfterBookUpdate(book sim.Book, operation sim.SimOperation) bool {
	errs.Check(l.consumeOps != 0)
	l.curOps++
	if l.curOps < l.consumeOps {
		return false
	}
	l.curOps = 0
	l.hasOldTob = false
	if l.lastOptionId.Invalid() {
		return false
	}
	l.bid.update(book, l.lastOptionId, true)
	l.ask.update(book, l.lastOptionId, true)

	return l.bid.updated() || l.ask.updated()
}

type TobUpdate byte

const (
	TobUpdateBothSides TobUpdate = 1 << iota
	TobUpdateAssumeUpdated
)

func (tob *tob) update(book sim.Book, oid packet.OptionId, updateNew bool) {
	pl := &tob.Old
	if updateNew {
		pl = &tob.New
	}
	*pl = sim.EmptyPriceLevel
	if tob.Check || tob.Flags&TobUpdateBothSides != 0 && updateNew {
		if pls := book.GetTop(oid, tob.Side, 1); len(pls) > 0 {
			*pl = pls[0].Clone()
		}
	}
}

func (tob *tob) updated() bool {
	return tob.Check && (tob.Flags&TobUpdateAssumeUpdated != 0 || !tob.Old.Equals(tob.New) && (tob.Old.Price() != 0 || tob.New.Price() != 0))
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ebnf is a library for EBNF grammars. The input is text ([]byte)
// satisfying the following grammar (represented itself in EBNF):
//
//	Production  = name "=" [ Expression ] "." .
//	Expression  = Alternative { "|" Alternative } .
//	Alternative = Term { Term } .
//	Term        = name | token [ "..." token ] | Group | Option | Repetition .
//	Group       = "(" Expression ")" .
//	Option      = "[" Expression "]" .
//	Repetition  = "{" Expression "}" .
//
// A name is a Go identifier, a token is a Go string, and comments
// and white space follow the same rules as for the Go language.
// Production names starting with an uppercase Unicode letter denote
// non-terminal productions (i.e., productions which allow white-space
// and comments between tokens); all other production names denote
// lexical productions.
//
package ebnf

import (
	"go/scanner"
	"go/token"
	"os"
	"unicode"
	"utf8"
)

// ----------------------------------------------------------------------------
// Internal representation

type (
	// An Expression node represents a production expression.
	Expression interface {
		// Pos is the position of the first character of the syntactic construct
		Pos() token.Pos
	}

	// An Alternative node represents a non-empty list of alternative expressions.
	Alternative []Expression // x | y | z

	// A Sequence node represents a non-empty list of sequential expressions.
	Sequence []Expression // x y z

	// A Name node represents a production name.
	Name struct {
		StringPos token.Pos
		String    string
	}

	// A Token node represents a literal.
	Token struct {
		StringPos token.Pos
		String    string
	}

	// A List node represents a range of characters.
	Range struct {
		Begin, End *Token // begin ... end
	}

	// A Group node represents a grouped expression.
	Group struct {
		Lparen token.Pos
		Body   Expression // (body)
	}

	// An Option node represents an optional expression.
	Option struct {
		Lbrack token.Pos
		Body   Expression // [body]
	}

	// A Repetition node represents a repeated expression.
	Repetition struct {
		Lbrace token.Pos
		Body   Expression // {body}
	}

	// A Production node represents an EBNF production.
	Production struct {
		Name *Name
		Expr Expression
	}

	// A Grammar is a set of EBNF productions. The map
	// is indexed by production name.
	//
	Grammar map[string]*Production
)

func (x Alternative) Pos() token.Pos { return x[0].Pos() } // the parser always generates non-empty Alternative
func (x Sequence) Pos() token.Pos    { return x[0].Pos() } // the parser always generates non-empty Sequences
func (x *Name) Pos() token.Pos       { return x.StringPos }
func (x *Token) Pos() token.Pos      { return x.StringPos }
func (x *Range) Pos() token.Pos      { return x.Begin.Pos() }
func (x *Group) Pos() token.Pos      { return x.Lparen }
func (x *Option) Pos() token.Pos     { return x.Lbrack }
func (x *Repetition) Pos() token.Pos { return x.Lbrace }
func (x *Production) Pos() token.Pos { return x.Name.Pos() }

// ----------------------------------------------------------------------------
// Grammar verification

func isLexical(name string) bool {
	ch, _ := utf8.DecodeRuneInString(name)
	return !unicode.IsUpper(ch)
}

type verifier struct {
	fset *token.FileSet
	scanner.ErrorVector
	worklist []*Production
	reached  Grammar // set of productions reached from (and including) the root production
	grammar  Grammar
}

func (v *verifier) error(pos token.Pos, msg string) {
	v.Error(v.fset.Position(pos), msg)
}

func (v *verifier) push(prod *Production) {
	name := prod.Name.String
	if _, found := v.reached[name]; !found {
		v.worklist = append(v.worklist, prod)
		v.reached[name] = prod
	}
}

func (v *verifier) verifyChar(x *Token) int {
	s := x.String
	if utf8.RuneCountInString(s) != 1 {
		v.error(x.Pos(), "single char expected, found "+s)
		return 0
	}
	ch, _ := utf8.DecodeRuneInString(s)
	return ch
}

func (v *verifier) verifyExpr(expr Expression, lexical bool) {
	switch x := expr.(type) {
	case nil:
		// empty expression
	case Alternative:
		for _, e := range x {
			v.verifyExpr(e, lexical)
		}
	case Sequence:
		for _, e := range x {
			v.verifyExpr(e, lexical)
		}
	case *Name:
		// a production with this name must exist;
		// add it to the worklist if not yet processed
		if prod, found := v.grammar[x.String]; found {
			v.push(prod)
		} else {
			v.error(x.Pos(), "missing production "+x.String)
		}
		// within a lexical production references
		// to non-lexical productions are invalid
		if lexical && !isLexical(x.String) {
			v.error(x.Pos(), "reference to non-lexical production "+x.String)
		}
	case *Token:
		// nothing to do for now
	case *Range:
		i := v.verifyChar(x.Begin)
		j := v.verifyChar(x.End)
		if i >= j {
			v.error(x.Pos(), "decreasing character range")
		}
	case *Group:
		v.verifyExpr(x.Body, lexical)
	case *Option:
		v.verifyExpr(x.Body, lexical)
	case *Repetition:
		v.verifyExpr(x.Body, lexical)
	default:
		panic("unreachable")
	}
}

func (v *verifier) verify(fset *token.FileSet, grammar Grammar, start string) {
	// find root production
	root, found := grammar[start]
	if !found {
		// token.NoPos doesn't require a file set;
		// ok to set v.fset only afterwards
		v.error(token.NoPos, "no start production "+start)
		return
	}

	// initialize verifier
	v.fset = fset
	v.ErrorVector.Reset()
	v.worklist = v.worklist[0:0]
	v.reached = make(Grammar)
	v.grammar = grammar

	// work through the worklist
	v.push(root)
	for {
		n := len(v.worklist) - 1
		if n < 0 {
			break
		}
		prod := v.worklist[n]
		v.worklist = v.worklist[0:n]
		v.verifyExpr(prod.Expr, isLexical(prod.Name.String))
	}

	// check if all productions were reached
	if len(v.reached) < len(v.grammar) {
		for name, prod := range v.grammar {
			if _, found := v.reached[name]; !found {
				v.error(prod.Pos(), name+" is unreachable")
			}
		}
	}
}

// Verify checks that:
//	- all productions used are defined
//	- all productions defined are used when beginning at start
//	- lexical productions refer only to other lexical productions
//
// Position information is interpreted relative to the file set fset.
//
func Verify(fset *token.FileSet, grammar Grammar, start string) os.Error {
	var v verifier
	v.verify(fset, grammar, start)
	return v.GetError(scanner.Sorted)
}
<commit_msg>ebnf: update comment<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ebnf is a library for EBNF grammars. The input is text ([]byte)
// satisfying the following grammar (represented itself in EBNF):
//
//	Production  = name "=" [ Expression ] "." .
//	Expression  = Alternative { "|" Alternative } .
//	Alternative = Term { Term } .
//	Term        = name | token [ "…" token ] | Group | Option | Repetition .
//	Group       = "(" Expression ")" .
//	Option      = "[" Expression "]" .
//	Repetition  = "{" Expression "}" .
//
// A name is a Go identifier, a token is a Go string, and comments
// and white space follow the same rules as for the Go language.
// Production names starting with an uppercase Unicode letter denote
// non-terminal productions (i.e., productions which allow white-space
// and comments between tokens); all other production names denote
// lexical productions.
//
package ebnf

import (
	"go/scanner"
	"go/token"
	"os"
	"unicode"
	"utf8"
)

// ----------------------------------------------------------------------------
// Internal representation

type (
	// An Expression node represents a production expression.
	Expression interface {
		// Pos is the position of the first character of the syntactic construct
		Pos() token.Pos
	}

	// An Alternative node represents a non-empty list of alternative expressions.
	Alternative []Expression // x | y | z

	// A Sequence node represents a non-empty list of sequential expressions.
	Sequence []Expression // x y z

	// A Name node represents a production name.
	Name struct {
		StringPos token.Pos
		String    string
	}

	// A Token node represents a literal.
	Token struct {
		StringPos token.Pos
		String    string
	}

	// A List node represents a range of characters.
	Range struct {
		Begin, End *Token // begin ... end
	}

	// A Group node represents a grouped expression.
	Group struct {
		Lparen token.Pos
		Body   Expression // (body)
	}

	// An Option node represents an optional expression.
	Option struct {
		Lbrack token.Pos
		Body   Expression // [body]
	}

	// A Repetition node represents a repeated expression.
	Repetition struct {
		Lbrace token.Pos
		Body   Expression // {body}
	}

	// A Production node represents an EBNF production.
	Production struct {
		Name *Name
		Expr Expression
	}

	// A Grammar is a set of EBNF productions. The map
	// is indexed by production name.
	//
	Grammar map[string]*Production
)

func (x Alternative) Pos() token.Pos { return x[0].Pos() } // the parser always generates non-empty Alternative
func (x Sequence) Pos() token.Pos    { return x[0].Pos() } // the parser always generates non-empty Sequences
func (x *Name) Pos() token.Pos       { return x.StringPos }
func (x *Token) Pos() token.Pos      { return x.StringPos }
func (x *Range) Pos() token.Pos      { return x.Begin.Pos() }
func (x *Group) Pos() token.Pos      { return x.Lparen }
func (x *Option) Pos() token.Pos     { return x.Lbrack }
func (x *Repetition) Pos() token.Pos { return x.Lbrace }
func (x *Production) Pos() token.Pos { return x.Name.Pos() }

// ----------------------------------------------------------------------------
// Grammar verification

func isLexical(name string) bool {
	ch, _ := utf8.DecodeRuneInString(name)
	return !unicode.IsUpper(ch)
}

type verifier struct {
	fset *token.FileSet
	scanner.ErrorVector
	worklist []*Production
	reached  Grammar // set of productions reached from (and including) the root production
	grammar  Grammar
}

func (v *verifier) error(pos token.Pos, msg string) {
	v.Error(v.fset.Position(pos), msg)
}

func (v *verifier) push(prod *Production) {
	name := prod.Name.String
	if _, found := v.reached[name]; !found {
		v.worklist = append(v.worklist, prod)
		v.reached[name] = prod
	}
}

func (v *verifier) verifyChar(x *Token) int {
	s := x.String
	if utf8.RuneCountInString(s) != 1 {
		v.error(x.Pos(), "single char expected, found "+s)
		return 0
	}
	ch, _ := utf8.DecodeRuneInString(s)
	return ch
}

func (v *verifier) verifyExpr(expr Expression, lexical bool) {
	switch x := expr.(type) {
	case nil:
		// empty expression
	case Alternative:
		for _, e := range x {
			v.verifyExpr(e, lexical)
		}
	case Sequence:
		for _, e := range x {
			v.verifyExpr(e, lexical)
		}
	case *Name:
		// a production with this name must exist;
		// add it to the worklist if not yet processed
		if prod, found := v.grammar[x.String]; found {
			v.push(prod)
		} else {
			v.error(x.Pos(), "missing production "+x.String)
		}
		// within a lexical production references
		// to non-lexical productions are invalid
		if lexical && !isLexical(x.String) {
			v.error(x.Pos(), "reference to non-lexical production "+x.String)
		}
	case *Token:
		// nothing to do for now
	case *Range:
		i := v.verifyChar(x.Begin)
		j := v.verifyChar(x.End)
		if i >= j {
			v.error(x.Pos(), "decreasing character range")
		}
	case *Group:
		v.verifyExpr(x.Body, lexical)
	case *Option:
		v.verifyExpr(x.Body, lexical)
	case *Repetition:
		v.verifyExpr(x.Body, lexical)
	default:
		panic("unreachable")
	}
}

func (v *verifier) verify(fset *token.FileSet, grammar Grammar, start string) {
	// find root production
	root, found := grammar[start]
	if !found {
		// token.NoPos doesn't require a file set;
		// ok to set v.fset only afterwards
		v.error(token.NoPos, "no start production "+start)
		return
	}

	// initialize verifier
	v.fset = fset
	v.ErrorVector.Reset()
	v.worklist = v.worklist[0:0]
	v.reached = make(Grammar)
	v.grammar = grammar

	// work through the worklist
	v.push(root)
	for {
		n := len(v.worklist) - 1
		if n < 0 {
			break
		}
		prod := v.worklist[n]
		v.worklist = v.worklist[0:n]
		v.verifyExpr(prod.Expr, isLexical(prod.Name.String))
	}

	// check if all productions were reached
	if len(v.reached) < len(v.grammar) {
		for name, prod := range v.grammar {
			if _, found := v.reached[name]; !found {
				v.error(prod.Pos(), name+" is unreachable")
			}
		}
	}
}

// Verify checks that:
//	- all productions used are defined
//	- all productions defined are used when beginning at start
//	- lexical productions refer only to other lexical productions
//
// Position information is interpreted relative to the file set fset.
//
func Verify(fset *token.FileSet, grammar Grammar, start string) os.Error {
	var v verifier
	v.verify(fset, grammar, start)
	return v.GetError(scanner.Sorted)
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package utf8 implements functions and constants to support text encoded in
// UTF-8. This package calls a Unicode character a rune for brevity.
package utf8

import "unicode" // only needed for a couple of constants

// Numbers fundamental to the encoding.
const (
	RuneError = unicode.ReplacementChar // the "error" Rune or "replacement character".
	RuneSelf  = 0x80                    // characters below Runeself are represented as themselves in a single byte.
	UTFMax    = 4                       // maximum number of bytes of a UTF-8 encoded Unicode character.
)

const (
	_T1 = 0x00 // 0000 0000
	_Tx = 0x80 // 1000 0000
	_T2 = 0xC0 // 1100 0000
	_T3 = 0xE0 // 1110 0000
	_T4 = 0xF0 // 1111 0000
	_T5 = 0xF8 // 1111 1000

	_Maskx = 0x3F // 0011 1111
	_Mask2 = 0x1F // 0001 1111
	_Mask3 = 0x0F // 0000 1111
	_Mask4 = 0x07 // 0000 0111

	_Rune1Max = 1<<7 - 1
	_Rune2Max = 1<<11 - 1
	_Rune3Max = 1<<16 - 1
	_Rune4Max = 1<<21 - 1
)

func decodeRuneInternal(p []byte) (rune, size int, short bool) {
	n := len(p)
	if n < 1 {
		return RuneError, 0, true
	}
	c0 := p[0]

	// 1-byte, 7-bit sequence?
	if c0 < _Tx {
		return int(c0), 1, false
	}

	// unexpected continuation byte?
	if c0 < _T2 {
		return RuneError, 1, false
	}

	// need first continuation byte
	if n < 2 {
		return RuneError, 1, true
	}
	c1 := p[1]
	if c1 < _Tx || _T2 <= c1 {
		return RuneError, 1, false
	}

	// 2-byte, 11-bit sequence?
	if c0 < _T3 {
		rune = int(c0&_Mask2)<<6 | int(c1&_Maskx)
		if rune <= _Rune1Max {
			return RuneError, 1, false
		}
		return rune, 2, false
	}

	// need second continuation byte
	if n < 3 {
		return RuneError, 1, true
	}
	c2 := p[2]
	if c2 < _Tx || _T2 <= c2 {
		return RuneError, 1, false
	}

	// 3-byte, 16-bit sequence?
	if c0 < _T4 {
		rune = int(c0&_Mask3)<<12 | int(c1&_Maskx)<<6 | int(c2&_Maskx)
		if rune <= _Rune2Max {
			return RuneError, 1, false
		}
		return rune, 3, false
	}

	// need third continuation byte
	if n < 4 {
		return RuneError, 1, true
	}
	c3 := p[3]
	if c3 < _Tx || _T2 <= c3 {
		return RuneError, 1, false
	}

	// 4-byte, 21-bit sequence?
	if c0 < _T5 {
		rune = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
		if rune <= _Rune3Max {
			return RuneError, 1, false
		}
		return rune, 4, false
	}

	// error
	return RuneError, 1, false
}

func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
	n := len(s)
	if n < 1 {
		return RuneError, 0, true
	}
	c0 := s[0]

	// 1-byte, 7-bit sequence?
	if c0 < _Tx {
		return int(c0), 1, false
	}

	// unexpected continuation byte?
	if c0 < _T2 {
		return RuneError, 1, false
	}

	// need first continuation byte
	if n < 2 {
		return RuneError, 1, true
	}
	c1 := s[1]
	if c1 < _Tx || _T2 <= c1 {
		return RuneError, 1, false
	}

	// 2-byte, 11-bit sequence?
	if c0 < _T3 {
		rune = int(c0&_Mask2)<<6 | int(c1&_Maskx)
		if rune <= _Rune1Max {
			return RuneError, 1, false
		}
		return rune, 2, false
	}

	// need second continuation byte
	if n < 3 {
		return RuneError, 1, true
	}
	c2 := s[2]
	if c2 < _Tx || _T2 <= c2 {
		return RuneError, 1, false
	}

	// 3-byte, 16-bit sequence?
	if c0 < _T4 {
		rune = int(c0&_Mask3)<<12 | int(c1&_Maskx)<<6 | int(c2&_Maskx)
		if rune <= _Rune2Max {
			return RuneError, 1, false
		}
		return rune, 3, false
	}

	// need third continuation byte
	if n < 4 {
		return RuneError, 1, true
	}
	c3 := s[3]
	if c3 < _Tx || _T2 <= c3 {
		return RuneError, 1, false
	}

	// 4-byte, 21-bit sequence?
	if c0 < _T5 {
		rune = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
		if rune <= _Rune3Max {
			return RuneError, 1, false
		}
		return rune, 4, false
	}

	// error
	return RuneError, 1, false
}

// FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
// An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
func FullRune(p []byte) bool {
	_, _, short := decodeRuneInternal(p)
	return !short
}

// FullRuneInString is like FullRune but its input is a string.
func FullRuneInString(s string) bool {
	_, _, short := decodeRuneInStringInternal(s)
	return !short
}

// DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes.
func DecodeRune(p []byte) (rune, size int) {
	rune, size, _ = decodeRuneInternal(p)
	return
}

// DecodeRuneInString is like DecodeRune but its input is a string.
func DecodeRuneInString(s string) (rune, size int) {
	rune, size, _ = decodeRuneInStringInternal(s)
	return
}

// DecodeLastRune unpacks the last UTF-8 encoding in p
// and returns the rune and its width in bytes.
func DecodeLastRune(p []byte) (rune, size int) {
	end := len(p)
	if end == 0 {
		return RuneError, 0
	}
	start := end - 1
	rune = int(p[start])
	if rune < RuneSelf {
		return rune, 1
	}
	// guard against O(n^2) behavior when traversing
	// backwards through strings with long sequences of
	// invalid UTF-8.
	lim := end - UTFMax
	if lim < 0 {
		lim = 0
	}
	for start--; start >= lim; start-- {
		if RuneStart(p[start]) {
			break
		}
	}
	if start < 0 {
		start = 0
	}
	rune, size = DecodeRune(p[start:end])
	if start+size != end {
		return RuneError, 1
	}
	return rune, size
}

// DecodeLastRuneInString is like DecodeLastRune but its input is a string.
func DecodeLastRuneInString(s string) (rune, size int) {
	end := len(s)
	if end == 0 {
		return RuneError, 0
	}
	start := end - 1
	rune = int(s[start])
	if rune < RuneSelf {
		return rune, 1
	}
	// guard against O(n^2) behavior when traversing
	// backwards through strings with long sequences of
	// invalid UTF-8.
	lim := end - UTFMax
	if lim < 0 {
		lim = 0
	}
	for start--; start >= lim; start-- {
		if RuneStart(s[start]) {
			break
		}
	}
	if start < 0 {
		start = 0
	}
	rune, size = DecodeRuneInString(s[start:end])
	if start+size != end {
		return RuneError, 1
	}
	return rune, size
}

// RuneLen returns the number of bytes required to encode the rune.
func RuneLen(rune int) int {
	switch {
	case rune <= _Rune1Max:
		return 1
	case rune <= _Rune2Max:
		return 2
	case rune <= _Rune3Max:
		return 3
	case rune <= _Rune4Max:
		return 4
	}
	return -1
}

// EncodeRune writes into p (which must be large enough) the UTF-8 encoding of the rune.
// It returns the number of bytes written.
func EncodeRune(p []byte, rune int) int {
	// Negative values are erroneous.  Making it unsigned addresses the problem.
	r := uint(rune)

	if r <= _Rune1Max {
		p[0] = byte(r)
		return 1
	}

	if r <= _Rune2Max {
		p[0] = _T2 | byte(r>>6)
		p[1] = _Tx | byte(r)&_Maskx
		return 2
	}

	if r > unicode.MaxRune {
		r = RuneError
	}

	if r <= _Rune3Max {
		p[0] = _T3 | byte(r>>12)
		p[1] = _Tx | byte(r>>6)&_Maskx
		p[2] = _Tx | byte(r)&_Maskx
		return 3
	}

	p[0] = _T4 | byte(r>>18)
	p[1] = _Tx | byte(r>>12)&_Maskx
	p[2] = _Tx | byte(r>>6)&_Maskx
	p[3] = _Tx | byte(r)&_Maskx
	return 4
}

// RuneCount returns the number of runes in p.  Erroneous and short
// encodings are treated as single runes of width 1 byte.
func RuneCount(p []byte) int {
	i := 0
	var n int
	for n = 0; i < len(p); n++ {
		if p[i] < RuneSelf {
			i++
		} else {
			_, size := DecodeRune(p[i:])
			i += size
		}
	}
	return n
}

// RuneCountInString is like RuneCount but its input is a string.
func RuneCountInString(s string) (n int) {
	for _ = range s {
		n++
	}
	return
}

// RuneStart reports whether the byte could be the first byte of
// an encoded rune.  Second and subsequent bytes always have the top
// two bits set to 10.
func RuneStart(b byte) bool { return b&0xC0 != 0x80 }
<commit_msg>utf8: rename some internal constants to remove leading underscores. How quaint.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package utf8 implements functions and constants to support text encoded in
// UTF-8. This package calls a Unicode character a rune for brevity.
package utf8

import "unicode" // only needed for a couple of constants

// Numbers fundamental to the encoding.
const (
	RuneError = unicode.ReplacementChar // the "error" Rune or "replacement character".
	RuneSelf  = 0x80                    // characters below Runeself are represented as themselves in a single byte.
	UTFMax    = 4                       // maximum number of bytes of a UTF-8 encoded Unicode character.
)

const (
	t1 = 0x00 // 0000 0000
	tx = 0x80 // 1000 0000
	t2 = 0xC0 // 1100 0000
	t3 = 0xE0 // 1110 0000
	t4 = 0xF0 // 1111 0000
	t5 = 0xF8 // 1111 1000

	maskx = 0x3F // 0011 1111
	mask2 = 0x1F // 0001 1111
	mask3 = 0x0F // 0000 1111
	mask4 = 0x07 // 0000 0111

	rune1Max = 1<<7 - 1
	rune2Max = 1<<11 - 1
	rune3Max = 1<<16 - 1
	rune4Max = 1<<21 - 1
)

func decodeRuneInternal(p []byte) (rune, size int, short bool) {
	n := len(p)
	if n < 1 {
		return RuneError, 0, true
	}
	c0 := p[0]

	// 1-byte, 7-bit sequence?
	if c0 < tx {
		return int(c0), 1, false
	}

	// unexpected continuation byte?
	if c0 < t2 {
		return RuneError, 1, false
	}

	// need first continuation byte
	if n < 2 {
		return RuneError, 1, true
	}
	c1 := p[1]
	if c1 < tx || t2 <= c1 {
		return RuneError, 1, false
	}

	// 2-byte, 11-bit sequence?
	if c0 < t3 {
		rune = int(c0&mask2)<<6 | int(c1&maskx)
		if rune <= rune1Max {
			return RuneError, 1, false
		}
		return rune, 2, false
	}

	// need second continuation byte
	if n < 3 {
		return RuneError, 1, true
	}
	c2 := p[2]
	if c2 < tx || t2 <= c2 {
		return RuneError, 1, false
	}

	// 3-byte, 16-bit sequence?
	if c0 < t4 {
		rune = int(c0&mask3)<<12 | int(c1&maskx)<<6 | int(c2&maskx)
		if rune <= rune2Max {
			return RuneError, 1, false
		}
		return rune, 3, false
	}

	// need third continuation byte
	if n < 4 {
		return RuneError, 1, true
	}
	c3 := p[3]
	if c3 < tx || t2 <= c3 {
		return RuneError, 1, false
	}

	// 4-byte, 21-bit sequence?
	if c0 < t5 {
		rune = int(c0&mask4)<<18 | int(c1&maskx)<<12 | int(c2&maskx)<<6 | int(c3&maskx)
		if rune <= rune3Max {
			return RuneError, 1, false
		}
		return rune, 4, false
	}

	// error
	return RuneError, 1, false
}

func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
	n := len(s)
	if n < 1 {
		return RuneError, 0, true
	}
	c0 := s[0]

	// 1-byte, 7-bit sequence?
	if c0 < tx {
		return int(c0), 1, false
	}

	// unexpected continuation byte?
	if c0 < t2 {
		return RuneError, 1, false
	}

	// need first continuation byte
	if n < 2 {
		return RuneError, 1, true
	}
	c1 := s[1]
	if c1 < tx || t2 <= c1 {
		return RuneError, 1, false
	}

	// 2-byte, 11-bit sequence?
	if c0 < t3 {
		rune = int(c0&mask2)<<6 | int(c1&maskx)
		if rune <= rune1Max {
			return RuneError, 1, false
		}
		return rune, 2, false
	}

	// need second continuation byte
	if n < 3 {
		return RuneError, 1, true
	}
	c2 := s[2]
	if c2 < tx || t2 <= c2 {
		return RuneError, 1, false
	}

	// 3-byte, 16-bit sequence?
	if c0 < t4 {
		rune = int(c0&mask3)<<12 | int(c1&maskx)<<6 | int(c2&maskx)
		if rune <= rune2Max {
			return RuneError, 1, false
		}
		return rune, 3, false
	}

	// need third continuation byte
	if n < 4 {
		return RuneError, 1, true
	}
	c3 := s[3]
	if c3 < tx || t2 <= c3 {
		return RuneError, 1, false
	}

	// 4-byte, 21-bit sequence?
	if c0 < t5 {
		rune = int(c0&mask4)<<18 | int(c1&maskx)<<12 | int(c2&maskx)<<6 | int(c3&maskx)
		if rune <= rune3Max {
			return RuneError, 1, false
		}
		return rune, 4, false
	}

	// error
	return RuneError, 1, false
}

// FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
// An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
func FullRune(p []byte) bool {
	_, _, short := decodeRuneInternal(p)
	return !short
}

// FullRuneInString is like FullRune but its input is a string.
func FullRuneInString(s string) bool {
	_, _, short := decodeRuneInStringInternal(s)
	return !short
}

// DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes.
func DecodeRune(p []byte) (rune, size int) {
	rune, size, _ = decodeRuneInternal(p)
	return
}

// DecodeRuneInString is like DecodeRune but its input is a string.
func DecodeRuneInString(s string) (rune, size int) {
	rune, size, _ = decodeRuneInStringInternal(s)
	return
}

// DecodeLastRune unpacks the last UTF-8 encoding in p
// and returns the rune and its width in bytes.
func DecodeLastRune(p []byte) (rune, size int) {
	end := len(p)
	if end == 0 {
		return RuneError, 0
	}
	start := end - 1
	rune = int(p[start])
	if rune < RuneSelf {
		return rune, 1
	}
	// guard against O(n^2) behavior when traversing
	// backwards through strings with long sequences of
	// invalid UTF-8.
	lim := end - UTFMax
	if lim < 0 {
		lim = 0
	}
	for start--; start >= lim; start-- {
		if RuneStart(p[start]) {
			break
		}
	}
	if start < 0 {
		start = 0
	}
	rune, size = DecodeRune(p[start:end])
	if start+size != end {
		return RuneError, 1
	}
	return rune, size
}

// DecodeLastRuneInString is like DecodeLastRune but its input is a string.
func DecodeLastRuneInString(s string) (rune, size int) {
	end := len(s)
	if end == 0 {
		return RuneError, 0
	}
	start := end - 1
	rune = int(s[start])
	if rune < RuneSelf {
		return rune, 1
	}
	// guard against O(n^2) behavior when traversing
	// backwards through strings with long sequences of
	// invalid UTF-8.
	lim := end - UTFMax
	if lim < 0 {
		lim = 0
	}
	for start--; start >= lim; start-- {
		if RuneStart(s[start]) {
			break
		}
	}
	if start < 0 {
		start = 0
	}
	rune, size = DecodeRuneInString(s[start:end])
	if start+size != end {
		return RuneError, 1
	}
	return rune, size
}

// RuneLen returns the number of bytes required to encode the rune.
func RuneLen(rune int) int {
	switch {
	case rune <= rune1Max:
		return 1
	case rune <= rune2Max:
		return 2
	case rune <= rune3Max:
		return 3
	case rune <= rune4Max:
		return 4
	}
	return -1
}

// EncodeRune writes into p (which must be large enough) the UTF-8 encoding of the rune.
// It returns the number of bytes written.
func EncodeRune(p []byte, rune int) int {
	// Negative values are erroneous.  Making it unsigned addresses the problem.
	r := uint(rune)

	if r <= rune1Max {
		p[0] = byte(r)
		return 1
	}

	if r <= rune2Max {
		p[0] = t2 | byte(r>>6)
		p[1] = tx | byte(r)&maskx
		return 2
	}

	if r > unicode.MaxRune {
		r = RuneError
	}

	if r <= rune3Max {
		p[0] = t3 | byte(r>>12)
		p[1] = tx | byte(r>>6)&maskx
		p[2] = tx | byte(r)&maskx
		return 3
	}

	p[0] = t4 | byte(r>>18)
	p[1] = tx | byte(r>>12)&maskx
	p[2] = tx | byte(r>>6)&maskx
	p[3] = tx | byte(r)&maskx
	return 4
}

// RuneCount returns the number of runes in p.  Erroneous and short
// encodings are treated as single runes of width 1 byte.
func RuneCount(p []byte) int {
	i := 0
	var n int
	for n = 0; i < len(p); n++ {
		if p[i] < RuneSelf {
			i++
		} else {
			_, size := DecodeRune(p[i:])
			i += size
		}
	}
	return n
}

// RuneCountInString is like RuneCount but its input is a string.
func RuneCountInString(s string) (n int) {
	for _ = range s {
		n++
	}
	return
}

// RuneStart reports whether the byte could be the first byte of
// an encoded rune.  Second and subsequent bytes always have the top
// two bits set to 10.
func RuneStart(b byte) bool { return b&0xC0 != 0x80 }
<|endoftext|>


<commit_before>// Copyright 2010 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package w32

import (
    "fmt"
    "syscall"
    "unsafe"
)

func MakeIntResource(id uint16) *uint16 {
    return (*uint16)(unsafe.Pointer(uintptr(id)))
}

func LOWORD(dw uint) uint16 {
    return uint16(dw)
}

func HIWORD(dw uint) uint16 {
    return uint16(dw >> 16 & 0xffff)
}

func LoadLib(name string) uintptr {
    lib, err := syscall.LoadLibrary(name)
    if err != nil {
        panic(fmt.Sprintf("syscall.LoadLibrary('%s') failed: %s",
            name, err.Error()))
    }
    return uintptr(lib)
}

func GetProcAddr(lib uintptr, name string) uintptr {
    addr, err := syscall.GetProcAddress(syscall.Handle(lib), name)
    if err != nil {
        panic(fmt.Sprintf("syscal.GetProcAddress(%d, '%s') failed: %s",
            lib, name, err.Error()))
    }
    return uintptr(addr)
}

func BoolToBOOL(value bool) BOOL {
	if value {
		return 1
	}

	return 0
}

func UTF16PtrToString(s *uint16) string {
	return syscall.UTF16ToString((*[1 << 30]uint16)(unsafe.Pointer(s))[0:])
}
<commit_msg>Change algorithm in UTF16PtrToString.<commit_after>// Copyright 2010 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package w32

import (
    "fmt"
    "syscall"
    "unsafe"
    "unicode/utf16"
)

func MakeIntResource(id uint16) *uint16 {
    return (*uint16)(unsafe.Pointer(uintptr(id)))
}

func LOWORD(dw uint) uint16 {
    return uint16(dw)
}

func HIWORD(dw uint) uint16 {
    return uint16(dw >> 16 & 0xffff)
}

func LoadLib(name string) uintptr {
    lib, err := syscall.LoadLibrary(name)
    if err != nil {
        panic(fmt.Sprintf("syscall.LoadLibrary('%s') failed: %s",
            name, err.Error()))
    }
    return uintptr(lib)
}

func GetProcAddr(lib uintptr, name string) uintptr {
    addr, err := syscall.GetProcAddress(syscall.Handle(lib), name)
    if err != nil {
        panic(fmt.Sprintf("syscal.GetProcAddress(%d, '%s') failed: %s",
            lib, name, err.Error()))
    }
    return uintptr(addr)
}

func BoolToBOOL(value bool) BOOL {
	if value {
		return 1
	}

	return 0
}

func UTF16PtrToString(cstr *uint16) string {
    if cstr != nil {
        us := make([]uint16, 0, 256)
        for p := uintptr(unsafe.Pointer(cstr)); ; p += 2 {
            u := *(*uint16)(unsafe.Pointer(p))
            if u == 0 {
                return string(utf16.Decode(us))
            }
            us = append(us, u)
        }
    }

    return ""
}
<|endoftext|>