<commit_before>package utils

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"io"
	"math/rand"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/eirka/eirka-libs/amazon"
	"github.com/eirka/eirka-libs/config"

	local "github.com/eirka/eirka-post/config"
)

// valid file extensions
var validExt = map[string]bool{
	".jpg":  true,
	".jpeg": true,
	".png":  true,
	".gif":  true,
	".webm": true,
}

type ImageType struct {
	File        multipart.File
	Header      *multipart.FileHeader
	Filename    string
	Thumbnail   string
	Ext         string
	MD5         string
	OrigWidth   int
	OrigHeight  int
	ThumbWidth  int
	ThumbHeight int
	image       *bytes.Buffer
	mime        string
	duration    int
}

func (i *ImageType) IsValid() bool {

	if i.Filename == "" {
		return false
	}

	if i.Thumbnail == "" {
		return false
	}

	if i.Ext == "" {
		return false
	}

	if i.MD5 == "" {
		return false
	}

	if i.mime == "" {
		return false
	}

	return true
}

func (i *ImageType) IsValidPost() bool {
	if i.OrigWidth == 0 {
		return false
	}

	if i.OrigHeight == 0 {
		return false
	}

	if i.ThumbWidth == 0 {
		return false
	}

	if i.ThumbHeight == 0 {
		return false
	}

	return true
}

// ProcessFile will check file integrity, get an md5, and make filenames
func (i *ImageType) ProcessFile() (err error) {

	// check given file ext
	err = i.checkReqExt()
	if err != nil {
		return
	}

	// get file md5
	err = i.getMD5()
	if err != nil {
		return
	}

	// check file magic sig
	err = i.checkMagic()
	if err != nil {
		return
	}

	return

}

// save an image file
func (i *ImageType) SaveImage() (err error) {

	// check image stats
	err = i.getStats()
	if err != nil {
		return
	}

	// save the file to disk
	err = i.saveFile()
	if err != nil {
		return
	}

	// create a thumbnail
	err = i.createThumbnail()
	if err != nil {
		return
	}

	// check final state
	if !i.IsValidPost() {
		return errors.New("ImageType is not valid")
	}

	return

}

// Get file extension from request header
func (i *ImageType) checkReqExt() (err error) {
	// Get ext from request header
	name := i.Header.Filename
	ext := filepath.Ext(name)

	if ext == "" {
		return errors.New("no file extension")
	}

	// Check to see if extension is allowed
	ext_check := isAllowedExt(ext)
	if !ext_check {
		return errors.New("format not supported")
	}

	return

}

// Check if file ext allowed
func isAllowedExt(ext string) bool {

	if validExt[strings.ToLower(ext)] {
		return true
	}

	return false

}

// Get image MD5 and write file into buffer
func (i *ImageType) getMD5() (err error) {

	defer i.File.Close()

	hasher := md5.New()

	i.image = new(bytes.Buffer)

	// Save file and also read into hasher for md5
	_, err = io.Copy(i.image, io.TeeReader(i.File, hasher))
	if err != nil {
		return errors.New("problem copying file")
	}

	// Set md5sum from hasher
	i.MD5 = hex.EncodeToString(hasher.Sum(nil))

	return

}

func (i *ImageType) checkMagic() (err error) {

	// detect the mime type
	i.mime = http.DetectContentType(i.image.Bytes())

	switch i.mime {
	case "image/png":
		i.Ext = ".png"
	case "image/jpeg":
		i.Ext = ".jpg"
	case "image/gif":
		i.Ext = ".gif"
	case "video/webm":
		i.Ext = ".webm"
	default:
		return errors.New("unknown file type")
	}

	// Check to see if extension is allowed
	ext_check := isAllowedExt(i.Ext)
	if !ext_check {
		return errors.New("format not supported")
	}

	return

}

func (i *ImageType) getStats() (err error) {

	// decode image config
	img, _, err := image.DecodeConfig(bytes.NewReader(i.image.Bytes()))
	if err != nil {
		return errors.New("problem decoding image")
	}

	// set original width
	i.OrigWidth = img.Width
	// set original height
	i.OrigHeight = img.Height

	// Check against maximum sizes
	switch {
	case i.OrigWidth > config.Settings.Limits.ImageMaxWidth:
		return errors.New("image width too large")
	case img.Width < config.Settings.Limits.ImageMinWidth:
		return errors.New("image width too small")
	case i.OrigHeight > config.Settings.Limits.ImageMaxHeight:
		return errors.New("image height too large")
	case img.Height < config.Settings.Limits.ImageMinHeight:
		return errors.New("image height too small")
	case i.image.Len() > config.Settings.Limits.ImageMaxSize:
		return errors.New("image size too large")
	}

	return

}

func (i *ImageType) saveFile() (err error) {

	defer i.image.Reset()

	// generate filenames
	i.makeFilenames()

	if !i.IsValid() {
		return errors.New("ImageType is not valid")
	}

	imagefile := filepath.Join(local.Settings.Directories.ImageDir, i.Filename)

	image, err := os.Create(imagefile)
	if err != nil {
		return errors.New("problem saving file")
	}
	defer image.Close()

	_, err = io.Copy(image, bytes.NewReader(i.image.Bytes()))
	if err != nil {
		return errors.New("problem saving file")
	}

	s3 := amazon.New()

	err = s3.Save(imagefile, fmt.Sprintf("src/%s", i.Filename), i.mime)
	if err != nil {
		return
	}

	return

}

// Make a random unix time filename
func (i *ImageType) makeFilenames() {

	// Create seed for random
	rand.Seed(time.Now().UnixNano())

	// Get random 3 digit int to append to unix time
	rand_t := rand.Intn(899) + 100

	// Get current unix time
	time_t := time.Now().Unix()

	// Append random int to unix time
	file_t := fmt.Sprintf("%d%d", time_t, rand_t)

	// Append ext to filename
	i.Filename = fmt.Sprintf("%s%s", file_t, i.Ext)

	// Append jpg to thumbnail name because it is always a jpg
	i.Thumbnail = fmt.Sprintf("%ss.jpg", file_t)

	return

}

func (i *ImageType) createThumbnail() (err error) {

	if !i.IsValid() {
		return errors.New("ImageType is not valid")
	}

	object := amazon.LambdaThumbnail{
		Bucket:    config.Settings.Amazon.Bucket,
		Filename:  i.Filename,
		Thumbnail: i.Thumbnail,
		MaxWidth:  config.Settings.Limits.ThumbnailMaxWidth,
		MaxHeight: config.Settings.Limits.ThumbnailMaxHeight,
	}

	lambda := amazon.New()

	// run our lambda job and get the dimensions
	i.ThumbWidth, i.ThumbHeight, err = lambda.Execute(object)
	if err != nil {
		return
	}

	return

}
<commit_msg>fix up ext function<commit_after>package utils

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"image"
	_ "image/gif"
	_ "image/jpeg"
	_ "image/png"
	"io"
	"math/rand"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/eirka/eirka-libs/amazon"
	"github.com/eirka/eirka-libs/config"

	local "github.com/eirka/eirka-post/config"
)

// valid file extensions
var validExt = map[string]bool{
	".jpg":  true,
	".jpeg": true,
	".png":  true,
	".gif":  true,
	".webm": true,
}

type ImageType struct {
	File        multipart.File
	Header      *multipart.FileHeader
	Filename    string
	Thumbnail   string
	Ext         string
	MD5         string
	OrigWidth   int
	OrigHeight  int
	ThumbWidth  int
	ThumbHeight int
	image       *bytes.Buffer
	mime        string
	duration    int
}

func (i *ImageType) IsValid() bool {

	if i.Filename == "" {
		return false
	}

	if i.Thumbnail == "" {
		return false
	}

	if i.Ext == "" {
		return false
	}

	if i.MD5 == "" {
		return false
	}

	if i.mime == "" {
		return false
	}

	return true
}

func (i *ImageType) IsValidPost() bool {
	if i.OrigWidth == 0 {
		return false
	}

	if i.OrigHeight == 0 {
		return false
	}

	if i.ThumbWidth == 0 {
		return false
	}

	if i.ThumbHeight == 0 {
		return false
	}

	return true
}

// ProcessFile will check file integrity, get an md5, and make filenames
func (i *ImageType) ProcessFile() (err error) {

	// check given file ext
	err = i.checkReqExt()
	if err != nil {
		return
	}

	// get file md5
	err = i.getMD5()
	if err != nil {
		return
	}

	// check file magic sig
	err = i.checkMagic()
	if err != nil {
		return
	}

	return

}

// save an image file
func (i *ImageType) SaveImage() (err error) {

	// check image stats
	err = i.getStats()
	if err != nil {
		return
	}

	// save the file to disk
	err = i.saveFile()
	if err != nil {
		return
	}

	// create a thumbnail
	err = i.createThumbnail()
	if err != nil {
		return
	}

	// check final state
	if !i.IsValidPost() {
		return errors.New("ImageType is not valid")
	}

	return

}

// Get file extension from request header
func (i *ImageType) checkReqExt() (err error) {
	// Get ext from request header
	name := i.Header.Filename
	ext := filepath.Ext(name)

	if ext == "" {
		return errors.New("no file extension")
	}

	// Check to see if extension is allowed
	if !isAllowedExt(ext) {
		return errors.New("format not supported")
	}

	return

}

// Check if file ext allowed
func isAllowedExt(ext string) bool {
	return validExt[strings.ToLower(ext)]
}

// Get image MD5 and write file into buffer
func (i *ImageType) getMD5() (err error) {

	defer i.File.Close()

	hasher := md5.New()

	i.image = new(bytes.Buffer)

	// Save file and also read into hasher for md5
	_, err = io.Copy(i.image, io.TeeReader(i.File, hasher))
	if err != nil {
		return errors.New("problem copying file")
	}

	// Set md5sum from hasher
	i.MD5 = hex.EncodeToString(hasher.Sum(nil))

	return

}

func (i *ImageType) checkMagic() (err error) {

	// detect the mime type
	i.mime = http.DetectContentType(i.image.Bytes())

	switch i.mime {
	case "image/png":
		i.Ext = ".png"
	case "image/jpeg":
		i.Ext = ".jpg"
	case "image/gif":
		i.Ext = ".gif"
	case "video/webm":
		i.Ext = ".webm"
	default:
		return errors.New("unknown file type")
	}

	// Check to see if extension is allowed
	if !isAllowedExt(i.Ext) {
		return errors.New("format not supported")
	}

	return

}

func (i *ImageType) getStats() (err error) {

	// decode image config
	img, _, err := image.DecodeConfig(bytes.NewReader(i.image.Bytes()))
	if err != nil {
		return errors.New("problem decoding image")
	}

	// set original width
	i.OrigWidth = img.Width
	// set original height
	i.OrigHeight = img.Height

	// Check against maximum sizes
	switch {
	case i.OrigWidth > config.Settings.Limits.ImageMaxWidth:
		return errors.New("image width too large")
	case img.Width < config.Settings.Limits.ImageMinWidth:
		return errors.New("image width too small")
	case i.OrigHeight > config.Settings.Limits.ImageMaxHeight:
		return errors.New("image height too large")
	case img.Height < config.Settings.Limits.ImageMinHeight:
		return errors.New("image height too small")
	case i.image.Len() > config.Settings.Limits.ImageMaxSize:
		return errors.New("image size too large")
	}

	return

}

func (i *ImageType) saveFile() (err error) {

	defer i.image.Reset()

	// generate filenames
	i.makeFilenames()

	if !i.IsValid() {
		return errors.New("ImageType is not valid")
	}

	imagefile := filepath.Join(local.Settings.Directories.ImageDir, i.Filename)

	image, err := os.Create(imagefile)
	if err != nil {
		return errors.New("problem saving file")
	}
	defer image.Close()

	_, err = io.Copy(image, bytes.NewReader(i.image.Bytes()))
	if err != nil {
		return errors.New("problem saving file")
	}

	s3 := amazon.New()

	err = s3.Save(imagefile, fmt.Sprintf("src/%s", i.Filename), i.mime)
	if err != nil {
		return
	}

	return

}

// Make a random unix time filename
func (i *ImageType) makeFilenames() {

	// Create seed for random
	rand.Seed(time.Now().UnixNano())

	// Get random 3 digit int to append to unix time
	rand_t := rand.Intn(899) + 100

	// Get current unix time
	time_t := time.Now().Unix()

	// Append random int to unix time
	file_t := fmt.Sprintf("%d%d", time_t, rand_t)

	// Append ext to filename
	i.Filename = fmt.Sprintf("%s%s", file_t, i.Ext)

	// Append jpg to thumbnail name because it is always a jpg
	i.Thumbnail = fmt.Sprintf("%ss.jpg", file_t)

	return

}

func (i *ImageType) createThumbnail() (err error) {

	if !i.IsValid() {
		return errors.New("ImageType is not valid")
	}

	object := amazon.LambdaThumbnail{
		Bucket:    config.Settings.Amazon.Bucket,
		Filename:  i.Filename,
		Thumbnail: i.Thumbnail,
		MaxWidth:  config.Settings.Limits.ThumbnailMaxWidth,
		MaxHeight: config.Settings.Limits.ThumbnailMaxHeight,
	}

	lambda := amazon.New()

	// run our lambda job and get the dimensions
	i.ThumbWidth, i.ThumbHeight, err = lambda.Execute(object)
	if err != nil {
		return
	}

	return

}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Fabrício Godoy
 *
 * 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 dot_test

import (
	"fmt"
	"regexp"

	"gopkg.in/raiqub/dot.v1"
)

func isValidUrl(url string) bool {
	const pattern = `^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$`
	r := regexp.MustCompile(pattern)
	return r.MatchString(url)
}

func Example_stringSlice() {
	list := []string{
		"https://www.google.com",
		"https://www.facebook.com",
		"http://www.youtube.com",
		"http://www.yahoo.com",
		"http://www.amazon.com",
		"https://en.wikipedia.org",
	}

	if dot.StringSlice(list).TrueForAll(isValidUrl) {
		fmt.Println("All URLs from list is valid")
	} else {
		fmt.Println("Not all URLs from list is valid")
	}

	if dot.StringSlice(list).IndexOf("HTTP://WWW.YAHOO.COM", true) == 3 {
		fmt.Println("Yahoo URL was found on 4th element of the list")
	} else {
		fmt.Println("Yahoo URL was not found")
	}

	if dot.StringSlice(list).Exists("https://www.facebook.com", false) {
		fmt.Println("Facebook URL was found")
	} else {
		fmt.Println("Facebook URL was not found")
	}

	// Output:
	// All URLs from list is valid
	// Yahoo URL was found on 4th element of the list
	// Facebook URL was found
}
<commit_msg>Removed deprecated example for StringSlice<commit_after><|endoftext|>


<commit_before>package digests

import (
	"encoding/json"
	"fmt"
	"math"
	"strings"

	"github.com/ion-channel/ionic/scanner"
	"github.com/ion-channel/ionic/scans"
)

var (
	// ErrFailedValueAssertion is the error returned when the value for
	// constructing a new digest does not convert to the digest data type
	// specified
	ErrFailedValueAssertion = fmt.Errorf("failed to assert value for given data type")

	// ErrUnsupportedType is the error returned when the data type for
	// constructing the digest is not a valid type
	ErrUnsupportedType = fmt.Errorf("unsupported digest data type")
)

// Digest is only the important parts for display
type Digest struct {
	Index          int             `json:"index"`
	Title          string          `json:"title"`
	Data           json.RawMessage `json:"data"`
	ScanID         string          `json:"scan_id"`
	RuleID         string          `json:"rule_id"`
	RulesetID      string          `json:"ruleset_id"`
	Evaluated      bool            `json:"evaluated"`
	Pending        bool            `json:"pending"`
	Passed         bool            `json:"passed"`
	PassedMessage  string          `json:"passed_message"`
	Warning        bool            `json:"warning"`
	WarningMessage string          `json:"warning_message,omitempty"`
	Errored        bool            `json:"errored"`
	ErroredMessage string          `json:"errored_message,omitempty"`

	singularTitle string
	pluralTitle   string
}

type boolean struct {
	Bool bool `json:"bool"`
}

type chars struct {
	Chars string `json:"chars"`
}

type count struct {
	Count int `json:"count"`
}

type list struct {
	List []string `json:"list"`
}

type percent struct {
	Percent float64 `json:"percent"`
}

// NewDigest takes a title, data type,value, evaluation, and status to attempt
// constructing a digest. It returns a digest and any error that it encounters
// while trying to construct the digest.
func NewDigest(status *scanner.ScanStatus, index int, singular, plural string) *Digest {
	var errored bool
	var erroredMsg string

	if status != nil && strings.ToLower(status.Status) == "errored" {
		errored = true
		erroredMsg = status.Message
	}

	d := &Digest{
		Index:          index,
		Pending:        status == nil,
		Errored:        errored,
		ErroredMessage: erroredMsg,
		Title:          plural,
		singularTitle:  singular,
		pluralTitle:    plural,
	}

	return d
}

// AppendEval takes an evaluation, data type, and value to interleave into the
// digest. It will also use the data to determine whether or not to show it's
// singular or plural title. It returns an error if the data type does not match
// the value provided.
func (d *Digest) AppendEval(eval *scans.Evaluation, dataType string, value interface{}) error {
	var data []byte
	var err error
	title := d.pluralTitle

	switch strings.ToLower(dataType) {
	case "bool", "boolean":
		b, ok := value.(bool)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(boolean{b})
	case "chars":
		c, ok := value.(string)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(chars{c})
	case "count":
		c, ok := value.(int)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(count{c})
		if c == 1 {
			title = d.singularTitle
		}
	case "list":
		l, ok := value.([]string)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(&list{l})
		if len(l) == 1 {
			title = d.singularTitle
		}
	case "percent":
		p, ok := value.(float64)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(percent{math.Round(p*100) / 100})
	default:
		return ErrUnsupportedType
	}

	if err != nil {
		return fmt.Errorf("failed to marshal digest data: %v", err.Error())
	}

	d.Data = data
	d.Title = title
	d.ScanID = eval.ID
	d.RuleID = eval.RuleID
	d.RulesetID = eval.RulesetID
	d.Evaluated = (strings.ToLower(eval.Type) != "not evaluated")
	d.Passed = eval.Passed
	d.PassedMessage = eval.Description

	return nil
}
<commit_msg>the docs needed to be updated<commit_after>package digests

import (
	"encoding/json"
	"fmt"
	"math"
	"strings"

	"github.com/ion-channel/ionic/scanner"
	"github.com/ion-channel/ionic/scans"
)

var (
	// ErrFailedValueAssertion is the error returned when the value for
	// constructing a new digest does not convert to the digest data type
	// specified
	ErrFailedValueAssertion = fmt.Errorf("failed to assert value for given data type")

	// ErrUnsupportedType is the error returned when the data type for
	// constructing the digest is not a valid type
	ErrUnsupportedType = fmt.Errorf("unsupported digest data type")
)

// Digest is only the important parts for display
type Digest struct {
	Index          int             `json:"index"`
	Title          string          `json:"title"`
	Data           json.RawMessage `json:"data"`
	ScanID         string          `json:"scan_id"`
	RuleID         string          `json:"rule_id"`
	RulesetID      string          `json:"ruleset_id"`
	Evaluated      bool            `json:"evaluated"`
	Pending        bool            `json:"pending"`
	Passed         bool            `json:"passed"`
	PassedMessage  string          `json:"passed_message"`
	Warning        bool            `json:"warning"`
	WarningMessage string          `json:"warning_message,omitempty"`
	Errored        bool            `json:"errored"`
	ErroredMessage string          `json:"errored_message,omitempty"`

	singularTitle string
	pluralTitle   string
}

type boolean struct {
	Bool bool `json:"bool"`
}

type chars struct {
	Chars string `json:"chars"`
}

type count struct {
	Count int `json:"count"`
}

type list struct {
	List []string `json:"list"`
}

type percent struct {
	Percent float64 `json:"percent"`
}

// NewDigest takes a scan status, ordering index, and a singular and plural
// version of the digest title. The status is leveraged to determine the first
// levels of a digest status. The index provides an ordered location if a list
// of Digests are sorted. The singular and plural titles are used to display as
// singular title if data is added that warrants a singular title, and otherwise
// will favor a plural title. A newly constructed Digest with the appropriate
// settings is returned.
func NewDigest(status *scanner.ScanStatus, index int, singular, plural string) *Digest {
	var errored bool
	var erroredMsg string

	if status != nil && strings.ToLower(status.Status) == "errored" {
		errored = true
		erroredMsg = status.Message
	}

	d := &Digest{
		Index:          index,
		Pending:        status == nil,
		Errored:        errored,
		ErroredMessage: erroredMsg,
		Title:          plural,
		singularTitle:  singular,
		pluralTitle:    plural,
	}

	return d
}

// AppendEval takes an evaluation, data type, and value to interleave into the
// digest. It will also use the data to determine whether or not to show it's
// singular or plural title. It returns an error if the data type does not match
// the value provided.
func (d *Digest) AppendEval(eval *scans.Evaluation, dataType string, value interface{}) error {
	var data []byte
	var err error
	title := d.pluralTitle

	switch strings.ToLower(dataType) {
	case "bool", "boolean":
		b, ok := value.(bool)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(boolean{b})
	case "chars":
		c, ok := value.(string)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(chars{c})
	case "count":
		c, ok := value.(int)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(count{c})
		if c == 1 {
			title = d.singularTitle
		}
	case "list":
		l, ok := value.([]string)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(&list{l})
		if len(l) == 1 {
			title = d.singularTitle
		}
	case "percent":
		p, ok := value.(float64)
		if !ok {
			return ErrFailedValueAssertion
		}

		data, err = json.Marshal(percent{math.Round(p*100) / 100})
	default:
		return ErrUnsupportedType
	}

	if err != nil {
		return fmt.Errorf("failed to marshal digest data: %v", err.Error())
	}

	d.Data = data
	d.Title = title
	d.ScanID = eval.ID
	d.RuleID = eval.RuleID
	d.RulesetID = eval.RulesetID
	d.Evaluated = (strings.ToLower(eval.Type) != "not evaluated")
	d.Passed = eval.Passed
	d.PassedMessage = eval.Description

	return nil
}
<|endoftext|>


<commit_before>package utils

import (
	"bytes"
	"crypto/rand"
	"io"

	"github.com/lucas-clemente/quic-go/protocol"
)

// ReadStream is the read part of a QUIC stream
type ReadStream interface {
	io.Reader
	io.ByteReader
}

// Stream is the interface for QUIC streams
type Stream interface {
	io.Reader
	io.ByteReader
	io.Writer
	io.Closer
	StreamID() protocol.StreamID
	CloseRemote(offset protocol.ByteCount)
}

// ReadUintN reads N bytes
func ReadUintN(b io.ByteReader, length uint8) (uint64, error) {
	var res uint64
	for i := uint8(0); i < length; i++ {
		bt, err := b.ReadByte()
		if err != nil {
			return 0, err
		}
		res ^= uint64(bt) << (i * 8)
	}
	return res, nil
}

// ReadUint64 reads a uint64
func ReadUint64(b io.ByteReader) (uint64, error) {
	var b1, b2, b3, b4, b5, b6, b7, b8 uint8
	var err error
	if b1, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b2, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b3, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b4, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b5, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b6, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b7, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b8, err = b.ReadByte(); err != nil {
		return 0, err
	}
	return uint64(b1) + uint64(b2)<<8 + uint64(b3)<<16 + uint64(b4)<<24 + uint64(b5)<<32 + uint64(b6)<<40 + uint64(b7)<<48 + uint64(b8)<<56, nil
}

// ReadUint32 reads a uint32
func ReadUint32(b io.ByteReader) (uint32, error) {
	var b1, b2, b3, b4 uint8
	var err error
	if b1, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b2, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b3, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b4, err = b.ReadByte(); err != nil {
		return 0, err
	}
	return uint32(b1) + uint32(b2)<<8 + uint32(b3)<<16 + uint32(b4)<<24, nil
}

// ReadUint16 reads a uint16
func ReadUint16(b io.ByteReader) (uint16, error) {
	var b1, b2 uint8
	var err error
	if b1, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b2, err = b.ReadByte(); err != nil {
		return 0, err
	}
	return uint16(b1) + uint16(b2)<<8, nil
}

// WriteUint64 writes a uint64
func WriteUint64(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i & 0xff))
	b.WriteByte(uint8((i >> 8) & 0xff))
	b.WriteByte(uint8((i >> 16) & 0xff))
	b.WriteByte(uint8((i >> 24) & 0xff))
	b.WriteByte(uint8((i >> 32) & 0xff))
	b.WriteByte(uint8((i >> 40) & 0xff))
	b.WriteByte(uint8((i >> 48) & 0xff))
	b.WriteByte(uint8(i >> 56))
}

// WriteUint56 writes 56 bit of a uint64
func WriteUint56(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i & 0xff))
	b.WriteByte(uint8((i >> 8) & 0xff))
	b.WriteByte(uint8((i >> 16) & 0xff))
	b.WriteByte(uint8((i >> 24) & 0xff))
	b.WriteByte(uint8((i >> 32) & 0xff))
	b.WriteByte(uint8((i >> 40) & 0xff))
	b.WriteByte(uint8((i >> 48)))
}

// WriteUint48 writes 48 bit of a uint64
func WriteUint48(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i & 0xff))
	b.WriteByte(uint8((i >> 8) & 0xff))
	b.WriteByte(uint8((i >> 16) & 0xff))
	b.WriteByte(uint8((i >> 24) & 0xff))
	b.WriteByte(uint8((i >> 32) & 0xff))
	b.WriteByte(uint8((i >> 40)))
}

// WriteUint40 writes 40 bit of a uint64
func WriteUint40(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i & 0xff))
	b.WriteByte(uint8((i >> 8) & 0xff))
	b.WriteByte(uint8((i >> 16) & 0xff))
	b.WriteByte(uint8((i >> 24) & 0xff))
	b.WriteByte(uint8((i >> 32)))
}

// WriteUint32 writes a uint32
func WriteUint32(b *bytes.Buffer, i uint32) {
	b.WriteByte(uint8(i & 0xff))
	b.WriteByte(uint8((i >> 8) & 0xff))
	b.WriteByte(uint8((i >> 16) & 0xff))
	b.WriteByte(uint8((i >> 24) & 0xff))
}

// WriteUint24 writes 24 bit of a uint32
func WriteUint24(b *bytes.Buffer, i uint32) {
	b.WriteByte(uint8(i & 0xff))
	b.WriteByte(uint8((i >> 8) & 0xff))
	b.WriteByte(uint8((i >> 16) & 0xff))
}

// WriteUint16 writes a uint16
func WriteUint16(b *bytes.Buffer, i uint16) {
	b.WriteByte(uint8(i & 0xff))
	b.WriteByte(uint8((i >> 8) & 0xff))
}

// RandomBit returns a cryptographically secure random bit (encoded as true / false)
func RandomBit() (bool, error) {
	b := make([]byte, 1)
	_, err := rand.Read(b)
	if err != nil {
		return false, err
	}
	if uint8(b[0])%2 == 0 {
		return false, nil
	}
	return true, nil
}

// Uint32Slice attaches the methods of sort.Interface to []uint32, sorting in increasing order.
type Uint32Slice []uint32

func (s Uint32Slice) Len() int           { return len(s) }
func (s Uint32Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Uint32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
<commit_msg>remove unused byte masks from WriteUint functions<commit_after>package utils

import (
	"bytes"
	"crypto/rand"
	"io"

	"github.com/lucas-clemente/quic-go/protocol"
)

// ReadStream is the read part of a QUIC stream
type ReadStream interface {
	io.Reader
	io.ByteReader
}

// Stream is the interface for QUIC streams
type Stream interface {
	io.Reader
	io.ByteReader
	io.Writer
	io.Closer
	StreamID() protocol.StreamID
	CloseRemote(offset protocol.ByteCount)
}

// ReadUintN reads N bytes
func ReadUintN(b io.ByteReader, length uint8) (uint64, error) {
	var res uint64
	for i := uint8(0); i < length; i++ {
		bt, err := b.ReadByte()
		if err != nil {
			return 0, err
		}
		res ^= uint64(bt) << (i * 8)
	}
	return res, nil
}

// ReadUint64 reads a uint64
func ReadUint64(b io.ByteReader) (uint64, error) {
	var b1, b2, b3, b4, b5, b6, b7, b8 uint8
	var err error
	if b1, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b2, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b3, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b4, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b5, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b6, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b7, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b8, err = b.ReadByte(); err != nil {
		return 0, err
	}
	return uint64(b1) + uint64(b2)<<8 + uint64(b3)<<16 + uint64(b4)<<24 + uint64(b5)<<32 + uint64(b6)<<40 + uint64(b7)<<48 + uint64(b8)<<56, nil
}

// ReadUint32 reads a uint32
func ReadUint32(b io.ByteReader) (uint32, error) {
	var b1, b2, b3, b4 uint8
	var err error
	if b1, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b2, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b3, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b4, err = b.ReadByte(); err != nil {
		return 0, err
	}
	return uint32(b1) + uint32(b2)<<8 + uint32(b3)<<16 + uint32(b4)<<24, nil
}

// ReadUint16 reads a uint16
func ReadUint16(b io.ByteReader) (uint16, error) {
	var b1, b2 uint8
	var err error
	if b1, err = b.ReadByte(); err != nil {
		return 0, err
	}
	if b2, err = b.ReadByte(); err != nil {
		return 0, err
	}
	return uint16(b1) + uint16(b2)<<8, nil
}

// WriteUint64 writes a uint64
func WriteUint64(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i))
	b.WriteByte(uint8(i >> 8))
	b.WriteByte(uint8(i >> 16))
	b.WriteByte(uint8(i >> 24))
	b.WriteByte(uint8(i >> 32))
	b.WriteByte(uint8(i >> 40))
	b.WriteByte(uint8(i >> 48))
	b.WriteByte(uint8(i >> 56))
}

// WriteUint56 writes 56 bit of a uint64
func WriteUint56(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i))
	b.WriteByte(uint8(i >> 8))
	b.WriteByte(uint8(i >> 16))
	b.WriteByte(uint8(i >> 24))
	b.WriteByte(uint8(i >> 32))
	b.WriteByte(uint8(i >> 40))
	b.WriteByte(uint8(i >> 48))
}

// WriteUint48 writes 48 bit of a uint64
func WriteUint48(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i))
	b.WriteByte(uint8(i >> 8))
	b.WriteByte(uint8(i >> 16))
	b.WriteByte(uint8(i >> 24))
	b.WriteByte(uint8(i >> 32))
	b.WriteByte(uint8(i >> 40))
}

// WriteUint40 writes 40 bit of a uint64
func WriteUint40(b *bytes.Buffer, i uint64) {
	b.WriteByte(uint8(i))
	b.WriteByte(uint8(i >> 8))
	b.WriteByte(uint8(i >> 16))
	b.WriteByte(uint8(i >> 24))
	b.WriteByte(uint8(i >> 32))
}

// WriteUint32 writes a uint32
func WriteUint32(b *bytes.Buffer, i uint32) {
	b.WriteByte(uint8(i))
	b.WriteByte(uint8(i >> 8))
	b.WriteByte(uint8(i >> 16))
	b.WriteByte(uint8(i >> 24))
}

// WriteUint24 writes 24 bit of a uint32
func WriteUint24(b *bytes.Buffer, i uint32) {
	b.WriteByte(uint8(i))
	b.WriteByte(uint8(i >> 8))
	b.WriteByte(uint8(i >> 16))
}

// WriteUint16 writes a uint16
func WriteUint16(b *bytes.Buffer, i uint16) {
	b.WriteByte(uint8(i))
	b.WriteByte(uint8(i >> 8))
}

// RandomBit returns a cryptographically secure random bit (encoded as true / false)
func RandomBit() (bool, error) {
	b := make([]byte, 1)
	_, err := rand.Read(b)
	if err != nil {
		return false, err
	}
	if uint8(b[0])%2 == 0 {
		return false, nil
	}
	return true, nil
}

// Uint32Slice attaches the methods of sort.Interface to []uint32, sorting in increasing order.
type Uint32Slice []uint32

func (s Uint32Slice) Len() int           { return len(s) }
func (s Uint32Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s Uint32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
<|endoftext|>


<commit_before>package utils

import (
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"reflect"
	"strings"
	"text/template"
	"unicode"

	"github.com/hacdias/caddy-hugo/assets"
	"github.com/hacdias/caddy-hugo/config"
	"github.com/spf13/cobra"
	"github.com/spf13/hugo/commands"
	"github.com/spf13/viper"
)

// CanBeEdited checks if the extension of a file is supported by the editor
func CanBeEdited(filename string) bool {
	extensions := [...]string{
		"md", "markdown", "mdown", "mmark",
		"asciidoc", "adoc", "ad",
		"rst",
		".json", ".toml", ".yaml",
		".css", ".sass", ".scss",
		".js",
		".html",
		".txt",
	}

	for _, extension := range extensions {
		if strings.HasSuffix(filename, extension) {
			return true
		}
	}

	return false
}

// CopyFile is used to copy a file
func CopyFile(old, new string) error {
	// Open the file and create a new one
	r, err := os.Open(old)
	if err != nil {
		return err
	}
	defer r.Close()

	w, err := os.Create(new)
	if err != nil {
		return err
	}
	defer w.Close()

	// Copy the content
	_, err = io.Copy(w, r)
	if err != nil {
		return err
	}

	return nil
}

// Defined checks if variable is defined in a struct
func Defined(data interface{}, field string) bool {
	t := reflect.Indirect(reflect.ValueOf(data)).Type()

	if t.Kind() != reflect.Struct {
		log.Print("Non-struct type not allowed.")
		return false
	}

	_, b := t.FieldByName(field)
	return b
}

// Dict allows to send more than one variable into a template
func Dict(values ...interface{}) (map[string]interface{}, error) {
	if len(values)%2 != 0 {
		return nil, errors.New("invalid dict call")
	}
	dict := make(map[string]interface{}, len(values)/2)
	for i := 0; i < len(values); i += 2 {
		key, ok := values[i].(string)
		if !ok {
			return nil, errors.New("dict keys must be strings")
		}
		dict[key] = values[i+1]
	}

	return dict, nil
}

// GetTemplate is used to get a ready to use template based on the url and on
// other sent templates
func GetTemplate(r *http.Request, functions template.FuncMap, templates ...string) (*template.Template, error) {
	// If this is a pjax request, use the minimal template to send only
	// the main content
	if r.Header.Get("X-PJAX") == "true" {
		templates = append(templates, "base_minimal")
	} else {
		templates = append(templates, "base_full")
	}

	var tpl *template.Template

	// For each template, add it to the the tpl variable
	for i, t := range templates {
		// Get the template from the assets
		page, err := assets.Asset("templates/" + t + ".tmpl")

		// Check if there is some error. If so, the template doesn't exist
		if err != nil {
			log.Print(err)
			return new(template.Template), err
		}

		// If it's the first iteration, creates a new template and add the
		// functions map
		if i == 0 {
			tpl, err = template.New(t).Funcs(functions).Parse(string(page))
		} else {
			tpl, err = tpl.Parse(string(page))
		}

		if err != nil {
			log.Print(err)
			return new(template.Template), err
		}
	}

	return tpl, nil
}

// IsMap checks if some variable is a map
func IsMap(sth interface{}) bool {
	return reflect.ValueOf(sth).Kind() == reflect.Map
}

// IsSlice checks if some variable is a slice
func IsSlice(sth interface{}) bool {
	return reflect.ValueOf(sth).Kind() == reflect.Slice
}

// ParseComponents parses the components of an URL creating an array
func ParseComponents(r *http.Request) []string {
	//The URL that the user queried.
	path := r.URL.Path
	path = strings.TrimSpace(path)
	//Cut off the leading and trailing forward slashes, if they exist.
	//This cuts off the leading forward slash.
	if strings.HasPrefix(path, "/") {
		path = path[1:]
	}
	//This cuts off the trailing forward slash.
	if strings.HasSuffix(path, "/") {
		cutOffLastCharLen := len(path) - 1
		path = path[:cutOffLastCharLen]
	}
	//We need to isolate the individual components of the path.
	components := strings.Split(path, "/")
	return components
}

// Run is used to run the static website generator
func Run(c *config.Config) {
	create := false

	if _, err := os.Stat(c.Path + "config.yaml"); os.IsNotExist(err) {
		create = true
	}

	if _, err := os.Stat(c.Path + "config.json"); os.IsNotExist(err) {
		create = true
	}

	if _, err := os.Stat(c.Path + "config.toml"); os.IsNotExist(err) {
		create = true
	}

	if create {
		fmt.Print("Are you sure you want to generate a Hugo website on " + c.Path + "? (y/n)")
		cmd := &cobra.Command{}
		cmd.Flags().Bool("force", true, "")
		commands.NewSite(cmd, []string{c.Path})
	}

	cwd, err := os.Getwd()

	if err != nil {
		log.Print("Can't get working directory.")
	}

	err = os.Chdir(c.Path)

	if err != nil {
		log.Print("Can't get working directory.")
	}

	viper.Reset()
	commands.HugoCmd.ParseFlags(c.Args)
	err = commands.HugoCmd.RunE(nil, nil)

	if err != nil {
		log.Print(err)
	}

	err = os.Chdir(cwd)

	if err != nil {
		log.Print("Can't get working directory.")
	}
}

var splitCapitalizeExceptions = map[string]string{
	"youtube":    "YouTube",
	"github":     "GitHub",
	"googleplus": "Google Plus",
	"linkedin":   "LinkedIn",
}

// SplitCapitalize splits a string by its uppercase letters and capitalize the
// first letter of the string
func SplitCapitalize(name string) string {
	if val, ok := splitCapitalizeExceptions[strings.ToLower(name)]; ok {
		return val
	}

	var words []string
	l := 0
	for s := name; s != ""; s = s[l:] {
		l = strings.IndexFunc(s[1:], unicode.IsUpper) + 1
		if l <= 0 {
			l = len(s)
		}
		words = append(words, s[:l])
	}

	name = ""

	for _, element := range words {
		name += element + " "
	}

	name = strings.ToLower(name[:len(name)-1])
	name = strings.ToUpper(string(name[0])) + name[1:]

	return name
}
<commit_msg>remove question<commit_after>package utils

import (
	"errors"
	"io"
	"log"
	"net/http"
	"os"
	"reflect"
	"strings"
	"text/template"
	"unicode"

	"github.com/hacdias/caddy-hugo/assets"
	"github.com/hacdias/caddy-hugo/config"
	"github.com/spf13/cobra"
	"github.com/spf13/hugo/commands"
	"github.com/spf13/viper"
)

// CanBeEdited checks if the extension of a file is supported by the editor
func CanBeEdited(filename string) bool {
	extensions := [...]string{
		"md", "markdown", "mdown", "mmark",
		"asciidoc", "adoc", "ad",
		"rst",
		".json", ".toml", ".yaml",
		".css", ".sass", ".scss",
		".js",
		".html",
		".txt",
	}

	for _, extension := range extensions {
		if strings.HasSuffix(filename, extension) {
			return true
		}
	}

	return false
}

// CopyFile is used to copy a file
func CopyFile(old, new string) error {
	// Open the file and create a new one
	r, err := os.Open(old)
	if err != nil {
		return err
	}
	defer r.Close()

	w, err := os.Create(new)
	if err != nil {
		return err
	}
	defer w.Close()

	// Copy the content
	_, err = io.Copy(w, r)
	if err != nil {
		return err
	}

	return nil
}

// Defined checks if variable is defined in a struct
func Defined(data interface{}, field string) bool {
	t := reflect.Indirect(reflect.ValueOf(data)).Type()

	if t.Kind() != reflect.Struct {
		log.Print("Non-struct type not allowed.")
		return false
	}

	_, b := t.FieldByName(field)
	return b
}

// Dict allows to send more than one variable into a template
func Dict(values ...interface{}) (map[string]interface{}, error) {
	if len(values)%2 != 0 {
		return nil, errors.New("invalid dict call")
	}
	dict := make(map[string]interface{}, len(values)/2)
	for i := 0; i < len(values); i += 2 {
		key, ok := values[i].(string)
		if !ok {
			return nil, errors.New("dict keys must be strings")
		}
		dict[key] = values[i+1]
	}

	return dict, nil
}

// GetTemplate is used to get a ready to use template based on the url and on
// other sent templates
func GetTemplate(r *http.Request, functions template.FuncMap, templates ...string) (*template.Template, error) {
	// If this is a pjax request, use the minimal template to send only
	// the main content
	if r.Header.Get("X-PJAX") == "true" {
		templates = append(templates, "base_minimal")
	} else {
		templates = append(templates, "base_full")
	}

	var tpl *template.Template

	// For each template, add it to the the tpl variable
	for i, t := range templates {
		// Get the template from the assets
		page, err := assets.Asset("templates/" + t + ".tmpl")

		// Check if there is some error. If so, the template doesn't exist
		if err != nil {
			log.Print(err)
			return new(template.Template), err
		}

		// If it's the first iteration, creates a new template and add the
		// functions map
		if i == 0 {
			tpl, err = template.New(t).Funcs(functions).Parse(string(page))
		} else {
			tpl, err = tpl.Parse(string(page))
		}

		if err != nil {
			log.Print(err)
			return new(template.Template), err
		}
	}

	return tpl, nil
}

// IsMap checks if some variable is a map
func IsMap(sth interface{}) bool {
	return reflect.ValueOf(sth).Kind() == reflect.Map
}

// IsSlice checks if some variable is a slice
func IsSlice(sth interface{}) bool {
	return reflect.ValueOf(sth).Kind() == reflect.Slice
}

// ParseComponents parses the components of an URL creating an array
func ParseComponents(r *http.Request) []string {
	//The URL that the user queried.
	path := r.URL.Path
	path = strings.TrimSpace(path)
	//Cut off the leading and trailing forward slashes, if they exist.
	//This cuts off the leading forward slash.
	if strings.HasPrefix(path, "/") {
		path = path[1:]
	}
	//This cuts off the trailing forward slash.
	if strings.HasSuffix(path, "/") {
		cutOffLastCharLen := len(path) - 1
		path = path[:cutOffLastCharLen]
	}
	//We need to isolate the individual components of the path.
	components := strings.Split(path, "/")
	return components
}

// Run is used to run the static website generator
func Run(c *config.Config) {
	create := false

	if _, err := os.Stat(c.Path + "config.yaml"); os.IsNotExist(err) {
		create = true
	}

	if _, err := os.Stat(c.Path + "config.json"); os.IsNotExist(err) {
		create = true
	}

	if _, err := os.Stat(c.Path + "config.toml"); os.IsNotExist(err) {
		create = true
	}

	if create {
		cmd := &cobra.Command{}
		cmd.Flags().Bool("force", true, "")
		commands.NewSite(cmd, []string{c.Path})
	}

	cwd, err := os.Getwd()

	if err != nil {
		log.Print("Can't get working directory.")
	}

	err = os.Chdir(c.Path)

	if err != nil {
		log.Print("Can't get working directory.")
	}

	viper.Reset()
	commands.HugoCmd.ParseFlags(c.Args)
	err = commands.HugoCmd.RunE(nil, nil)

	if err != nil {
		log.Print(err)
	}

	err = os.Chdir(cwd)

	if err != nil {
		log.Print("Can't get working directory.")
	}
}

var splitCapitalizeExceptions = map[string]string{
	"youtube":    "YouTube",
	"github":     "GitHub",
	"googleplus": "Google Plus",
	"linkedin":   "LinkedIn",
}

// SplitCapitalize splits a string by its uppercase letters and capitalize the
// first letter of the string
func SplitCapitalize(name string) string {
	if val, ok := splitCapitalizeExceptions[strings.ToLower(name)]; ok {
		return val
	}

	var words []string
	l := 0
	for s := name; s != ""; s = s[l:] {
		l = strings.IndexFunc(s[1:], unicode.IsUpper) + 1
		if l <= 0 {
			l = len(s)
		}
		words = append(words, s[:l])
	}

	name = ""

	for _, element := range words {
		name += element + " "
	}

	name = strings.ToLower(name[:len(name)-1])
	name = strings.ToUpper(string(name[0])) + name[1:]

	return name
}
<|endoftext|>


<commit_before>/*
Copyright 2015-2016, RadiantBlue Technologies, Inc.

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 utils provides various utilities that are used throughout the project.

Provide functions to return canned responses: StatusOK, StatusBadRequest, and StatusInternalServerError.
*/
package utils

import (
	"fmt"
	"net/http"
	"os"

	"github.com/venicegeo/pzsvc-sdk-go/job"
	"github.com/venicegeo/pzsvc-sdk-go/s3"
)

// FunctionFunc defines the signature of our function creator.
type FunctionFunc func(
	http.ResponseWriter,
	*http.Request,
	*job.OutputMsg,
	job.InputMsg,
)

// MakeFunction wraps the individual PDAL functions.
// Parse the input and output filenames, creating files as needed. Download the
// input data and upload the output data.
func MakeFunction(
	fn func(
		http.ResponseWriter,
		*http.Request,
		*job.OutputMsg,
		job.InputMsg,
		string,
		string,
	),
) FunctionFunc {
	return func(
		w http.ResponseWriter,
		r *http.Request,
		res *job.OutputMsg,
		msg job.InputMsg,
	) {
		var inputName, outputName string
		var fileIn, fileOut *os.File

		// Split the source S3 key string, interpreting the last element as the
		// input filename. Create the input file, throwing 500 on error.
		inputName = s3.ParseFilenameFromKey(msg.Source.Key)
		fileIn, err := os.Create(inputName)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer fileIn.Close()

		// If provided, split the destination S3 key string, interpreting the last
		// element as the output filename. Create the output file, throwing 500 on
		// error.
		if len(msg.Destination.Key) > 0 {
			outputName = s3.ParseFilenameFromKey(msg.Destination.Key)
		}

		// Download the source data from S3, throwing 500 on error.
		err = s3.Download(fileIn, msg.Source.Bucket, msg.Source.Key)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		info, err := os.Stat(outputName)
		if err != nil {
			fmt.Println(info)
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		// Run the PDAL function.
		fn(w, r, res, msg, inputName, outputName)

		// If an output has been created, upload the destination data to S3,
		// throwing 500 on error.
		if len(msg.Destination.Key) > 0 {
			fileOut, err = os.Open(outputName)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			defer fileOut.Close()
			err = s3.Upload(fileOut, msg.Destination.Bucket, msg.Destination.Key)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		}
	}
}
<commit_msg>do not error<commit_after>/*
Copyright 2015-2016, RadiantBlue Technologies, Inc.

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 utils provides various utilities that are used throughout the project.

Provide functions to return canned responses: StatusOK, StatusBadRequest, and StatusInternalServerError.
*/
package utils

import (
	"fmt"
	"net/http"
	"os"

	"github.com/venicegeo/pzsvc-sdk-go/job"
	"github.com/venicegeo/pzsvc-sdk-go/s3"
)

// FunctionFunc defines the signature of our function creator.
type FunctionFunc func(
	http.ResponseWriter,
	*http.Request,
	*job.OutputMsg,
	job.InputMsg,
)

// MakeFunction wraps the individual PDAL functions.
// Parse the input and output filenames, creating files as needed. Download the
// input data and upload the output data.
func MakeFunction(
	fn func(
		http.ResponseWriter,
		*http.Request,
		*job.OutputMsg,
		job.InputMsg,
		string,
		string,
	),
) FunctionFunc {
	return func(
		w http.ResponseWriter,
		r *http.Request,
		res *job.OutputMsg,
		msg job.InputMsg,
	) {
		var inputName, outputName string
		var fileIn, fileOut *os.File

		// Split the source S3 key string, interpreting the last element as the
		// input filename. Create the input file, throwing 500 on error.
		inputName = s3.ParseFilenameFromKey(msg.Source.Key)
		fileIn, err := os.Create(inputName)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer fileIn.Close()

		// If provided, split the destination S3 key string, interpreting the last
		// element as the output filename. Create the output file, throwing 500 on
		// error.
		if len(msg.Destination.Key) > 0 {
			outputName = s3.ParseFilenameFromKey(msg.Destination.Key)
		}

		// Download the source data from S3, throwing 500 on error.
		err = s3.Download(fileIn, msg.Source.Bucket, msg.Source.Key)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		info, _ := os.Stat(outputName)
		fmt.Println(info)
		// if err != nil {
		// 	http.Error(w, err.Error(), http.StatusInternalServerError)
		// 	return
		// }

		// Run the PDAL function.
		fn(w, r, res, msg, inputName, outputName)

		// If an output has been created, upload the destination data to S3,
		// throwing 500 on error.
		if len(msg.Destination.Key) > 0 {
			fileOut, err = os.Open(outputName)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
			defer fileOut.Close()
			err = s3.Upload(fileOut, msg.Destination.Bucket, msg.Destination.Key)
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Package table allows read and write sorted key/value.
package table

import (
	"encoding/binary"
)

/*
Table:

Table is consist of one or more data blocks, an optional filter block
a metaindex block, an index block and a table footer. Metaindex block
is a special block used to keep parameters of the table, such as filter
block name and its block handle. Index block is a special block used to
keep record of data blocks offset and length, index block use one as
restart interval. The key used by index block are the last key of preceding
block, shorter separator of adjacent blocks or shorter successor of the
last key of the last block. Filter block is an optional block contains
sequence of filter data generated by a filter generator.

Table data structure:
                                                         + optional
                                                        /
    +--------------+--------------+--------------+------+-------+-----------------+-------------+--------+
    | data block 1 |      ...     | data block n | filter block | metaindex block | index block | footer |
    +--------------+--------------+--------------+--------------+-----------------+-------------+--------+

Table footer:

      +------------------- 40-bytes -------------------+
     /                                                  \
    +------------------------+--------------------+------+-----------------+
    | metaindex block handle / index block handle / ---- | magic (8-bytes) |
    +------------------------+--------------------+------+-----------------+

    The magic are first 64-bit of SHA-1 sum of "http://code.google.com/p/leveldb/".

NOTE: All fixed-length integer are little-endian.
*/

/*
Block:

Block is consist of one or more key/value entries and a block trailer.
Block entry shares key prefix with its preceding key until a restart
point reached. A block should contains at least one restart point.
First restart point are always zero.

Block data structure:

      + restart point                 + restart point (depends on restart interval)
     /                               /
    +---------------+---------------+---------------+---------------+---------+
    | block entry 1 | block entry 2 |      ...      | block entry n | trailer |
    +---------------+---------------+---------------+---------------+---------+

Key/value entry:

              +---- key len ----+
             /                   \
    +-------+---------+-----------+---------+--------------------+--------------+----------------+
    | shared (varint) | not shared (varint) | value len (varint) | key (varlen) | value (varlen) |
    +-----------------+---------------------+--------------------+--------------+----------------+

    Block entry shares key prefix with its preceding key:
    Conditions:
        restart_interval=2
        entry one  : key=deck,value=v1
        entry two  : key=dock,value=v2
        entry three: key=duck,value=v3
    The entries will be encoded as follow:

      + restart point (offset=0)                                                 + restart point (offset=16)
     /                                                                          /
    +-----+-----+-----+----------+--------+-----+-----+-----+---------+--------+-----+-----+-----+----------+--------+
    |  0  |  4  |  2  |  "deck"  |  "v1"  |  1  |  3  |  2  |  "ock"  |  "v2"  |  0  |  4  |  2  |  "duck"  |  "v3"  |
    +-----+-----+-----+----------+--------+-----+-----+-----+---------+--------+-----+-----+-----+----------+--------+
     \                                   / \                                  / \                                   /
      +----------- entry one -----------+   +----------- entry two ----------+   +----------- entry one -----------+

    The block trailer will contains two restart points:

    +------------+-----------+--------+
    |     0      |    16     |   2    |
    +------------+-----------+--------+
     \                      /
      +-- restart points --+

Block trailer:

      +-- 4-bytes --+
     /               \
    +-----------------+-----------------+-----------------+------------------------------+
    | restart point 1 |       ....      | restart point n | restart points len (4-bytes) |
    +-----------------+-----------------+-----------------+------------------------------+

NOTE: All fixed-length integer are little-endian.
*/

/*
Filter block:

Filter block consist of one or more filter data and a filter block trailer.
The trailer contains filter data offsets, a trailer offset and a 1-byte base Lg.

Filter block data structure:

      + offset 1      + offset 2      + offset n      + trailer offset
     /               /               /               /
    +---------------+---------------+---------------+---------+
    | filter data 1 |      ...      | filter data n | trailer |
    +---------------+---------------+---------------+---------+

Filter block trailer:

      +- 4-bytes -+
     /             \
    +---------------+---------------+---------------+-------------------------+------------------+
    |    offset 1   |      ....     |    offset n   | filter offset (4-bytes) | base Lg (1-byte) |
    +-------------- +---------------+---------------+-------------------------+------------------+

NOTE: All fixed-length integer are little-endian.
*/

const (
	blockTrailerLen = 5
	footerLen       = 48

	magic = "\x57\xfb\x80\x8b\x24\x75\x47\xdb"

	// The block type gives the per-block compression format.
	// These constants are part of the file format and should not be changed.
	blockTypeNoCompression     = 0
	blockTypeSnappyCompression = 1

	// Generate new filter every 2KB of data
	filterBaseLg = 11
	filterBase   = 1 << filterBaseLg
)

type blockHandle struct {
	offset, length uint64
}

func decodeBlockHandle(src []byte) (blockHandle, int) {
	offset, n := binary.Uvarint(src)
	length, m := binary.Uvarint(src[n:])
	if n == 0 || m == 0 {
		return blockHandle{}, 0
	}
	return blockHandle{offset, length}, n + m
}

func encodeBlockHandle(dst []byte, b blockHandle) int {
	n := binary.PutUvarint(dst, b.offset)
	m := binary.PutUvarint(dst[n:], b.length)
	return n + m
}
<commit_msg>table: Fixes table format documentations<commit_after>// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Package table allows read and write sorted key/value.
package table

import (
	"encoding/binary"
)

/*
Table:

Table is consist of one or more data blocks, an optional filter block
a metaindex block, an index block and a table footer. Metaindex block
is a special block used to keep parameters of the table, such as filter
block name and its block handle. Index block is a special block used to
keep record of data blocks offset and length, index block use one as
restart interval. The key used by index block are the last key of preceding
block, shorter separator of adjacent blocks or shorter successor of the
last key of the last block. Filter block is an optional block contains
sequence of filter data generated by a filter generator.

Table data structure:
                                                         + optional
                                                        /
    +--------------+--------------+--------------+------+-------+-----------------+-------------+--------+
    | data block 1 |      ...     | data block n | filter block | metaindex block | index block | footer |
    +--------------+--------------+--------------+--------------+-----------------+-------------+--------+

Table footer:

      +------------------- 40-bytes -------------------+
     /                                                  \
    +------------------------+--------------------+------+-----------------+
    | metaindex block handle / index block handle / ---- | magic (8-bytes) |
    +------------------------+--------------------+------+-----------------+

    The magic are first 64-bit of SHA-1 sum of "http://code.google.com/p/leveldb/".

NOTE: All fixed-length integer are little-endian.
*/

/*
Block:

Block is consist of one or more key/value entries and a block trailer.
Block entry shares key prefix with its preceding key until a restart
point reached. A block should contains at least one restart point.
First restart point are always zero.

Block data structure:

      + restart point                 + restart point (depends on restart interval)
     /                               /
    +---------------+---------------+---------------+---------------+---------+
    | block entry 1 | block entry 2 |      ...      | block entry n | trailer |
    +---------------+---------------+---------------+---------------+---------+

Key/value entry:

              +---- key len ----+
             /                   \
    +-------+---------+-----------+---------+--------------------+--------------+----------------+
    | shared (varint) | not shared (varint) | value len (varint) | key (varlen) | value (varlen) |
    +-----------------+---------------------+--------------------+--------------+----------------+

    Block entry shares key prefix with its preceding key:
    Conditions:
        restart_interval=2
        entry one  : key=deck,value=v1
        entry two  : key=dock,value=v2
        entry three: key=duck,value=v3
    The entries will be encoded as follow:

      + restart point (offset=0)                                                 + restart point (offset=16)
     /                                                                          /
    +-----+-----+-----+----------+--------+-----+-----+-----+---------+--------+-----+-----+-----+----------+--------+
    |  0  |  4  |  2  |  "deck"  |  "v1"  |  1  |  3  |  2  |  "ock"  |  "v2"  |  0  |  4  |  2  |  "duck"  |  "v3"  |
    +-----+-----+-----+----------+--------+-----+-----+-----+---------+--------+-----+-----+-----+----------+--------+
     \                                   / \                                  / \                                   /
      +----------- entry one -----------+   +----------- entry two ----------+   +---------- entry three ----------+

    The block trailer will contains two restart points:

    +------------+-----------+--------+
    |     0      |    16     |   2    |
    +------------+-----------+---+----+
     \                      /     \
      +-- restart points --+       + restart points length

Block trailer:

      +-- 4-bytes --+
     /               \
    +-----------------+-----------------+-----------------+------------------------------+
    | restart point 1 |       ....      | restart point n | restart points len (4-bytes) |
    +-----------------+-----------------+-----------------+------------------------------+

NOTE: All fixed-length integer are little-endian.
*/

/*
Filter block:

Filter block consist of one or more filter data and a filter block trailer.
The trailer contains filter data offsets, a trailer offset and a 1-byte base Lg.

Filter block data structure:

      + offset 1      + offset 2      + offset n      + trailer offset
     /               /               /               /
    +---------------+---------------+---------------+---------+
    | filter data 1 |      ...      | filter data n | trailer |
    +---------------+---------------+---------------+---------+

Filter block trailer:

      +- 4-bytes -+
     /             \
    +---------------+---------------+---------------+-------------------------+------------------+
    |    offset 1   |      ....     |    offset n   | filter offset (4-bytes) | base Lg (1-byte) |
    +-------------- +---------------+---------------+-------------------------+------------------+

NOTE: All fixed-length integer are little-endian.
*/

const (
	blockTrailerLen = 5
	footerLen       = 48

	magic = "\x57\xfb\x80\x8b\x24\x75\x47\xdb"

	// The block type gives the per-block compression format.
	// These constants are part of the file format and should not be changed.
	blockTypeNoCompression     = 0
	blockTypeSnappyCompression = 1

	// Generate new filter every 2KB of data
	filterBaseLg = 11
	filterBase   = 1 << filterBaseLg
)

type blockHandle struct {
	offset, length uint64
}

func decodeBlockHandle(src []byte) (blockHandle, int) {
	offset, n := binary.Uvarint(src)
	length, m := binary.Uvarint(src[n:])
	if n == 0 || m == 0 {
		return blockHandle{}, 0
	}
	return blockHandle{offset, length}, n + m
}

func encodeBlockHandle(dst []byte, b blockHandle) int {
	n := binary.PutUvarint(dst, b.offset)
	m := binary.PutUvarint(dst[n:], b.length)
	return n + m
}
<|endoftext|>


<commit_before>// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package kusttest_test

import (
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"testing"

	"sigs.k8s.io/kustomize/api/filesys"
	"sigs.k8s.io/kustomize/api/ifc"
	pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
	"sigs.k8s.io/kustomize/api/konfig"
	fLdr "sigs.k8s.io/kustomize/api/loader"
	"sigs.k8s.io/kustomize/api/provider"
	"sigs.k8s.io/kustomize/api/resmap"
	valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
	"sigs.k8s.io/kustomize/api/types"
)

// HarnessEnhanced manages a full plugin environment for tests.
type HarnessEnhanced struct {
	// An instance of *testing.T, and a filesystem (likely in-memory)
	// for loading test data - plugin config, resources to transform, etc.
	Harness

	// plugintestEnv holds the plugin compiler and data needed to
	// create compilation sub-processes.
	pte *pluginTestEnv

	// rf creates Resources from byte streams.
	rf *resmap.Factory

	// A file loader using the Harness.fSys to read test data.
	ldr ifc.Loader

	// If true, wipe the ifc.loader root (not the plugin loader root)
	// as part of cleanup.
	shouldWipeLdrRoot bool

	// A plugin loader that loads plugins from a (real) file system.
	pl *pLdr.Loader
}

func MakeEnhancedHarness(t *testing.T) *HarnessEnhanced {
	r := makeBaseEnhancedHarness(t)
	r.Harness = MakeHarnessWithFs(t, filesys.MakeFsInMemory())
	// Point the Harness's file loader to the root ('/')
	// of the in-memory file system.
	r.ResetLoaderRoot(filesys.Separator)
	return r
}

func MakeEnhancedHarnessWithTmpRoot(t *testing.T) *HarnessEnhanced {
	r := makeBaseEnhancedHarness(t)
	fSys := filesys.MakeFsOnDisk()
	r.Harness = MakeHarnessWithFs(t, fSys)
	tmpDir, err := ioutil.TempDir("", "kust-testing-")
	if err != nil {
		panic("test harness cannot make tmp dir: " + err.Error())
	}
	r.ldr, err = fLdr.NewLoader(fLdr.RestrictionRootOnly, tmpDir, fSys)
	if err != nil {
		panic("test harness cannot make ldr at tmp dir: " + err.Error())
	}
	r.shouldWipeLdrRoot = true
	return r
}

func makeBaseEnhancedHarness(t *testing.T) *HarnessEnhanced {
	rf := resmap.NewFactory(
		provider.NewDefaultDepProvider().GetResourceFactory())
	return &HarnessEnhanced{
		pte: newPluginTestEnv(t).set(),
		rf:  rf,
		pl: pLdr.NewLoader(
			types.EnabledPluginConfig(types.BploLoadFromFileSys),
			rf,
			// Plugin configs are always located on disk,
			// regardless of the test harness's FS
			filesys.MakeFsOnDisk())}
}

func (th *HarnessEnhanced) ErrIfNoHelm() error {
	_, err := exec.LookPath(th.GetPluginConfig().HelmConfig.Command)
	return err
}

func (th *HarnessEnhanced) GetRoot() string {
	return th.ldr.Root()
}

func (th *HarnessEnhanced) Reset() {
	if th.shouldWipeLdrRoot {
		if !strings.HasPrefix(th.ldr.Root(), os.TempDir()) {
			// sanity check.
			panic("something strange about th.ldr.Root() = " + th.ldr.Root())
		}
		os.RemoveAll(th.ldr.Root())
	}
	th.pte.reset()
}

func (th *HarnessEnhanced) GetPluginConfig() *types.PluginConfig {
	return th.pl.Config()
}

func (th *HarnessEnhanced) PrepBuiltin(k string) *HarnessEnhanced {
	return th.BuildGoPlugin(konfig.BuiltinPluginPackage, "", k)
}

func (th *HarnessEnhanced) BuildGoPlugin(g, v, k string) *HarnessEnhanced {
	th.pte.prepareGoPlugin(g, v, k)
	return th
}

func (th *HarnessEnhanced) PrepExecPlugin(g, v, k string) *HarnessEnhanced {
	th.pte.prepareExecPlugin(g, v, k)
	return th
}

// ResetLoaderRoot interprets its argument as an absolute directory path.
// It creates the directory, and creates the harness's file loader
// rooted in that directory.
func (th *HarnessEnhanced) ResetLoaderRoot(root string) {
	if err := th.fSys.Mkdir(root); err != nil {
		th.t.Fatal(err)
	}
	ldr, err := fLdr.NewLoader(
		fLdr.RestrictionRootOnly, root, th.fSys)
	if err != nil {
		th.t.Fatalf("Unable to make loader: %v", err)
	}
	th.ldr = ldr
}

func (th *HarnessEnhanced) LoadAndRunGenerator(
	config string) resmap.ResMap {
	res, err := th.rf.RF().FromBytes([]byte(config))
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	g, err := th.pl.LoadGenerator(
		th.ldr, valtest_test.MakeFakeValidator(), res)
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	rm, err := g.Generate()
	if err != nil {
		th.t.Fatalf("generate err: %v", err)
	}
	rm.RemoveBuildAnnotations()
	return rm
}

func (th *HarnessEnhanced) LoadAndRunTransformer(
	config, input string) resmap.ResMap {
	resMap, err := th.RunTransformer(config, input)
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	return resMap
}

func (th *HarnessEnhanced) RunTransformerAndCheckResult(
	config, input, expected string) {
	resMap := th.LoadAndRunTransformer(config, input)
	th.AssertActualEqualsExpectedNoIdAnnotations(resMap, expected)
}

func (th *HarnessEnhanced) ErrorFromLoadAndRunTransformer(
	config, input string) error {
	_, err := th.RunTransformer(config, input)
	return err
}

type AssertFunc func(t *testing.T, err error)

func (th *HarnessEnhanced) RunTransformerAndCheckError(
	config, input string, assertFn AssertFunc) {
	_, err := th.RunTransformer(config, input)
	assertFn(th.t, err)
}

func (th *HarnessEnhanced) RunTransformer(
	config, input string) (resmap.ResMap, error) {
	resMap, err := th.rf.NewResMapFromBytes([]byte(input))
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	return th.RunTransformerFromResMap(config, resMap)
}

func (th *HarnessEnhanced) RunTransformerFromResMap(
	config string, resMap resmap.ResMap) (resmap.ResMap, error) {
	transConfig, err := th.rf.RF().FromBytes([]byte(config))
	if err != nil {
		th.t.Logf("config: '%s'", config)
		th.t.Fatalf("Err: %v", err)
	}
	g, err := th.pl.LoadTransformer(
		th.ldr, valtest_test.MakeFakeValidator(), transConfig)
	if err != nil {
		return nil, err
	}
	err = g.Transform(resMap)
	return resMap, err
}
<commit_msg>Add testharness mkdir function.<commit_after>// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

package kusttest_test

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"

	"sigs.k8s.io/kustomize/api/filesys"
	"sigs.k8s.io/kustomize/api/ifc"
	pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
	"sigs.k8s.io/kustomize/api/konfig"
	fLdr "sigs.k8s.io/kustomize/api/loader"
	"sigs.k8s.io/kustomize/api/provider"
	"sigs.k8s.io/kustomize/api/resmap"
	valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
	"sigs.k8s.io/kustomize/api/types"
)

// HarnessEnhanced manages a full plugin environment for tests.
type HarnessEnhanced struct {
	// An instance of *testing.T, and a filesystem (likely in-memory)
	// for loading test data - plugin config, resources to transform, etc.
	Harness

	// plugintestEnv holds the plugin compiler and data needed to
	// create compilation sub-processes.
	pte *pluginTestEnv

	// rf creates Resources from byte streams.
	rf *resmap.Factory

	// A file loader using the Harness.fSys to read test data.
	ldr ifc.Loader

	// If true, wipe the ifc.loader root (not the plugin loader root)
	// as part of cleanup.
	shouldWipeLdrRoot bool

	// A plugin loader that loads plugins from a (real) file system.
	pl *pLdr.Loader
}

func MakeEnhancedHarness(t *testing.T) *HarnessEnhanced {
	r := makeBaseEnhancedHarness(t)
	r.Harness = MakeHarnessWithFs(t, filesys.MakeFsInMemory())
	// Point the Harness's file loader to the root ('/')
	// of the in-memory file system.
	r.ResetLoaderRoot(filesys.Separator)
	return r
}

func MakeEnhancedHarnessWithTmpRoot(t *testing.T) *HarnessEnhanced {
	r := makeBaseEnhancedHarness(t)
	fSys := filesys.MakeFsOnDisk()
	r.Harness = MakeHarnessWithFs(t, fSys)
	tmpDir, err := ioutil.TempDir("", "kust-testing-")
	if err != nil {
		panic("test harness cannot make tmp dir: " + err.Error())
	}
	r.ldr, err = fLdr.NewLoader(fLdr.RestrictionRootOnly, tmpDir, fSys)
	if err != nil {
		panic("test harness cannot make ldr at tmp dir: " + err.Error())
	}
	r.shouldWipeLdrRoot = true
	return r
}

func makeBaseEnhancedHarness(t *testing.T) *HarnessEnhanced {
	rf := resmap.NewFactory(
		provider.NewDefaultDepProvider().GetResourceFactory())
	return &HarnessEnhanced{
		pte: newPluginTestEnv(t).set(),
		rf:  rf,
		pl: pLdr.NewLoader(
			types.EnabledPluginConfig(types.BploLoadFromFileSys),
			rf,
			// Plugin configs are always located on disk,
			// regardless of the test harness's FS
			filesys.MakeFsOnDisk())}
}

func (th *HarnessEnhanced) ErrIfNoHelm() error {
	_, err := exec.LookPath(th.GetPluginConfig().HelmConfig.Command)
	return err
}

func (th *HarnessEnhanced) GetRoot() string {
	return th.ldr.Root()
}

func (th *HarnessEnhanced) MkDir(path string) string {
	dir := filepath.Join(th.ldr.Root(), path)
	th.GetFSys().Mkdir(dir)
	return dir
}

func (th *HarnessEnhanced) Reset() {
	if th.shouldWipeLdrRoot {
		if !strings.HasPrefix(th.ldr.Root(), os.TempDir()) {
			// sanity check.
			panic("something strange about th.ldr.Root() = " + th.ldr.Root())
		}
		os.RemoveAll(th.ldr.Root())
	}
	th.pte.reset()
}

func (th *HarnessEnhanced) GetPluginConfig() *types.PluginConfig {
	return th.pl.Config()
}

func (th *HarnessEnhanced) PrepBuiltin(k string) *HarnessEnhanced {
	return th.BuildGoPlugin(konfig.BuiltinPluginPackage, "", k)
}

func (th *HarnessEnhanced) BuildGoPlugin(g, v, k string) *HarnessEnhanced {
	th.pte.prepareGoPlugin(g, v, k)
	return th
}

func (th *HarnessEnhanced) PrepExecPlugin(g, v, k string) *HarnessEnhanced {
	th.pte.prepareExecPlugin(g, v, k)
	return th
}

// ResetLoaderRoot interprets its argument as an absolute directory path.
// It creates the directory, and creates the harness's file loader
// rooted in that directory.
func (th *HarnessEnhanced) ResetLoaderRoot(root string) {
	if err := th.fSys.Mkdir(root); err != nil {
		th.t.Fatal(err)
	}
	ldr, err := fLdr.NewLoader(
		fLdr.RestrictionRootOnly, root, th.fSys)
	if err != nil {
		th.t.Fatalf("Unable to make loader: %v", err)
	}
	th.ldr = ldr
}

func (th *HarnessEnhanced) LoadAndRunGenerator(
	config string) resmap.ResMap {
	res, err := th.rf.RF().FromBytes([]byte(config))
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	g, err := th.pl.LoadGenerator(
		th.ldr, valtest_test.MakeFakeValidator(), res)
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	rm, err := g.Generate()
	if err != nil {
		th.t.Fatalf("generate err: %v", err)
	}
	rm.RemoveBuildAnnotations()
	return rm
}

func (th *HarnessEnhanced) LoadAndRunTransformer(
	config, input string) resmap.ResMap {
	resMap, err := th.RunTransformer(config, input)
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	return resMap
}

func (th *HarnessEnhanced) RunTransformerAndCheckResult(
	config, input, expected string) {
	resMap := th.LoadAndRunTransformer(config, input)
	th.AssertActualEqualsExpectedNoIdAnnotations(resMap, expected)
}

func (th *HarnessEnhanced) ErrorFromLoadAndRunTransformer(
	config, input string) error {
	_, err := th.RunTransformer(config, input)
	return err
}

type AssertFunc func(t *testing.T, err error)

func (th *HarnessEnhanced) RunTransformerAndCheckError(
	config, input string, assertFn AssertFunc) {
	_, err := th.RunTransformer(config, input)
	assertFn(th.t, err)
}

func (th *HarnessEnhanced) RunTransformer(
	config, input string) (resmap.ResMap, error) {
	resMap, err := th.rf.NewResMapFromBytes([]byte(input))
	if err != nil {
		th.t.Fatalf("Err: %v", err)
	}
	return th.RunTransformerFromResMap(config, resMap)
}

func (th *HarnessEnhanced) RunTransformerFromResMap(
	config string, resMap resmap.ResMap) (resmap.ResMap, error) {
	transConfig, err := th.rf.RF().FromBytes([]byte(config))
	if err != nil {
		th.t.Logf("config: '%s'", config)
		th.t.Fatalf("Err: %v", err)
	}
	g, err := th.pl.LoadTransformer(
		th.ldr, valtest_test.MakeFakeValidator(), transConfig)
	if err != nil {
		return nil, err
	}
	err = g.Transform(resMap)
	return resMap, err
}
<|endoftext|>


<commit_before>package openapi

import "errors"

// codebeat:disable[TOO_MANY_IVARS]

// Parameter Object
type Parameter struct {
	Name            string
	In              string
	Description     string
	Required        bool
	Deprecated      string
	AllowEmptyValue bool `yaml:"allowEmptyValue"`

	Style         string
	Explode       bool
	AllowReserved bool `yaml:"allowReserved"`
	Schema        *Schema
	Example       interface{}
	Examples      map[string]*Example

	Content map[string]*MediaType

	Ref string `yaml:"$ref"`
}

// Validate the values of Parameter object.
// This function DOES NOT check whether the name field correspond to the associated path or not.
func (parameter Parameter) Validate() error {
	if parameter.Name == "" {
		return errors.New("parameter.name is required")
	}
	if parameter.In == "" {
		return errors.New("parameter.in is required")
	}
	if parameter.In == "path" && !parameter.Required {
		return errors.New("if parameter.in is path, required must be true")
	}
	validaters := []validater{parameter.Schema}
	if v, ok := parameter.Example.(validater); ok {
		validaters = append(validaters, v)
	}

	// example has no validation

	if len(parameter.Content) > 1 {
		return errors.New("parameter.content must only contain one entry")
	}
	for _, mediaType := range parameter.Content {
		validaters = append(validaters, mediaType)
	}
	return validateAll(validaters)
}
<commit_msg>fix: from test<commit_after>package openapi

import "errors"

// codebeat:disable[TOO_MANY_IVARS]

// Parameter Object
type Parameter struct {
	Name            string
	In              string
	Description     string
	Required        bool
	Deprecated      string
	AllowEmptyValue bool `yaml:"allowEmptyValue"`

	Style         string
	Explode       bool
	AllowReserved bool `yaml:"allowReserved"`
	Schema        *Schema
	Example       interface{}
	Examples      map[string]*Example

	Content map[string]*MediaType

	Ref string `yaml:"$ref"`
}

// Validate the values of Parameter object.
// This function DOES NOT check whether the name field correspond to the associated path or not.
func (parameter Parameter) Validate() error {
	if parameter.Name == "" {
		return errors.New("parameter.name is required")
	}
	if parameter.In == "" {
		return errors.New("parameter.in is required")
	}
	switch parameter.In {
	case "query", "header", "path", "cookie":
	default:
		return errors.New("parameter.in should be one of: query, header, path, cookie")
	}
	if parameter.In == "path" && !parameter.Required {
		return errors.New("if parameter.in is path, required must be true")
	}
	if parameter.In != "query" && parameter.AllowEmptyValue {
		return errors.New("allowEmptyValue is valid only for query parameters")
	}
	validaters := []validater{}
	if parameter.Schema != nil {
		validaters = append(validaters, parameter.Schema)
	}
	if v, ok := parameter.Example.(validater); ok {
		validaters = append(validaters, v)
	}

	// example has no validation

	if len(parameter.Content) > 1 {
		return errors.New("parameter.content must only contain one entry")
	}
	for _, mediaType := range parameter.Content {
		validaters = append(validaters, mediaType)
	}
	return validateAll(validaters)
}
<|endoftext|>


<commit_before>// Copyright 2011 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 oglematchers_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"testing"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type FailingTest struct {
}

func init()                     { RegisterTestSuite(&FailingTest{}) }
func TestOgletest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *FailingTest) PassingMethod() {
}

func (t *FailingTest) Equals() {
	ExpectThat(17, Equals(17.5))
	ExpectThat(17, Equals("taco"))
}

func (t *FailingTest) LessThan() {
	ExpectThat(18, LessThan(17))
	ExpectThat(18, LessThan("taco"))
}

func (t *FailingTest) HasSubstr() {
	ExpectThat("taco", HasSubstr("ac"))
	ExpectThat(17, HasSubstr("ac"))
}

func (t *FailingTest) UserErrorMessage() {
	ExpectThat(17, Equals(19), "foo bar")
}

func (t *FailingTest) ModifiedExpectation() {
	ExpectThat(17, HasSubstr("ac")).SetCaller("foo.go", 112)
	ExpectEq(17, 19).SetCaller("bar.go", 117)
}

func (t FailingTest) ExpectationAliases() {
	ExpectEq(17, 17.5)
	ExpectEq("taco", 17.5)

	ExpectLe(17, 16.9)
	ExpectLt(17, 16.9)
	ExpectLt(17, "taco")

	ExpectGe(17, 17.1)
	ExpectGt(17, 17.1)
	ExpectGt(17, "taco")

	ExpectNe(17, 17.0)
	ExpectNe(17, "taco")

	ExpectFalse(true)
	ExpectFalse("taco")

	ExpectTrue(false)
	ExpectTrue("taco")
}

func (t *FailingTest) AssertThatFailure() {
	AssertThat(17, Equals(19))
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertEqFailure() {
	AssertEq(19, 17)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertNeFailure() {
	AssertNe(19, 19)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertLeFailure() {
	AssertLe(19, 17)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertLtFailure() {
	AssertLt(19, 17)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertGeFailure() {
	AssertGe(17, 19)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertGtFailure() {
	AssertGt(17, 19)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertTrueFailure() {
	AssertTrue("taco")
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertFalseFailure() {
	AssertFalse("taco")
	panic("Shouldn't get here.")
}
<commit_msg>Added an integration test for #13.<commit_after>// Copyright 2011 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 oglematchers_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"testing"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type FailingTest struct {
}

func init()                     { RegisterTestSuite(&FailingTest{}) }
func TestOgletest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *FailingTest) PassingMethod() {
}

func (t *FailingTest) Equals() {
	ExpectThat(17, Equals(17.5))
	ExpectThat(17, Equals("taco"))
}

func (t *FailingTest) LessThan() {
	ExpectThat(18, LessThan(17))
	ExpectThat(18, LessThan("taco"))
}

func (t *FailingTest) HasSubstr() {
	ExpectThat("taco", HasSubstr("ac"))
	ExpectThat(17, HasSubstr("ac"))
}

func (t *FailingTest) ExpectWithUserErrorMessages() {
	ExpectThat(17, Equals(19), "foo bar: %d", 112)
	ExpectEq(17, 17.5, "foo bar: %d", 112)
	ExpectLe(17, 16.9, "foo bar: %d", 112)
	ExpectLt(17, 16.9, "foo bar: %d", 112)
	ExpectGe(17, 17.1, "foo bar: %d", 112)
	ExpectGt(17, "taco", "foo bar: %d", 112)
	ExpectNe(17, 17.0, "foo bar: %d", 112)
	ExpectFalse(true, "foo bar: %d", 112)
	ExpectTrue(false, "foo bar: %d", 112)
}

func (t *FailingTest) AssertWithUserErrorMessages() {
	AssertThat(17, Equals(19), "foo bar: %d", 112)
}

func (t *FailingTest) ModifiedExpectation() {
	ExpectThat(17, HasSubstr("ac")).SetCaller("foo.go", 112)
	ExpectEq(17, 19).SetCaller("bar.go", 117)
}

func (t FailingTest) ExpectationAliases() {
	ExpectEq(17, 17.5)
	ExpectEq("taco", 17.5)

	ExpectLe(17, 16.9)
	ExpectLt(17, 16.9)
	ExpectLt(17, "taco")

	ExpectGe(17, 17.1)
	ExpectGt(17, 17.1)
	ExpectGt(17, "taco")

	ExpectNe(17, 17.0)
	ExpectNe(17, "taco")

	ExpectFalse(true)
	ExpectFalse("taco")

	ExpectTrue(false)
	ExpectTrue("taco")
}

func (t *FailingTest) AssertThatFailure() {
	AssertThat(17, Equals(19))
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertEqFailure() {
	AssertEq(19, 17)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertNeFailure() {
	AssertNe(19, 19)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertLeFailure() {
	AssertLe(19, 17)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertLtFailure() {
	AssertLt(19, 17)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertGeFailure() {
	AssertGe(17, 19)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertGtFailure() {
	AssertGt(17, 19)
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertTrueFailure() {
	AssertTrue("taco")
	panic("Shouldn't get here.")
}

func (t *FailingTest) AssertFalseFailure() {
	AssertFalse("taco")
	panic("Shouldn't get here.")
}
<|endoftext|>