<commit_before>// Copyright 2014 Rana Ian. All rights reserved.
// Use of this source code is governed by The MIT License
// found in the accompanying LICENSE file.

package ora

/*
#include <oci.h>
#include "version.h"
*/
import "C"
import (
	"unsafe"
)

type bndInt64 struct {
	stmt      *Stmt
	ocibnd    *C.OCIBind
	ociNumber C.OCINumber
}

func (bnd *bndInt64) bind(value int64, position int, stmt *Stmt) error {
	bnd.stmt = stmt
	r := C.OCINumberFromInt(
		bnd.stmt.ses.srv.env.ocierr, //OCIError            *err,
		unsafe.Pointer(&value),      //const void          *inum,
		8,                   //uword               inum_length,
		C.OCI_NUMBER_SIGNED, //uword               inum_s_flag,
		&bnd.ociNumber)      //OCINumber           *number );
	if r == C.OCI_ERROR {
		return bnd.stmt.ses.srv.env.ociError()
	}
	r = C.OCIBINDBYPOS(
		bnd.stmt.ocistmt,                  //OCIStmt      *stmtp,
		(**C.OCIBind)(&bnd.ocibnd),        //OCIBind      **bindpp,
		bnd.stmt.ses.srv.env.ocierr,       //OCIError     *errhp,
		C.ub4(position),                   //ub4          position,
		unsafe.Pointer(&bnd.ociNumber),    //void         *valuep,
		C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8          value_sz,
		C.SQLT_VNU,                        //ub2          dty,
		nil,                               //void         *indp,
		nil,                               //ub2          *alenp,
		nil,                               //ub2          *rcodep,
		0,                                 //ub4          maxarr_len,
		nil,                               //ub4          *curelep,
		C.OCI_DEFAULT)                     //ub4          mode );
	if r == C.OCI_ERROR {
		return bnd.stmt.ses.srv.env.ociError()
	}
	return nil
}

func (bnd *bndInt64) setPtr() error {
	return nil
}

func (bnd *bndInt64) close() (err error) {
	defer func() {
		if value := recover(); value != nil {
			err = errRecover(value)
		}
	}()

	stmt := bnd.stmt
	bnd.stmt = nil
	bnd.ocibnd = nil
	stmt.putBnd(bndIdxInt64, bnd)
	return nil
}
<commit_msg>revised error recovery method<commit_after>// Copyright 2014 Rana Ian. All rights reserved.
// Use of this source code is governed by The MIT License
// found in the accompanying LICENSE file.

package ora

/*
#include <oci.h>
#include "version.h"
*/
import "C"
import (
	"unsafe"
)

type bndInt64 struct {
	stmt      *Stmt
	ocibnd    *C.OCIBind
	ociNumber C.OCINumber
}

func (bnd *bndInt64) bind(value int64, position int, stmt *Stmt) error {
	bnd.stmt = stmt
	r := C.OCINumberFromInt(
		bnd.stmt.ses.srv.env.ocierr, //OCIError            *err,
		unsafe.Pointer(&value),      //const void          *inum,
		8,                   //uword               inum_length,
		C.OCI_NUMBER_SIGNED, //uword               inum_s_flag,
		&bnd.ociNumber)      //OCINumber           *number );
	if r == C.OCI_ERROR {
		return bnd.stmt.ses.srv.env.ociError()
	}
	r = C.OCIBINDBYPOS(
		bnd.stmt.ocistmt,                  //OCIStmt      *stmtp,
		(**C.OCIBind)(&bnd.ocibnd),        //OCIBind      **bindpp,
		bnd.stmt.ses.srv.env.ocierr,       //OCIError     *errhp,
		C.ub4(position),                   //ub4          position,
		unsafe.Pointer(&bnd.ociNumber),    //void         *valuep,
		C.LENGTH_TYPE(C.sizeof_OCINumber), //sb8          value_sz,
		C.SQLT_VNU,                        //ub2          dty,
		nil,                               //void         *indp,
		nil,                               //ub2          *alenp,
		nil,                               //ub2          *rcodep,
		0,                                 //ub4          maxarr_len,
		nil,                               //ub4          *curelep,
		C.OCI_DEFAULT)                     //ub4          mode );
	if r == C.OCI_ERROR {
		return bnd.stmt.ses.srv.env.ociError()
	}
	return nil
}

func (bnd *bndInt64) setPtr() error {
	return nil
}

func (bnd *bndInt64) close() (err error) {
	defer func() {
		if value := recover(); value != nil {
			err = errR(value)
		}
	}()

	stmt := bnd.stmt
	bnd.stmt = nil
	bnd.ocibnd = nil
	stmt.putBnd(bndIdxInt64, bnd)
	return nil
}
<|endoftext|>


<commit_before>package ui

import(
	"encoding/json"
	"fmt"
	"net/http"

	"golang.org/x/net/context"
	"google.golang.org/appengine/urlfetch"

	fdb "github.com/skypies/flightdb2"
	"github.com/skypies/flightdb2/fgae"
	"github.com/skypies/flightdb2/ref"
)

func init() {
	http.HandleFunc("/fdb/json", UIOptionsHandler(jsonHandler))
		http.HandleFunc("/fdb/snarf", UIOptionsHandler(snarfHandler))
}

// {{{ LookupIdspec

func LookupIdspec(db fgae.FlightDB, idspec fdb.IdSpec) ([]*fdb.Flight, error) {
	flights := []*fdb.Flight{}

	if idspec.Duration == 0 {
		// This is a point-in-time idspec; we want the single, most recent match only
		if result,err := db.LookupMostRecent(db.NewQuery().ByIdSpec(idspec)); err != nil {
			return flights, err
		} else {
			flights = append(flights, result)
		}

	} else {
		// This is a range idspec; we want everything that matches.
		if results,err := db.LookupAll(db.NewQuery().ByIdSpec(idspec)); err != nil {
			return flights, err
		} else {
			flights = append(flights, results...)
		}
	}
	return flights, nil
}

// }}}

// {{{ jsonHandler

func jsonHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	opt,_ := GetUIOptions(ctx)
	db := fgae.FlightDB{C:ctx}

	// This whole Airframe cache thing should be automatic, and upstream from here.
	airframes := ref.NewAirframeCache(ctx)

	idspecs,err := opt.IdSpecs()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	flights := []*fdb.Flight{}
	for _,idspec := range idspecs {
		if results,err := LookupIdspec(db, idspec); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		} else if len(results) == 0 {
			http.NotFound(w,r)
			//http.Error(w, fmt.Sprintf("idspec %s not found", idspec), http.StatusNotFound)
			return
		} else {
			for _,f := range results {
				if f == nil { continue }  // Bad input data ??
				if af := airframes.Get(f.IcaoId); af != nil {
					f.Airframe = *af
				}
				if r.FormValue("notracks") != "" {
					f.PruneTrackContents()
				}
				flights = append(flights, f)
			}
		}
	}

	jsonBytes,err := json.MarshalIndent(flights, "", " ")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(jsonBytes)
}

// }}}
// {{{ snarfHandler

func snarfHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	// opt,_ := GetUIOptions(ctx)
	client := urlfetch.Client(ctx)
	db := fgae.FlightDB{C:ctx}

	// This might well be broken nowadays; consider opt.Idspecs()[0]
	url := "http://fdb.serfr1.org/fdb/json?idspec=" + r.FormValue("idspec")

	str := fmt.Sprintf("Snarfer!\n--\n%s\n--\n", url)

	flights := []fdb.Flight{}
	if resp,err := client.Get(url); err != nil {
		http.Error(w, "XX: "+err.Error(), http.StatusInternalServerError)
		return
	} else {
		defer resp.Body.Close()

		if resp.StatusCode != http.StatusOK {
			err = fmt.Errorf ("Bad status: %v", resp.Status)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		} else if err := json.NewDecoder(resp.Body).Decode(&flights); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}

	str += "Snarfed:-\n"
	for _,f := range flights {
		str += fmt.Sprintf(" * %s\n", f)
	}
	str += "--\n"

	for _,f := range flights {
		if err := db.PersistFlight(&f); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}
	str += "all persisted OK!\n"

	w.Header().Set("Content-Type", "text/plain")
	w.Write([]byte(str))
}

// }}}

// {{{ -------------------------={ E N D }=----------------------------------

// Local variables:
// folded-file: t
// end:

// }}}
<commit_msg>Get the snarfing all working again<commit_after>package ui

import(
	"encoding/json"
	"fmt"
	"net/http"

	"golang.org/x/net/context"
	"google.golang.org/appengine/urlfetch"

	fdb "github.com/skypies/flightdb2"
	"github.com/skypies/flightdb2/fgae"
	"github.com/skypies/flightdb2/ref"
)

func init() {
	http.HandleFunc("/fdb/json", UIOptionsHandler(jsonHandler))
		http.HandleFunc("/fdb/snarf", UIOptionsHandler(snarfHandler))
}

// {{{ LookupIdspec

func LookupIdspec(db fgae.FlightDB, idspec fdb.IdSpec) ([]*fdb.Flight, error) {
	flights := []*fdb.Flight{}

	if idspec.Duration == 0 {
		// This is a point-in-time idspec; we want the single, most recent match only
		if result,err := db.LookupMostRecent(db.NewQuery().ByIdSpec(idspec)); err != nil {
			return flights, err
		} else {
			flights = append(flights, result)
		}

	} else {
		// This is a range idspec; we want everything that matches.
		if results,err := db.LookupAll(db.NewQuery().ByIdSpec(idspec)); err != nil {
			return flights, err
		} else {
			flights = append(flights, results...)
		}
	}
	return flights, nil
}

// }}}

// {{{ jsonHandler

// /fdb/json?idspec=...  - dumps an entire flight object out as JSON.

func jsonHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	opt,_ := GetUIOptions(ctx)
	db := fgae.FlightDB{C:ctx}

	// This whole Airframe cache thing should be automatic, and upstream from here.
	airframes := ref.NewAirframeCache(ctx)

	idspecs,err := opt.IdSpecs()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	flights := []*fdb.Flight{}
	for _,idspec := range idspecs {
		if results,err := LookupIdspec(db, idspec); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		} else if len(results) == 0 {
			http.NotFound(w,r)
			//http.Error(w, fmt.Sprintf("idspec %s not found", idspec), http.StatusNotFound)
			return
		} else {
			for _,f := range results {
				if f == nil { continue }  // Bad input data ??
				if af := airframes.Get(f.IcaoId); af != nil {
					f.Airframe = *af
				}
				if r.FormValue("notracks") != "" {
					f.PruneTrackContents()
				}
				flights = append(flights, f)
			}
		}
	}

	jsonBytes,err := json.MarshalIndent(flights, "", " ")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(jsonBytes)
}

// }}}
// {{{ snarfHandler

// /fdb/snarf?idspec=...  - pull the idspecs from prod, insert into local DB. For debugging.

func snarfHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	opt,_ := GetUIOptions(ctx)
	client := urlfetch.Client(ctx)
	db := fgae.FlightDB{C:ctx}

	str := "Snarfer!\n--\n\n"

	idspecs,err := opt.IdSpecs()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	allFlights := []fdb.Flight{}
	for _,idspec := range idspecs {
		theseFlights := []fdb.Flight{}
		url := fmt.Sprintf("http://fdb.serfr1.org/fdb/json?idspec=%s", idspec)
		str += fmt.Sprintf("-- snarfing: %s\n", url)

		if resp,err := client.Get(url); err != nil {
			http.Error(w, "XX: "+err.Error(), http.StatusInternalServerError)
			return
		} else {
			defer resp.Body.Close()

			if resp.StatusCode != http.StatusOK {
				err = fmt.Errorf ("Bad status: %v", resp.Status)
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			} else if err := json.NewDecoder(resp.Body).Decode(&theseFlights); err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		}
		allFlights = append(allFlights, theseFlights...)

		str += "-- Found:-\n"
		for _,f := range theseFlights {
			str += fmt.Sprintf(" * %s\n", f)
		}
		str += "--\n"
	}

	for _,f := range allFlights {
		if err := db.PersistFlight(&f); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}
	str += "all persisted OK!\n"

	w.Header().Set("Content-Type", "text/plain")
	w.Write([]byte(str))
}

// }}}

// {{{ -------------------------={ E N D }=----------------------------------

// Local variables:
// folded-file: t
// end:

// }}}
<|endoftext|>


<commit_before>package template

import (
	"github.com/skygeario/skygear-server/pkg/core/config"
)

// Spec is an template spec.
type Spec struct {
	// Type is the type of the template.
	Type config.TemplateItemType `json:"type"`
	// Default is the default content of the template.
	Default string `json:"default,omitempty"`
	// IsKeyed indicates whether the template content may vary according to some key
	IsKeyed bool `json:"is_keyed"`
	// IsHTML indicates whether the template content is HTML
	IsHTML bool `json:"is_html"`
	// Defines is a list of defines to be parsed after the main template is parsed.
	Defines []string `json:"-"`
}
<commit_msg>Add Translation to Spec<commit_after>package template

import (
	"github.com/skygeario/skygear-server/pkg/core/config"
)

// Spec is an template spec.
type Spec struct {
	// Type is the type of the template.
	Type config.TemplateItemType `json:"type"`
	// Default is the default content of the template.
	Default string `json:"default,omitempty"`
	// IsKeyed indicates whether the template content may vary according to some key
	IsKeyed bool `json:"is_keyed"`
	// IsHTML indicates whether the template content is HTML
	IsHTML bool `json:"is_html"`
	// Defines is a list of defines to be parsed after the main template is parsed.
	Defines []string `json:"-"`
	// Translation expresses that this template depends on another template to provide translation.
	Translation config.TemplateItemType `json:"-"`
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/hmac"
	"crypto/md4"
	"crypto/md5"
	"crypto/ripemd160"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"flag"
	"fmt"
	"hash"
	"hash/adler32"
	"hash/crc32"
	"hash/crc64"
	"hash/fnv"
	"io"
	"os"
	"sort"
	"strings"
)

const (
	version   = "1.0"
	chunkSize = 32768 // Read files in 32KB chunks
)

var (
	alg  *string = flag.String("a", "md5", "algorithm")
	key  *string = flag.String("k", "", "key (for hashes that use a key, e.g. HMAC)")
	salt *string = flag.String("salt", "", "salt")
	hashStr  *bool = flag.Bool("s", false, "hash a string")
)

var (
	algDescs = map[string]string{
		"adler32":         "Adler-32 checksum (RFC 1950)",
		"crc32":           "32-bit cyclic redundancy check (CRC-32) checksum (defaults to IEEE polynomial)",
		"crc32ieee":       "CRC-32 using the IEEE polynomial (0xedb88320)",
		"crc32castagnoli": "CRC-32 using the Castagnoli polynomial (0x82f63b78)",
		"crc32koopman":    "CRC-32 using the Koopman polynomial (0xeb31d82e)",
		"crc64":           "64-bit cyclic redundancy check (CRC-64) checksum (defaults to ISO polynomial)",
		"crc64iso":        "CRC-64 using the ISO polynomial (0xD800000000000000)",
		"crc64ecma":       "CRC-64 using the ECMA polynomial (0xC96C5795D7870F42)",
		"fnv":             "FNV-1 non-cryptographic hash (defaults to fnv32)",
		"fnv32":           "32-bit FNV-1",
		"fnv32a":          "32-bit FNV-1a",
		"fnv64":           "64-bit FNV-1",
		"fnv64a":          "64-bit FNV-1a",
		"hmac":            "Keyed-Hash Message Authentication Code (HMAC) (requires -k <key>) (defaults to SHA-256)",
		"hmacmd5":         "HMAC using MD5 (requires -k <key>)",
		"hmacsha1":        "HMAC using SHA-1 (requires -k <key>)",
		"hmacsha256":      "HMAC using SHA-256 (requires -k <key>)",
		"hmacsha512":      "HMAC using SHA-512 (requires -k <key>)",
		"md4":             "MD4 hash (RFC 1320)",
		"md5":             "MD5 hash (RFC 1321)",
		"ripemd160":       "RIPEMD-160 hash",
		"sha1":            "SHA-1 hash (RFC 3174)",
		"sha224":          "SHA-224 hash (FIPS 180-2)",
		"sha256":          "SHA-256 hash (FIPS 180-2)",
		"sha384":          "SHA-384 hash (FIPS 180-2)",
		"sha512":          "SHA-512 hash (FIPS 180-2)",
	}
)

func GetGenerator(a string) (hash.Hash, os.Error) {
	var g hash.Hash
	switch a {
	default:
		return md5.New(), os.NewError("Invalid algorithm")
	case "adler32":
		g = adler32.New()
	case "crc32", "crc32ieee":
		g = crc32.New(crc32.MakeTable(crc32.IEEE))
	case "crc32castagnoli":
		g = crc32.New(crc32.MakeTable(crc32.Castagnoli))
	case "crc32koopman":
		g = crc32.New(crc32.MakeTable(crc32.Koopman))
	case "crc64", "crc64iso":
		g = crc64.New(crc64.MakeTable(crc64.ISO))
	case "crc64ecma":
		g = crc64.New(crc64.MakeTable(crc64.ECMA))
	case "fnv", "fnv32":
		g = fnv.New32()
	case "fnv32a":
		g = fnv.New32a()
	case "fnv64":
		g = fnv.New64()
	case "fnv64a":
		g = fnv.New64a()
	case "hmac", "hmacsha256":
		g = hmac.NewSHA256([]byte(*key))
	case "hmacmd5":
		g = hmac.NewMD5([]byte(*key))
	case "hmacsha1":
		g = hmac.NewSHA1([]byte(*key))
	case "hmacsha512":
		g = hmac.New(sha512.New, []byte(*key))
	case "md4":
		g = md4.New()
	case "md5":
		g = md5.New()
	case "ripemd160":
		g = ripemd160.New()
	case "sha1":
		g = sha1.New()
	case "sha224":
		g = sha256.New224()
	case "sha256":
		g = sha256.New()
	case "sha384":
		g = sha512.New384()
	case "sha512":
		g = sha512.New()
	}
	return g, nil
}

func HashString(gen hash.Hash, s string) string {
	gen.Write([]byte(s))
	return fmt.Sprintf("%x", gen.Sum())
}

func HashFile(gen hash.Hash, f io.Reader) (string, os.Error) {
	buf := make([]byte, chunkSize)
	gen.Write([]byte(*salt))
	for {
		bytesRead, err := f.Read(buf)
		if err != nil {
			if err == os.EOF && bytesRead == 0 { // Empty file
				gen.Write([]byte(""))
			} else {
				return "", err
			}
		} else {
			gen.Write(buf[:bytesRead])
		}
		if bytesRead < chunkSize { // EOF
			break
		}
	}
	return fmt.Sprintf("%x", gen.Sum()), nil
}

func Usage() {
	fmt.Println("Usage:", os.Args[0], "[-a <algorithm>] [-salt <salt>] [-s <string to hash>] / <file(s) to hash>\n")
	fmt.Println("Examples:")
	fmt.Println(" ", os.Args[0], `-a md5 document.txt               `, "Generate MD5 hash of a file")
	fmt.Println(" ", os.Args[0], `-a md5 *                          `, "Generate MD5 hash of all files in folder")
	fmt.Println(" ", os.Args[0], `-a sha1 -s hello world            `, "Generate SHA-1 hash of a string")
	fmt.Println(" ", os.Args[0], `-a sha1 -salt s4lt -s hello world `, "Generate salted SHA-1 hash of a string")
	fmt.Println("")
	fmt.Println("Available algorithms (default is MD5):")
	mk := make([]string, len(algDescs))
	i := 0
	for k, _ := range algDescs {
		mk[i] = k
		i++
	}
	sort.Strings(mk)
	for _, v := range mk {
		fmt.Printf("  %-15s %s\n", v, algDescs[v])
	}
	fmt.Println("")
	fmt.Println(`Note: For complex strings, put the string in a file, then run Picugen on
      the file. (Don't add newlines to the file as they will alter the output.)`)
}

func main() {
	flag.Parse()
	if flag.NArg() == 0 {
		Usage()
		return
	}
	*alg = strings.ToLower(*alg)
	gen, err := GetGenerator(*alg)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	if *hashStr {
		var s string
		for i, word := range flag.Args() {
			if i > 0 {
				s += " "
			}
			s += word
		}
		fmt.Println(HashString(gen, *salt+s))
	} else {
		for _, path := range flag.Args() {
			var res string
			f, err := os.Open(path)
			defer f.Close()
			if err != nil {
				res = err.String()
			} else {
				h, err := HashFile(gen, f)
				if err != nil {
					res = err.String()
				} else {
					res = h
				}
			}
			fmt.Println(res, "", path)
			gen.Reset()
		}
	}
}
<commit_msg>Don't defer f.Close as it won't happen before main() exits<commit_after>package main

import (
	"crypto/hmac"
	"crypto/md4"
	"crypto/md5"
	"crypto/ripemd160"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"flag"
	"fmt"
	"hash"
	"hash/adler32"
	"hash/crc32"
	"hash/crc64"
	"hash/fnv"
	"io"
	"os"
	"sort"
	"strings"
)

const (
	version   = "1.0"
	chunkSize = 32768 // Read files in 32KB chunks
)

var (
	alg  *string = flag.String("a", "md5", "algorithm")
	key  *string = flag.String("k", "", "key (for hashes that use a key, e.g. HMAC)")
	salt *string = flag.String("salt", "", "salt")
	hashStr  *bool = flag.Bool("s", false, "hash a string")
)

var (
	algDescs = map[string]string{
		"adler32":         "Adler-32 checksum (RFC 1950)",
		"crc32":           "32-bit cyclic redundancy check (CRC-32) checksum (defaults to IEEE polynomial)",
		"crc32ieee":       "CRC-32 using the IEEE polynomial (0xedb88320)",
		"crc32castagnoli": "CRC-32 using the Castagnoli polynomial (0x82f63b78)",
		"crc32koopman":    "CRC-32 using the Koopman polynomial (0xeb31d82e)",
		"crc64":           "64-bit cyclic redundancy check (CRC-64) checksum (defaults to ISO polynomial)",
		"crc64iso":        "CRC-64 using the ISO polynomial (0xD800000000000000)",
		"crc64ecma":       "CRC-64 using the ECMA polynomial (0xC96C5795D7870F42)",
		"fnv":             "FNV-1 non-cryptographic hash (defaults to fnv32)",
		"fnv32":           "32-bit FNV-1",
		"fnv32a":          "32-bit FNV-1a",
		"fnv64":           "64-bit FNV-1",
		"fnv64a":          "64-bit FNV-1a",
		"hmac":            "Keyed-Hash Message Authentication Code (HMAC) (requires -k <key>) (defaults to SHA-256)",
		"hmacmd5":         "HMAC using MD5 (requires -k <key>)",
		"hmacsha1":        "HMAC using SHA-1 (requires -k <key>)",
		"hmacsha256":      "HMAC using SHA-256 (requires -k <key>)",
		"hmacsha512":      "HMAC using SHA-512 (requires -k <key>)",
		"md4":             "MD4 hash (RFC 1320)",
		"md5":             "MD5 hash (RFC 1321)",
		"ripemd160":       "RIPEMD-160 hash",
		"sha1":            "SHA-1 hash (RFC 3174)",
		"sha224":          "SHA-224 hash (FIPS 180-2)",
		"sha256":          "SHA-256 hash (FIPS 180-2)",
		"sha384":          "SHA-384 hash (FIPS 180-2)",
		"sha512":          "SHA-512 hash (FIPS 180-2)",
	}
)

func GetGenerator(a string) (hash.Hash, os.Error) {
	var g hash.Hash
	switch a {
	default:
		return md5.New(), os.NewError("Invalid algorithm")
	case "adler32":
		g = adler32.New()
	case "crc32", "crc32ieee":
		g = crc32.New(crc32.MakeTable(crc32.IEEE))
	case "crc32castagnoli":
		g = crc32.New(crc32.MakeTable(crc32.Castagnoli))
	case "crc32koopman":
		g = crc32.New(crc32.MakeTable(crc32.Koopman))
	case "crc64", "crc64iso":
		g = crc64.New(crc64.MakeTable(crc64.ISO))
	case "crc64ecma":
		g = crc64.New(crc64.MakeTable(crc64.ECMA))
	case "fnv", "fnv32":
		g = fnv.New32()
	case "fnv32a":
		g = fnv.New32a()
	case "fnv64":
		g = fnv.New64()
	case "fnv64a":
		g = fnv.New64a()
	case "hmac", "hmacsha256":
		g = hmac.NewSHA256([]byte(*key))
	case "hmacmd5":
		g = hmac.NewMD5([]byte(*key))
	case "hmacsha1":
		g = hmac.NewSHA1([]byte(*key))
	case "hmacsha512":
		g = hmac.New(sha512.New, []byte(*key))
	case "md4":
		g = md4.New()
	case "md5":
		g = md5.New()
	case "ripemd160":
		g = ripemd160.New()
	case "sha1":
		g = sha1.New()
	case "sha224":
		g = sha256.New224()
	case "sha256":
		g = sha256.New()
	case "sha384":
		g = sha512.New384()
	case "sha512":
		g = sha512.New()
	}
	return g, nil
}

func HashString(gen hash.Hash, s string) string {
	gen.Write([]byte(s))
	return fmt.Sprintf("%x", gen.Sum())
}

func HashFile(gen hash.Hash, f io.Reader) (string, os.Error) {
	buf := make([]byte, chunkSize)
	gen.Write([]byte(*salt))
	for {
		bytesRead, err := f.Read(buf)
		if err != nil {
			if err == os.EOF && bytesRead == 0 { // Empty file
				gen.Write([]byte(""))
			} else {
				return "", err
			}
		} else {
			gen.Write(buf[:bytesRead])
		}
		if bytesRead < chunkSize { // EOF
			break
		}
	}
	return fmt.Sprintf("%x", gen.Sum()), nil
}

func Usage() {
	fmt.Println("Usage:", os.Args[0], "[-a <algorithm>] [-salt <salt>] [-s <string to hash>] / <file(s) to hash>\n")
	fmt.Println("Examples:")
	fmt.Println(" ", os.Args[0], `-a md5 document.txt               `, "Generate MD5 hash of a file")
	fmt.Println(" ", os.Args[0], `-a md5 *                          `, "Generate MD5 hash of all files in folder")
	fmt.Println(" ", os.Args[0], `-a sha1 -s hello world            `, "Generate SHA-1 hash of a string")
	fmt.Println(" ", os.Args[0], `-a sha1 -salt s4lt -s hello world `, "Generate salted SHA-1 hash of a string")
	fmt.Println("")
	fmt.Println("Available algorithms (default is MD5):")
	mk := make([]string, len(algDescs))
	i := 0
	for k, _ := range algDescs {
		mk[i] = k
		i++
	}
	sort.Strings(mk)
	for _, v := range mk {
		fmt.Printf("  %-15s %s\n", v, algDescs[v])
	}
	fmt.Println("")
	fmt.Println(`Note: For complex strings, put the string in a file, then run Picugen on
      the file. (Don't add newlines to the file as they will alter the output.)`)
}

func main() {
	flag.Parse()
	if flag.NArg() == 0 {
		Usage()
		return
	}
	*alg = strings.ToLower(*alg)
	gen, err := GetGenerator(*alg)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	if *hashStr {
		var s string
		for i, word := range flag.Args() {
			if i > 0 {
				s += " "
			}
			s += word
		}
		fmt.Println(HashString(gen, *salt+s))
	} else {
		for _, path := range flag.Args() {
			var res string
			f, err := os.Open(path)
			if err != nil {
				res = err.String()
			} else {
				h, err := HashFile(gen, f)
				if err != nil {
					res = err.String()
				} else {
					res = h
				}
			}
			fmt.Println(res, "", path)
			f.Close()
			gen.Reset()
		}
	}
}
<|endoftext|>


<commit_before>package elbv2

import (
	"context"
	awssdk "github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	elbv2sdk "github.com/aws/aws-sdk-go/service/elbv2"
	"github.com/pkg/errors"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/config"
	elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
	"time"
)

const (
	defaultWaitLSExistencePollInterval = 2 * time.Second
	defaultWaitLSExistenceTimeout      = 20 * time.Second
)

func buildSDKActions(modelActions []elbv2model.Action, featureGates config.FeatureGates) ([]*elbv2sdk.Action, error) {
	var sdkActions []*elbv2sdk.Action
	if len(modelActions) != 0 {
		sdkActions = make([]*elbv2sdk.Action, 0, len(modelActions))
		for index, modelAction := range modelActions {
			sdkAction, err := buildSDKAction(modelAction, featureGates)
			if err != nil {
				return nil, err
			}
			sdkAction.Order = awssdk.Int64(int64(index) + 1)
			sdkActions = append(sdkActions, sdkAction)
		}
	}
	return sdkActions, nil
}

func buildSDKAction(modelAction elbv2model.Action, featureGates config.FeatureGates) (*elbv2sdk.Action, error) {
	sdkObj := &elbv2sdk.Action{}
	sdkObj.Type = awssdk.String(string(modelAction.Type))
	if modelAction.AuthenticateCognitoConfig != nil {
		sdkObj.AuthenticateCognitoConfig = buildSDKAuthenticateCognitoActionConfig(*modelAction.AuthenticateCognitoConfig)
	}
	if modelAction.AuthenticateOIDCConfig != nil {
		sdkObj.AuthenticateOidcConfig = buildSDKAuthenticateOidcActionConfig(*modelAction.AuthenticateOIDCConfig)
	}
	if modelAction.FixedResponseConfig != nil {
		sdkObj.FixedResponseConfig = buildSDKFixedResponseActionConfig(*modelAction.FixedResponseConfig)
	}
	if modelAction.RedirectConfig != nil {
		sdkObj.RedirectConfig = buildSDKRedirectActionConfig(*modelAction.RedirectConfig)
	}
	if modelAction.ForwardConfig != nil {
		forwardConfig, err := buildSDKForwardActionConfig(*modelAction.ForwardConfig)
		if err != nil {
			return nil, err
		}
		if !featureGates.Enabled(config.WeightedTargetGroups) {
			if len(forwardConfig.TargetGroups) == 1 {
				sdkObj.TargetGroupArn = forwardConfig.TargetGroups[0].TargetGroupArn
			} else {
				return nil, errors.New("Weighted target groups feature is disabled.")
			}
		} else {
			sdkObj.ForwardConfig = forwardConfig
		}
	}
	return sdkObj, nil
}

func buildSDKAuthenticateCognitoActionConfig(modelCfg elbv2model.AuthenticateCognitoActionConfig) *elbv2sdk.AuthenticateCognitoActionConfig {
	return &elbv2sdk.AuthenticateCognitoActionConfig{
		AuthenticationRequestExtraParams: awssdk.StringMap(modelCfg.AuthenticationRequestExtraParams),
		OnUnauthenticatedRequest:         (*string)(modelCfg.OnUnauthenticatedRequest),
		Scope:                            modelCfg.Scope,
		SessionCookieName:                modelCfg.SessionCookieName,
		SessionTimeout:                   modelCfg.SessionTimeout,
		UserPoolArn:                      awssdk.String(modelCfg.UserPoolARN),
		UserPoolClientId:                 awssdk.String(modelCfg.UserPoolClientID),
		UserPoolDomain:                   awssdk.String(modelCfg.UserPoolDomain),
	}
}

func buildSDKAuthenticateOidcActionConfig(modelCfg elbv2model.AuthenticateOIDCActionConfig) *elbv2sdk.AuthenticateOidcActionConfig {
	return &elbv2sdk.AuthenticateOidcActionConfig{
		AuthenticationRequestExtraParams: awssdk.StringMap(modelCfg.AuthenticationRequestExtraParams),
		OnUnauthenticatedRequest:         (*string)(modelCfg.OnUnauthenticatedRequest),
		Scope:                            modelCfg.Scope,
		SessionCookieName:                modelCfg.SessionCookieName,
		SessionTimeout:                   modelCfg.SessionTimeout,
		ClientId:                         awssdk.String(modelCfg.ClientID),
		ClientSecret:                     awssdk.String(modelCfg.ClientSecret),
		Issuer:                           awssdk.String(modelCfg.Issuer),
		AuthorizationEndpoint:            awssdk.String(modelCfg.AuthorizationEndpoint),
		TokenEndpoint:                    awssdk.String(modelCfg.TokenEndpoint),
		UserInfoEndpoint:                 awssdk.String(modelCfg.UserInfoEndpoint),
	}
}

func buildSDKFixedResponseActionConfig(modelCfg elbv2model.FixedResponseActionConfig) *elbv2sdk.FixedResponseActionConfig {
	return &elbv2sdk.FixedResponseActionConfig{
		ContentType: modelCfg.ContentType,
		MessageBody: modelCfg.MessageBody,
		StatusCode:  awssdk.String(modelCfg.StatusCode),
	}
}

func buildSDKRedirectActionConfig(modelCfg elbv2model.RedirectActionConfig) *elbv2sdk.RedirectActionConfig {
	return &elbv2sdk.RedirectActionConfig{
		Host:       modelCfg.Host,
		Path:       modelCfg.Path,
		Port:       modelCfg.Port,
		Protocol:   modelCfg.Protocol,
		Query:      modelCfg.Query,
		StatusCode: awssdk.String(modelCfg.StatusCode),
	}
}

func buildSDKForwardActionConfig(modelCfg elbv2model.ForwardActionConfig) (*elbv2sdk.ForwardActionConfig, error) {
	ctx := context.Background()
	sdkObj := &elbv2sdk.ForwardActionConfig{}
	var tgTuples []*elbv2sdk.TargetGroupTuple
	for _, tgt := range modelCfg.TargetGroups {
		tgARN, err := tgt.TargetGroupARN.Resolve(ctx)
		if err != nil {
			return nil, err
		}
		tgTuples = append(tgTuples, &elbv2sdk.TargetGroupTuple{
			TargetGroupArn: awssdk.String(tgARN),
			Weight:         tgt.Weight,
		})
	}
	sdkObj.TargetGroups = tgTuples
	if modelCfg.TargetGroupStickinessConfig != nil {
		sdkObj.TargetGroupStickinessConfig = &elbv2sdk.TargetGroupStickinessConfig{
			DurationSeconds: modelCfg.TargetGroupStickinessConfig.DurationSeconds,
			Enabled:         modelCfg.TargetGroupStickinessConfig.Enabled,
		}
	}

	return sdkObj, nil
}

func buildSDKRuleConditions(modelConditions []elbv2model.RuleCondition) []*elbv2sdk.RuleCondition {
	var sdkConditions []*elbv2sdk.RuleCondition
	if len(modelConditions) != 0 {
		sdkConditions = make([]*elbv2sdk.RuleCondition, 0, len(modelConditions))
		for _, modelCondition := range modelConditions {
			sdkCondition := buildSDKRuleCondition(modelCondition)
			sdkConditions = append(sdkConditions, sdkCondition)
		}
	}
	return sdkConditions
}

func buildSDKRuleCondition(modelCondition elbv2model.RuleCondition) *elbv2sdk.RuleCondition {
	sdkObj := &elbv2sdk.RuleCondition{}
	sdkObj.Field = awssdk.String(string(modelCondition.Field))
	if modelCondition.HostHeaderConfig != nil {
		sdkObj.HostHeaderConfig = buildSDKHostHeaderConditionConfig(*modelCondition.HostHeaderConfig)
	}
	if modelCondition.HTTPHeaderConfig != nil {
		sdkObj.HttpHeaderConfig = buildSDKHTTPHeaderConditionConfig(*modelCondition.HTTPHeaderConfig)
	}
	if modelCondition.HTTPRequestMethodConfig != nil {
		sdkObj.HttpRequestMethodConfig = buildSDKHTTPRequestMethodConditionConfig(*modelCondition.HTTPRequestMethodConfig)
	}
	if modelCondition.PathPatternConfig != nil {
		sdkObj.PathPatternConfig = buildSDKPathPatternConditionConfig(*modelCondition.PathPatternConfig)
	}
	if modelCondition.QueryStringConfig != nil {
		sdkObj.QueryStringConfig = buildSDKQueryStringConditionConfig(*modelCondition.QueryStringConfig)
	}
	if modelCondition.SourceIPConfig != nil {
		sdkObj.SourceIpConfig = buildSDKSourceIpConditionConfig(*modelCondition.SourceIPConfig)
	}
	return sdkObj
}

func buildSDKHostHeaderConditionConfig(modelCfg elbv2model.HostHeaderConditionConfig) *elbv2sdk.HostHeaderConditionConfig {
	return &elbv2sdk.HostHeaderConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKHTTPHeaderConditionConfig(modelCfg elbv2model.HTTPHeaderConditionConfig) *elbv2sdk.HttpHeaderConditionConfig {
	return &elbv2sdk.HttpHeaderConditionConfig{
		HttpHeaderName: awssdk.String(modelCfg.HTTPHeaderName),
		Values:         awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKHTTPRequestMethodConditionConfig(modelCfg elbv2model.HTTPRequestMethodConditionConfig) *elbv2sdk.HttpRequestMethodConditionConfig {
	return &elbv2sdk.HttpRequestMethodConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKPathPatternConditionConfig(modelCfg elbv2model.PathPatternConditionConfig) *elbv2sdk.PathPatternConditionConfig {
	return &elbv2sdk.PathPatternConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKQueryStringConditionConfig(modelCfg elbv2model.QueryStringConditionConfig) *elbv2sdk.QueryStringConditionConfig {
	kvPairs := make([]*elbv2sdk.QueryStringKeyValuePair, 0, len(modelCfg.Values))
	for _, value := range modelCfg.Values {
		kvPairs = append(kvPairs, &elbv2sdk.QueryStringKeyValuePair{
			Key:   value.Key,
			Value: awssdk.String(value.Value),
		})
	}
	return &elbv2sdk.QueryStringConditionConfig{
		Values: kvPairs,
	}
}

func buildSDKSourceIpConditionConfig(modelCfg elbv2model.SourceIPConditionConfig) *elbv2sdk.SourceIpConditionConfig {
	return &elbv2sdk.SourceIpConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func isListenerNotFoundError(err error) bool {
	var awsErr awserr.Error
	if errors.As(err, &awsErr) {
		return awsErr.Code() == "ListenerNotFound"
	}
	return false
}
<commit_msg>fix error string<commit_after>package elbv2

import (
	"context"
	awssdk "github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	elbv2sdk "github.com/aws/aws-sdk-go/service/elbv2"
	"github.com/pkg/errors"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/config"
	elbv2model "sigs.k8s.io/aws-load-balancer-controller/pkg/model/elbv2"
	"time"
)

const (
	defaultWaitLSExistencePollInterval = 2 * time.Second
	defaultWaitLSExistenceTimeout      = 20 * time.Second
)

func buildSDKActions(modelActions []elbv2model.Action, featureGates config.FeatureGates) ([]*elbv2sdk.Action, error) {
	var sdkActions []*elbv2sdk.Action
	if len(modelActions) != 0 {
		sdkActions = make([]*elbv2sdk.Action, 0, len(modelActions))
		for index, modelAction := range modelActions {
			sdkAction, err := buildSDKAction(modelAction, featureGates)
			if err != nil {
				return nil, err
			}
			sdkAction.Order = awssdk.Int64(int64(index) + 1)
			sdkActions = append(sdkActions, sdkAction)
		}
	}
	return sdkActions, nil
}

func buildSDKAction(modelAction elbv2model.Action, featureGates config.FeatureGates) (*elbv2sdk.Action, error) {
	sdkObj := &elbv2sdk.Action{}
	sdkObj.Type = awssdk.String(string(modelAction.Type))
	if modelAction.AuthenticateCognitoConfig != nil {
		sdkObj.AuthenticateCognitoConfig = buildSDKAuthenticateCognitoActionConfig(*modelAction.AuthenticateCognitoConfig)
	}
	if modelAction.AuthenticateOIDCConfig != nil {
		sdkObj.AuthenticateOidcConfig = buildSDKAuthenticateOidcActionConfig(*modelAction.AuthenticateOIDCConfig)
	}
	if modelAction.FixedResponseConfig != nil {
		sdkObj.FixedResponseConfig = buildSDKFixedResponseActionConfig(*modelAction.FixedResponseConfig)
	}
	if modelAction.RedirectConfig != nil {
		sdkObj.RedirectConfig = buildSDKRedirectActionConfig(*modelAction.RedirectConfig)
	}
	if modelAction.ForwardConfig != nil {
		forwardConfig, err := buildSDKForwardActionConfig(*modelAction.ForwardConfig)
		if err != nil {
			return nil, err
		}
		if !featureGates.Enabled(config.WeightedTargetGroups) {
			if len(forwardConfig.TargetGroups) == 1 {
				sdkObj.TargetGroupArn = forwardConfig.TargetGroups[0].TargetGroupArn
			} else {
				return nil, errors.New("weighted target groups feature is disabled")
			}
		} else {
			sdkObj.ForwardConfig = forwardConfig
		}
	}
	return sdkObj, nil
}

func buildSDKAuthenticateCognitoActionConfig(modelCfg elbv2model.AuthenticateCognitoActionConfig) *elbv2sdk.AuthenticateCognitoActionConfig {
	return &elbv2sdk.AuthenticateCognitoActionConfig{
		AuthenticationRequestExtraParams: awssdk.StringMap(modelCfg.AuthenticationRequestExtraParams),
		OnUnauthenticatedRequest:         (*string)(modelCfg.OnUnauthenticatedRequest),
		Scope:                            modelCfg.Scope,
		SessionCookieName:                modelCfg.SessionCookieName,
		SessionTimeout:                   modelCfg.SessionTimeout,
		UserPoolArn:                      awssdk.String(modelCfg.UserPoolARN),
		UserPoolClientId:                 awssdk.String(modelCfg.UserPoolClientID),
		UserPoolDomain:                   awssdk.String(modelCfg.UserPoolDomain),
	}
}

func buildSDKAuthenticateOidcActionConfig(modelCfg elbv2model.AuthenticateOIDCActionConfig) *elbv2sdk.AuthenticateOidcActionConfig {
	return &elbv2sdk.AuthenticateOidcActionConfig{
		AuthenticationRequestExtraParams: awssdk.StringMap(modelCfg.AuthenticationRequestExtraParams),
		OnUnauthenticatedRequest:         (*string)(modelCfg.OnUnauthenticatedRequest),
		Scope:                            modelCfg.Scope,
		SessionCookieName:                modelCfg.SessionCookieName,
		SessionTimeout:                   modelCfg.SessionTimeout,
		ClientId:                         awssdk.String(modelCfg.ClientID),
		ClientSecret:                     awssdk.String(modelCfg.ClientSecret),
		Issuer:                           awssdk.String(modelCfg.Issuer),
		AuthorizationEndpoint:            awssdk.String(modelCfg.AuthorizationEndpoint),
		TokenEndpoint:                    awssdk.String(modelCfg.TokenEndpoint),
		UserInfoEndpoint:                 awssdk.String(modelCfg.UserInfoEndpoint),
	}
}

func buildSDKFixedResponseActionConfig(modelCfg elbv2model.FixedResponseActionConfig) *elbv2sdk.FixedResponseActionConfig {
	return &elbv2sdk.FixedResponseActionConfig{
		ContentType: modelCfg.ContentType,
		MessageBody: modelCfg.MessageBody,
		StatusCode:  awssdk.String(modelCfg.StatusCode),
	}
}

func buildSDKRedirectActionConfig(modelCfg elbv2model.RedirectActionConfig) *elbv2sdk.RedirectActionConfig {
	return &elbv2sdk.RedirectActionConfig{
		Host:       modelCfg.Host,
		Path:       modelCfg.Path,
		Port:       modelCfg.Port,
		Protocol:   modelCfg.Protocol,
		Query:      modelCfg.Query,
		StatusCode: awssdk.String(modelCfg.StatusCode),
	}
}

func buildSDKForwardActionConfig(modelCfg elbv2model.ForwardActionConfig) (*elbv2sdk.ForwardActionConfig, error) {
	ctx := context.Background()
	sdkObj := &elbv2sdk.ForwardActionConfig{}
	var tgTuples []*elbv2sdk.TargetGroupTuple
	for _, tgt := range modelCfg.TargetGroups {
		tgARN, err := tgt.TargetGroupARN.Resolve(ctx)
		if err != nil {
			return nil, err
		}
		tgTuples = append(tgTuples, &elbv2sdk.TargetGroupTuple{
			TargetGroupArn: awssdk.String(tgARN),
			Weight:         tgt.Weight,
		})
	}
	sdkObj.TargetGroups = tgTuples
	if modelCfg.TargetGroupStickinessConfig != nil {
		sdkObj.TargetGroupStickinessConfig = &elbv2sdk.TargetGroupStickinessConfig{
			DurationSeconds: modelCfg.TargetGroupStickinessConfig.DurationSeconds,
			Enabled:         modelCfg.TargetGroupStickinessConfig.Enabled,
		}
	}

	return sdkObj, nil
}

func buildSDKRuleConditions(modelConditions []elbv2model.RuleCondition) []*elbv2sdk.RuleCondition {
	var sdkConditions []*elbv2sdk.RuleCondition
	if len(modelConditions) != 0 {
		sdkConditions = make([]*elbv2sdk.RuleCondition, 0, len(modelConditions))
		for _, modelCondition := range modelConditions {
			sdkCondition := buildSDKRuleCondition(modelCondition)
			sdkConditions = append(sdkConditions, sdkCondition)
		}
	}
	return sdkConditions
}

func buildSDKRuleCondition(modelCondition elbv2model.RuleCondition) *elbv2sdk.RuleCondition {
	sdkObj := &elbv2sdk.RuleCondition{}
	sdkObj.Field = awssdk.String(string(modelCondition.Field))
	if modelCondition.HostHeaderConfig != nil {
		sdkObj.HostHeaderConfig = buildSDKHostHeaderConditionConfig(*modelCondition.HostHeaderConfig)
	}
	if modelCondition.HTTPHeaderConfig != nil {
		sdkObj.HttpHeaderConfig = buildSDKHTTPHeaderConditionConfig(*modelCondition.HTTPHeaderConfig)
	}
	if modelCondition.HTTPRequestMethodConfig != nil {
		sdkObj.HttpRequestMethodConfig = buildSDKHTTPRequestMethodConditionConfig(*modelCondition.HTTPRequestMethodConfig)
	}
	if modelCondition.PathPatternConfig != nil {
		sdkObj.PathPatternConfig = buildSDKPathPatternConditionConfig(*modelCondition.PathPatternConfig)
	}
	if modelCondition.QueryStringConfig != nil {
		sdkObj.QueryStringConfig = buildSDKQueryStringConditionConfig(*modelCondition.QueryStringConfig)
	}
	if modelCondition.SourceIPConfig != nil {
		sdkObj.SourceIpConfig = buildSDKSourceIpConditionConfig(*modelCondition.SourceIPConfig)
	}
	return sdkObj
}

func buildSDKHostHeaderConditionConfig(modelCfg elbv2model.HostHeaderConditionConfig) *elbv2sdk.HostHeaderConditionConfig {
	return &elbv2sdk.HostHeaderConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKHTTPHeaderConditionConfig(modelCfg elbv2model.HTTPHeaderConditionConfig) *elbv2sdk.HttpHeaderConditionConfig {
	return &elbv2sdk.HttpHeaderConditionConfig{
		HttpHeaderName: awssdk.String(modelCfg.HTTPHeaderName),
		Values:         awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKHTTPRequestMethodConditionConfig(modelCfg elbv2model.HTTPRequestMethodConditionConfig) *elbv2sdk.HttpRequestMethodConditionConfig {
	return &elbv2sdk.HttpRequestMethodConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKPathPatternConditionConfig(modelCfg elbv2model.PathPatternConditionConfig) *elbv2sdk.PathPatternConditionConfig {
	return &elbv2sdk.PathPatternConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func buildSDKQueryStringConditionConfig(modelCfg elbv2model.QueryStringConditionConfig) *elbv2sdk.QueryStringConditionConfig {
	kvPairs := make([]*elbv2sdk.QueryStringKeyValuePair, 0, len(modelCfg.Values))
	for _, value := range modelCfg.Values {
		kvPairs = append(kvPairs, &elbv2sdk.QueryStringKeyValuePair{
			Key:   value.Key,
			Value: awssdk.String(value.Value),
		})
	}
	return &elbv2sdk.QueryStringConditionConfig{
		Values: kvPairs,
	}
}

func buildSDKSourceIpConditionConfig(modelCfg elbv2model.SourceIPConditionConfig) *elbv2sdk.SourceIpConditionConfig {
	return &elbv2sdk.SourceIpConditionConfig{
		Values: awssdk.StringSlice(modelCfg.Values),
	}
}

func isListenerNotFoundError(err error) bool {
	var awsErr awserr.Error
	if errors.As(err, &awsErr) {
		return awsErr.Code() == "ListenerNotFound"
	}
	return false
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package charm

import (
	"net/url"
	"os"
	"path"

	"github.com/juju/errors"
	"github.com/juju/utils"
	"gopkg.in/juju/charm.v6-unstable"

	"github.com/juju/juju/downloader"
)

// Download exposes the downloader.Download methods needed here.
type Download interface {
	// Wait blocks until the download completes or the abort channel
	// receives.
	Wait(abort <-chan struct{}) (downloader.Status, error)
}

// BundlesDir is responsible for storing and retrieving charm bundles
// identified by state charms.
type BundlesDir struct {
	path          string
	startDownload func(downloader.Request) (Download, error)
}

// NewBundlesDir returns a new BundlesDir which uses path for storage.
func NewBundlesDir(path string, startDownload func(downloader.Request) (Download, error)) *BundlesDir {
	if startDownload == nil {
		startDownload = func(req downloader.Request) (Download, error) {
			opener := downloader.NewHTTPBlobOpener(utils.NoVerifySSLHostnames)
			dl := downloader.StartDownload(req, opener)
			return dl, nil
		}
	}

	return &BundlesDir{
		path:          path,
		startDownload: startDownload,
	}
}

// Read returns a charm bundle from the directory. If no bundle exists yet,
// one will be downloaded and validated and copied into the directory before
// being returned. Downloads will be aborted if a value is received on abort.
func (d *BundlesDir) Read(info BundleInfo, abort <-chan struct{}) (Bundle, error) {
	path := d.bundlePath(info)
	if _, err := os.Stat(path); err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}
		if err := d.download(info, path, abort); err != nil {
			return nil, err
		}
	}
	return charm.ReadCharmArchive(path)
}

// download fetches the supplied charm and checks that it has the correct sha256
// hash, then copies it into the directory. If a value is received on abort, the
// download will be stopped.
func (d *BundlesDir) download(info BundleInfo, target string, abort <-chan struct{}) (err error) {
	archiveURLs, err := info.ArchiveURLs()
	if err != nil {
		return errors.Annotatef(err, "failed to get download URLs for charm %q", info.URL())
	}

	dir := d.downloadsPath()
	filename, err := download(info, archiveURLs, dir, d.startDownload, abort)
	if err != nil {
		return errors.Annotatef(err, "failed to download charm %q from %q", info.URL(), archiveURLs)
	}
	defer errors.DeferredAnnotatef(&err, "downloaded but failed to copy charm to %q from %q", target, filename)

	if err := os.MkdirAll(d.path, 0755); err != nil {
		return errors.Trace(err)
	}
	// We must make sure that the file is closed by this point since
	// renaming an open file is not possible on Windows
	if err := os.Rename(filename, target); err != nil {
		return errors.Trace(err)
	}
	return nil
}

func download(info BundleInfo, archiveURLs []*url.URL, targetDir string, startDownload func(downloader.Request) (Download, error), abort <-chan struct{}) (filename string, err error) {
	if err := os.MkdirAll(targetDir, 0755); err != nil {
		return "", errors.Trace(err)
	}

	var status downloader.Status
	for _, archiveURL := range archiveURLs {
		logger.Infof("downloading %s from %s", info.URL(), archiveURL)
		dl, err2 := startDownload(downloader.Request{
			URL:       archiveURL,
			TargetDir: targetDir,
		})
		if err2 != nil {
			return "", errors.Trace(err2)
		}
		status, err = dl.Wait(abort)
		if err == nil {
			defer status.File.Close()
			break
		}
		logger.Errorf("download request to %s failed: %v", archiveURL, err)
	}
	if err != nil {
		return "", errors.Trace(err)
	}
	logger.Infof("download complete")

	actualSha256, _, err := utils.ReadSHA256(status.File)
	if err != nil {
		return "", errors.Trace(err)
	}
	archiveSha256, err := info.ArchiveSha256()
	if err != nil {
		return "", errors.Trace(err)
	}
	if actualSha256 != archiveSha256 {
		return "", errors.Errorf(
			"expected sha256 %q, got %q", archiveSha256, actualSha256,
		)
	}
	logger.Infof("download verified")

	return status.File.Name(), nil
}

// bundlePath returns the path to the location where the verified charm
// bundle identified by info will be, or has been, saved.
func (d *BundlesDir) bundlePath(info BundleInfo) string {
	return d.bundleURLPath(info.URL())
}

// bundleURLPath returns the path to the location where the verified charm
// bundle identified by url will be, or has been, saved.
func (d *BundlesDir) bundleURLPath(url *charm.URL) string {
	return path.Join(d.path, charm.Quote(url.String()))
}

// downloadsPath returns the path to the directory into which charms are
// downloaded.
func (d *BundlesDir) downloadsPath() string {
	return path.Join(d.path, "downloads")
}
<commit_msg>Always close the file if there is one.<commit_after>// Copyright 2012-2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package charm

import (
	"net/url"
	"os"
	"path"

	"github.com/juju/errors"
	"github.com/juju/utils"
	"gopkg.in/juju/charm.v6-unstable"

	"github.com/juju/juju/downloader"
)

// Download exposes the downloader.Download methods needed here.
type Download interface {
	// Wait blocks until the download completes or the abort channel
	// receives.
	Wait(abort <-chan struct{}) (downloader.Status, error)
}

// BundlesDir is responsible for storing and retrieving charm bundles
// identified by state charms.
type BundlesDir struct {
	path          string
	startDownload func(downloader.Request) (Download, error)
}

// NewBundlesDir returns a new BundlesDir which uses path for storage.
func NewBundlesDir(path string, startDownload func(downloader.Request) (Download, error)) *BundlesDir {
	if startDownload == nil {
		startDownload = func(req downloader.Request) (Download, error) {
			opener := downloader.NewHTTPBlobOpener(utils.NoVerifySSLHostnames)
			dl := downloader.StartDownload(req, opener)
			return dl, nil
		}
	}

	return &BundlesDir{
		path:          path,
		startDownload: startDownload,
	}
}

// Read returns a charm bundle from the directory. If no bundle exists yet,
// one will be downloaded and validated and copied into the directory before
// being returned. Downloads will be aborted if a value is received on abort.
func (d *BundlesDir) Read(info BundleInfo, abort <-chan struct{}) (Bundle, error) {
	path := d.bundlePath(info)
	if _, err := os.Stat(path); err != nil {
		if !os.IsNotExist(err) {
			return nil, err
		}
		if err := d.download(info, path, abort); err != nil {
			return nil, err
		}
	}
	return charm.ReadCharmArchive(path)
}

// download fetches the supplied charm and checks that it has the correct sha256
// hash, then copies it into the directory. If a value is received on abort, the
// download will be stopped.
func (d *BundlesDir) download(info BundleInfo, target string, abort <-chan struct{}) (err error) {
	archiveURLs, err := info.ArchiveURLs()
	if err != nil {
		return errors.Annotatef(err, "failed to get download URLs for charm %q", info.URL())
	}

	dir := d.downloadsPath()
	filename, err := download(info, archiveURLs, dir, d.startDownload, abort)
	if err != nil {
		return errors.Annotatef(err, "failed to download charm %q from %q", info.URL(), archiveURLs)
	}
	defer errors.DeferredAnnotatef(&err, "downloaded but failed to copy charm to %q from %q", target, filename)

	if err := os.MkdirAll(d.path, 0755); err != nil {
		return errors.Trace(err)
	}
	// We must make sure that the file is closed by this point since
	// renaming an open file is not possible on Windows
	if err := os.Rename(filename, target); err != nil {
		return errors.Trace(err)
	}
	return nil
}

func download(info BundleInfo, archiveURLs []*url.URL, targetDir string, startDownload func(downloader.Request) (Download, error), abort <-chan struct{}) (filename string, err error) {
	if err := os.MkdirAll(targetDir, 0755); err != nil {
		return "", errors.Trace(err)
	}

	var status downloader.Status
	for _, archiveURL := range archiveURLs {
		logger.Infof("downloading %s from %s", info.URL(), archiveURL)
		dl, err2 := startDownload(downloader.Request{
			URL:       archiveURL,
			TargetDir: targetDir,
		})
		if err2 != nil {
			return "", errors.Trace(err2)
		}
		status, err = dl.Wait(abort)
		if status.File != nil {
			defer status.File.Close()
		}
		if err == nil {
			break
		}
		logger.Errorf("download request to %s failed: %v", archiveURL, err)
	}
	if err != nil {
		return "", errors.Trace(err)
	}
	logger.Infof("download complete")

	actualSha256, _, err := utils.ReadSHA256(status.File)
	if err != nil {
		return "", errors.Trace(err)
	}
	archiveSha256, err := info.ArchiveSha256()
	if err != nil {
		return "", errors.Trace(err)
	}
	if actualSha256 != archiveSha256 {
		return "", errors.Errorf(
			"expected sha256 %q, got %q", archiveSha256, actualSha256,
		)
	}
	logger.Infof("download verified")

	return status.File.Name(), nil
}

// bundlePath returns the path to the location where the verified charm
// bundle identified by info will be, or has been, saved.
func (d *BundlesDir) bundlePath(info BundleInfo) string {
	return d.bundleURLPath(info.URL())
}

// bundleURLPath returns the path to the location where the verified charm
// bundle identified by url will be, or has been, saved.
func (d *BundlesDir) bundleURLPath(url *charm.URL) string {
	return path.Join(d.path, charm.Quote(url.String()))
}

// downloadsPath returns the path to the directory into which charms are
// downloaded.
func (d *BundlesDir) downloadsPath() string {
	return path.Join(d.path, "downloads")
}
<|endoftext|>


<commit_before>// Copyright 2020 The Inet.Af 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 netaddr

import "math/bits"

// uint128 represents a uint128 using two uint64s.
//
// When the methods below mention a bit number, bit 0 is the most
// significant bit (in hi) and bit 127 is the lowest (lo&1).
type uint128 struct {
	hi uint64
	lo uint64
}

// isZero reports whether u == 0.
//
// It's faster than u == (uint128{}) because the compiler (as of Go
// 1.15/1.16b1) doesn't do this trick and instead inserts a branch in
// its eq alg's generated code.
func (u uint128) isZero() bool { return u.hi|u.lo == 0 }

// and returns the bitwise AND of u and m (u&m).
func (u uint128) and(m uint128) uint128 {
	return uint128{u.hi & m.hi, u.lo & m.lo}
}

// xor returns the bitwise XOR of u and m (u^m).
func (u uint128) xor(m uint128) uint128 {
	return uint128{u.hi ^ m.hi, u.lo ^ m.lo}
}

// or returns the bitwise OR of u and m (u|m).
func (u uint128) or(m uint128) uint128 {
	return uint128{u.hi | m.hi, u.lo | m.lo}
}

// not returns the bitwise NOT of u.
func (u uint128) not() uint128 {
	return uint128{^u.hi, ^u.lo}
}

// subOne returns u - 1.
func (u uint128) subOne() uint128 {
	lo, borrow := bits.Sub64(u.lo, 1, 0)
	return uint128{u.hi - borrow, lo}
}

// addOne returns u + 1.
func (u uint128) addOne() uint128 {
	lo, carry := bits.Add64(u.lo, 1, 0)
	return uint128{u.hi + carry, lo}
}

func u64CommonPrefixLen(a, b uint64) uint8 {
	return uint8(bits.LeadingZeros64(a ^ b))
}

func (a uint128) commonPrefixLen(b uint128) (n uint8) {
	if n = u64CommonPrefixLen(a.hi, b.hi); n == 64 {
		n += u64CommonPrefixLen(a.lo, b.lo)
	}
	return
}

func (u *uint128) halves() [2]*uint64 {
	return [2]*uint64{&u.hi, &u.lo}
}

// bitsSetFrom returns a copy of u with the given bit
// and all subsequent ones set.
func (u uint128) bitsSetFrom(bit uint8) uint128 {
	return u.or(mask6[bit].not())
}

// bitsClearedFrom returns a copy of u with the given bit
// and all subsequent ones cleared.
func (u uint128) bitsClearedFrom(bit uint8) uint128 {
	return u.and(mask6[bit])
}
<commit_msg>netaddr: change uint128.commonPrefixLen receiver name for consistency (#121)<commit_after>// Copyright 2020 The Inet.Af 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 netaddr

import "math/bits"

// uint128 represents a uint128 using two uint64s.
//
// When the methods below mention a bit number, bit 0 is the most
// significant bit (in hi) and bit 127 is the lowest (lo&1).
type uint128 struct {
	hi uint64
	lo uint64
}

// isZero reports whether u == 0.
//
// It's faster than u == (uint128{}) because the compiler (as of Go
// 1.15/1.16b1) doesn't do this trick and instead inserts a branch in
// its eq alg's generated code.
func (u uint128) isZero() bool { return u.hi|u.lo == 0 }

// and returns the bitwise AND of u and m (u&m).
func (u uint128) and(m uint128) uint128 {
	return uint128{u.hi & m.hi, u.lo & m.lo}
}

// xor returns the bitwise XOR of u and m (u^m).
func (u uint128) xor(m uint128) uint128 {
	return uint128{u.hi ^ m.hi, u.lo ^ m.lo}
}

// or returns the bitwise OR of u and m (u|m).
func (u uint128) or(m uint128) uint128 {
	return uint128{u.hi | m.hi, u.lo | m.lo}
}

// not returns the bitwise NOT of u.
func (u uint128) not() uint128 {
	return uint128{^u.hi, ^u.lo}
}

// subOne returns u - 1.
func (u uint128) subOne() uint128 {
	lo, borrow := bits.Sub64(u.lo, 1, 0)
	return uint128{u.hi - borrow, lo}
}

// addOne returns u + 1.
func (u uint128) addOne() uint128 {
	lo, carry := bits.Add64(u.lo, 1, 0)
	return uint128{u.hi + carry, lo}
}

func u64CommonPrefixLen(a, b uint64) uint8 {
	return uint8(bits.LeadingZeros64(a ^ b))
}

func (u uint128) commonPrefixLen(v uint128) (n uint8) {
	if n = u64CommonPrefixLen(u.hi, v.hi); n == 64 {
		n += u64CommonPrefixLen(u.lo, v.lo)
	}
	return
}

func (u *uint128) halves() [2]*uint64 {
	return [2]*uint64{&u.hi, &u.lo}
}

// bitsSetFrom returns a copy of u with the given bit
// and all subsequent ones set.
func (u uint128) bitsSetFrom(bit uint8) uint128 {
	return u.or(mask6[bit].not())
}

// bitsClearedFrom returns a copy of u with the given bit
// and all subsequent ones cleared.
func (u uint128) bitsClearedFrom(bit uint8) uint128 {
	return u.and(mask6[bit])
}
<|endoftext|>


<commit_before>// Package goxlsx accesses Excel 2007 (.xslx) for reading.
package goxlsx

import (
	"archive/zip"
	"bytes"
	"encoding/xml"
	"errors"
	"fmt"
	"io"
	"strconv"
	"strings"
)

// NumWorksheets returns the number of worksheets in a file.
func (s *Spreadsheet) NumWorksheets() int {
	return len(s.worksheets)
}

func readWorkbook(data []byte, s *Spreadsheet) ([]*Worksheet, error) {
	wb := &workbook{}
	err := xml.Unmarshal(data, wb)
	if err != nil {
		return nil, err
	}

	var worksheets []*Worksheet

	for i := 0; i < len(wb.Sheets); i++ {
		w := &Worksheet{}
		w.spreadsheet = s
		w.Name = wb.Sheets[i].Name
		w.id = wb.Sheets[i].SheetID
		w.rid = wb.Sheets[i].Rid
		worksheets = append(worksheets, w)
	}
	return worksheets, nil
}

func readStrings(data []byte) ([]string, error) {
	var (
		err           error
		token         xml.Token
		sharedStrings []string
		buf           []byte
	)

	d := xml.NewDecoder(bytes.NewReader(data))
	for {
		token, err = d.Token()
		if err != nil {
			if err != io.EOF {
				return nil, err
			}
			break
		}
		switch x := token.(type) {
		case xml.StartElement:
			switch x.Name.Local {
			case "sst":
				// root element
				for i := 0; i < len(x.Attr); i++ {
					if x.Attr[i].Name.Local == "uniqueCount" {
						count, err := strconv.Atoi(x.Attr[i].Value)
						if err != nil {
							return nil, err
						}
						sharedStrings = make([]string, 0, count)
					}
				}
			}
		case xml.CharData:
			buf = x.Copy()
		case xml.EndElement:
			switch x.Name.Local {
			case "t":
				sharedStrings = append(sharedStrings, string(buf))
			}
		}

	}
	return sharedStrings, nil
}

// OpenFile reads a file located at the given path and returns a spreadsheet object.
func OpenFile(path string) (*Spreadsheet, error) {
	xlsx := new(Spreadsheet)
	xlsx.filepath = path
	xlsx.uncompressedFiles = make(map[string][]byte)
	xlsx.sharedCells = make(map[string]*cell)

	r, err := zip.OpenReader(path)
	if err != nil {
		return nil, err
	}
	defer r.Close()

	for _, f := range r.File {
		buf := make([]byte, f.UncompressedSize64)
		rc, err := f.Open()
		if err != nil {
			return nil, err
		}
		size, err := io.ReadFull(rc, buf)
		if err != nil {
			return nil, err
		}
		if size != int(f.UncompressedSize64) {
			return nil, fmt.Errorf("read (%d) not equal to uncompressed size (%d)", size, f.UncompressedSize64)
		}

		xlsx.uncompressedFiles[f.Name] = buf
	}
	xlsx.relationships, err = readRelationships(xlsx.uncompressedFiles["xl/_rels/workbook.xml.rels"])
	if err != nil {
		return nil, err
	}
	xlsx.worksheets, err = readWorkbook(xlsx.uncompressedFiles["xl/workbook.xml"], xlsx)
	if err != nil {
		return nil, err
	}
	xlsx.sharedStrings, err = readStrings(xlsx.uncompressedFiles["xl/sharedStrings.xml"])
	if err != nil {
		return nil, err
	}
	xlsx.uncompressedFiles["xl/sharedStrings.xml"] = nil

	return xlsx, nil
}

func readRelationships(data []byte) (map[string]relationship, error) {
	rels := &xslxRelationships{}
	err := xml.Unmarshal(data, rels)
	if err != nil {
		return nil, err
	}
	ret := make(map[string]relationship)
	for _, v := range rels.Relationship {
		ret[v.Id] = relationship{Type: v.Type, Target: v.Target}
	}
	return ret, nil
}

// excelpos is something like "AC101"
func stringToPosition(excelpos string) (int, int) {
	var columnnumber, rownumber rune
	for _, v := range excelpos {
		if v >= 'A' && v <= 'Z' {
			columnnumber = columnnumber*26 + v - 'A' + 1
		}
		if v >= '0' && v <= '9' {
			rownumber = rownumber*10 + v - '0'
		}
	}
	return int(columnnumber), int(rownumber)
}

// Cell returns the contents of cell at column, row, where 1,1 is the top left corner. The return value is always a string.
// The user is in charge to convert this value to a number, if necessary. Formulae are not returned.
func (ws *Worksheet) Cell(column, row int) string {
	xrow := ws.rows[row]
	if xrow == nil {
		return ""
	}
	if xrow.Cells[column] == nil {
		return ""
	}
	val := xrow.Cells[column].Value
	return strings.Replace(val, "_x000D_", "", -1)
}

// Cell returns the contents of cell at column, row, where 1,1 is the top left corner.
// The return value is always a float64 and an error code != nil if the cell contents can't be
// decoded as a float.
func (ws *Worksheet) Cellf(column, row int) (float64, error) {
	var tmpstr string
	xrow := ws.rows[row]
	if xrow == nil {
		return 0, errors.New("Not a float")
	}
	if xrow.Cells[column] == nil {
		return 0, errors.New("Not a float")
	}
	tmpstr = xrow.Cells[column].Value
	flt, err := strconv.ParseFloat(tmpstr, 64)
	return flt, err
}

func (s *Spreadsheet) readWorksheet(data []byte) (*Worksheet, error) {
	r := bytes.NewReader(data)
	dec := xml.NewDecoder(r)
	ws := &Worksheet{}
	rows := make(map[int]*row)

	const (
		CTSharedString = iota
		CTNumber
		CTOther
	)

	var (
		err        error
		token      xml.Token
		rownum     int
		currentRow *row
		celltype   int
		incell     bool
		cellnumber rune
	)
	for {
		token, err = dec.Token()
		if err != nil {
			if err != io.EOF {
				return nil, err
			}
			break
		}
		switch x := token.(type) {
		case xml.StartElement:
			switch x.Name.Local {
			case "dimension":
				for _, a := range x.Attr {
					if a.Name.Local == "ref" {
						// example: ref="A1:AC101"
						tmp := strings.Split(a.Value, ":")
						ws.MinColumn, ws.MinRow = stringToPosition(tmp[0])
						ws.MaxColumn, ws.MaxRow = stringToPosition(tmp[1])
					}
				}
			case "row":
				currentRow = &row{}
				currentRow.Cells = make(map[int]*cell)
				for _, a := range x.Attr {
					if a.Name.Local == "r" {
						rownum, err = strconv.Atoi(a.Value)
						if err != nil {
							return nil, err
						}
					}
				}
				currentRow.Num = rownum
				rows[rownum] = currentRow
			case "v":
				incell = true
			case "c":
				celltype = CTOther
				cellnumber = 0
				for _, a := range x.Attr {
					switch a.Name.Local {
					case "r":
						for _, v := range a.Value {
							if v >= 'A' && v <= 'Z' {
								cellnumber = cellnumber*26 + v - 'A' + 1
							}
						}
					case "t":
						if a.Value == "s" {
							celltype = CTSharedString
						} else if a.Value == "n" {
							celltype = CTNumber
						}
					}

				}
			}
		case xml.EndElement:
			switch x.Name.Local {
			case "v":
				incell = false
			}
		case xml.CharData:
			if incell {
				var currentCell *cell

				if celltype == CTSharedString {
					currentCell = s.getSharedCell(string(x))
				} else {
					currentCell = &cell{}
					currentCell.Value = string(x)
				}
				currentRow.Cells[int(cellnumber)] = currentCell
			}
		}
	}
	ws.rows = rows
	return ws, nil
}

func (s *Spreadsheet) getSharedCell(idx string) *cell {
	if c, ok := s.sharedCells[idx]; ok {
		return c
	}

	valInt, _ := strconv.Atoi(idx)

	c := &cell{}
	c.Value = s.sharedStrings[valInt]
	s.sharedCells[idx] = c
	return c
}

// GetWorksheet returns the worksheet with the given number, starting at 0.
func (s *Spreadsheet) GetWorksheet(number int) (*Worksheet, error) {
	if number >= len(s.worksheets) || number < 0 {
		return nil, errors.New("index out of range")
	}
	rid := s.worksheets[number].rid
	filename := "xl/" + s.relationships[rid].Target
	ws, err := s.readWorksheet(s.uncompressedFiles[filename])
	ws.filename = filename
	ws.Name = s.worksheets[number].Name
	if err != nil {
		return nil, err
	}
	return ws, nil
}
<commit_msg>Bugfix Excel reader<commit_after>// Package goxlsx accesses Excel 2007 (.xslx) for reading.
package goxlsx

import (
	"archive/zip"
	"bytes"
	"encoding/xml"
	"errors"
	"fmt"
	"io"
	"strconv"
	"strings"
)

// NumWorksheets returns the number of worksheets in a file.
func (s *Spreadsheet) NumWorksheets() int {
	return len(s.worksheets)
}

func readWorkbook(data []byte, s *Spreadsheet) ([]*Worksheet, error) {
	wb := &workbook{}
	err := xml.Unmarshal(data, wb)
	if err != nil {
		return nil, err
	}

	var worksheets []*Worksheet

	for i := 0; i < len(wb.Sheets); i++ {
		w := &Worksheet{}
		w.spreadsheet = s
		w.Name = wb.Sheets[i].Name
		w.id = wb.Sheets[i].SheetID
		w.rid = wb.Sheets[i].Rid
		worksheets = append(worksheets, w)
	}
	return worksheets, nil
}

func readStrings(data []byte) ([]string, error) {
	var (
		err           error
		token         xml.Token
		sharedStrings []string
		buf           []byte
	)

	d := xml.NewDecoder(bytes.NewReader(data))
	for {
		token, err = d.Token()
		if err != nil {
			if err != io.EOF {
				return nil, err
			}
			break
		}
		switch x := token.(type) {
		case xml.StartElement:
			// when there is no char data, there must be an empty string for sharedStrings
			buf = []byte{}
			switch x.Name.Local {
			case "sst":
				// root element
				for i := 0; i < len(x.Attr); i++ {
					if x.Attr[i].Name.Local == "uniqueCount" {
						count, err := strconv.Atoi(x.Attr[i].Value)
						if err != nil {
							return nil, err
						}
						sharedStrings = make([]string, 0, count)
					}
				}
			}
		case xml.CharData:
			buf = x.Copy()
		case xml.EndElement:
			switch x.Name.Local {
			case "t":
				sharedStrings = append(sharedStrings, string(buf))
			}
		}

	}
	return sharedStrings, nil
}

// OpenFile reads a file located at the given path and returns a spreadsheet object.
func OpenFile(path string) (*Spreadsheet, error) {
	xlsx := new(Spreadsheet)
	xlsx.filepath = path
	xlsx.uncompressedFiles = make(map[string][]byte)
	xlsx.sharedCells = make(map[string]*cell)

	r, err := zip.OpenReader(path)
	if err != nil {
		return nil, err
	}
	defer r.Close()

	for _, f := range r.File {
		buf := make([]byte, f.UncompressedSize64)
		rc, err := f.Open()
		if err != nil {
			return nil, err
		}
		size, err := io.ReadFull(rc, buf)
		if err != nil {
			return nil, err
		}
		if size != int(f.UncompressedSize64) {
			return nil, fmt.Errorf("read (%d) not equal to uncompressed size (%d)", size, f.UncompressedSize64)
		}

		xlsx.uncompressedFiles[f.Name] = buf
	}
	xlsx.relationships, err = readRelationships(xlsx.uncompressedFiles["xl/_rels/workbook.xml.rels"])
	if err != nil {
		return nil, err
	}
	xlsx.worksheets, err = readWorkbook(xlsx.uncompressedFiles["xl/workbook.xml"], xlsx)
	if err != nil {
		return nil, err
	}
	xlsx.sharedStrings, err = readStrings(xlsx.uncompressedFiles["xl/sharedStrings.xml"])
	if err != nil {
		return nil, err
	}
	xlsx.uncompressedFiles["xl/sharedStrings.xml"] = nil

	return xlsx, nil
}

func readRelationships(data []byte) (map[string]relationship, error) {
	rels := &xslxRelationships{}
	err := xml.Unmarshal(data, rels)
	if err != nil {
		return nil, err
	}
	ret := make(map[string]relationship)
	for _, v := range rels.Relationship {
		ret[v.Id] = relationship{Type: v.Type, Target: v.Target}
	}
	return ret, nil
}

// excelpos is something like "AC101"
func stringToPosition(excelpos string) (int, int) {
	var columnnumber, rownumber rune
	for _, v := range excelpos {
		if v >= 'A' && v <= 'Z' {
			columnnumber = columnnumber*26 + v - 'A' + 1
		}
		if v >= '0' && v <= '9' {
			rownumber = rownumber*10 + v - '0'
		}
	}
	return int(columnnumber), int(rownumber)
}

// Cell returns the contents of cell at column, row, where 1,1 is the top left corner. The return value is always a string.
// The user is in charge to convert this value to a number, if necessary. Formulae are not returned.
func (ws *Worksheet) Cell(column, row int) string {
	xrow := ws.rows[row]
	if xrow == nil {
		return ""
	}
	if xrow.Cells[column] == nil {
		return ""
	}
	val := xrow.Cells[column].Value
	return strings.Replace(val, "_x000D_", "", -1)
}

// Cell returns the contents of cell at column, row, where 1,1 is the top left corner.
// The return value is always a float64 and an error code != nil if the cell contents can't be
// decoded as a float.
func (ws *Worksheet) Cellf(column, row int) (float64, error) {
	var tmpstr string
	xrow := ws.rows[row]
	if xrow == nil {
		return 0, errors.New("Not a float")
	}
	if xrow.Cells[column] == nil {
		return 0, errors.New("Not a float")
	}
	tmpstr = xrow.Cells[column].Value
	flt, err := strconv.ParseFloat(tmpstr, 64)
	return flt, err
}

func (s *Spreadsheet) readWorksheet(data []byte) (*Worksheet, error) {
	r := bytes.NewReader(data)
	dec := xml.NewDecoder(r)
	ws := &Worksheet{}
	rows := make(map[int]*row)

	const (
		CTSharedString = iota
		CTNumber
		CTOther
	)

	var (
		err        error
		token      xml.Token
		rownum     int
		currentRow *row
		celltype   int
		incell     bool
		cellnumber rune
	)
	for {
		token, err = dec.Token()
		if err != nil {
			if err != io.EOF {
				return nil, err
			}
			break
		}
		switch x := token.(type) {
		case xml.StartElement:
			switch x.Name.Local {
			case "dimension":
				for _, a := range x.Attr {
					if a.Name.Local == "ref" {
						// example: ref="A1:AC101"
						tmp := strings.Split(a.Value, ":")
						ws.MinColumn, ws.MinRow = stringToPosition(tmp[0])
						ws.MaxColumn, ws.MaxRow = stringToPosition(tmp[1])
					}
				}
			case "row":
				currentRow = &row{}
				currentRow.Cells = make(map[int]*cell)
				for _, a := range x.Attr {
					if a.Name.Local == "r" {
						rownum, err = strconv.Atoi(a.Value)
						if err != nil {
							return nil, err
						}
					}
				}
				currentRow.Num = rownum
				rows[rownum] = currentRow
			case "v":
				incell = true
			case "c":
				celltype = CTOther
				cellnumber = 0
				for _, a := range x.Attr {
					switch a.Name.Local {
					case "r":
						for _, v := range a.Value {
							if v >= 'A' && v <= 'Z' {
								cellnumber = cellnumber*26 + v - 'A' + 1
							}
						}
					case "t":
						if a.Value == "s" {
							celltype = CTSharedString
						} else if a.Value == "n" {
							celltype = CTNumber
						}
					}

				}
			}
		case xml.EndElement:
			switch x.Name.Local {
			case "v":
				incell = false
			}
		case xml.CharData:
			if incell {
				var currentCell *cell

				if celltype == CTSharedString {
					currentCell = s.getSharedCell(string(x))
				} else {
					currentCell = &cell{}
					currentCell.Value = string(x)
				}
				currentRow.Cells[int(cellnumber)] = currentCell
			}
		}
	}
	ws.rows = rows
	return ws, nil
}

func (s *Spreadsheet) getSharedCell(idx string) *cell {
	if c, ok := s.sharedCells[idx]; ok {
		return c
	}

	valInt, _ := strconv.Atoi(idx)

	c := &cell{}
	c.Value = s.sharedStrings[valInt]
	s.sharedCells[idx] = c
	return c
}

// GetWorksheet returns the worksheet with the given number, starting at 0.
func (s *Spreadsheet) GetWorksheet(number int) (*Worksheet, error) {
	if number >= len(s.worksheets) || number < 0 {
		return nil, errors.New("index out of range")
	}
	rid := s.worksheets[number].rid
	filename := "xl/" + s.relationships[rid].Target
	ws, err := s.readWorksheet(s.uncompressedFiles[filename])
	ws.filename = filename
	ws.Name = s.worksheets[number].Name
	if err != nil {
		return nil, err
	}
	return ws, nil
}
<|endoftext|>


<commit_before>package fileserver

import (
	"errors"
	"fmt"
	"net/http"
)

type Server interface {
	http.Handler
	Root() string
}

type Params map[string]interface{}

type Factory map[string]Constructor

func (f Factory) New(root string, typ string, params Params) Server {
	for typeName, constructor := range f {
		if typ == typeName {
			return constructor(root, params)
		}
	}
	return defaultConstructor(root, params)
}

func (f Factory) Register(name string, constructor Constructor) error {
	if name == "" {
		return errors.New("fileserver: name is empty")
	}
	if constructor == nil {
		return errors.New("fileserver: constructor is nil")
	}
	if _, ok := f[name]; ok {
		return fmt.Errorf("fileserver: type %q is registered", name)
	}
	f[name] = constructor
	return nil
}

func (f Factory) Types() []string {
	types := make([]string, 0, len(f))
	for typ := range f {
		types = append(types, typ)
	}
	return types
}

type defaultServer struct {
	http.Handler
	root string
}

func (fs defaultServer) Root() string {
	return fs.root
}

var defaultConstructor Constructor = func(root string, params Params) Server {
	return &defaultServer{
		Handler: http.FileServer(http.Dir(root)),
		root:    root,
	}
}

type Constructor func(root string, params Params) Server
<commit_msg>fileserver: list default server in Types()<commit_after>package fileserver

import (
	"errors"
	"fmt"
	"net/http"
)

type Server interface {
	http.Handler
	Root() string
}

type Params map[string]interface{}

type Factory map[string]Constructor

func (f Factory) New(root string, typ string, params Params) Server {
	for typeName, constructor := range f {
		if typ == typeName {
			return constructor(root, params)
		}
	}
	return defaultConstructor(root, params)
}

func (f Factory) Register(name string, constructor Constructor) error {
	if name == "" {
		return errors.New("fileserver: name is empty")
	}
	if constructor == nil {
		return errors.New("fileserver: constructor is nil")
	}
	if _, ok := f[name]; ok || name == "default" {
		return fmt.Errorf("fileserver: type %q is registered", name)
	}
	f[name] = constructor
	return nil
}

func (f Factory) Types() []string {
	types := make([]string, 0, len(f)+1)
	for typ := range f {
		types = append(types, typ)
	}
	types = append(types, "default")
	return types
}

type defaultServer struct {
	http.Handler
	root string
}

func (fs defaultServer) Root() string {
	return fs.root
}

var defaultConstructor Constructor = func(root string, params Params) Server {
	return &defaultServer{
		Handler: http.FileServer(http.Dir(root)),
		root:    root,
	}
}

type Constructor func(root string, params Params) Server
<|endoftext|>


<commit_before>package wav

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"io"
	"time"

	"github.com/faiface/beep"
	"github.com/pkg/errors"
)

// Decode takes a ReadCloser containing audio data in WAVE format and returns a StreamSeekCloser,
// which streams that audio. The Seek method will panic if rc is not io.Seeker.
//
// Do not close the supplied ReadSeekCloser, instead, use the Close method of the returned
// StreamSeekCloser when you want to release the resources.
func Decode(rc io.ReadCloser) (s beep.StreamSeekCloser, format beep.Format, err error) {
	d := decoder{rc: rc}
	defer func() { // hacky way to always close rsc if an error occured
		if err != nil {
			d.rc.Close()
		}
	}()

	// READ "RIFF" header
	if err := binary.Read(rc, binary.LittleEndian, d.h.RiffMark[:]); err != nil {
		return nil, beep.Format{}, errors.Wrap(err, "wav")
	}

	if string(d.h.RiffMark[:]) != "RIFF" {
		return nil, beep.Format{}, errors.New(fmt.Sprintf("wav: missing RIFF at the beginning > %s",string(d.h.RiffMark[:])))
	}

	// READ Total file size
	if err := binary.Read(rc, binary.LittleEndian, &d.h.FileSize); err != nil {
		return nil, beep.Format{}, errors.Wrap(err,"wav: missing RIFF file size")
	}

	if err := binary.Read(rc, binary.LittleEndian, d.h.WaveMark[:]); err != nil {
		return nil, beep.Format{}, errors.Wrap(err,"wav: missing RIFF file type")
	}

	if string(d.h.WaveMark[:]) != "WAVE" {
		return nil, beep.Format{}, errors.New("wav: unsupported file type")
	}

	//check each formtypes
	ft := [4]byte {0,0,0,0}

	var fs int32 = 0

	for string(ft[:]) != "data" {

		if err = binary.Read(rc,binary.LittleEndian,ft[:]); err != nil {
			return nil, beep.Format{}, errors.Wrap(err, "wav: missing chunk type")
		}

		switch {
			case string(ft[:]) == "fmt " : {
				d.h.FmtMark = ft
				if err := binary.Read(rc,binary.LittleEndian,&d.h.FormatSize); err != nil {
					return nil, beep.Format{}, errors.New("wav: missing format chunk size")
				}

				if err := binary.Read(rc,binary.LittleEndian,&d.h.FormatType); err != nil {
					return nil, beep.Format{}, errors.New("wav: missing format type")
				}

				//WAVEFORMATEXTENSIBLE
				if d.h.FormatType == -2 {
					fmtchunk := formatchunkextensible {0,0,0,0,0,0,0,0,[18]byte{
					0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
					if err := binary.Read(rc,binary.LittleEndian,&fmtchunk); err != nil {
						return nil, beep.Format{}, errors.New("wav: missing format chunk body")
					} else {
						d.h.NumChans      = fmtchunk.NumChans
						d.h.SampleRate    = fmtchunk.SampleRate
						d.h.ByteRate      = fmtchunk.ByteRate
						d.h.BytesPerFrame = fmtchunk.BytesPerFrame
						d.h.BitsPerSample = fmtchunk.BitsPerSample
					}
					if fmtchunk.SubFormat != [18]byte{0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71} {
						return nil, beep.Format{}, errors.New(fmt.Sprintf("wav: unsupported sub format type - %s",hex.EncodeToString(fmtchunk.SubFormat[:])))
					}
				//WAVEFORMAT or WAVEFORMATEX
				} else {
					fmtchunk := formatchunk {0,0,0,0,0}
					if err := binary.Read(rc,binary.LittleEndian,&fmtchunk); err != nil {
						return nil, beep.Format{}, errors.New("wav: missing format chunk body")
					} else {
						d.h.NumChans      = fmtchunk.NumChans
						d.h.SampleRate    = fmtchunk.SampleRate
						d.h.ByteRate      = fmtchunk.ByteRate
						d.h.BytesPerFrame = fmtchunk.BytesPerFrame
						d.h.BitsPerSample = fmtchunk.BitsPerSample
					}
					//it would be skipping cbSize (WAVEFORMATEX's last member).
					if d.h.FormatSize > 16 {
						trash := make([]byte,d.h.FormatSize - 16)
						if err := binary.Read(rc,binary.LittleEndian,trash); err != nil {
							return nil, beep.Format{}, errors.Wrap(err,"wav: missing extended format chunk body")
						}
					}
				}

			}

			case string(ft[:]) == "data" : {
				d.h.DataMark = ft
				if err := binary.Read(rc,binary.LittleEndian,&d.h.DataSize); err != nil {
					return nil, beep.Format{}, errors.Wrap(err,"wav: missing data chunk size")
				}
			}

			default : {
				if err := binary.Read(rc,binary.LittleEndian,&fs); err != nil {
					return nil, beep.Format{}, errors.Wrap(err,"wav: missing unknown chunk size")
				}
				trash := make([]byte,fs)
				if err := binary.Read(rc,binary.LittleEndian,trash); err != nil {
					return nil, beep.Format{}, errors.Wrap(err,"wav: missing unknown chunk body")
				}
			}
		}
	}

	if string(d.h.FmtMark[:]) != "fmt " {
		return nil, beep.Format{}, errors.New("wav: missing format chunk marker")
	}
	if string(d.h.DataMark[:]) != "data" {
		return nil, beep.Format{}, errors.New("wav: missing data chunk marker")
	}
	if d.h.FormatType != 1 && d.h.FormatType != -2 {
		return nil, beep.Format{}, errors.New(fmt.Sprintf("wav: unsupported format type - %d",d.h.FormatType))
	}
	if d.h.NumChans <= 0 {
		return nil, beep.Format{}, errors.New("wav: invalid number of channels (less than 1)")
	}
	if d.h.BitsPerSample != 8 && d.h.BitsPerSample != 16 {
		return nil, beep.Format{}, errors.New("wav: unsupported number of bits per sample, 8 or 16 are supported")
	}
	format = beep.Format{
		SampleRate:  beep.SampleRate(d.h.SampleRate),
		NumChannels: int(d.h.NumChans),
		Precision:   int(d.h.BitsPerSample / 8),
	}
	return &d, format, nil
}
type formatchunk struct {
	NumChans      int16
	SampleRate    int32
	ByteRate      int32
	BytesPerFrame int16
	BitsPerSample int16
}

type formatchunkextensible struct {
	NumChans      int16
	SampleRate    int32
	ByteRate      int32
	BytesPerFrame int16
	BitsPerSample int16
	SubFormatSize int16
	Samples int16
	ChannelMask int16
	SubFormat [18]byte
}

type header struct {
	RiffMark      [4]byte
	FileSize      int32

	WaveMark      [4]byte

	FmtMark       [4]byte
	FormatSize    int32
	FormatType    int16

	NumChans      int16
	SampleRate    int32
	ByteRate      int32
	BytesPerFrame int16
	BitsPerSample int16

	DataMark      [4]byte
	DataSize      int32
}

type decoder struct {
	rc  io.ReadCloser
	h   header
	pos int32
	err error
}

func (d *decoder) Stream(samples [][2]float64) (n int, ok bool) {
	if d.err != nil || d.pos >= d.h.DataSize {
		return 0, false
	}
	bytesPerFrame := int(d.h.BytesPerFrame)
	numBytes := int32(len(samples) * bytesPerFrame)
	if numBytes > d.h.DataSize-d.pos {
		numBytes = d.h.DataSize - d.pos
	}
	p := make([]byte, numBytes)
	n, err := d.rc.Read(p)
	if err != nil && err != io.EOF {
		d.err = err
	}
	switch {
	case d.h.BitsPerSample == 8 && d.h.NumChans == 1:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			val := float64(p[i])/(1<<8-1)*2 - 1
			samples[j][0] = val
			samples[j][1] = val
		}
	case d.h.BitsPerSample == 8 && d.h.NumChans >= 2:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			samples[j][0] = float64(p[i+0])/(1<<8-1)*2 - 1
			samples[j][1] = float64(p[i+1])/(1<<8-1)*2 - 1
		}
	case d.h.BitsPerSample == 16 && d.h.NumChans == 1:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			val := float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1<<15 - 1)
			samples[j][0] = val
			samples[j][1] = val
		}
	case d.h.BitsPerSample == 16 && d.h.NumChans >= 2:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			samples[j][0] = float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1<<15 - 1)
			samples[j][1] = float64(int16(p[i+2])+int16(p[i+3])*(1<<8)) / (1<<15 - 1)
		}
	}
	d.pos += int32(n)
	return n / bytesPerFrame, true
}

func (d *decoder) Err() error {
	return d.err
}

func (d *decoder) Len() int {
	numBytes := time.Duration(d.h.DataSize)
	perFrame := time.Duration(d.h.BytesPerFrame)
	return int(numBytes / perFrame)
}

func (d *decoder) Position() int {
	return int(d.pos / int32(d.h.BytesPerFrame))
}

func (d *decoder) Seek(p int) error {
	seeker, ok := d.rc.(io.Seeker)
	if !ok {
		panic(fmt.Errorf("wav: seek: resource is not io.Seeker"))
	}
	if p < 0 || d.Len() < p {
		return fmt.Errorf("wav: seek position %v out of range [%v, %v]", p, 0, d.Len())
	}
	pos := int32(p) * int32(d.h.BytesPerFrame)
	_, err := seeker.Seek(int64(pos)+44, io.SeekStart) // 44 is the size of the header
	if err != nil {
		return errors.Wrap(err, "wav: seek error")
	}
	d.pos = pos
	return nil
}

func (d *decoder) Close() error {
	err := d.rc.Close()
	if err != nil {
		return errors.Wrap(err, "wav")
	}
	return nil
}
<commit_msg>fixed to fit writting manners<commit_after>package wav

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"io"
	"time"

	"github.com/faiface/beep"
	"github.com/pkg/errors"
)

// Decode takes a ReadCloser containing audio data in WAVE format and returns a StreamSeekCloser,
// which streams that audio. The Seek method will panic if rc is not io.Seeker.
//
// Do not close the supplied ReadSeekCloser, instead, use the Close method of the returned
// StreamSeekCloser when you want to release the resources.
func Decode(rc io.ReadCloser) (s beep.StreamSeekCloser, format beep.Format, err error) {
	d := decoder{rc: rc}
	defer func() { // hacky way to always close rsc if an error occured
		if err != nil {
			d.rc.Close()
		}
	}()

	// READ "RIFF" header
	if err := binary.Read(rc, binary.LittleEndian, d.h.RiffMark[:]); err != nil {
		return nil, beep.Format{}, errors.Wrap(err, "wav")
	}

	if string(d.h.RiffMark[:]) != "RIFF" {
		return nil, beep.Format{}, errors.New(fmt.Sprintf("wav: missing RIFF at the beginning > %s", string(d.h.RiffMark[:])))
	}

	// READ Total file size
	if err := binary.Read(rc, binary.LittleEndian, &d.h.FileSize); err != nil {
		return nil, beep.Format{}, errors.Wrap(err, "wav: missing RIFF file size")
	}

	if err := binary.Read(rc, binary.LittleEndian, d.h.WaveMark[:]); err != nil {
		return nil, beep.Format{}, errors.Wrap(err, "wav: missing RIFF file type")
	}

	if string(d.h.WaveMark[:]) != "WAVE" {
		return nil, beep.Format{}, errors.New("wav: unsupported file type")
	}

	// check each formtypes
	ft := [4]byte{0, 0, 0, 0}

	var fs int32 = 0

	for string(ft[:]) != "data" {

		if err = binary.Read(rc, binary.LittleEndian, ft[:]); err != nil {
			return nil, beep.Format{}, errors.Wrap(err, "wav: missing chunk type")
		}

		switch {
		case string(ft[:]) == "fmt ":
			{
				d.h.FmtMark = ft
				if err := binary.Read(rc, binary.LittleEndian, &d.h.FormatSize); err != nil {
					return nil, beep.Format{}, errors.New("wav: missing format chunk size")
				}

				if err := binary.Read(rc, binary.LittleEndian, &d.h.FormatType); err != nil {
					return nil, beep.Format{}, errors.New("wav: missing format type")
				}

				if d.h.FormatType == -2 {
					// WAVEFORMATEXTENSIBLE
					fmtchunk := formatchunkextensible{0, 0, 0, 0, 0, 0, 0, 0, [18]byte{
						0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
					if err := binary.Read(rc, binary.LittleEndian, &fmtchunk); err != nil {
						return nil, beep.Format{}, errors.New("wav: missing format chunk body")
					} else {
						d.h.NumChans = fmtchunk.NumChans
						d.h.SampleRate = fmtchunk.SampleRate
						d.h.ByteRate = fmtchunk.ByteRate
						d.h.BytesPerFrame = fmtchunk.BytesPerFrame
						d.h.BitsPerSample = fmtchunk.BitsPerSample
					}
					if fmtchunk.SubFormat != [18]byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} {
						return nil, beep.Format{}, errors.New(fmt.Sprintf("wav: unsupported sub format type - %s", hex.EncodeToString(fmtchunk.SubFormat[:])))
					}
				} else {
					// WAVEFORMAT or WAVEFORMATEX
					fmtchunk := formatchunk{0, 0, 0, 0, 0}
					if err := binary.Read(rc, binary.LittleEndian, &fmtchunk); err != nil {
						return nil, beep.Format{}, errors.New("wav: missing format chunk body")
					} else {
						d.h.NumChans = fmtchunk.NumChans
						d.h.SampleRate = fmtchunk.SampleRate
						d.h.ByteRate = fmtchunk.ByteRate
						d.h.BytesPerFrame = fmtchunk.BytesPerFrame
						d.h.BitsPerSample = fmtchunk.BitsPerSample
					}
					// it would be skipping cbSize (WAVEFORMATEX's last member).
					if d.h.FormatSize > 16 {
						trash := make([]byte, d.h.FormatSize-16)
						if err := binary.Read(rc, binary.LittleEndian, trash); err != nil {
							return nil, beep.Format{}, errors.Wrap(err, "wav: missing extended format chunk body")
						}
					}
				}

			}

		case string(ft[:]) == "data":
			{
				d.h.DataMark = ft
				if err := binary.Read(rc, binary.LittleEndian, &d.h.DataSize); err != nil {
					return nil, beep.Format{}, errors.Wrap(err, "wav: missing data chunk size")
				}
			}

		default:
			{
				if err := binary.Read(rc, binary.LittleEndian, &fs); err != nil {
					return nil, beep.Format{}, errors.Wrap(err, "wav: missing unknown chunk size")
				}
				trash := make([]byte, fs)
				if err := binary.Read(rc, binary.LittleEndian, trash); err != nil {
					return nil, beep.Format{}, errors.Wrap(err, "wav: missing unknown chunk body")
				}
			}
		}
	}

	if string(d.h.FmtMark[:]) != "fmt " {
		return nil, beep.Format{}, errors.New("wav: missing format chunk marker")
	}
	if string(d.h.DataMark[:]) != "data" {
		return nil, beep.Format{}, errors.New("wav: missing data chunk marker")
	}
	if d.h.FormatType != 1 && d.h.FormatType != -2 {
		return nil, beep.Format{}, errors.New(fmt.Sprintf("wav: unsupported format type - %d", d.h.FormatType))
	}
	if d.h.NumChans <= 0 {
		return nil, beep.Format{}, errors.New("wav: invalid number of channels (less than 1)")
	}
	if d.h.BitsPerSample != 8 && d.h.BitsPerSample != 16 {
		return nil, beep.Format{}, errors.New("wav: unsupported number of bits per sample, 8 or 16 are supported")
	}
	format = beep.Format{
		SampleRate:  beep.SampleRate(d.h.SampleRate),
		NumChannels: int(d.h.NumChans),
		Precision:   int(d.h.BitsPerSample / 8),
	}
	return &d, format, nil
}

type formatchunk struct {
	NumChans      int16
	SampleRate    int32
	ByteRate      int32
	BytesPerFrame int16
	BitsPerSample int16
}

type formatchunkextensible struct {
	NumChans      int16
	SampleRate    int32
	ByteRate      int32
	BytesPerFrame int16
	BitsPerSample int16
	SubFormatSize int16
	Samples       int16
	ChannelMask   int16
	SubFormat     [18]byte
}

type header struct {
	RiffMark [4]byte
	FileSize int32

	WaveMark [4]byte

	FmtMark    [4]byte
	FormatSize int32
	FormatType int16

	NumChans      int16
	SampleRate    int32
	ByteRate      int32
	BytesPerFrame int16
	BitsPerSample int16

	DataMark [4]byte
	DataSize int32
}

type decoder struct {
	rc  io.ReadCloser
	h   header
	pos int32
	err error
}

func (d *decoder) Stream(samples [][2]float64) (n int, ok bool) {
	if d.err != nil || d.pos >= d.h.DataSize {
		return 0, false
	}
	bytesPerFrame := int(d.h.BytesPerFrame)
	numBytes := int32(len(samples) * bytesPerFrame)
	if numBytes > d.h.DataSize-d.pos {
		numBytes = d.h.DataSize - d.pos
	}
	p := make([]byte, numBytes)
	n, err := d.rc.Read(p)
	if err != nil && err != io.EOF {
		d.err = err
	}
	switch {
	case d.h.BitsPerSample == 8 && d.h.NumChans == 1:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			val := float64(p[i])/(1<<8-1)*2 - 1
			samples[j][0] = val
			samples[j][1] = val
		}
	case d.h.BitsPerSample == 8 && d.h.NumChans >= 2:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			samples[j][0] = float64(p[i+0])/(1<<8-1)*2 - 1
			samples[j][1] = float64(p[i+1])/(1<<8-1)*2 - 1
		}
	case d.h.BitsPerSample == 16 && d.h.NumChans == 1:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			val := float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1<<15 - 1)
			samples[j][0] = val
			samples[j][1] = val
		}
	case d.h.BitsPerSample == 16 && d.h.NumChans >= 2:
		for i, j := 0, 0; i <= n-bytesPerFrame; i, j = i+bytesPerFrame, j+1 {
			samples[j][0] = float64(int16(p[i+0])+int16(p[i+1])*(1<<8)) / (1<<15 - 1)
			samples[j][1] = float64(int16(p[i+2])+int16(p[i+3])*(1<<8)) / (1<<15 - 1)
		}
	}
	d.pos += int32(n)
	return n / bytesPerFrame, true
}

func (d *decoder) Err() error {
	return d.err
}

func (d *decoder) Len() int {
	numBytes := time.Duration(d.h.DataSize)
	perFrame := time.Duration(d.h.BytesPerFrame)
	return int(numBytes / perFrame)
}

func (d *decoder) Position() int {
	return int(d.pos / int32(d.h.BytesPerFrame))
}

func (d *decoder) Seek(p int) error {
	seeker, ok := d.rc.(io.Seeker)
	if !ok {
		panic(fmt.Errorf("wav: seek: resource is not io.Seeker"))
	}
	if p < 0 || d.Len() < p {
		return fmt.Errorf("wav: seek position %v out of range [%v, %v]", p, 0, d.Len())
	}
	pos := int32(p) * int32(d.h.BytesPerFrame)
	_, err := seeker.Seek(int64(pos)+44, io.SeekStart) // 44 is the size of the header
	if err != nil {
		return errors.Wrap(err, "wav: seek error")
	}
	d.pos = pos
	return nil
}

func (d *decoder) Close() error {
	err := d.rc.Close()
	if err != nil {
		return errors.Wrap(err, "wav")
	}
	return nil
}
<|endoftext|>