<commit_before>// Package grbac implements core of RBAC (role-based access control)
//
// https://en.wikipedia.org/wiki/Role-based_access_control
package grbac

import (
	"errors"
	"sync"
)

//Error codes returned by failures to change roles.
var (
	ErrRoleHasAlreadyPerm   = errors.New("role already has permission")
	ErrRoleNotPerm          = errors.New("role does not have permission")
	ErrRoleHasAlreadyParent = errors.New("role already has the parent ")
	ErrNoParent             = errors.New("parent does not exist")
)

// Roler represents a role in RBAC and describes minimum set of functions
// for storing, managing and checking permissions associated with the role.
type Roler interface {
	Name() string
	Permissions() map[string]bool
	AllPermissions() map[string]bool
	Permit(string) error
	IsAllowed(...string) bool
	Revoke(string) error
	Parents() map[string]Roler
	AllParents() map[string]Roler
	HasParent(string) bool
	SetParent(Roler) error
	RemoveParent(string) error
}

// Role is default implementation of Roler.
type Role struct {
	name        string
	permissions map[string]bool
	parents     map[string]Roler

	mutex sync.RWMutex
}

// NewRole creates a new instance of Role structure.
func NewRole(name string) *Role {
	return &Role{
		name:        name,
		permissions: make(map[string]bool),
		parents:     make(map[string]Roler),
		mutex:       sync.RWMutex{},
	}
}

// Name returns the name of the role.
func (r *Role) Name() string {
	return r.name
}

// Permissions returns a copy of the list of the role permissions,
// but does not include parental permissions.
func (r *Role) Permissions() map[string]bool {
	newPerms := make(map[string]bool)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for k, v := range r.permissions {
		newPerms[k] = v
	}
	return newPerms
}

// AllPermissions returns a list of all the permissions of the role
// including parental permission.
func (r *Role) AllPermissions() map[string]bool {
	newPerms := make(map[string]bool)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for k, v := range r.permissions {
		newPerms[k] = v
	}

	for _, p := range r.parents {
		for k, v := range p.AllPermissions() {
			newPerms[k] = v
		}
	}

	return newPerms
}

// Permit adds a permission for to the role.
//
// Returns ErrRoleHasAlreadyPerm if the role already has permission.
func (r *Role) Permit(perm string) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if r.permissions[perm] {
		return ErrRoleHasAlreadyPerm
	}
	r.permissions[perm] = true
	return nil
}

// IsAllowed checks permissions listed in the perms.
// IsAllowed  returns true only if all permissions from perms are present
// in the role.
func (r *Role) IsAllowed(perms ...string) bool {
	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for _, perm := range perms {

		if r.permissions[perm] {
			continue
		}

		isFound := false
		for _, p := range r.parents {
			if p.IsAllowed(perm) {
				isFound = true
				break
			}
		}

		if !isFound {
			return false
		}
	}

	return true
}

// Revoke revokes permission from the role
// The function returns ErrRoleNotPerm if the role does not have permission
func (r *Role) Revoke(perm string) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if !r.permissions[perm] {
		return ErrRoleNotPerm
	}

	delete(r.permissions, perm)
	return nil
}

// Parents returns a map to direct parents of the role.
//
// Key of the map - a name of the parent.
func (r *Role) Parents() map[string]Roler {
	newParents := make(map[string]Roler)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for k, v := range r.parents {
		newParents[k] = v
	}
	return newParents
}

// AllParents returns a map of direct parents and subpaprents of the role.
//
// Key of the map - a name of the parent.
func (r *Role) AllParents() map[string]Roler {
	newParents := make(map[string]Roler)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for k, v := range r.parents {
		newParents[k] = v
	}

	for _, p := range r.parents {
		for k, v := range p.AllParents() {
			newParents[k] = v
		}
	}

	return newParents
}

// HasParent checks direct parent in the role
func (r *Role) HasParent(name string) bool {
	r.mutex.RLock()
	defer r.mutex.RUnlock()

	_, ok := r.parents[name]
	return ok
}

// SetParent adds to the Role a new parent.
// Returns ErrRoleHasAlreadyParent if a parent is already available.
func (r *Role) SetParent(role Roler) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if _, ok := r.parents[role.Name()]; ok {
		return ErrRoleHasAlreadyParent
	}

	r.parents[role.Name()] = role
	return nil
}

// RemoveParent remove parent from the role.
func (r *Role) RemoveParent(name string) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if _, ok := r.parents[name]; !ok {
		return ErrNoParent
	}

	delete(r.parents, name)
	return nil
}
<commit_msg>Improve AllPermission loops<commit_after>// Package grbac implements core of RBAC (role-based access control)
//
// https://en.wikipedia.org/wiki/Role-based_access_control
package grbac

import (
	"errors"
	"sync"
)

//Error codes returned by failures to change roles.
var (
	ErrRoleHasAlreadyPerm   = errors.New("role already has permission")
	ErrRoleNotPerm          = errors.New("role does not have permission")
	ErrRoleHasAlreadyParent = errors.New("role already has the parent ")
	ErrNoParent             = errors.New("parent does not exist")
)

// Roler represents a role in RBAC and describes minimum set of functions
// for storing, managing and checking permissions associated with the role.
type Roler interface {
	Name() string
	Permissions() map[string]bool
	AllPermissions() map[string]bool
	Permit(string) error
	IsAllowed(...string) bool
	Revoke(string) error
	Parents() map[string]Roler
	AllParents() map[string]Roler
	HasParent(string) bool
	SetParent(Roler) error
	RemoveParent(string) error
}

// Role is default implementation of Roler.
type Role struct {
	name        string
	permissions map[string]bool
	parents     map[string]Roler

	mutex sync.RWMutex
}

// NewRole creates a new instance of Role structure.
func NewRole(name string) *Role {
	return &Role{
		name:        name,
		permissions: make(map[string]bool),
		parents:     make(map[string]Roler),
		mutex:       sync.RWMutex{},
	}
}

// Name returns the name of the role.
func (r *Role) Name() string {
	return r.name
}

// Permissions returns a copy of the list of the role permissions,
// but does not include parental permissions.
func (r *Role) Permissions() map[string]bool {
	newPerms := make(map[string]bool)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for k, v := range r.permissions {
		newPerms[k] = v
	}
	return newPerms
}

// AllPermissions returns a list of all the permissions of the role
// including parental permission.
func (r *Role) AllPermissions() map[string]bool {
	newPerms := make(map[string]bool)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for permission := range r.permissions {
		newPerms[permission] = true
	}

	for _, parent := range r.parents {
		for permisson := range parent.AllPermissions() {
			newPerms[permisson] = true
		}
	}

	return newPerms
}

// Permit adds a permission for to the role.
//
// Returns ErrRoleHasAlreadyPerm if the role already has permission.
func (r *Role) Permit(perm string) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if r.permissions[perm] {
		return ErrRoleHasAlreadyPerm
	}
	r.permissions[perm] = true
	return nil
}

// IsAllowed checks permissions listed in the perms.
// IsAllowed  returns true only if all permissions from perms are present
// in the role.
func (r *Role) IsAllowed(perms ...string) bool {
	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for _, perm := range perms {

		if r.permissions[perm] {
			continue
		}

		isFound := false
		for _, p := range r.parents {
			if p.IsAllowed(perm) {
				isFound = true
				break
			}
		}

		if !isFound {
			return false
		}
	}

	return true
}

// Revoke revokes permission from the role
// The function returns ErrRoleNotPerm if the role does not have permission
func (r *Role) Revoke(perm string) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if !r.permissions[perm] {
		return ErrRoleNotPerm
	}

	delete(r.permissions, perm)
	return nil
}

// Parents returns a map to direct parents of the role.
//
// Key of the map - a name of the parent.
func (r *Role) Parents() map[string]Roler {
	newParents := make(map[string]Roler)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for k, v := range r.parents {
		newParents[k] = v
	}
	return newParents
}

// AllParents returns a map of direct parents and subpaprents of the role.
//
// Key of the map - a name of the parent.
func (r *Role) AllParents() map[string]Roler {
	newParents := make(map[string]Roler)

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for k, v := range r.parents {
		newParents[k] = v
	}

	for _, p := range r.parents {
		for k, v := range p.AllParents() {
			newParents[k] = v
		}
	}

	return newParents
}

// HasParent checks direct parent in the role
func (r *Role) HasParent(name string) bool {
	r.mutex.RLock()
	defer r.mutex.RUnlock()

	_, ok := r.parents[name]
	return ok
}

// SetParent adds to the Role a new parent.
// Returns ErrRoleHasAlreadyParent if a parent is already available.
func (r *Role) SetParent(role Roler) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if _, ok := r.parents[role.Name()]; ok {
		return ErrRoleHasAlreadyParent
	}

	r.parents[role.Name()] = role
	return nil
}

// RemoveParent remove parent from the role.
func (r *Role) RemoveParent(name string) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	if _, ok := r.parents[name]; !ok {
		return ErrNoParent
	}

	delete(r.parents, name)
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/gorilla/websocket"
	"log"
	"net/http"
)

type room struct {
	// forward is a channel that holds incoming messages
	// that should be forwarded to the other clients.
	forward chan []byte
	// join is a channel for clients wishing to join the room.
	join chan *client
	// leave is a channel for clients wishing to leave the room.
	leave chan *client
	// clients holds all current clients in this room.
	clients map[*client]bool
}

const (
	socketBufferSize  = 1024
	messageBufferSize = 256
)

var (
	upgrader = websocket.Upgrader{
		ReadBufferSize:  socketBufferSize,
		WriteBufferSize: socketBufferSize,
	}
)

func (r *room) run() {
	for {
		select {
		case client := <-r.join:
			// joining
			r.clients[client] = true
		case client := <-r.leave:
			// leaving
			delete(r.clients, client)
			close(client.send)
		case msg := <-r.forward:
			// forward message to all clients
			for client := range r.clients {
				select {
				case client.send <- msg:
				// send the message
				default:
					// failed to send
					delete(r.clients, client)
					close(client.send)
				}
			}
		}
	}
}

func (room *room) ServeHttp(w http.ResponseWriter, r *http.Request) {
	socket, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal("websocket.upgrader:", err)
		return
	}
	client := &client{
		socket: socket,
		send:   make(chan []byte, messageBufferSize),
		room:   room,
	}

	room.join <- client
	defer func() { room.leave <- client }()
	go client.write()
	client.read()
}
<commit_msg>add newRoom() methos<commit_after>package main

import (
	"log"
	"net/http"

	"github.com/gorilla/websocket"
)

type room struct {
	// forward is a channel that holds incoming messages
	// that should be forwarded to the other clients.
	forward chan []byte
	// join is a channel for clients wishing to join the room.
	join chan *client
	// leave is a channel for clients wishing to leave the room.
	leave chan *client
	// clients holds all current clients in this room.
	clients map[*client]bool
}

const (
	socketBufferSize  = 1024
	messageBufferSize = 256
)

var (
	upgrader = websocket.Upgrader{
		ReadBufferSize:  socketBufferSize,
		WriteBufferSize: socketBufferSize,
	}
)

func newRoom() *room {
	return &room{
		forward: make(chan []byte),
		join:    make(chan *client),
		leave:   make(chan *client),
		clients: make(map[*client]bool),
	}
}

func (r *room) run() {
	for {
		select {
		case client := <-r.join:
			// joining
			r.clients[client] = true
		case client := <-r.leave:
			// leaving
			delete(r.clients, client)
			close(client.send)
		case msg := <-r.forward:
			// forward message to all clients
			for client := range r.clients {
				select {
				case client.send <- msg:
				// send the message
				default:
					// failed to send
					delete(r.clients, client)
					close(client.send)
				}
			}
		}
	}
}

func (room *room) ServeHttp(w http.ResponseWriter, r *http.Request) {
	socket, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal("websocket.upgrader:", err)
		return
	}
	client := &client{
		socket: socket,
		send:   make(chan []byte, messageBufferSize),
		room:   room,
	}

	room.join <- client
	defer func() { room.leave <- client }()
	go client.write()
	client.read()
}
<|endoftext|>


<commit_before>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:     April 21, 2022
;       related version of root zone:     2022042101
;
; FORMERLY NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     199.9.14.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:200::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file`
<commit_msg>Automatic update for Wed May  4 08:20:02 UTC 2022<commit_after>package dnsr

var root = `
;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  <file>"
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC
;       under anonymous FTP as
;           file                /domain/named.cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:     May 03, 2022
;       related version of root zone:     2022050301
;
; FORMERLY NS.INTERNIC.NET
;
.                        3600000      NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     199.9.14.201
B.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:200::b
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
C.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
E.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
G.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     198.97.190.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7fd::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:9f::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:dc3::35
; End of file`
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"

	"github.com/gorilla/mux"
	"github.com/nuveo/prest/config"
	cfgMiddleware "github.com/nuveo/prest/config/middlewares"
	"github.com/nuveo/prest/config/router"
	"github.com/nuveo/prest/controllers"
	"github.com/nuveo/prest/middlewares"
	"github.com/rs/cors"
	"github.com/spf13/cobra"
	"github.com/urfave/negroni"
	// postgres driver for migrate
	_ "gopkg.in/mattes/migrate.v1/driver/postgres"
)

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "prest",
	Short: "Serve a RESTful API from any PostgreSQL database",
	Long:  `Serve a RESTful API from any PostgreSQL database, start HTTP server`,
	Run: func(cmd *cobra.Command, args []string) {
		app()
	},
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	migrateCmd.AddCommand(createCmd)
	migrateCmd.AddCommand(downCmd)
	migrateCmd.AddCommand(gotoCmd)
	migrateCmd.AddCommand(mversionCmd)
	migrateCmd.AddCommand(nextCmd)
	migrateCmd.AddCommand(redoCmd)
	migrateCmd.AddCommand(upCmd)
	migrateCmd.AddCommand(resetCmd)
	RootCmd.AddCommand(versionCmd)
	RootCmd.AddCommand(migrateCmd)
	migrateCmd.PersistentFlags().StringVar(&url, "url", driverURL(), "Database driver url")
	migrateCmd.PersistentFlags().StringVar(&path, "path", config.PrestConf.MigrationsPath, "Migrations directory")

	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func app() {
	n := cfgMiddleware.GetApp()
	r := router.Get()

	r.HandleFunc("/databases", controllers.GetDatabases).Methods("GET")
	r.HandleFunc("/schemas", controllers.GetSchemas).Methods("GET")
	r.HandleFunc("/tables", controllers.GetTables).Methods("GET")
	r.HandleFunc("/_QUERIES/{queriesLocation}/{script}", controllers.ExecuteFromScripts)
	r.HandleFunc("/{database}/{schema}", controllers.GetTablesByDatabaseAndSchema).Methods("GET")

	crudRoutes := mux.NewRouter().PathPrefix("/").Subrouter().StrictSlash(true)

	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.SelectFromTables).Methods("GET")
	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.InsertInTables).Methods("POST")
	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.DeleteFromTable).Methods("DELETE")
	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.UpdateTable).Methods("PUT", "PATCH")

	r.PathPrefix("/").Handler(negroni.New(
		middlewares.AccessControl(),
		negroni.Wrap(crudRoutes),
	))

	if config.PrestConf.CORSAllowOrigin != nil {
		c := cors.New(cors.Options{
			AllowedOrigins: config.PrestConf.CORSAllowOrigin,
		})
		n.Use(c)
	}

	n.UseHandler(r)
	n.Run(fmt.Sprintf(":%v", config.PrestConf.HTTPPort))
}
<commit_msg>fix cors (#183)<commit_after>package cmd

import (
	"fmt"
	"os"

	"github.com/gorilla/mux"
	"github.com/nuveo/prest/config"
	cfgMiddleware "github.com/nuveo/prest/config/middlewares"
	"github.com/nuveo/prest/config/router"
	"github.com/nuveo/prest/controllers"
	"github.com/nuveo/prest/middlewares"
	"github.com/spf13/cobra"
	"github.com/urfave/negroni"
	// postgres driver for migrate
	_ "gopkg.in/mattes/migrate.v1/driver/postgres"
)

// RootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
	Use:   "prest",
	Short: "Serve a RESTful API from any PostgreSQL database",
	Long:  `Serve a RESTful API from any PostgreSQL database, start HTTP server`,
	Run: func(cmd *cobra.Command, args []string) {
		app()
	},
}

// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
	migrateCmd.AddCommand(createCmd)
	migrateCmd.AddCommand(downCmd)
	migrateCmd.AddCommand(gotoCmd)
	migrateCmd.AddCommand(mversionCmd)
	migrateCmd.AddCommand(nextCmd)
	migrateCmd.AddCommand(redoCmd)
	migrateCmd.AddCommand(upCmd)
	migrateCmd.AddCommand(resetCmd)
	RootCmd.AddCommand(versionCmd)
	RootCmd.AddCommand(migrateCmd)
	migrateCmd.PersistentFlags().StringVar(&url, "url", driverURL(), "Database driver url")
	migrateCmd.PersistentFlags().StringVar(&path, "path", config.PrestConf.MigrationsPath, "Migrations directory")

	if err := RootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

func app() {
	n := cfgMiddleware.GetApp()
	r := router.Get()
	r.HandleFunc("/databases", controllers.GetDatabases).Methods("GET")
	r.HandleFunc("/schemas", controllers.GetSchemas).Methods("GET")
	r.HandleFunc("/tables", controllers.GetTables).Methods("GET")
	r.HandleFunc("/_QUERIES/{queriesLocation}/{script}", controllers.ExecuteFromScripts)
	r.HandleFunc("/{database}/{schema}", controllers.GetTablesByDatabaseAndSchema).Methods("GET")
	crudRoutes := mux.NewRouter().PathPrefix("/").Subrouter().StrictSlash(true)
	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.SelectFromTables).Methods("GET")
	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.InsertInTables).Methods("POST")
	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.DeleteFromTable).Methods("DELETE")
	crudRoutes.HandleFunc("/{database}/{schema}/{table}", controllers.UpdateTable).Methods("PUT", "PATCH")
	r.PathPrefix("/").Handler(negroni.New(
		middlewares.AccessControl(),
		negroni.Wrap(crudRoutes),
	))
	n.UseHandler(r)
	n.Run(fmt.Sprintf(":%v", config.PrestConf.HTTPPort))
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"unicode"
)

type isfunc func(rune) bool

func charcounter(reader io.Reader) (map[string]int, error) {

	counts := map[string]int{}

	functs := map[string]isfunc{
		"digit": unicode.IsDigit,
		"space": unicode.IsSpace,
		"punct": unicode.IsPunct,
		"symbl": unicode.IsSymbol,
		"lettr": unicode.IsLetter,
	}

	in := bufio.NewReader(reader)
	for {
		r, _, err := in.ReadRune()
		if err == io.EOF {
			break
		}
		// Skipping all previously collected stat.
		if err != nil {
			return nil, err
		}

		for t, fn := range functs {
			if fn(r) {
				counts[t]++
			}
		}
	}
	return counts, nil
}

/*
  $ cat /usr/share/dict/american-english | go run charconunt.go
  type    count
  lettr   813173
  space   99171
  punct   26243
*/

func main() {

	counts, err := charcounter(os.Stdin)
	if err != nil {
		fmt.Fprintf(os.Stderr, "charcount: %s", err)
	}
	// TODO: add descending order output (sort).
	fmt.Printf("type\tcount\n")
	for t, n := range counts {
		fmt.Printf("%s\t%d\n", t, n)
	}
}
<commit_msg>Added exit(1) in case of error.<commit_after>package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"unicode"
)

type isfunc func(rune) bool

func charcounter(reader io.Reader) (map[string]int, error) {

	counts := map[string]int{}

	functs := map[string]isfunc{
		"digit": unicode.IsDigit,
		"space": unicode.IsSpace,
		"punct": unicode.IsPunct,
		"symbl": unicode.IsSymbol,
		"lettr": unicode.IsLetter,
	}

	in := bufio.NewReader(reader)
	for {
		r, _, err := in.ReadRune()
		if err == io.EOF {
			break
		}
		// Skipping all previously collected stat.
		if err != nil {
			return nil, err
		}

		for t, fn := range functs {
			if fn(r) {
				counts[t]++
			}
		}
	}
	return counts, nil
}

/*
  $ cat /usr/share/dict/american-english | go run charconunt.go
  type    count
  lettr   813173
  space   99171
  punct   26243
*/

func main() {

	counts, err := charcounter(os.Stdin)
	if err != nil {
		fmt.Fprintf(os.Stderr, "charcount: %s", err)
		os.Exit(1)
	}
	// TODO: add descending order output (sort).
	fmt.Printf("type\tcount\n")
	for t, n := range counts {
		fmt.Printf("%s\t%d\n", t, n)
	}
}
<|endoftext|>


<commit_before>package tinysql

import (
	"database/sql"
	"reflect"
	"time"
)

// 数据行
type Rows struct {
	rows    *sql.Rows
	err     error
	columns map[string]int
}

// parse 解析fields值到value中
func (this *Rows) parse(value reflect.Value, index int, fields []interface{}) error {
	switch value.Kind() {
	case reflect.Bool:
		var b = sql.NullBool{}
		var err = b.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if b.Valid {
			value.SetBool(b.Bool)
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		var i = sql.NullInt64{}
		var err = i.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if i.Valid {
			value.SetInt(i.Int64)
		}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		var i = sql.NullInt64{}
		var err = i.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if i.Valid {
			value.SetUint(uint64(i.Int64))
		}
	case reflect.Float32, reflect.Float64:
		var f = sql.NullFloat64{}
		var err = f.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if f.Valid {
			value.SetFloat(f.Float64)
		}
	case reflect.String:
		var s = sql.NullString{}
		var err = s.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if s.Valid {
			value.SetString(s.String)
		}
	case reflect.Struct:
		{
			if value.Type().String() == "time.Time" {
				//时间结构体解析
				var s = sql.NullString{}
				var err = s.Scan(*(fields[index].(*interface{})))
				if err != nil {
					return err
				}
				if s.Valid {
					result, err := time.ParseInLocation("2006-01-02 15:04:05", s.String, time.Local)
					if err == nil {
						value.Set(reflect.ValueOf(result))
					}
				}
			} else {
				//常规结构体解析
				for i := 0; i < value.NumField(); i++ {
					var fieldValue = value.Field(i)
					var fieldType = value.Type().Field(i)
					if fieldType.Anonymous {
						//匿名组合字段,进行递归解析
						this.parse(fieldValue, 0, fields)
					} else {
						//非匿名字段
						if fieldValue.CanSet() {
							var fieldName = fieldType.Tag.Get("col")
							if fieldName == "-" {
								//如果是-,则忽略当前字段
								continue
							}
							if fieldName == "" {
								//如果为空,则使用字段名
								fieldName = transFieldName(fieldType.Name)
							}
							var index = this.columns[fieldName]
							this.parse(fieldValue, index, fields)
						}
					}
				}
			}
		}

	}
	return nil
}

// scan 扫描单行数据
func (this *Rows) scan(data reflect.Value) error {
	if this.columns == nil {
		var columns, err = this.rows.Columns()
		if err != nil {
			return this.err
		}
		this.columns = make(map[string]int, len(columns))
		for i, n := range columns {
			this.columns[n] = i
		}
	}
	var fields = make([]interface{}, len(this.columns))
	for i := 0; i < len(fields); i++ {
		var pif interface{}
		fields[i] = &pif
	}
	var err = this.rows.Scan(fields...)
	if err == nil {
		err = this.parse(data, 0, fields)
	}
	return err
}

// Scan 扫描数据行
//  data:将数据行中的数据解析到data中,data可以是 基础类型,time.Time类型,结构体,数组类型 的指针
//  return:(扫描的行数,错误)
func (this *Rows) Scan(data interface{}) (int, error) {
	if this.err == nil {
		// 类型解析
		var d, err = newData(data)
		if err != nil {
			return 0, err
		}
		//行解析
		for this.rows.Next() && d.Next() {
			var n = d.New()
			this.err = this.scan(n)
			if this.err != nil {
				return 0, this.err
			}
			d.SetBack(n)
		}
		this.rows.Close()
		return d.length, nil
	}
	return 0, this.err
}

// Error 返回数据行错误
func (this *Rows) Error() error {
	return this.err
}

// 数据类型
type data struct {
	t       reflect.Type
	v       reflect.Value
	setType reflect.Type
	length  int
	slice   bool
}

// newData 创建一个data
func newData(v interface{}) (*data, error) {
	var d = new(data)
	d.t = reflect.TypeOf(v)
	d.v = reflect.ValueOf(v)
	if d.v.Kind() == reflect.Ptr {
		//取指针指向的值
		d.t = d.t.Elem()
		d.v = d.v.Elem()
		switch d.t.Kind() {
		case reflect.Slice:
			{
				d.slice = true
				d.setType = d.t.Elem()
			}
		default:
			{
				d.setType = d.t
				if d.t.Kind() == reflect.Ptr {
					//如果对象为指针
					d.t = d.t.Elem()
					d.v.Set(reflect.New(d.t))
					d.v = d.v.Elem()
				}
			}
		}
		return d, nil
	}
	return nil, TinySqlErrorParamInvalidError.Format(d.t.Name()).Error()
}

// New 获取一个可Set的值
func (this *data) New() reflect.Value {
	this.length++
	if this.slice {
		var v reflect.Value
		if this.setType.Kind() == reflect.Ptr {
			v = reflect.New(this.setType.Elem()).Elem()
		} else {
			v = reflect.New(this.setType).Elem()
		}
		return v
	}
	return this.v
}

// SetBack 将New()的值设置回data
func (this *data) SetBack(value reflect.Value) {
	if this.slice {
		var v = value
		if this.setType.Kind() == reflect.Ptr {
			v = v.Addr()
		}
		this.v.Set(reflect.Append(this.v, v))
	}

}

// Next 能否继续获取
func (this *data) Next() bool {
	if this.slice {
		return true
	}
	return this.length < 1
}
<commit_msg>修复bug<commit_after>package tinysql

import (
	"database/sql"
	"reflect"
	"time"
)

// 数据行
type Rows struct {
	rows    *sql.Rows
	err     error
	columns map[string]int
}

// parse 解析fields值到value中
func (this *Rows) parse(value reflect.Value, index int, fields []interface{}) error {
	switch value.Kind() {
	case reflect.Bool:
		var b = sql.NullBool{}
		var err = b.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if b.Valid {
			value.SetBool(b.Bool)
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		var i = sql.NullInt64{}
		var err = i.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if i.Valid {
			value.SetInt(i.Int64)
		}
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		var i = sql.NullInt64{}
		var err = i.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if i.Valid {
			value.SetUint(uint64(i.Int64))
		}
	case reflect.Float32, reflect.Float64:
		var f = sql.NullFloat64{}
		var err = f.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if f.Valid {
			value.SetFloat(f.Float64)
		}
	case reflect.String:
		var s = sql.NullString{}
		var err = s.Scan(*(fields[index].(*interface{})))
		if err != nil {
			return err
		}
		if s.Valid {
			value.SetString(s.String)
		}
	case reflect.Struct:
		{
			if value.Type().String() == "time.Time" {
				//时间结构体解析
				var s = sql.NullString{}
				var err = s.Scan(*(fields[index].(*interface{})))
				if err != nil {
					return err
				}
				if s.Valid {
					result, err := time.ParseInLocation("2006-01-02 15:04:05", s.String, time.Local)
					if err == nil {
						value.Set(reflect.ValueOf(result))
					}
				}
			} else {
				//常规结构体解析
				for i := 0; i < value.NumField(); i++ {
					var fieldValue = value.Field(i)
					var fieldType = value.Type().Field(i)
					if fieldType.Anonymous {
						//匿名组合字段,进行递归解析
						this.parse(fieldValue, 0, fields)
					} else {
						//非匿名字段
						if fieldValue.CanSet() {
							var fieldName = fieldType.Tag.Get("col")
							if fieldName == "-" {
								//如果是-,则忽略当前字段
								continue
							}
							if fieldName == "" {
								//如果为空,则使用字段名
								fieldName = transFieldName(fieldType.Name)
							}
							var index, ok = this.columns[fieldName]
							if ok {
								this.parse(fieldValue, index, fields)
							}
						}
					}
				}
			}
		}

	}
	return nil
}

// scan 扫描单行数据
func (this *Rows) scan(data reflect.Value) error {
	if this.columns == nil {
		var columns, err = this.rows.Columns()
		if err != nil {
			return this.err
		}
		this.columns = make(map[string]int, len(columns))
		for i, n := range columns {
			this.columns[n] = i
		}
	}
	var fields = make([]interface{}, len(this.columns))
	for i := 0; i < len(fields); i++ {
		var pif interface{}
		fields[i] = &pif
	}
	var err = this.rows.Scan(fields...)
	if err == nil {
		err = this.parse(data, 0, fields)
	}
	return err
}

// Scan 扫描数据行
//  data:将数据行中的数据解析到data中,data可以是 基础类型,time.Time类型,结构体,数组类型 的指针
//  return:(扫描的行数,错误)
func (this *Rows) Scan(data interface{}) (int, error) {
	if this.err == nil {
		// 类型解析
		var d, err = newData(data)
		if err != nil {
			return 0, err
		}
		//行解析
		for this.rows.Next() && d.Next() {
			var n = d.New()
			this.err = this.scan(n)
			if this.err != nil {
				return 0, this.err
			}
			d.SetBack(n)
		}
		this.rows.Close()
		return d.length, nil
	}
	return 0, this.err
}

// Error 返回数据行错误
func (this *Rows) Error() error {
	return this.err
}

// 数据类型
type data struct {
	t       reflect.Type
	v       reflect.Value
	setType reflect.Type
	length  int
	slice   bool
}

// newData 创建一个data
func newData(v interface{}) (*data, error) {
	var d = new(data)
	d.t = reflect.TypeOf(v)
	d.v = reflect.ValueOf(v)
	if d.v.Kind() == reflect.Ptr {
		//取指针指向的值
		d.t = d.t.Elem()
		d.v = d.v.Elem()
		switch d.t.Kind() {
		case reflect.Slice:
			{
				d.slice = true
				d.setType = d.t.Elem()
			}
		default:
			{
				d.setType = d.t
				if d.t.Kind() == reflect.Ptr {
					//如果对象为指针
					d.t = d.t.Elem()
					d.v.Set(reflect.New(d.t))
					d.v = d.v.Elem()
				}
			}
		}
		return d, nil
	}
	return nil, TinySqlErrorParamInvalidError.Format(d.t.Name()).Error()
}

// New 获取一个可Set的值
func (this *data) New() reflect.Value {
	this.length++
	if this.slice {
		var v reflect.Value
		if this.setType.Kind() == reflect.Ptr {
			v = reflect.New(this.setType.Elem()).Elem()
		} else {
			v = reflect.New(this.setType).Elem()
		}
		return v
	}
	return this.v
}

// SetBack 将New()的值设置回data
func (this *data) SetBack(value reflect.Value) {
	if this.slice {
		var v = value
		if this.setType.Kind() == reflect.Ptr {
			v = v.Addr()
		}
		this.v.Set(reflect.Append(this.v, v))
	}

}

// Next 能否继续获取
func (this *data) Next() bool {
	if this.slice {
		return true
	}
	return this.length < 1
}
<|endoftext|>


<commit_before>package main

import (
	"debug/pe"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"reflect"
	"strings"
	"unsafe"
)

type ImageResourceDirectory struct {
	Characteristics      uint32
	TimeDateStamp        uint32
	MajorVersion         uint16
	MinorVersion         uint16
	NumberOfNamedEntries uint16
	NumberOfIdEntries    uint16
}

type ImageResourceDirectoryEntry struct {
	NameOrId     uint32
	OffsetToData uint32
}

type ImageResourceDataEntry struct {
	OffsetToData uint32
	Size1        uint32
	CodePage     uint32
	Reserved     uint32
}

type Symbol struct {
	Name           [8]byte
	Value          uint32
	SectionNumber  uint16
	Type           uint16
	StorageClass   uint8
	AuxiliaryCount uint8
}

type StringsHeader struct {
	Length uint32
}

const (
	MASK_SUBDIRECTORY = 1 << 31
	TYPE_MANIFEST     = 24
)

var (
	STRING_RSRC = [8]byte{'.', 'r', 's', 'r', 'c', 0, 0, 0}
)

type Writer struct {
	W      io.Writer
	Offset uint32 //FIXME: uint64?
	Err    error
}

func (w *Writer) WriteLE(v interface{}) {
	if w.Err != nil {
		return
	}
	w.Err = binary.Write(w.W, binary.LittleEndian, v)
	if w.Err != nil {
		return
	}
	w.Offset += uint32(reflect.TypeOf(v).Size())
}

func main() {
	err := run()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func run() error {
	//TODO: allow options:
	// -o FILENAME - output file name
	// + advanced specification of multiple resources, as a tree (json?)
	if len(os.Args) <= 1 {
		return fmt.Errorf("USAGE: %s FILE.exe.manifest\n"+
			"Generates FILE.res",
			os.Args[0])
	}

	//TODO: try to simplify by adding fake section at beginning, containing strings table in data, and characteristics saying "drop me when linking"

	//var fix2 uint32
	//fix2 = 0x02ca // symbols (strings) table at the end

	fname := os.Args[1]
	suffix := ".exe.manifest"
	if !strings.HasSuffix(fname, suffix) {
		return fmt.Errorf("Filename '%s' does not end in suffix '%s'", fname, suffix)
	}
	fname = fname[:len(fname)-len(suffix)]

	manifest, err := ioutil.ReadFile(fname + suffix)
	if err != nil {
		return err
	}

	out, err := os.Create(fname + ".res")
	if err != nil {
		return err
	}
	defer out.Close()
	w := Writer{W: out}

	// precalculate some important offsets in resulting file, that we must know earlier
	rawdataoff := uint32(unsafe.Sizeof(pe.FileHeader{}) + unsafe.Sizeof(pe.SectionHeader32{}))
	rawdatalen := uint32(3*unsafe.Sizeof(ImageResourceDirectory{})+
		3*unsafe.Sizeof(ImageResourceDirectoryEntry{})+
		1*unsafe.Sizeof(ImageResourceDataEntry{})) +
		uint32(len(manifest))
	diroff := rawdataoff
	symoff := rawdataoff + rawdatalen

	coffhdr := pe.FileHeader{
		Machine:              0x014c, //FIXME: find out how to differentiate this value, or maybe not necessary for Go
		NumberOfSections:     1,      // .rsrc
		TimeDateStamp:        0,      // was also 0 in sample data from MinGW's windres.exe
		PointerToSymbolTable: uint32(symoff),
		NumberOfSymbols:      1,
		SizeOfOptionalHeader: 0,
		Characteristics:      0x0104, //FIXME: copied from windres.exe output, find out what should be here and why
	}
	w.WriteLE(coffhdr)
	if w.Err != nil {
		return fmt.Errorf("Error writing COFF header: %s", w.Err)
	}

	secthdr := pe.SectionHeader32{
		Name:             STRING_RSRC,
		SizeOfRawData:    rawdatalen,
		PointerToRawData: rawdataoff,
	}
	w.WriteLE(secthdr)
	if w.Err != nil {
		return fmt.Errorf("Error writing .rsrc section header: %s", w.Err)
	}

	// now, build "directory hierarchy" of .rsrc section: first type, then id/name, then language

	w.WriteLE(ImageResourceDirectory{
		NumberOfIdEntries: 1,
	})
	w.WriteLE(ImageResourceDirectoryEntry{
		NameOrId:     TYPE_MANIFEST,
		OffsetToData: MASK_SUBDIRECTORY | (w.Offset + uint32(unsafe.Sizeof(ImageResourceDirectoryEntry{})) - diroff),
	})
	w.WriteLE(ImageResourceDirectory{
		NumberOfIdEntries: 1,
	})
	w.WriteLE(ImageResourceDirectoryEntry{
		NameOrId:     1, // ID
		OffsetToData: MASK_SUBDIRECTORY | (w.Offset + uint32(unsafe.Sizeof(ImageResourceDirectoryEntry{})) - diroff),
	})
	w.WriteLE(ImageResourceDirectory{
		NumberOfIdEntries: 1,
	})
	w.WriteLE(ImageResourceDirectoryEntry{
		NameOrId:     0x0409, //FIXME: language; what value should be here?
		OffsetToData: w.Offset + uint32(unsafe.Sizeof(ImageResourceDirectoryEntry{})) - diroff,
	})

	w.WriteLE(ImageResourceDataEntry{
		OffsetToData: w.Offset + uint32(unsafe.Sizeof(ImageResourceDataEntry{})) - diroff,
		Size1:        uint32(len(manifest)),
		CodePage:     0, //FIXME: what value here? for now just tried 0
	})

	if w.Err != nil {
		return fmt.Errorf("Error writing .rsrc Directory Hierarchy: %s", w.Err)
	}

	//if fix2 > 0 {
	//	manifest = append(manifest, []byte{
	//		'.', 'r',
	//		's', 'r', 'c', 0,
	//		0, 0, 0, 0,
	//		0, 0, 1, 0,
	//		0, 0, 3, 0,
	//		4, 0, 0, 0,
	//	}...)
	//}

	_, err = w.W.Write(manifest)
	if err != nil {
		return fmt.Errorf("Error writing manifest contents: %s", err)
	}

	w.WriteLE(Symbol{
		Name:           STRING_RSRC,
		Value:          0,
		SectionNumber:  1,
		Type:           0, // FIXME: wtf?
		StorageClass:   3, // FIXME: is it ok? and uint8? and what does the value mean?
		AuxiliaryCount: 0, // FIXME: wtf?
	})

	w.WriteLE(StringsHeader{
		Length: uint32(unsafe.Sizeof(StringsHeader{})), // empty strings table -- but we must still show size of the table's header...
	})

	if w.Err != nil {
		return fmt.Errorf("Error writing .rsrc Symbol Table & Strings: %s", w.Err)
	}

	return nil
}
<commit_msg>fix lost section.Characteristics<commit_after>package main

import (
	"debug/pe"
	"encoding/binary"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"reflect"
	"strings"
	"unsafe"
)

type ImageResourceDirectory struct {
	Characteristics      uint32
	TimeDateStamp        uint32
	MajorVersion         uint16
	MinorVersion         uint16
	NumberOfNamedEntries uint16
	NumberOfIdEntries    uint16
}

type ImageResourceDirectoryEntry struct {
	NameOrId     uint32
	OffsetToData uint32
}

type ImageResourceDataEntry struct {
	OffsetToData uint32
	Size1        uint32
	CodePage     uint32
	Reserved     uint32
}

type Symbol struct {
	Name           [8]byte
	Value          uint32
	SectionNumber  uint16
	Type           uint16
	StorageClass   uint8
	AuxiliaryCount uint8
}

type StringsHeader struct {
	Length uint32
}

const (
	MASK_SUBDIRECTORY = 1 << 31
	TYPE_MANIFEST     = 24
)

var (
	STRING_RSRC = [8]byte{'.', 'r', 's', 'r', 'c', 0, 0, 0}
)

type Writer struct {
	W      io.Writer
	Offset uint32 //FIXME: uint64?
	Err    error
}

func (w *Writer) WriteLE(v interface{}) {
	if w.Err != nil {
		return
	}
	w.Err = binary.Write(w.W, binary.LittleEndian, v)
	if w.Err != nil {
		return
	}
	w.Offset += uint32(reflect.TypeOf(v).Size())
}

func main() {
	err := run()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func run() error {
	//TODO: allow options:
	// -o FILENAME - output file name
	// + advanced specification of multiple resources, as a tree (json?)
	if len(os.Args) <= 1 {
		return fmt.Errorf("USAGE: %s FILE.exe.manifest\n"+
			"Generates FILE.res",
			os.Args[0])
	}

	//TODO: try to simplify by adding fake section at beginning, containing strings table in data, and characteristics saying "drop me when linking"

	//var fix2 uint32
	//fix2 = 0x02ca // symbols (strings) table at the end

	fname := os.Args[1]
	suffix := ".exe.manifest"
	if !strings.HasSuffix(fname, suffix) {
		return fmt.Errorf("Filename '%s' does not end in suffix '%s'", fname, suffix)
	}
	fname = fname[:len(fname)-len(suffix)]

	manifest, err := ioutil.ReadFile(fname + suffix)
	if err != nil {
		return err
	}

	out, err := os.Create(fname + ".res")
	if err != nil {
		return err
	}
	defer out.Close()
	w := Writer{W: out}

	// precalculate some important offsets in resulting file, that we must know earlier
	rawdataoff := uint32(unsafe.Sizeof(pe.FileHeader{}) + unsafe.Sizeof(pe.SectionHeader32{}))
	rawdatalen := uint32(3*unsafe.Sizeof(ImageResourceDirectory{})+
		3*unsafe.Sizeof(ImageResourceDirectoryEntry{})+
		1*unsafe.Sizeof(ImageResourceDataEntry{})) +
		uint32(len(manifest))
	diroff := rawdataoff
	symoff := rawdataoff + rawdatalen

	coffhdr := pe.FileHeader{
		Machine:              0x014c, //FIXME: find out how to differentiate this value, or maybe not necessary for Go
		NumberOfSections:     1,      // .rsrc
		TimeDateStamp:        0,      // was also 0 in sample data from MinGW's windres.exe
		PointerToSymbolTable: uint32(symoff),
		NumberOfSymbols:      1,
		SizeOfOptionalHeader: 0,
		Characteristics:      0x0104, //FIXME: copied from windres.exe output, find out what should be here and why
	}
	w.WriteLE(coffhdr)
	if w.Err != nil {
		return fmt.Errorf("Error writing COFF header: %s", w.Err)
	}

	secthdr := pe.SectionHeader32{
		Name:             STRING_RSRC,
		SizeOfRawData:    rawdatalen,
		PointerToRawData: rawdataoff,
		Characteristics:  0x40000040, // "INITIALIZED_DATA MEM_READ" ?
	}
	w.WriteLE(secthdr)
	if w.Err != nil {
		return fmt.Errorf("Error writing .rsrc section header: %s", w.Err)
	}

	// now, build "directory hierarchy" of .rsrc section: first type, then id/name, then language

	w.WriteLE(ImageResourceDirectory{
		NumberOfIdEntries: 1,
	})
	w.WriteLE(ImageResourceDirectoryEntry{
		NameOrId:     TYPE_MANIFEST,
		OffsetToData: MASK_SUBDIRECTORY | (w.Offset + uint32(unsafe.Sizeof(ImageResourceDirectoryEntry{})) - diroff),
	})
	w.WriteLE(ImageResourceDirectory{
		NumberOfIdEntries: 1,
	})
	w.WriteLE(ImageResourceDirectoryEntry{
		NameOrId:     1, // ID
		OffsetToData: MASK_SUBDIRECTORY | (w.Offset + uint32(unsafe.Sizeof(ImageResourceDirectoryEntry{})) - diroff),
	})
	w.WriteLE(ImageResourceDirectory{
		NumberOfIdEntries: 1,
	})
	w.WriteLE(ImageResourceDirectoryEntry{
		NameOrId:     0x0409, //FIXME: language; what value should be here?
		OffsetToData: w.Offset + uint32(unsafe.Sizeof(ImageResourceDirectoryEntry{})) - diroff,
	})

	w.WriteLE(ImageResourceDataEntry{
		OffsetToData: w.Offset + uint32(unsafe.Sizeof(ImageResourceDataEntry{})) - diroff,
		Size1:        uint32(len(manifest)),
		CodePage:     0, //FIXME: what value here? for now just tried 0
	})

	if w.Err != nil {
		return fmt.Errorf("Error writing .rsrc Directory Hierarchy: %s", w.Err)
	}

	//if fix2 > 0 {
	//	manifest = append(manifest, []byte{
	//		'.', 'r',
	//		's', 'r', 'c', 0,
	//		0, 0, 0, 0,
	//		0, 0, 1, 0,
	//		0, 0, 3, 0,
	//		4, 0, 0, 0,
	//	}...)
	//}

	_, err = w.W.Write(manifest)
	if err != nil {
		return fmt.Errorf("Error writing manifest contents: %s", err)
	}

	w.WriteLE(Symbol{
		Name:           STRING_RSRC,
		Value:          0,
		SectionNumber:  1,
		Type:           0, // FIXME: wtf?
		StorageClass:   3, // FIXME: is it ok? and uint8? and what does the value mean?
		AuxiliaryCount: 0, // FIXME: wtf?
	})

	w.WriteLE(StringsHeader{
		Length: uint32(unsafe.Sizeof(StringsHeader{})), // empty strings table -- but we must still show size of the table's header...
	})

	if w.Err != nil {
		return fmt.Errorf("Error writing .rsrc Symbol Table & Strings: %s", w.Err)
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 (
	"flag"
	"github.com/jacobsa/comeback/registry"
	"log"
	"time"
)

var g_jobName = flag.String("job", "", "Job name within the config file.")

var cmdSave = &Command{
	Name: "save",
	Run: runSave,
}

func runSave(args []string) {
	cfg := getConfig()

	// Look for the specified job.
	if *g_jobName == "" {
		log.Fatalln("You must set the -job flag.")
	}

	job, ok := cfg.Jobs[*g_jobName]
	if !ok {
		log.Fatalln("Unknown job:", *g_jobName)
	}

	// Grab dependencies.
	dirSaver := getDirSaver()
	reg := getRegistry()

	// Choose a start time for the job.
	startTime := time.Now()

	// Call the directory saver.
	score, err := dirSaver.Save(job.BasePath, "", job.Excludes)
	if err != nil {
		log.Fatalln(err)
	}

	// Register the successful backup.
	randSrc := getRandSrc()
	completedJob := registry.CompletedJob{
		Id:        randUint64(randSrc),
		Name:      *g_jobName,
		StartTime: startTime,
		Score:     score,
	}

	if err = reg.RecordBackup(completedJob); err != nil {
		log.Fatalln("Recoding to registry:", err)
	}

	log.Printf("Successfully backed up. ID: %16x\n", completedJob.Id)
}
<commit_msg>Did the same for save.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 (
	"github.com/jacobsa/comeback/registry"
	"log"
	"time"
)

var cmdSave = &Command{
	Name: "save",
}

var g_jobName = cmdSave.Flags.String("job", "", "Job name within the config file.")

func init() {
	cmdSave.Run = runSave  // Break flag-related dependency loop.
}

func runSave(args []string) {
	cfg := getConfig()

	// Look for the specified job.
	if *g_jobName == "" {
		log.Fatalln("You must set the -job flag.")
	}

	job, ok := cfg.Jobs[*g_jobName]
	if !ok {
		log.Fatalln("Unknown job:", *g_jobName)
	}

	// Grab dependencies.
	dirSaver := getDirSaver()
	reg := getRegistry()

	// Choose a start time for the job.
	startTime := time.Now()

	// Call the directory saver.
	score, err := dirSaver.Save(job.BasePath, "", job.Excludes)
	if err != nil {
		log.Fatalln(err)
	}

	// Register the successful backup.
	randSrc := getRandSrc()
	completedJob := registry.CompletedJob{
		Id:        randUint64(randSrc),
		Name:      *g_jobName,
		StartTime: startTime,
		Score:     score,
	}

	if err = reg.RecordBackup(completedJob); err != nil {
		log.Fatalln("Recoding to registry:", err)
	}

	log.Printf("Successfully backed up. ID: %16x\n", completedJob.Id)
}
<|endoftext|>


<commit_before>package sbus

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/satori/go.uuid"
)

func New(transp Transport, log *logrus.Entry) *Sbus {
	return &Sbus{log, transp}
}

type Message struct {
	Subject string          `json:"subject"`
	Data    json.RawMessage `json:"data,omitempty"`
	Meta    Meta            `json:"meta,omitempty"`
}

func (m Message) WithMeta(key string, value interface{}) Message {
	if m.Meta == nil {
		m.Meta = Meta{}
	}
	m.Meta[key] = value
	return m
}

func (m Message) Unmarshal(v interface{}) error {
	return json.Unmarshal([]byte(m.Data), v)
}

func (m Message) String() string {
	re, _ := json.Marshal(m)
	return string(re)
}

type Meta map[string]interface{}

type MessageHandler func(Message) error

type Transport interface {
	Sub(subject string, handler MessageHandler) error
	SubOnce(subject string, handler MessageHandler) error
	Pub(msg *Message) error
}

type Sbus struct {
	log    *logrus.Entry
	transp Transport
}

func (s *Sbus) Sub(subject string, handler MessageHandler) {
	if err := s.transp.Sub(subject, handler); err != nil {
		s.log.WithError(err).Errorf("Error on subscribe to %s", subject)
	}
}

func (s *Sbus) Pub(subject string, data interface{}) error {
	return s.PubM(Message{subject, Marshal(data), nil})
}

func (s *Sbus) PubM(msg Message) error {
	err := s.transp.Pub(&msg)
	if err != nil {
		s.log.WithError(err).Errorf("Error on publish %v", msg)
	}
	return err
}

func (s *Sbus) Request(subject string, data interface{}, handler MessageHandler, timeout time.Duration) error {
	return s.RequestM(Message{subject, Marshal(data), nil}, handler, timeout)
}

func (s *Sbus) RequestM(msg Message, handler MessageHandler, timeout time.Duration) error {
	uid, err := uuid.NewV4()
	if err != nil {
		return err
	}

	replyTo := msg.Subject + "-" + uid.String()

	s.transp.SubOnce(replyTo, handler)
	return s.PubM(msg.WithMeta("replyTo", replyTo))
}

func (s *Sbus) Reply(msg Message, response interface{}) error {
	if replyTo, ok := msg.Meta["replyTo"]; ok {
		return s.Pub(fmt.Sprintf("%s", replyTo), response)
	}
	return fmt.Errorf("Error on replay: not found 'replyTo' field in request %v!", msg)
}

func Marshal(data interface{}) []byte {
	resp, _ := json.MarshalIndent(data, "", "  ")
	return resp
}
<commit_msg>impr nginx settings: timeouts and buffers<commit_after>package sbus

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/satori/go.uuid"
)

func New(transp Transport, log *logrus.Entry) *Sbus {
	return &Sbus{log, transp}
}

type Message struct {
	Subject string          `json:"subject"`
	Data    json.RawMessage `json:"data,omitempty"`
	Meta    Meta            `json:"meta,omitempty"`
}

func (m Message) WithMeta(key string, value interface{}) Message {
	if m.Meta == nil {
		m.Meta = Meta{}
	}
	m.Meta[key] = value
	return m
}

func (m Message) Unmarshal(v interface{}) error {
	return json.Unmarshal([]byte(m.Data), v)
}

func (m Message) String() string {
	re, _ := json.Marshal(m)
	return string(re)
}

type Meta map[string]interface{}

type MessageHandler func(Message) error

type Transport interface {
	Sub(subject string, handler MessageHandler) error
	SubOnce(subject string, handler MessageHandler) error
	Pub(msg *Message) error
}

type Sbus struct {
	log    *logrus.Entry
	transp Transport
}

func (s *Sbus) Sub(subject string, handler MessageHandler) {
	if err := s.transp.Sub(subject, handler); err != nil {
		s.log.WithError(err).Errorf("Error on subscribe to %s", subject)
	}
}

func (s *Sbus) Pub(subject string, data interface{}) error {
	return s.PubM(Message{subject, Marshal(data), nil})
}

func (s *Sbus) PubM(msg Message) error {
	err := s.transp.Pub(&msg)
	if err != nil {
		s.log.WithError(err).Errorf("Error on publish %v", msg)
	}
	return err
}

func (s *Sbus) Request(subject string, data interface{}, handler MessageHandler, timeout time.Duration) error {
	return s.RequestM(Message{subject, Marshal(data), nil}, handler, timeout)
}

func (s *Sbus) RequestM(msg Message, handler MessageHandler, timeout time.Duration) error {
	uid, err := uuid.NewV4()
	if err != nil {
		return err
	}

	replyTo := msg.Subject + "-" + uid.String()

	s.transp.SubOnce(replyTo, handler)
	return s.PubM(msg.WithMeta("replyTo", replyTo))
}

func (s *Sbus) Reply(msg Message, response interface{}) error {
	if replyTo, ok := msg.Meta["replyTo"]; ok {
		return s.Pub(fmt.Sprintf("%s", replyTo), response)
	}
	return fmt.Errorf("Error on replay: not found 'replyTo' field in request %v!", msg)
}

func Marshal(data interface{}) []byte {
	resp, _ := json.MarshalIndent(data, "", "  ")
	return resp
}
<|endoftext|>


<commit_before>package segygo

import (
	"bytes"
	"encoding/binary"
	"io/ioutil"
	//"log"
	"os"
	"unsafe"
	"reflect"
	"github.com/op/go-logging"
)

var log = logging.MustGetLogger("segygo")
var format = logging.MustStringFormatter(
	`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
)

const Version = "0.1"
const SEGY_DESC_HDR_LEN = 3200
const SEGY_BIN_HDR_LEN = 400
const SEGY_TRACE_HDR_LEN = 240

type BinHeader struct {
	Jobid, Lino, Reno                                                                                int32
	Ntrpr, Nart                                                                                int16
	Hdt, Dto, Hns, Nso                                                                                uint16
	Format, Fold, Tsort, Vscode, Hsfs, Hsfe, Hslen, Hstyp, Schn, Hstas, Hstae, Htatyp, Hcorr, Bgrcv, Rcvm, Mfeet, Polyt, Vgpol int16
	Hunass                                                                                [170]int16 // unassigned
}

type TraceHeader struct {
	Tracel                                                               int32
	Tracer                                                               int32
	Fldr                                                                 int32
	Tracf                                                                int32
	Ep                                                                   int32
	CDP                                                                  int32
	CDPT                                                                 int32
	Trid                                                                 int16
	Nvs                                                                  int16
	Nhs                                                                  int16
	Duse                                                                 int16
	Offset                                                               int32
	Gelev                                                                int32
	Selev                                                                int32
	Sdepth                                                               int32
	Gdel                                                                 int32
	Sdel                                                                 int32
	SwDep                                                                int32
	GwDep                                                                int32
	Scalel                                                               int16
	Scalco                                                               int16
	Sx                                                                   int32
	Sy                                                                   int32
	Gx                                                                   int32
	Gy                                                                   int32
	CoUnit                                                               int16
	WeVel                                                                int16
	SweVel                                                               int16
	Sut, Gut, Sstat, Gstat, Tstat, Laga, Lagb, Delrt, Muts, Mute         int16
	Ns, Dt                                                               uint16
	Gain, Igc, Igi, Corr, Sfs, Sfe, Slen, Styp, Stas, Stae, Tatyp        int16
	Afilf, Afils, NoFilf, NoFils, Lcf, Hcf, Lcs, Hcs, Year, Day          int16
	Hour, Minute, Sec, Timbas, Trwf, Grnors, Grnofr, Grnlof, Gaps, Otrav int16
	D1, F1, D2, F2, Ungpow, Unscale                                      float32
	Ntr                                                                  int32
	Mark, Shortpad                                                       int16
	Unass                                                                [14]int16 // unassigned short array
}

type Trace struct {
	TraceHeader
	Data []float32
}

type SegyFile struct {
	Filename string
	Header   BinHeader
	NrTraces int64
	file     *os.File
	Position int64
	LogLevel logging.Level
}

func CreateFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	f, err := os.Create(filename)
	defer f.Close()

	if err != nil {
		return s, err
	}

	s.LogLevel = logging.WARNING

	// Setup proper logging
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1Formatter := logging.NewBackendFormatter(backend1, format)
	logging.SetBackend(backend1Formatter)
	logging.SetLevel(s.LogLevel, "")

	log.Debugf("Creating SEG-Y file: %s", s.Filename)

	s.Filename = filename
	s.Header = binHdr
	s.NrTraces = 0
	s.file = f
	s.Position = 0

	accum := make([]byte, 3200)
	r := bytes.NewWriter(accum)
	//binary.Write()

	return s, err

}

func OpenFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return s, err
	}

	s.Filename = filename
	s.LogLevel = logging.WARNING

	// Setup proper logging
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1Formatter := logging.NewBackendFormatter(backend1, format)
	logging.SetBackend(backend1Formatter)
	logging.SetLevel(s.LogLevel, "")

	accum := []byte{}
	accum = append(accum, b...)

	accum2 := accum[3200:]
	r := bytes.NewReader(accum2)
	log.Debugf("Number of bytes: %d", r.Len())

	if err = binary.Read(r, binary.BigEndian, &binHdr); err != nil {
		log.Errorf("Error reading segy file (bigendian). %s", err)
		return s, err
	}

	// Open and store the os.File object in our struct
	file, err := os.Open(s.Filename)
	s.file = file

	s.Header = binHdr
	s.NrTraces = s.GetNrTraces()

	return s, err
}

func (s *SegyFile) SetVerbose(verbose bool) {

	if verbose {
		s.LogLevel = logging.DEBUG
		logging.SetLevel(s.LogLevel, "")
	} else {
		s.LogLevel = logging.WARNING
		logging.SetLevel(s.LogLevel, "")
	}

}

func (s *SegyFile) GetNrTraces() int64 {
	fi, err := s.file.Stat()
	if err != nil {
		log.Warning("unable to get Stat()")
		log.Fatal(err)
	}
	size := fi.Size()
	nSamples := s.Header.Hns
	txtAndBinarySize := int64(SEGY_DESC_HDR_LEN + SEGY_BIN_HDR_LEN)
	nTraces := ((size - txtAndBinarySize) / (int64(SEGY_TRACE_HDR_LEN) + int64(nSamples)*int64(unsafe.Sizeof(float32(1)))))

	return nTraces
}

func (s *SegyFile) GetNrSamples() int32 {
	return int32(s.Header.Hns)
}

func (s *SegyFile) GetHeader() map[string]interface{} {
	m := make(map[string]interface{})
	v := reflect.ValueOf(s.Header)
	for i := 0; i < v.NumField(); i++ {
		key := v.Type().Field(i).Name
		val := v.Field(i).Interface()
		log.Debugf("name = %s, value = %d", key, val)
		m[key] = val
	}

	return m
}

func (s *SegyFile) ReadTrace() (Trace, error) {
	trace := Trace{}
	traceBuff := make([]float32, s.GetNrSamples())
	byteBuff := make([]byte, s.GetNrSamples()*4)
	trace.Data = traceBuff

	trcHdrBuff := make([]byte, SEGY_TRACE_HDR_LEN)
	bytesRead, err := s.file.Read(trcHdrBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	trcHdrReader := bytes.NewReader(trcHdrBuff)
	err = binary.Read(trcHdrReader, binary.BigEndian, &trace.TraceHeader)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	bytesRead, err = s.file.Read(byteBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	if bytesRead == 0 {
		log.Infof("No bytes read for trace #", s.Position)
	}

	for i := range trace.Data {
		trace.Data[i] = float32(binary.BigEndian.Uint32(byteBuff[i*4 : (i+1)*4]))
	}

	// Then figure out the size of the data, and read it
	return trace, nil
}
<commit_msg>closing file when method exits<commit_after>package segygo

import (
	"bytes"
	"encoding/binary"
	"io/ioutil"
	//"log"
	"os"
	"unsafe"
	"reflect"
	"github.com/op/go-logging"
)

var log = logging.MustGetLogger("segygo")
var format = logging.MustStringFormatter(
	`%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`,
)

const Version = "0.1"
const SEGY_DESC_HDR_LEN = 3200
const SEGY_BIN_HDR_LEN = 400
const SEGY_TRACE_HDR_LEN = 240

type BinHeader struct {
	Jobid, Lino, Reno                                                                                int32
	Ntrpr, Nart                                                                                int16
	Hdt, Dto, Hns, Nso                                                                                uint16
	Format, Fold, Tsort, Vscode, Hsfs, Hsfe, Hslen, Hstyp, Schn, Hstas, Hstae, Htatyp, Hcorr, Bgrcv, Rcvm, Mfeet, Polyt, Vgpol int16
	Hunass                                                                                [170]int16 // unassigned
}

type TraceHeader struct {
	Tracel                                                               int32
	Tracer                                                               int32
	Fldr                                                                 int32
	Tracf                                                                int32
	Ep                                                                   int32
	CDP                                                                  int32
	CDPT                                                                 int32
	Trid                                                                 int16
	Nvs                                                                  int16
	Nhs                                                                  int16
	Duse                                                                 int16
	Offset                                                               int32
	Gelev                                                                int32
	Selev                                                                int32
	Sdepth                                                               int32
	Gdel                                                                 int32
	Sdel                                                                 int32
	SwDep                                                                int32
	GwDep                                                                int32
	Scalel                                                               int16
	Scalco                                                               int16
	Sx                                                                   int32
	Sy                                                                   int32
	Gx                                                                   int32
	Gy                                                                   int32
	CoUnit                                                               int16
	WeVel                                                                int16
	SweVel                                                               int16
	Sut, Gut, Sstat, Gstat, Tstat, Laga, Lagb, Delrt, Muts, Mute         int16
	Ns, Dt                                                               uint16
	Gain, Igc, Igi, Corr, Sfs, Sfe, Slen, Styp, Stas, Stae, Tatyp        int16
	Afilf, Afils, NoFilf, NoFils, Lcf, Hcf, Lcs, Hcs, Year, Day          int16
	Hour, Minute, Sec, Timbas, Trwf, Grnors, Grnofr, Grnlof, Gaps, Otrav int16
	D1, F1, D2, F2, Ungpow, Unscale                                      float32
	Ntr                                                                  int32
	Mark, Shortpad                                                       int16
	Unass                                                                [14]int16 // unassigned short array
}

type Trace struct {
	TraceHeader
	Data []float32
}

type SegyFile struct {
	Filename string
	Header   BinHeader
	NrTraces int64
	file     *os.File
	Position int64
	LogLevel logging.Level
}

func CreateFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	f, err := os.Create(filename)
	defer f.Close()

	if err != nil {
		return s, err
	}

	s.LogLevel = logging.WARNING

	// Setup proper logging
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1Formatter := logging.NewBackendFormatter(backend1, format)
	logging.SetBackend(backend1Formatter)
	logging.SetLevel(s.LogLevel, "")

	log.Debugf("Creating SEG-Y file: %s", s.Filename)

	s.Filename = filename
	s.Header = binHdr
	s.NrTraces = 0
	s.file = f
	s.Position = 0

	accum := make([]byte, 3200)
	r := bytes.NewWriter(accum)
	//binary.Write()

	return s, err

}

func OpenFile(filename string) (SegyFile, error) {
	var s SegyFile
	var binHdr BinHeader
	b, err := ioutil.ReadFile(filename)
	if err != nil {
		return s, err
	}

	s.Filename = filename
	s.LogLevel = logging.WARNING

	// Setup proper logging
	backend1 := logging.NewLogBackend(os.Stderr, "", 0)
	backend1Formatter := logging.NewBackendFormatter(backend1, format)
	logging.SetBackend(backend1Formatter)
	logging.SetLevel(s.LogLevel, "")

	accum := []byte{}
	accum = append(accum, b...)

	accum2 := accum[3200:]
	r := bytes.NewReader(accum2)
	log.Debugf("Number of bytes: %d", r.Len())

	if err = binary.Read(r, binary.BigEndian, &binHdr); err != nil {
		log.Errorf("Error reading segy file (bigendian). %s", err)
		return s, err
	}

	// Open and store the os.File object in our struct
	file, err := os.Open(s.Filename)
	s.file = file
	defer file.Close()

	s.Header = binHdr
	s.NrTraces = s.GetNrTraces()

	return s, err
}

func (s *SegyFile) SetVerbose(verbose bool) {

	if verbose {
		s.LogLevel = logging.DEBUG
		logging.SetLevel(s.LogLevel, "")
	} else {
		s.LogLevel = logging.WARNING
		logging.SetLevel(s.LogLevel, "")
	}

}

func (s *SegyFile) GetNrTraces() int64 {
	fi, err := s.file.Stat()
	if err != nil {
		log.Warning("unable to get Stat()")
		log.Fatal(err)
	}
	size := fi.Size()
	nSamples := s.Header.Hns
	txtAndBinarySize := int64(SEGY_DESC_HDR_LEN + SEGY_BIN_HDR_LEN)
	nTraces := ((size - txtAndBinarySize) / (int64(SEGY_TRACE_HDR_LEN) + int64(nSamples)*int64(unsafe.Sizeof(float32(1)))))

	return nTraces
}

func (s *SegyFile) GetNrSamples() int32 {
	return int32(s.Header.Hns)
}

func (s *SegyFile) GetHeader() map[string]interface{} {
	m := make(map[string]interface{})
	v := reflect.ValueOf(s.Header)
	for i := 0; i < v.NumField(); i++ {
		key := v.Type().Field(i).Name
		val := v.Field(i).Interface()
		log.Debugf("name = %s, value = %d", key, val)
		m[key] = val
	}

	return m
}

func (s *SegyFile) ReadTrace() (Trace, error) {
	trace := Trace{}
	traceBuff := make([]float32, s.GetNrSamples())
	byteBuff := make([]byte, s.GetNrSamples()*4)
	trace.Data = traceBuff

	trcHdrBuff := make([]byte, SEGY_TRACE_HDR_LEN)
	bytesRead, err := s.file.Read(trcHdrBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	trcHdrReader := bytes.NewReader(trcHdrBuff)
	err = binary.Read(trcHdrReader, binary.BigEndian, &trace.TraceHeader)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	bytesRead, err = s.file.Read(byteBuff)
	if err != nil {
		log.Fatal(err)
		return trace, err
	}

	if bytesRead == 0 {
		log.Infof("No bytes read for trace #", s.Position)
	}

	for i := range trace.Data {
		trace.Data[i] = float32(binary.BigEndian.Uint32(byteBuff[i*4 : (i+1)*4]))
	}

	// Then figure out the size of the data, and read it
	return trace, nil
}
<|endoftext|>


<commit_before>package cypress

import (
	"bufio"
	"container/list"
	"errors"
	"io"
	"sync"
	"time"
)

// A type use to send a stream of Messages reliably. This type works in
// coordination with Recv to make transport the stream reliably by
// buffering and acking messages.
type Send struct {
	OnClosed func()

	rw  io.ReadWriter
	enc *StreamEncoder
	buf []byte

	ackRead *bufio.Reader

	closed    bool
	window    int
	available int32
	reqs      *list.List

	ackLock sync.Mutex
	ackCond *sync.Cond
}

/*
* Note on window size: to maximize throughput, attempt to make this
* equation work: t * w = d * 2 or w =  d * 2 / t
*
* t = time between generated messages. Ie, if you're generating 1000
*     messages per second, t = 1ms
* w = the window size
* d = the transmission delay of the network
*
* So, t = 0.1ms and d = 0.05ms, then w = 2. This is the minimum window
* size to maximize throughput.
 */

// Given the transmission delay of the network (t) and the
// expected messages per second (mps), calculate the minimum
// window to use to maximize throughput.
func MinimumSendWindow(d time.Duration, mps int) int {
	t := time.Duration(mps/1000) * time.Millisecond

	return int((d * 20) / t)
}

var (
	// Disable windowing, acknowledge each message immediately
	NoWindow int = -1

	// An average messages/sec rate to calculate against
	DefaultMPSRate int = 1000

	// A decent minimum window that assures some improved throughput
	MinimumWindow = MinimumSendWindow(1*time.Millisecond, DefaultMPSRate)

	// A window for use on a fast lan where transmission delay is very small
	FastLanWindow = MinimumWindow

	// A window for use on a slower lan (cloud infrastructer, across AZ)
	SlowLanWindow = MinimumSendWindow(3*time.Millisecond, DefaultMPSRate)

	// A window for use over faster internet paths
	FastInternetWindow = MinimumSendWindow(10*time.Millisecond, DefaultMPSRate)

	// A window for use over slowe internet paths
	SlowInternetWindow = MinimumSendWindow(50*time.Millisecond, DefaultMPSRate)
)

// Create a new Send, reading and writing from rw. Window controls
// the size of the ack window to use. See MinimumSendWindow and the Window
// variables for information window sizes. If the window is set to 0, the
// default window size is used.
// NOTE: The window size has a big effect on the throughput of Send, so
// be sure to consider it's value. The larger the window, the higher
// the memory usage and throughput. Fast lans only require a small window
// because there is a very small transmission delay.
func NewSend(rw io.ReadWriteCloser, window int) *Send {
	switch window {
	case -1:
		window = 1
	case 0:
		window = MinimumWindow
	}

	s := &Send{
		rw:        rw,
		enc:       NewStreamEncoder(rw),
		buf:       make([]byte, window),
		ackRead:   bufio.NewReader(rw),
		window:    window,
		available: int32(window),
		reqs:      list.New(),
	}

	s.ackCond = sync.NewCond(&s.ackLock)

	go s.backgroundAck()

	return s
}

// Send the start of a stream to the remote side. This will initialize
// the stream to use Snappy for compression and reliable transmission.
func (s *Send) SendHandshake() error {
	hdr := &StreamHeader{
		Compression: NONE.Enum(),
		Mode:        StreamHeader_RELIABLE.Enum(),
	}

	return s.enc.WriteCustomHeader(hdr)
}

// Send the Message. If there is an error, nack the message so it can
// be sent again later.
func (s *Send) transmit(m *Message) error {
	err := s.enc.Receive(m)
	if err != nil {
		s.sendNacks()
		return ErrClosed
	}

	return nil
}

// Indicates that both sides of the stream have gotten confused and are
// no longer is sync.
var ErrStreamUnsynced = errors.New("stream unsynced")

// Used to track all messages that are currently not ack'd by the remote
// side.
type sendInFlight struct {
	req SendRequest
	m   *Message
}

// Read any acks from the stream and remove them from the requests list.
func (s *Send) readAck() error {
	n, err := s.ackRead.Read(s.buf)
	if err != nil {
		return err
	}

	for i := 0; i < n; i++ {
		if s.buf[0] != 'k' {
			return ErrStreamUnsynced
		}

		f := s.reqs.Back()

		if f == nil {
			continue
		}

		if inf, ok := f.Value.(sendInFlight); ok {
			if inf.req != nil {
				inf.req.Ack(inf.m)
			}
		}

		s.reqs.Remove(f)
	}

	s.ackLock.Lock()
	s.available += int32(n)
	s.ackCond.Signal()
	s.ackLock.Unlock()

	return nil
}

// Tell the sender about all the messages that it was not able to get
// acks about and thus should be resent.
func (s *Send) sendNacks() {
	if s.closed {
		return
	}

	for e := s.reqs.Back(); e != nil; e = e.Prev() {
		if inf, ok := e.Value.(sendInFlight); ok {
			if inf.req != nil {
				inf.req.Nack(inf.m)
			}
		}
	}

	s.closed = true

	if s.OnClosed != nil {
		s.OnClosed()
	}

	s.ackCond.Signal()
}

// Read acks forever and if there is an error reading acks, nack all
// inflight requests.
func (s *Send) backgroundAck() {
	for {
		err := s.readAck()
		if err != nil {
			s.ackLock.Lock()
			defer s.ackLock.Unlock()

			s.sendNacks()
			return
		}
	}
}

// Send a Message to the remote side
func (s *Send) Receive(m *Message) error {
	return s.Send(m, nil)
}

// Indicate that this Send is closed and can not be used
var ErrClosed = errors.New("send closed")

// Send a Message to the remote side. if req is not nil, then
// it will be updated as to the status of m, calling either
// Ack or Nack depending on if things go ok or not.
func (s *Send) Send(m *Message, req SendRequest) error {
	s.ackLock.Lock()
	defer s.ackLock.Unlock()

	if s.closed {
		if req != nil {
			req.Nack(m)
		}

		return ErrClosed
	}

	s.reqs.PushFront(sendInFlight{req, m})

	s.available--

	err := s.transmit(m)
	if err != nil {
		return err
	}

	for s.available == 0 {
		if s.closed {
			return ErrClosed
		}

		s.enc.Flush()
		s.ackCond.Wait()
	}

	return nil

}

func (s *Send) Close() error {
	return s.enc.Close()
}

func (s *Send) Flush() error {
	return s.enc.Flush()
}
<commit_msg>Revert "Use a buffered reader to read acks"<commit_after>package cypress

import (
	"container/list"
	"errors"
	"io"
	"sync"
	"time"
)

// A type use to send a stream of Messages reliably. This type works in
// coordination with Recv to make transport the stream reliably by
// buffering and acking messages.
type Send struct {
	OnClosed func()

	rw  io.ReadWriter
	enc *StreamEncoder
	buf []byte

	closed    bool
	window    int
	available int32
	reqs      *list.List

	ackLock sync.Mutex
	ackCond *sync.Cond
}

/*
* Note on window size: to maximize throughput, attempt to make this
* equation work: t * w = d * 2 or w =  d * 2 / t
*
* t = time between generated messages. Ie, if you're generating 1000
*     messages per second, t = 1ms
* w = the window size
* d = the transmission delay of the network
*
* So, t = 0.1ms and d = 0.05ms, then w = 2. This is the minimum window
* size to maximize throughput.
 */

// Given the transmission delay of the network (t) and the
// expected messages per second (mps), calculate the minimum
// window to use to maximize throughput.
func MinimumSendWindow(d time.Duration, mps int) int {
	t := time.Duration(mps/1000) * time.Millisecond

	return int((d * 20) / t)
}

var (
	// Disable windowing, acknowledge each message immediately
	NoWindow int = -1

	// An average messages/sec rate to calculate against
	DefaultMPSRate int = 1000

	// A decent minimum window that assures some improved throughput
	MinimumWindow = MinimumSendWindow(1*time.Millisecond, DefaultMPSRate)

	// A window for use on a fast lan where transmission delay is very small
	FastLanWindow = MinimumWindow

	// A window for use on a slower lan (cloud infrastructer, across AZ)
	SlowLanWindow = MinimumSendWindow(3*time.Millisecond, DefaultMPSRate)

	// A window for use over faster internet paths
	FastInternetWindow = MinimumSendWindow(10*time.Millisecond, DefaultMPSRate)

	// A window for use over slowe internet paths
	SlowInternetWindow = MinimumSendWindow(50*time.Millisecond, DefaultMPSRate)
)

// Create a new Send, reading and writing from rw. Window controls
// the size of the ack window to use. See MinimumSendWindow and the Window
// variables for information window sizes. If the window is set to 0, the
// default window size is used.
// NOTE: The window size has a big effect on the throughput of Send, so
// be sure to consider it's value. The larger the window, the higher
// the memory usage and throughput. Fast lans only require a small window
// because there is a very small transmission delay.
func NewSend(rw io.ReadWriteCloser, window int) *Send {
	switch window {
	case -1:
		window = 1
	case 0:
		window = MinimumWindow
	}

	s := &Send{
		rw:        rw,
		enc:       NewStreamEncoder(rw),
		buf:       make([]byte, window),
		window:    window,
		available: int32(window),
		reqs:      list.New(),
	}

	s.ackCond = sync.NewCond(&s.ackLock)

	go s.backgroundAck()

	return s
}

// Send the start of a stream to the remote side. This will initialize
// the stream to use Snappy for compression and reliable transmission.
func (s *Send) SendHandshake() error {
	hdr := &StreamHeader{
		Compression: NONE.Enum(),
		Mode:        StreamHeader_RELIABLE.Enum(),
	}

	return s.enc.WriteCustomHeader(hdr)
}

// Send the Message. If there is an error, nack the message so it can
// be sent again later.
func (s *Send) transmit(m *Message) error {
	err := s.enc.Receive(m)
	if err != nil {
		s.sendNacks()
		return ErrClosed
	}

	return nil
}

// Indicates that both sides of the stream have gotten confused and are
// no longer is sync.
var ErrStreamUnsynced = errors.New("stream unsynced")

// Used to track all messages that are currently not ack'd by the remote
// side.
type sendInFlight struct {
	req SendRequest
	m   *Message
}

// Read any acks from the stream and remove them from the requests list.
func (s *Send) readAck() error {
	n, err := s.rw.Read(s.buf)
	if err != nil {
		return err
	}

	for i := 0; i < n; i++ {
		if s.buf[0] != 'k' {
			return ErrStreamUnsynced
		}

		f := s.reqs.Back()

		if f == nil {
			continue
		}

		if inf, ok := f.Value.(sendInFlight); ok {
			if inf.req != nil {
				inf.req.Ack(inf.m)
			}
		}

		s.reqs.Remove(f)
	}

	s.ackLock.Lock()
	s.available += int32(n)
	s.ackCond.Signal()
	s.ackLock.Unlock()

	return nil
}

// Tell the sender about all the messages that it was not able to get
// acks about and thus should be resent.
func (s *Send) sendNacks() {
	if s.closed {
		return
	}

	for e := s.reqs.Back(); e != nil; e = e.Prev() {
		if inf, ok := e.Value.(sendInFlight); ok {
			if inf.req != nil {
				inf.req.Nack(inf.m)
			}
		}
	}

	s.closed = true

	if s.OnClosed != nil {
		s.OnClosed()
	}

	s.ackCond.Signal()
}

// Read acks forever and if there is an error reading acks, nack all
// inflight requests.
func (s *Send) backgroundAck() {
	for {
		err := s.readAck()
		if err != nil {
			s.ackLock.Lock()
			defer s.ackLock.Unlock()

			s.sendNacks()
			return
		}
	}
}

// Send a Message to the remote side
func (s *Send) Receive(m *Message) error {
	return s.Send(m, nil)
}

// Indicate that this Send is closed and can not be used
var ErrClosed = errors.New("send closed")

// Send a Message to the remote side. if req is not nil, then
// it will be updated as to the status of m, calling either
// Ack or Nack depending on if things go ok or not.
func (s *Send) Send(m *Message, req SendRequest) error {
	s.ackLock.Lock()
	defer s.ackLock.Unlock()

	if s.closed {
		if req != nil {
			req.Nack(m)
		}

		return ErrClosed
	}

	s.reqs.PushFront(sendInFlight{req, m})

	s.available--

	err := s.transmit(m)
	if err != nil {
		return err
	}

	for s.available == 0 {
		if s.closed {
			return ErrClosed
		}

		s.enc.Flush()
		s.ackCond.Wait()
	}

	return nil

}

func (s *Send) Close() error {
	return s.enc.Close()
}

func (s *Send) Flush() error {
	return s.enc.Flush()
}
<|endoftext|>