<commit_before>package jujutest

import (
	"bytes"
	"net/http"
)

// VirtualRoundTripper can be used to provide "http" responses without actually
// starting an HTTP server. It is used by calling:
// vfs := NewVirtualRoundTripper([]FileContent{<file contents>})
// http.DefaultTransport.(*http.Transport).RegisterProtocol("file", vfs)
// At which point requests to file:///foo will pull out the virtual content of
// the file named 'foo' passed into the RoundTripper constructor.
type VirtualRoundTripper struct {
	contents []FileContent
}

var _ http.RoundTripper = (*VirtualRoundTripper)(nil)

// When using RegisterProtocol on http.Transport, you can't actually change the
// registration. So we provide a RoundTripper that simply proxies to whatever
// we want as the current content.
type ProxyRoundTripper struct {
	Sub http.RoundTripper
}

var _ http.RoundTripper = (*ProxyRoundTripper)(nil)

func (prt *ProxyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	if prt.Sub == nil {
		panic("An attempt was made to request file content without having" +
			" the virtual filesystem initialized.")
	}
	return prt.Sub.RoundTrip(req)
}

// A simple content structure to pass data into VirtualRoundTripper. When using
// VRT, requests that match 'Name' will be served the value in 'Content'
type FileContent struct {
	Name    string
	Content string
}

// bytes.Buffer doesn't provide a Close method, but http.Response needs a
// ReadCloser, so we implement a no-op Close method.
type BufferCloser struct {
	*bytes.Buffer
}

func (bc BufferCloser) Close() error { return nil }

// Map the Path into Content based on FileContent.Name
func (v *VirtualRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	res := &http.Response{Proto: "HTTP/1.0",
		ProtoMajor: 1,
		Header:     make(http.Header),
		Close:      true,
	}
	for _, fc := range v.contents {
		if fc.Name == req.URL.Path {
			res.Status = "200 OK"
			res.StatusCode = http.StatusOK
			res.ContentLength = int64(len(fc.Content))
			res.Body = BufferCloser{bytes.NewBufferString(fc.Content)}
			return res, nil
		}
	}
	res.Status = "404 Not Found"
	res.StatusCode = http.StatusNotFound
	res.ContentLength = 0
	res.Body = BufferCloser{bytes.NewBufferString("")}
	return res, nil
}

func NewVirtualRoundTripper(contents []FileContent) *VirtualRoundTripper {
	return &VirtualRoundTripper{contents}
}
<commit_msg>go fmt<commit_after>package jujutest

import (
	"bytes"
	"net/http"
)

// VirtualRoundTripper can be used to provide "http" responses without actually
// starting an HTTP server. It is used by calling:
// vfs := NewVirtualRoundTripper([]FileContent{<file contents>})
// http.DefaultTransport.(*http.Transport).RegisterProtocol("file", vfs)
// At which point requests to file:///foo will pull out the virtual content of
// the file named 'foo' passed into the RoundTripper constructor.
type VirtualRoundTripper struct {
	contents []FileContent
}

var _ http.RoundTripper = (*VirtualRoundTripper)(nil)

// When using RegisterProtocol on http.Transport, you can't actually change the
// registration. So we provide a RoundTripper that simply proxies to whatever
// we want as the current content.
type ProxyRoundTripper struct {
	Sub http.RoundTripper
}

var _ http.RoundTripper = (*ProxyRoundTripper)(nil)

func (prt *ProxyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	if prt.Sub == nil {
		panic("An attempt was made to request file content without having" +
			" the virtual filesystem initialized.")
	}
	return prt.Sub.RoundTrip(req)
}

// A simple content structure to pass data into VirtualRoundTripper. When using
// VRT, requests that match 'Name' will be served the value in 'Content'
type FileContent struct {
	Name    string
	Content string
}

// bytes.Buffer doesn't provide a Close method, but http.Response needs a
// ReadCloser, so we implement a no-op Close method.
type BufferCloser struct {
	*bytes.Buffer
}

func (bc BufferCloser) Close() error { return nil }

// Map the Path into Content based on FileContent.Name
func (v *VirtualRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	res := &http.Response{Proto: "HTTP/1.0",
		ProtoMajor: 1,
		Header:     make(http.Header),
		Close:      true,
	}
	for _, fc := range v.contents {
		if fc.Name == req.URL.Path {
			res.Status = "200 OK"
			res.StatusCode = http.StatusOK
			res.ContentLength = int64(len(fc.Content))
			res.Body = BufferCloser{bytes.NewBufferString(fc.Content)}
			return res, nil
		}
	}
	res.Status = "404 Not Found"
	res.StatusCode = http.StatusNotFound
	res.ContentLength = 0
	res.Body = BufferCloser{bytes.NewBufferString("")}
	return res, nil
}

func NewVirtualRoundTripper(contents []FileContent) *VirtualRoundTripper {
	return &VirtualRoundTripper{contents}
}
<|endoftext|>


<commit_before>package slack

import (
	"encoding/json"
	"fmt"
	"log"
	"regexp"
	"strings"
)

const (
	slackEventTypeMessage = "message"

	maxMessageSize  = 4000
	maxMessageLines = 25
)

// Processor type processes inbound events from Slack
type Processor struct {
	// Connection to Slack
	con *Connection

	// Slack user information relating to the bot account
	self User

	// a sequence number to uniquely identify sent messages and correlate with acks from Slack
	sequence int

	// map of event handler functions to handle types of Slack event
	eventHandlers map[string]func(*Processor, map[string]interface{}, []byte)

	// map of users who are members of the Slack group
	users map[string]User
}

// event type represents an event sent to Slack e.g. messages
type event struct {
	Id      int    `json:"id"`
	Type    string `json:"type"`
	Channel string `json:"channel"`
	Text    string `json:"text"`
}

// user_change event type represents a user change event from Slack
type userChangeEvent struct {
	Type        string `json:"type"`
	UpdatedUser User   `json:"user"`
}

// send Event to Slack
func (p *Processor) sendEvent(eventType string, channel string, text string) error {
	p.sequence++

	response := &event{Id: p.sequence, Type: eventType, Channel: channel, Text: text}

	responseJson, err := json.Marshal(response)
	if err != nil {
		return err
	}

	p.con.Write(responseJson)

	return nil
}

/*
// Write the message on the specified channel to Slack
func (p *Processor) Write(channel string, text string) error {
	for len(text) > 0 {
		if len(text) <= maxMessageSize {
			if err := p.sendEvent(slackEventTypeMessage, channel, text); err != nil {
				return err
			}
			text = ""
		} else {
			// split message at a convenient place
			maxSizeChunk := text[:maxMessageSize]

			var breakIndex int
			if lastLineBreak := strings.LastIndex(maxSizeChunk, "\n"); lastLineBreak > -1 {
				breakIndex = lastLineBreak
			} else if lastWordBreak := strings.LastIndexAny(maxSizeChunk, "\n\t .,/\\-(){}[]|=+*&"); lastWordBreak > -1 {
				breakIndex = lastWordBreak
			} else {
				breakIndex = maxMessageSize
			}

			if err := p.sendEvent(slackEventTypeMessage, channel, text[:breakIndex]); err != nil {
				return err
			}

			if breakIndex != maxMessageSize {
				breakIndex++
			}

			text = text[breakIndex:]
		}
	}

	return nil
}
*/
// Write the message on the specified channel to Slack
func (p *Processor) Write(channel string, text string) error {
	for len(text) > 0 {
		lines := strings.Count(text, "\n")
		if len(text) <= maxMessageSize && lines <= maxMessageLines {
			if err := p.sendEvent(slackEventTypeMessage, channel, text); err != nil {
				return err
			}
			text = ""
		} else {
			// split message at a convenient place
			var breakIndex int
			maxSizeChunk := text

			if len(text) > maxMessageSize {
				maxSizeChunk := text[:maxMessageSize]
				lines = strings.Count(maxSizeChunk, "\n")
			}

			if lines > maxMessageLines {
				var index int
				for n := 0; index < len(maxSizeChunk) && n < maxMessageLines; n++ {
					p := strings.Index(maxSizeChunk[index:], "\n")
					if p == -1 {
						break
					}
					index += p
				}
				breakIndex = index
			} else if lastLineBreak := strings.LastIndex(maxSizeChunk, "\n"); lastLineBreak > -1 {
				breakIndex = lastLineBreak
			} else if lastWordBreak := strings.LastIndexAny(maxSizeChunk, "\n\t .,/\\-(){}[]|=+*&"); lastWordBreak > -1 {
				breakIndex = lastWordBreak
			} else {
				breakIndex = maxMessageSize
			}

			if err := p.sendEvent(slackEventTypeMessage, channel, text[:breakIndex]); err != nil {
				return err
			}

			if breakIndex != maxMessageSize {
				breakIndex++
			}

			text = text[breakIndex:]
		}
	}

	return nil
}

// Start processing events from Slack
func (p *Processor) Start() {
	for {
		msg := p.con.Read()

		log.Printf("%s", msg)

		var data map[string]interface{}
		err := json.Unmarshal(msg, &data)

		if err != nil {
			fmt.Printf("%T\n%s\n%#v\n", err, err, err)
			switch v := err.(type) {
			case *json.SyntaxError:
				fmt.Println(string(msg[v.Offset-40 : v.Offset]))
			}
			log.Printf("%s", msg)
			continue
		}

		// if reply_to attribute is present the event is an ack' for a sent message
		_, isReply := data["reply_to"]
		subtype, ok := data["subtype"]
		var isMessageChangedEvent bool

		if ok {
			isMessageChangedEvent = (subtype.(string) == "message_changed" || subtype.(string) == "message_deleted")
		}

		if !isReply && !isMessageChangedEvent {
			handler, ok := p.eventHandlers[data["type"].(string)]

			if ok {
				handler(p, data, msg)
			}
		}
	}
}

// updateUser updates or adds (if not already existing) the specifed user
func (p *Processor) updateUser(user User) {
	p.users[user.Id] = user
}

// onConnected is a callback for when the client connects (or reconnects) to Slack.
func (p *Processor) onConnected(con *Connection) {
	p.self = con.config.Self
	log.Printf("Connected to Slack as %s", p.self.Name)

	p.users = make(map[string]User)
	for _, user := range con.config.Users {
		p.updateUser(user)
	}
}

// type for callbacks to receive messages from Slack
type messageProcessor func(*Message)

// Starts processing events on the connection from Slack and passes any messages to the hear callback and only
// messages addressed to the bot to the respond callback
func EventProcessor(con *Connection, respond messageProcessor, hear messageProcessor) {
	p := Processor{
		con:  con,
		self: con.config.Self,
		eventHandlers: map[string]func(*Processor, map[string]interface{}, []byte){
			slackEventTypeMessage: func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				filterMessage(p, event, respond, hear)
			},
			"user_change": func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				var userEvent userChangeEvent
				err := json.Unmarshal(rawEvent, &userEvent)

				if err != nil {
					fmt.Printf("%T\n%s\n%#v\n", err, err, err)
					switch v := err.(type) {
					case *json.SyntaxError:
						fmt.Println(string(rawEvent[v.Offset-40 : v.Offset]))
					}
					log.Printf("%s", rawEvent)
				}
				p.updateUser(userEvent.UpdatedUser)
			},
			"hello": func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				p.onConnected(con)
			},
			"error": func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				log.Printf("Error received from Slack: %s", rawEvent)
			},
		},
		users: make(map[string]User),
	}

	p.Start()
}

// Invoke one of the specified callbacks for the message if appropriate
func filterMessage(p *Processor, data map[string]interface{}, respond messageProcessor, hear messageProcessor) {
	var userFullName string
	var userId string

	user, ok := data["user"]
	if ok {
		userId = user.(string)
		user, exists := p.users[userId]
		if exists {
			userFullName = user.RealName
		}
	}

	// process messages directed at Talbot
	r, _ := regexp.Compile("^(<@" + p.self.Id + ">|@?" + p.self.Name + "):? (.+)")

	text, ok := data["text"]
	if !ok || text == nil {
		return
	}

	matches := r.FindStringSubmatch(text.(string))

	if len(matches) == 3 {
		if respond != nil {
			m := &Message{eventStream: p, responseStrategy: reply, Text: matches[2], From: userFullName, fromId: userId, channel: data["channel"].(string)}
			respond(m)
		}
	} else if data["channel"].(string)[0] == 'D' {
		if respond != nil {
			// process direct messages
			m := &Message{eventStream: p, responseStrategy: send, Text: text.(string), From: userFullName, fromId: userId, channel: data["channel"].(string)}
			respond(m)
		}
	} else {
		if hear != nil {
			m := &Message{eventStream: p, responseStrategy: send, Text: text.(string), From: userFullName, fromId: userId, channel: data["channel"].(string)}
			hear(m)
		}
	}
}
<commit_msg>fixed chunking<commit_after>package slack

import (
	"encoding/json"
	"fmt"
	"log"
	"regexp"
	"strings"
)

const (
	slackEventTypeMessage = "message"

	maxMessageSize  = 4000
	maxMessageLines = 25
)

// Processor type processes inbound events from Slack
type Processor struct {
	// Connection to Slack
	con *Connection

	// Slack user information relating to the bot account
	self User

	// a sequence number to uniquely identify sent messages and correlate with acks from Slack
	sequence int

	// map of event handler functions to handle types of Slack event
	eventHandlers map[string]func(*Processor, map[string]interface{}, []byte)

	// map of users who are members of the Slack group
	users map[string]User
}

// event type represents an event sent to Slack e.g. messages
type event struct {
	Id      int    `json:"id"`
	Type    string `json:"type"`
	Channel string `json:"channel"`
	Text    string `json:"text"`
}

// user_change event type represents a user change event from Slack
type userChangeEvent struct {
	Type        string `json:"type"`
	UpdatedUser User   `json:"user"`
}

// send Event to Slack
func (p *Processor) sendEvent(eventType string, channel string, text string) error {
	p.sequence++

	response := &event{Id: p.sequence, Type: eventType, Channel: channel, Text: text}

	responseJson, err := json.Marshal(response)
	if err != nil {
		return err
	}

	p.con.Write(responseJson)

	return nil
}

/*
// Write the message on the specified channel to Slack
func (p *Processor) Write(channel string, text string) error {
	for len(text) > 0 {
		if len(text) <= maxMessageSize {
			if err := p.sendEvent(slackEventTypeMessage, channel, text); err != nil {
				return err
			}
			text = ""
		} else {
			// split message at a convenient place
			maxSizeChunk := text[:maxMessageSize]

			var breakIndex int
			if lastLineBreak := strings.LastIndex(maxSizeChunk, "\n"); lastLineBreak > -1 {
				breakIndex = lastLineBreak
			} else if lastWordBreak := strings.LastIndexAny(maxSizeChunk, "\n\t .,/\\-(){}[]|=+*&"); lastWordBreak > -1 {
				breakIndex = lastWordBreak
			} else {
				breakIndex = maxMessageSize
			}

			if err := p.sendEvent(slackEventTypeMessage, channel, text[:breakIndex]); err != nil {
				return err
			}

			if breakIndex != maxMessageSize {
				breakIndex++
			}

			text = text[breakIndex:]
		}
	}

	return nil
}
*/
// Write the message on the specified channel to Slack
func (p *Processor) Write(channel string, text string) error {
	for len(text) > 0 {
		lines := strings.Count(text, "\n")
		if len(text) <= maxMessageSize && lines <= maxMessageLines {
			if err := p.sendEvent(slackEventTypeMessage, channel, text); err != nil {
				return err
			}
			text = ""
		} else {
			// split message at a convenient place
			var breakIndex int
			maxSizeChunk := text

			if len(text) > maxMessageSize {
				maxSizeChunk := text[:maxMessageSize]
				lines = strings.Count(maxSizeChunk, "\n")
			}

			if lines > maxMessageLines {
				var index int
				for n := 0; index < len(maxSizeChunk) && n < maxMessageLines; n++ {
					p := strings.Index(maxSizeChunk[index:], "\n")
					if p == -1 {
						break
					}
					index += p + 1
				}
				breakIndex = index
			} else if lastLineBreak := strings.LastIndex(maxSizeChunk, "\n"); lastLineBreak > -1 {
				breakIndex = lastLineBreak
			} else if lastWordBreak := strings.LastIndexAny(maxSizeChunk, "\n\t .,/\\-(){}[]|=+*&"); lastWordBreak > -1 {
				breakIndex = lastWordBreak
			} else {
				breakIndex = maxMessageSize
			}

			if err := p.sendEvent(slackEventTypeMessage, channel, text[:breakIndex]); err != nil {
				return err
			}

			if breakIndex != maxMessageSize && lines <= maxMessageLines {
				breakIndex++
			}

			text = text[breakIndex:]
		}
	}

	return nil
}

// Start processing events from Slack
func (p *Processor) Start() {
	for {
		msg := p.con.Read()

		log.Printf("%s", msg)

		var data map[string]interface{}
		err := json.Unmarshal(msg, &data)

		if err != nil {
			fmt.Printf("%T\n%s\n%#v\n", err, err, err)
			switch v := err.(type) {
			case *json.SyntaxError:
				fmt.Println(string(msg[v.Offset-40 : v.Offset]))
			}
			log.Printf("%s", msg)
			continue
		}

		// if reply_to attribute is present the event is an ack' for a sent message
		_, isReply := data["reply_to"]
		subtype, ok := data["subtype"]
		var isMessageChangedEvent bool

		if ok {
			isMessageChangedEvent = (subtype.(string) == "message_changed" || subtype.(string) == "message_deleted")
		}

		if !isReply && !isMessageChangedEvent {
			handler, ok := p.eventHandlers[data["type"].(string)]

			if ok {
				handler(p, data, msg)
			}
		}
	}
}

// updateUser updates or adds (if not already existing) the specifed user
func (p *Processor) updateUser(user User) {
	p.users[user.Id] = user
}

// onConnected is a callback for when the client connects (or reconnects) to Slack.
func (p *Processor) onConnected(con *Connection) {
	p.self = con.config.Self
	log.Printf("Connected to Slack as %s", p.self.Name)

	p.users = make(map[string]User)
	for _, user := range con.config.Users {
		p.updateUser(user)
	}
}

// type for callbacks to receive messages from Slack
type messageProcessor func(*Message)

// Starts processing events on the connection from Slack and passes any messages to the hear callback and only
// messages addressed to the bot to the respond callback
func EventProcessor(con *Connection, respond messageProcessor, hear messageProcessor) {
	p := Processor{
		con:  con,
		self: con.config.Self,
		eventHandlers: map[string]func(*Processor, map[string]interface{}, []byte){
			slackEventTypeMessage: func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				filterMessage(p, event, respond, hear)
			},
			"user_change": func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				var userEvent userChangeEvent
				err := json.Unmarshal(rawEvent, &userEvent)

				if err != nil {
					fmt.Printf("%T\n%s\n%#v\n", err, err, err)
					switch v := err.(type) {
					case *json.SyntaxError:
						fmt.Println(string(rawEvent[v.Offset-40 : v.Offset]))
					}
					log.Printf("%s", rawEvent)
				}
				p.updateUser(userEvent.UpdatedUser)
			},
			"hello": func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				p.onConnected(con)
			},
			"error": func(p *Processor, event map[string]interface{}, rawEvent []byte) {
				log.Printf("Error received from Slack: %s", rawEvent)
			},
		},
		users: make(map[string]User),
	}

	p.Start()
}

// Invoke one of the specified callbacks for the message if appropriate
func filterMessage(p *Processor, data map[string]interface{}, respond messageProcessor, hear messageProcessor) {
	var userFullName string
	var userId string

	user, ok := data["user"]
	if ok {
		userId = user.(string)
		user, exists := p.users[userId]
		if exists {
			userFullName = user.RealName
		}
	}

	// process messages directed at Talbot
	r, _ := regexp.Compile("^(<@" + p.self.Id + ">|@?" + p.self.Name + "):? (.+)")

	text, ok := data["text"]
	if !ok || text == nil {
		return
	}

	matches := r.FindStringSubmatch(text.(string))

	if len(matches) == 3 {
		if respond != nil {
			m := &Message{eventStream: p, responseStrategy: reply, Text: matches[2], From: userFullName, fromId: userId, channel: data["channel"].(string)}
			respond(m)
		}
	} else if data["channel"].(string)[0] == 'D' {
		if respond != nil {
			// process direct messages
			m := &Message{eventStream: p, responseStrategy: send, Text: text.(string), From: userFullName, fromId: userId, channel: data["channel"].(string)}
			respond(m)
		}
	} else {
		if hear != nil {
			m := &Message{eventStream: p, responseStrategy: send, Text: text.(string), From: userFullName, fromId: userId, channel: data["channel"].(string)}
			hear(m)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"os"
	"strconv"
	"time"
	"unicode/utf16"
	"unicode/utf8"
)

func fmtField(name, value string) {
	fmt.Printf("%-25s%s\n", name+":", value)
}

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func hexs(a []byte) string {
	return hex.EncodeToString(a[:])
}

func uuid(a []byte) string {
	return fmt.Sprintf("%08x-%04x-%04x-%04x-%04x",
		a[:4],
		a[4:6],
		a[6:8],
		a[8:10],
		a[10:16])
}

/*
	utf16BytesToString converts UTF-16 encoded bytes, in big or
 	little endian byte order, to a UTF-8 encoded string.
 	http://stackoverflow.com/a/15794113
*/
func utf16BytesToString(b []byte, o binary.ByteOrder) string {
	utf := make([]uint16, (len(b)+(2-1))/2)
	for i := 0; i+(2-1) < len(b); i += 2 {
		utf[i/2] = o.Uint16(b[i:])
	}
	if len(b)/2 < len(utf) {
		utf[len(utf)-1] = utf8.RuneError
	}
	return string(utf16.Decode(utf))
}

/* VHD Dynamic and Differential Header */
/*
	Cookie 8
	Data Offset 8
	Table Offset 8
	Header Version 4
	Max Table Entries 4
	Block Size 4
	Checksum 4
	Parent Unique ID 16
	Parent Time Stamp 4
	Reserved 4
	Parent Unicode Name 512
	Parent Locator Entry 1 24
	Parent Locator Entry 2 24
	Parent Locator Entry 3 24
	Parent Locator Entry 4 24
	Parent Locator Entry 5 24
	Parent Locator Entry 6 24
	Parent Locator Entry 7 24
	Parent Locator Entry 8 24
	Reserved 256
*/
type VHDExtraHeader struct {
	Cookie              [8]byte
	DataOffset          [8]byte
	TableOffset         [8]byte
	HeaderVersion       [4]byte
	MaxTableEntries     [4]byte
	BlockSize           [4]byte
	Checksum            [4]byte
	ParentUUID          [16]byte
	ParentTimestamp     [4]byte
	Reserved            [4]byte
	ParentUnicodeName   [512]byte
	ParentLocatorEntry1 [24]byte
	ParentLocatorEntry2 [24]byte
	ParentLocatorEntry3 [24]byte
	ParentLocatorEntry4 [24]byte
	ParentLocatorEntry5 [24]byte
	ParentLocatorEntry6 [24]byte
	ParentLocatorEntry7 [24]byte
	ParentLocatorEntry8 [24]byte
	Reserved2           [256]byte
}

func (header *VHDExtraHeader) CookieString() string {
	return string(header.Cookie[:])
}

/* VHD Header */
/*
 Cookie 8
 Features 4
 File Format Version 4
 Data Offset 8
 Time Stamp 4
 Creator Application 4
 Creator Version 4
 Creator Host OS 4
 Original Size 8
 Current Size 8
 Disk Geometry 4
 Disk Type 4
 Checksum 4
 Unique Id 16
 Saved State 1
 Reserved 427
*/
type VHDHeader struct {
	Cookie             [8]byte
	Features           [4]byte
	FileFormatVersion  [4]byte
	DataOffset         [8]byte
	Timestamp          [4]byte
	CreatorApplication [4]byte
	CreatorVersion     [4]byte
	CreatorHostOS      [4]byte
	OriginalSize       [8]byte
	CurrentSize        [8]byte
	DiskGeometry       [4]byte
	DiskType           [4]byte
	Checksum           [4]byte
	UniqueId           [16]byte
	SavedState         [1]byte
	Reserved           [427]byte
}

func (h *VHDHeader) DiskTypeStr() (dt string) {
	switch h.DiskType[3] {
	case 0x00:
		dt = "None"
	case 0x01:
		dt = "Deprecated"
	case 0x02:
		dt = "Fixed"
	case 0x03:
		dt = "Dynamic"
	case 0x04:
		dt = "Differential"
	case 0x05:
		dt = "Reserved"
	case 0x06:
		dt = "Reserved"
	default:
		panic("Invalid disk type detected!")
	}

	return
}

func readVHDExtraHeader(f *os.File) {
	vhdHeader := make([]byte, 1024)
	_, err := f.Read(vhdHeader)
	check(err)

	var header VHDExtraHeader
	binary.Read(bytes.NewBuffer(vhdHeader[:]), binary.BigEndian, &header)

	fmtField("Cookie", header.CookieString())
	fmtField("Data offset", hexs(header.DataOffset[:]))
	fmtField("Table offset", hexs(header.TableOffset[:]))
	fmtField("Header version", hexs(header.HeaderVersion[:]))
	fmtField("Max table entries", hexs(header.MaxTableEntries[:]))
	fmtField("Block size", hexs(header.BlockSize[:]))
	fmtField("Checksum", hexs(header.Checksum[:]))
	fmtField("Parent UUID", uuid(header.ParentUUID[:]))

	// Seconds since January 1, 1970 12:00:00 AM in UTC/GMT.
	// 946684800 = January 1, 2000 12:00:00 AM in UTC/GMT.
	tstamp := binary.BigEndian.Uint32(header.ParentTimestamp[:])
	t := time.Unix(int64(946684800+tstamp), 0)
	fmtField("Timestamp", fmt.Sprintf("%s", t))

	fmtField("Reserved", hexs(header.Reserved[:]))
	parentName := utf16BytesToString(header.ParentUnicodeName[:],
		binary.BigEndian)
	fmtField("Parent Name", parentName)
	// Parent locator entries ignored since it's a dynamic disk
	sum := 0
	for _, b := range header.Reserved2 {
		sum += int(b)
	}
	fmtField("Reserved2", strconv.Itoa(sum))
}

func readVHDHeader(vhdHeader []byte) VHDHeader {

	var header VHDHeader
	binary.Read(bytes.NewBuffer(vhdHeader[:]), binary.BigEndian, &header)

	fmtField("Cookie", string(header.Cookie[:]))
	fmtField("Features", hexs(header.Features[:]))
	fmtField("File format version", hexs(header.FileFormatVersion[:]))

	dataOffset := binary.BigEndian.Uint64(header.DataOffset[:])
	fmtField("Data offset",
		fmt.Sprintf("%s (%d bytes)", hexs(header.DataOffset[:]), dataOffset))

	//// Seconds since January 1, 1970 12:00:00 AM in UTC/GMT.
	//// 946684800 = January 1, 2000 12:00:00 AM in UTC/GMT.
	t := time.Unix(int64(946684800+binary.BigEndian.Uint32(header.Timestamp[:])), 0)
	fmtField("Timestamp", fmt.Sprintf("%s", t))

	fmtField("Creator application", string(header.CreatorApplication[:]))
	fmtField("Creator version", hexs(header.CreatorVersion[:]))
	fmtField("Creator OS", string(header.CreatorHostOS[:]))

	originalSize := binary.BigEndian.Uint64(header.OriginalSize[:])
	fmtField("Original size",
		fmt.Sprintf("%s ( %d bytes )", hexs(header.OriginalSize[:]), originalSize))

	currentSize := binary.BigEndian.Uint64(header.OriginalSize[:])
	fmtField("Current size",
		fmt.Sprintf("%s ( %d bytes )", hexs(header.CurrentSize[:]), currentSize))

	cilinders := int64(binary.BigEndian.Uint16(header.DiskGeometry[:2]))
	heads := int64(header.DiskGeometry[2])
	sectors := int64(header.DiskGeometry[3])
	dsize := cilinders * heads * sectors * 512
	fmtField("Disk geometry",
		fmt.Sprintf("%s (c: %d, h: %d, s: %d) (%d bytes)",
			hexs(header.DiskGeometry[:]),
			cilinders,
			heads,
			sectors,
			dsize))

	fmtField("Disk type",
		fmt.Sprintf("%s (%s)", hexs(header.DiskType[:]), header.DiskTypeStr()))

	fmtField("Checksum", hexs(header.Checksum[:]))
	fmtField("UUID", uuid(header.UniqueId[:]))
	fmtField("Saved state", fmt.Sprintf("%d", header.SavedState[0]))

	return header
}

func main() {

	if len(os.Args) != 2 {
		fmt.Println("Usage: vhd-reader <vhd-file>")
		os.Exit(0)
	}

	vhd := os.Args[1]
	f, err := os.Open(vhd)
	check(err)
	defer f.Close()

	fmt.Println("\nReading VHD header...")
	vhdHeader := make([]byte, 512)
	_, err = f.Read(vhdHeader)
	check(err)
	header := readVHDHeader(vhdHeader)

	if header.DiskType[3] == 0x3 || header.DiskType[3] == 0x04 {
		fmt.Println("\nReading dynamic/differential VHD header...")
		readVHDExtraHeader(f)
	}

	// header should be equal to the footer, added for redundancy
	fmt.Println("\nReading VHD footer...")
	fstat, err := f.Stat()
	check(err)
	vhdFooter := make([]byte, 512)
	f.Seek(fstat.Size()-512, 0)
	_, err = f.Read(vhdFooter)
	check(err)
	readVHDHeader(vhdFooter)
}
<commit_msg>Fix label<commit_after>package main

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"os"
	"strconv"
	"time"
	"unicode/utf16"
	"unicode/utf8"
)

func fmtField(name, value string) {
	fmt.Printf("%-25s%s\n", name+":", value)
}

func check(e error) {
	if e != nil {
		panic(e)
	}
}

func hexs(a []byte) string {
	return hex.EncodeToString(a[:])
}

func uuid(a []byte) string {
	return fmt.Sprintf("%08x-%04x-%04x-%04x-%04x",
		a[:4],
		a[4:6],
		a[6:8],
		a[8:10],
		a[10:16])
}

/*
	utf16BytesToString converts UTF-16 encoded bytes, in big or
 	little endian byte order, to a UTF-8 encoded string.
 	http://stackoverflow.com/a/15794113
*/
func utf16BytesToString(b []byte, o binary.ByteOrder) string {
	utf := make([]uint16, (len(b)+(2-1))/2)
	for i := 0; i+(2-1) < len(b); i += 2 {
		utf[i/2] = o.Uint16(b[i:])
	}
	if len(b)/2 < len(utf) {
		utf[len(utf)-1] = utf8.RuneError
	}
	return string(utf16.Decode(utf))
}

/* VHD Dynamic and Differential Header */
/*
	Cookie 8
	Data Offset 8
	Table Offset 8
	Header Version 4
	Max Table Entries 4
	Block Size 4
	Checksum 4
	Parent Unique ID 16
	Parent Time Stamp 4
	Reserved 4
	Parent Unicode Name 512
	Parent Locator Entry 1 24
	Parent Locator Entry 2 24
	Parent Locator Entry 3 24
	Parent Locator Entry 4 24
	Parent Locator Entry 5 24
	Parent Locator Entry 6 24
	Parent Locator Entry 7 24
	Parent Locator Entry 8 24
	Reserved 256
*/
type VHDExtraHeader struct {
	Cookie              [8]byte
	DataOffset          [8]byte
	TableOffset         [8]byte
	HeaderVersion       [4]byte
	MaxTableEntries     [4]byte
	BlockSize           [4]byte
	Checksum            [4]byte
	ParentUUID          [16]byte
	ParentTimestamp     [4]byte
	Reserved            [4]byte
	ParentUnicodeName   [512]byte
	ParentLocatorEntry1 [24]byte
	ParentLocatorEntry2 [24]byte
	ParentLocatorEntry3 [24]byte
	ParentLocatorEntry4 [24]byte
	ParentLocatorEntry5 [24]byte
	ParentLocatorEntry6 [24]byte
	ParentLocatorEntry7 [24]byte
	ParentLocatorEntry8 [24]byte
	Reserved2           [256]byte
}

func (header *VHDExtraHeader) CookieString() string {
	return string(header.Cookie[:])
}

/* VHD Header */
/*
 Cookie 8
 Features 4
 File Format Version 4
 Data Offset 8
 Time Stamp 4
 Creator Application 4
 Creator Version 4
 Creator Host OS 4
 Original Size 8
 Current Size 8
 Disk Geometry 4
 Disk Type 4
 Checksum 4
 Unique Id 16
 Saved State 1
 Reserved 427
*/
type VHDHeader struct {
	Cookie             [8]byte
	Features           [4]byte
	FileFormatVersion  [4]byte
	DataOffset         [8]byte
	Timestamp          [4]byte
	CreatorApplication [4]byte
	CreatorVersion     [4]byte
	CreatorHostOS      [4]byte
	OriginalSize       [8]byte
	CurrentSize        [8]byte
	DiskGeometry       [4]byte
	DiskType           [4]byte
	Checksum           [4]byte
	UniqueId           [16]byte
	SavedState         [1]byte
	Reserved           [427]byte
}

func (h *VHDHeader) DiskTypeStr() (dt string) {
	switch h.DiskType[3] {
	case 0x00:
		dt = "None"
	case 0x01:
		dt = "Deprecated"
	case 0x02:
		dt = "Fixed"
	case 0x03:
		dt = "Dynamic"
	case 0x04:
		dt = "Differential"
	case 0x05:
		dt = "Reserved"
	case 0x06:
		dt = "Reserved"
	default:
		panic("Invalid disk type detected!")
	}

	return
}

func readVHDExtraHeader(f *os.File) {
	vhdHeader := make([]byte, 1024)
	_, err := f.Read(vhdHeader)
	check(err)

	var header VHDExtraHeader
	binary.Read(bytes.NewBuffer(vhdHeader[:]), binary.BigEndian, &header)

	fmtField("Cookie", header.CookieString())
	fmtField("Data offset", hexs(header.DataOffset[:]))
	fmtField("Table offset", hexs(header.TableOffset[:]))
	fmtField("Header version", hexs(header.HeaderVersion[:]))
	fmtField("Max table entries", hexs(header.MaxTableEntries[:]))
	fmtField("Block size", hexs(header.BlockSize[:]))
	fmtField("Checksum", hexs(header.Checksum[:]))
	fmtField("Parent UUID", uuid(header.ParentUUID[:]))

	// Seconds since January 1, 1970 12:00:00 AM in UTC/GMT.
	// 946684800 = January 1, 2000 12:00:00 AM in UTC/GMT.
	tstamp := binary.BigEndian.Uint32(header.ParentTimestamp[:])
	t := time.Unix(int64(946684800+tstamp), 0)
	fmtField("Parent timestamp", fmt.Sprintf("%s", t))

	fmtField("Reserved", hexs(header.Reserved[:]))
	parentName := utf16BytesToString(header.ParentUnicodeName[:],
		binary.BigEndian)
	fmtField("Parent Name", parentName)
	// Parent locator entries ignored since it's a dynamic disk
	sum := 0
	for _, b := range header.Reserved2 {
		sum += int(b)
	}
	fmtField("Reserved2", strconv.Itoa(sum))
}

func readVHDHeader(vhdHeader []byte) VHDHeader {

	var header VHDHeader
	binary.Read(bytes.NewBuffer(vhdHeader[:]), binary.BigEndian, &header)

	fmtField("Cookie", string(header.Cookie[:]))
	fmtField("Features", hexs(header.Features[:]))
	fmtField("File format version", hexs(header.FileFormatVersion[:]))

	dataOffset := binary.BigEndian.Uint64(header.DataOffset[:])
	fmtField("Data offset",
		fmt.Sprintf("%s (%d bytes)", hexs(header.DataOffset[:]), dataOffset))

	//// Seconds since January 1, 1970 12:00:00 AM in UTC/GMT.
	//// 946684800 = January 1, 2000 12:00:00 AM in UTC/GMT.
	t := time.Unix(int64(946684800+binary.BigEndian.Uint32(header.Timestamp[:])), 0)
	fmtField("Timestamp", fmt.Sprintf("%s", t))

	fmtField("Creator application", string(header.CreatorApplication[:]))
	fmtField("Creator version", hexs(header.CreatorVersion[:]))
	fmtField("Creator OS", string(header.CreatorHostOS[:]))

	originalSize := binary.BigEndian.Uint64(header.OriginalSize[:])
	fmtField("Original size",
		fmt.Sprintf("%s ( %d bytes )", hexs(header.OriginalSize[:]), originalSize))

	currentSize := binary.BigEndian.Uint64(header.OriginalSize[:])
	fmtField("Current size",
		fmt.Sprintf("%s ( %d bytes )", hexs(header.CurrentSize[:]), currentSize))

	cilinders := int64(binary.BigEndian.Uint16(header.DiskGeometry[:2]))
	heads := int64(header.DiskGeometry[2])
	sectors := int64(header.DiskGeometry[3])
	dsize := cilinders * heads * sectors * 512
	fmtField("Disk geometry",
		fmt.Sprintf("%s (c: %d, h: %d, s: %d) (%d bytes)",
			hexs(header.DiskGeometry[:]),
			cilinders,
			heads,
			sectors,
			dsize))

	fmtField("Disk type",
		fmt.Sprintf("%s (%s)", hexs(header.DiskType[:]), header.DiskTypeStr()))

	fmtField("Checksum", hexs(header.Checksum[:]))
	fmtField("UUID", uuid(header.UniqueId[:]))
	fmtField("Saved state", fmt.Sprintf("%d", header.SavedState[0]))

	return header
}

func main() {

	if len(os.Args) != 2 {
		fmt.Println("Usage: vhd-reader <vhd-file>")
		os.Exit(0)
	}

	vhd := os.Args[1]
	f, err := os.Open(vhd)
	check(err)
	defer f.Close()

	fmt.Println("\nReading VHD header...")
	vhdHeader := make([]byte, 512)
	_, err = f.Read(vhdHeader)
	check(err)
	header := readVHDHeader(vhdHeader)

	if header.DiskType[3] == 0x3 || header.DiskType[3] == 0x04 {
		fmt.Println("\nReading dynamic/differential VHD header...")
		readVHDExtraHeader(f)
	}

	// header should be equal to the footer, added for redundancy
	fmt.Println("\nReading VHD footer...")
	fstat, err := f.Stat()
	check(err)
	vhdFooter := make([]byte, 512)
	f.Seek(fstat.Size()-512, 0)
	_, err = f.Read(vhdFooter)
	check(err)
	readVHDHeader(vhdFooter)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"errors"
	"net/url"
	"net/http"
	"io/ioutil"
	"strings"
)

func getVideoInfo(videoId string) (string, error) {
	url := "http://youtube.com/get_video_info?video_id=" + videoId
	log("Requesting url: %s", url)
	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("An error occured while requesting the video information: '%s'", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return "", fmt.Errorf("An error occured while requesting the video information: non 200 status code received: '%s'", err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("An error occured while reading the video information: '%s'", err)
	}
	log("Got %d bytes answer", len(body))
	return string(body), nil
}

func decodeVideoInfo(response string) (streams streamList, err error) {
	// decode

	answer, err := url.ParseQuery(response)
	if err != nil {
		err = fmt.Errorf("parsing the server's answer: '%s'", err)
		return
	}

	// check the status

	status, ok := answer["status"]
	if !ok {
		err = fmt.Errorf("no response status found in the server's answer")
		return
	}
	if status[0] == "fail" {
		reason, ok := answer["reason"]
		if ok {
			err = fmt.Errorf("'fail' response status found in the server's answer, reason: '%s'", reason[0])
		} else {
			err = errors.New(fmt.Sprint("'fail' response status found in the server's answer, no reason given"))
		}
		return
	}
	if status[0] != "ok" {
		err = fmt.Errorf("non-success response status found in the server's answer (status: '%s')", status)
		return
	}

	log("Server answered with a success code")

	/*
	for k, v := range answer {
		log("%s: %#v", k, v)
	}
	*/

	// read the streams map

	stream_map, ok := answer["url_encoded_fmt_stream_map"]
	if !ok {
		err = errors.New(fmt.Sprint("no stream map found in the server's answer"))
		return
	}

	// read each stream

	streams_list := strings.Split(stream_map[0], ",")

	log("Found %d streams in answer", len(streams_list))

	for stream_pos, stream_raw := range streams_list {
		stream_qry, err := url.ParseQuery(stream_raw)
		if err != nil {
			log(fmt.Sprintf("An error occured while decoding one of the video's stream's information: stream %d: %s\n", stream_pos, err))
			continue
		}
		stream := stream{
			"quality": stream_qry["quality"][0],
			"type": stream_qry["type"][0],
			"url": stream_qry["url"][0],
			"sig": stream_qry["sig"][0],
			"title": answer["title"][0],
			"author": answer["author"][0],
		}
		streams = append(streams, stream)

		quality := stream.Quality()
		if quality == QUALITY_UNKNOWN {
			log("Found unknown quality '%s'", stream["quality"])
		}

		format := stream.Format()
		if format == FORMAT_UNKNOWN {
			log("Found unknown format '%s'", stream["type"])
		}

		log("Stream found: quality '%s', format '%s'", quality, format)
	}

	log("Successfully decoded %d streams", len(streams))

	return
}
<commit_msg>Add a check for answer and stream fields before reading them<commit_after>package main

import (
	"fmt"
	"errors"
	"net/url"
	"net/http"
	"io/ioutil"
	"strings"
)

func getVideoInfo(videoId string) (string, error) {
	url := "http://youtube.com/get_video_info?video_id=" + videoId
	log("Requesting url: %s", url)
	resp, err := http.Get(url)
	if err != nil {
		return "", fmt.Errorf("An error occured while requesting the video information: '%s'", err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return "", fmt.Errorf("An error occured while requesting the video information: non 200 status code received: '%s'", err)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("An error occured while reading the video information: '%s'", err)
	}
	log("Got %d bytes answer", len(body))
	return string(body), nil
}

func ensureFields(source url.Values, fields []string) (err error) {
	for _, field := range fields {
		if _, exists := source[field]; !exists {
			return fmt.Errorf("Field '%s' is missing in url.Values source", field)
		}
	}
	return nil
}

func decodeVideoInfo(response string) (streams streamList, err error) {
	// decode

	answer, err := url.ParseQuery(response)
	if err != nil {
		err = fmt.Errorf("parsing the server's answer: '%s'", err)
		return
	}

	// check the status

	err = ensureFields(answer, []string{"status", "url_encoded_fmt_stream_map", "title", "author"})
	if err != nil {
		err = fmt.Errorf("Missing fields in the server's answer: '%s'", err)
		return
	}

	status := answer["status"]
	if status[0] == "fail" {
		reason, ok := answer["reason"]
		if ok {
			err = fmt.Errorf("'fail' response status found in the server's answer, reason: '%s'", reason[0])
		} else {
			err = errors.New(fmt.Sprint("'fail' response status found in the server's answer, no reason given"))
		}
		return
	}
	if status[0] != "ok" {
		err = fmt.Errorf("non-success response status found in the server's answer (status: '%s')", status)
		return
	}

	log("Server answered with a success code")

	/*
	for k, v := range answer {
		log("%s: %#v", k, v)
	}
	*/

	// read the streams map

	stream_map := answer["url_encoded_fmt_stream_map"]

	// read each stream

	streams_list := strings.Split(stream_map[0], ",")

	log("Found %d streams in answer", len(streams_list))

	for stream_pos, stream_raw := range streams_list {
		stream_qry, err := url.ParseQuery(stream_raw)
		if err != nil {
			log(fmt.Sprintf("An error occured while decoding one of the video's stream's information: stream %d: %s\n", stream_pos, err))
			continue
		}
		err = ensureFields(stream_qry, []string{"quality", "type", "url", "sig"})
		if err != nil {
			log(fmt.Sprintf("Missing fields in one of the video's stream's information: stream %d: %s\n", stream_pos, err))
			continue
		}
		/* dumps the raw streams
		log(fmt.Sprintf("%v\n", stream_qry))
		*/
		stream := stream{
			"quality": stream_qry["quality"][0],
			"type": stream_qry["type"][0],
			"url": stream_qry["url"][0],
			"sig": stream_qry["sig"][0],
			"title": answer["title"][0],
			"author": answer["author"][0],
		}
		streams = append(streams, stream)

		quality := stream.Quality()
		if quality == QUALITY_UNKNOWN {
			log("Found unknown quality '%s'", stream["quality"])
		}

		format := stream.Format()
		if format == FORMAT_UNKNOWN {
			log("Found unknown format '%s'", stream["type"])
		}

		log("Stream found: quality '%s', format '%s'", quality, format)
	}

	log("Successfully decoded %d streams", len(streams))

	return
}
<|endoftext|>


<commit_before>/*
Package proj provides an interface to the Cartographic Projections Library PROJ.4 [cartography].

See: http://trac.osgeo.org/proj/

Example usage:

    merc, err := proj.NewProj("+proj=merc +ellps=clrk66 +lat_ts=33")
    defer merc.Close() // if omitted, this will be called on garbage collection
    if err != nil {
        log.Fatal(err)
    }

    ll, err := proj.NewProj("+proj=latlong")
    defer ll.Close()
    if err != nil {
        log.Fatal(err)
    }

    x, y, err := proj.Transform2(ll, merc, proj.DegToRad(-16), proj.DegToRad(20.25))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%.2f %.2f", x, y)  // should print: -1495284.21 1920596.79
*/
package proj

/*
#cgo LDFLAGS: -lproj
#include "proj.h"
*/
import "C"

import (
	"errors"
	"math"
	"runtime"
	"sync"
	"unsafe"
)

var (
	mu sync.Mutex
)

type Proj struct {
	pj     _Ctype_projPJ
	opened bool
}

func NewProj(definition string) (*Proj, error) {
	cs := C.CString(definition)
	defer C.free(unsafe.Pointer(cs))
	proj := &Proj{opened: false}

	mu.Lock()
	proj.pj = C.pj_init_plus(cs)
	errstring := C.GoString(C.get_err())
	mu.Unlock()

	var err error = nil
	if errstring == "" {
		proj.opened = true
	} else {
		err = errors.New(errstring)
	}

	runtime.SetFinalizer(proj, (*Proj).Close)

	return proj, err
}

func (p *Proj) Close() {
	if p.opened {
		C.pj_free(p.pj)
		p.opened = false
	}
}

func transform(srcpj, dstpj *Proj, x, y, z []float64) ([]float64, []float64, []float64, error) {
	if !(srcpj.opened && dstpj.opened) {
		return []float64{}, []float64{}, []float64{}, errors.New("projection is closed")
	}

	var x1, y1, z1 []C.double

	ln := len(x)
	if len(y) < ln {
		ln = len(y)
	}
	if z != nil && len(z) < ln {
		ln = len(z)
	}

	if ln == 0 {
		return []float64{}, []float64{}, []float64{}, nil
	}

	x1 = make([]C.double, ln)
	y1 = make([]C.double, ln)
	if z != nil {
		z1 = make([]C.double, ln)
	}
	for i := 0; i < ln; i++ {
		x1[i] = C.double(x[i])
		y1[i] = C.double(y[i])
		if z != nil {
			z1[i] = C.double(z[i])
		}
	}

	var e *C.char
	if z != nil {
		e = C.transform(srcpj.pj, dstpj.pj, C.long(ln), &x1[0], &y1[0], &z1[0])
	} else {
		e = C.transform(srcpj.pj, dstpj.pj, C.long(ln), &x1[0], &y1[0], nil)
	}

	if e != nil {
		return  []float64{}, []float64{}, []float64{}, errors.New(C.GoString(e))
	}

	var x2, y2, z2 []float64
	x2 = make([]float64, ln)
	y2 = make([]float64, ln)
	if z != nil {
		z2 = make([]float64, ln)
	}
	for i := 0; i < ln; i++ {
		x2[i] = float64(x1[i])
		y2[i] = float64(y1[i])
		if z != nil {
			z2[i] = float64(z1[i])
		}
	}
	return x2, y2, z2, nil
}

func Transform2(srcpj, dstpj *Proj, x, y float64) (float64, float64, error) {
	xx, yy, _, err := transform(srcpj, dstpj, []float64{x}, []float64{y}, nil)
	return xx[0], yy[0], err
}

func Transform3(srcpj, dstpj *Proj, x, y, z float64) (float64, float64, float64, error) {
	xx, yy, zz, err := transform(srcpj, dstpj, []float64{x}, []float64{y}, []float64{z})
	return xx[0], yy[0], zz[0], err
}

func Transform2lst(srcpj, dstpj *Proj, x, y []float64) ([]float64, []float64, error) {
	xx, yy, _, err := transform(srcpj, dstpj, x, y, nil)
	return xx, yy, err
}

func Transform3lst(srcpj, dstpj *Proj, x, y, z []float64) ([]float64, []float64, []float64, error) {
	return transform(srcpj, dstpj, x, y, z)
}

// Longitude and latitude in degrees
func Fwd(proj *Proj, long, lat float64) (x, y float64, err error) {
	if !proj.opened {
		return math.NaN(), math.NaN(), errors.New("projection is closed")
	}
	x1 := C.double(long)
	y1 := C.double(lat)
	e := C.fwd(proj.pj, &x1, &y1)
	if e != nil {
		return math.NaN(), math.NaN(), errors.New(C.GoString(e))
	}
	return float64(x1), float64(y1), nil
}

// Longitude and latitude in degrees
func Inv(proj *Proj, x, y float64) (long, lat float64, err error) {
	if !proj.opened {
		return math.NaN(), math.NaN(), errors.New("projection is closed")
	}
	x2 := C.double(x)
	y2 := C.double(y)
	e := C.inv(proj.pj, &x2, &y2)
	if e != nil {
		return math.NaN(), math.NaN(), errors.New(C.GoString(e))
	}
	return float64(x2), float64(y2), nil
}

func DegToRad(deg float64) float64 {
	return deg / 180.0 * math.Pi
}

func RadToDeg(rad float64) float64 {
	return rad / math.Pi * 180.0
}
<commit_msg>Fix for issue #2: mercator projection with longitude 90 causes panic<commit_after>/*
Package proj provides an interface to the Cartographic Projections Library PROJ.4 [cartography].

See: http://trac.osgeo.org/proj/

Example usage:

    merc, err := proj.NewProj("+proj=merc +ellps=clrk66 +lat_ts=33")
    defer merc.Close() // if omitted, this will be called on garbage collection
    if err != nil {
        log.Fatal(err)
    }

    ll, err := proj.NewProj("+proj=latlong")
    defer ll.Close()
    if err != nil {
        log.Fatal(err)
    }

    x, y, err := proj.Transform2(ll, merc, proj.DegToRad(-16), proj.DegToRad(20.25))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%.2f %.2f", x, y)  // should print: -1495284.21 1920596.79
*/
package proj

/*
#cgo LDFLAGS: -lproj
#include "proj.h"
*/
import "C"

import (
	"errors"
	"math"
	"runtime"
	"sync"
	"unsafe"
)

var (
	mu sync.Mutex
)

type Proj struct {
	pj     _Ctype_projPJ
	opened bool
}

func NewProj(definition string) (*Proj, error) {
	cs := C.CString(definition)
	defer C.free(unsafe.Pointer(cs))
	proj := &Proj{opened: false}

	mu.Lock()
	proj.pj = C.pj_init_plus(cs)
	errstring := C.GoString(C.get_err())
	mu.Unlock()

	var err error = nil
	if errstring == "" {
		proj.opened = true
	} else {
		err = errors.New(errstring)
	}

	runtime.SetFinalizer(proj, (*Proj).Close)

	return proj, err
}

func (p *Proj) Close() {
	if p.opened {
		C.pj_free(p.pj)
		p.opened = false
	}
}

func transform(srcpj, dstpj *Proj, x, y, z []float64) ([]float64, []float64, []float64, error) {
	if !(srcpj.opened && dstpj.opened) {
		return []float64{}, []float64{}, []float64{}, errors.New("projection is closed")
	}

	var x1, y1, z1 []C.double

	ln := len(x)
	if len(y) < ln {
		ln = len(y)
	}
	if z != nil && len(z) < ln {
		ln = len(z)
	}

	if ln == 0 {
		return []float64{}, []float64{}, []float64{}, nil
	}

	x1 = make([]C.double, ln)
	y1 = make([]C.double, ln)
	if z != nil {
		z1 = make([]C.double, ln)
	}
	for i := 0; i < ln; i++ {
		x1[i] = C.double(x[i])
		y1[i] = C.double(y[i])
		if z != nil {
			z1[i] = C.double(z[i])
		}
	}

	var e *C.char
	if z != nil {
		e = C.transform(srcpj.pj, dstpj.pj, C.long(ln), &x1[0], &y1[0], &z1[0])
	} else {
		e = C.transform(srcpj.pj, dstpj.pj, C.long(ln), &x1[0], &y1[0], nil)
	}

	if e != nil {
		return []float64{}, []float64{}, []float64{}, errors.New(C.GoString(e))
	}

	var x2, y2, z2 []float64
	x2 = make([]float64, ln)
	y2 = make([]float64, ln)
	if z != nil {
		z2 = make([]float64, ln)
	}
	for i := 0; i < ln; i++ {
		x2[i] = float64(x1[i])
		y2[i] = float64(y1[i])
		if z != nil {
			z2[i] = float64(z1[i])
		}
	}
	return x2, y2, z2, nil
}

func Transform2(srcpj, dstpj *Proj, x, y float64) (float64, float64, error) {
	xx, yy, _, err := transform(srcpj, dstpj, []float64{x}, []float64{y}, nil)
	if err != nil {
		return math.NaN(), math.NaN(), err
	}
	return xx[0], yy[0], err
}

func Transform3(srcpj, dstpj *Proj, x, y, z float64) (float64, float64, float64, error) {
	xx, yy, zz, err := transform(srcpj, dstpj, []float64{x}, []float64{y}, []float64{z})
	if err != nil {
		return math.NaN(), math.NaN(), math.NaN(), err
	}
	return xx[0], yy[0], zz[0], err
}

func Transform2lst(srcpj, dstpj *Proj, x, y []float64) ([]float64, []float64, error) {
	xx, yy, _, err := transform(srcpj, dstpj, x, y, nil)
	return xx, yy, err
}

func Transform3lst(srcpj, dstpj *Proj, x, y, z []float64) ([]float64, []float64, []float64, error) {
	return transform(srcpj, dstpj, x, y, z)
}

// Longitude and latitude in degrees
func Fwd(proj *Proj, long, lat float64) (x, y float64, err error) {
	if !proj.opened {
		return math.NaN(), math.NaN(), errors.New("projection is closed")
	}
	x1 := C.double(long)
	y1 := C.double(lat)
	e := C.fwd(proj.pj, &x1, &y1)
	if e != nil {
		return math.NaN(), math.NaN(), errors.New(C.GoString(e))
	}
	return float64(x1), float64(y1), nil
}

// Longitude and latitude in degrees
func Inv(proj *Proj, x, y float64) (long, lat float64, err error) {
	if !proj.opened {
		return math.NaN(), math.NaN(), errors.New("projection is closed")
	}
	x2 := C.double(x)
	y2 := C.double(y)
	e := C.inv(proj.pj, &x2, &y2)
	if e != nil {
		return math.NaN(), math.NaN(), errors.New(C.GoString(e))
	}
	return float64(x2), float64(y2), nil
}

func DegToRad(deg float64) float64 {
	return deg / 180.0 * math.Pi
}

func RadToDeg(rad float64) float64 {
	return rad / math.Pi * 180.0
}
<|endoftext|>


<commit_before>package vm

import (
	"os"
	"testing"
)

// Failures

func TestRWLockNewMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockAcquireReadLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.acquire_read_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockReleaseReadLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.release_read_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockAcquireWriteLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.acquire_write_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockReleaseWriteLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.release_write_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockWithReadLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_read_lock
		`, "InternalError: Can't yield without a block", 3, 1},
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_read_lock(5) do end
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockWithWriteLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_write_lock
		`, "InternalError: Can't yield without a block", 3, 1},
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_write_lock(5) do end
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkError(t, i, evaluated, tt.expected, getFilename(), tt.errorLine)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

// Isolated lock types

func TestRWLockAcquireAndReleaseReadLock(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new

	lock.acquire_read_lock
	lock.release_read_lock

	"completed"
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func TestRWLockAcquireAndReleaseWriteLock(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new

	lock.acquire_write_lock
	lock.release_write_lock

	"completed"
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func TestRWLockWithReadLockMethod(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new
	message = nil

	lock.with_read_lock do
		message = "completed"
	end

	message
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func TestRWLockWithWriteLockMethod(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new
	message = nil

	lock.with_write_lock do
		message = "completed"
	end

	message
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

// Mixed locks (functional tests)

func TestRWLockAcquireAndReleaseLocksReadBlocksWriteNoRaceDetection(t *testing.T) {
	skipRWLockTestIfRaceDetectionEnabled(t)

  code := `
  require 'concurrent/rw_lock'

  lock = Concurrent::RWLock.new
  message = nil

  thread do
    lock.acquire_read_lock
    sleep 2
    message ||= "thread 1"
    lock.release_read_lock
  end

  thread do
    sleep 1
    lock.acquire_write_lock
    message ||= "thread 2"
    lock.release_write_lock
  end

  sleep 3
  lock.with_read_lock do
    message
  end
  `

  expected := "thread 1"

  v := initTestVM()
  evaluated := v.testEval(t, code, getFilename())
  testStringObject(t, i, evaluated, expected)
  v.checkCFP(t, i, 0)
  v.checkSP(t, i, 1)
}

func TestRWLockWithReadLockReadBlocksWriteNoRaceDetection(t *testing.T) {
	skipRWLockTestIfRaceDetectionEnabled(t)

	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new
	message = nil

	thread do
	  lock.with_read_lock do
	    sleep 2
	    message ||= "thread 1"
	  end
	end

	thread do
	  sleep 1
	  lock.with_write_lock do
	    message ||= "thread 2"
	  end
	end

	sleep 3
	lock.with_read_lock do
		message
	end
	`

	expected := "thread 1"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func skipRWLockTestIfRaceDetectionEnabled(t *testing.T) {
	if os.Getenv("NO_RACE_DETECTION") == "" {
		t.Skip("skipping RW lock related tests")
	}
}
<commit_msg>Fixed failures from master merge<commit_after>package vm

import (
	"os"
	"testing"
)

// Failures

func TestRWLockNewMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkErrorMsg(t, i, evaluated, tt.expected)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockAcquireReadLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.acquire_read_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 0},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkErrorMsg(t, i, evaluated, tt.expected)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockReleaseReadLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.release_read_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkErrorMsg(t, i, evaluated, tt.expected)
		v.checkCFP(t, i, 0)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockAcquireWriteLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.acquire_write_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkErrorMsg(t, i, evaluated, tt.expected)
		v.checkCFP(t, i, 0)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockReleaseWriteLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.release_write_lock(5)
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 1},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkErrorMsg(t, i, evaluated, tt.expected)
		v.checkCFP(t, i, 0)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockWithReadLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_read_lock
		`, "InternalError: Can't yield without a block", 3, 1},
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_read_lock(5) do end
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 0},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkErrorMsg(t, i, evaluated, tt.expected)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

func TestRWLockWithWriteLockMethodFail(t *testing.T) {
	testsFail := []errorTestCase{
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_write_lock
		`, "InternalError: Can't yield without a block", 3, 1},
		{`
		require 'concurrent/rw_lock'
		Concurrent::RWLock.new.with_write_lock(5) do end
		`, "ArgumentError: Expected 0 arguments, got 1", 3, 0},
	}

	for i, tt := range testsFail {
		v := initTestVM()
		evaluated := v.testEval(t, tt.input, getFilename())
		checkErrorMsg(t, i, evaluated, tt.expected)
		v.checkCFP(t, i, tt.expectedCFP)
		v.checkSP(t, i, 1)
	}
}

// Isolated lock types

func TestRWLockAcquireAndReleaseReadLock(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new

	lock.acquire_read_lock
	lock.release_read_lock

	"completed"
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func TestRWLockAcquireAndReleaseWriteLock(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new

	lock.acquire_write_lock
	lock.release_write_lock

	"completed"
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func TestRWLockWithReadLockMethod(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new
	message = nil

	lock.with_read_lock do
		message = "completed"
	end

	message
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func TestRWLockWithWriteLockMethod(t *testing.T) {
	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new
	message = nil

	lock.with_write_lock do
		message = "completed"
	end

	message
	`

	expected := "completed"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

// Mixed locks (functional tests)

func TestRWLockAcquireAndReleaseLocksReadBlocksWriteNoRaceDetection(t *testing.T) {
	skipRWLockTestIfRaceDetectionEnabled(t)

  code := `
  require 'concurrent/rw_lock'

  lock = Concurrent::RWLock.new
  message = nil

  thread do
    lock.acquire_read_lock
    sleep 2
    message ||= "thread 1"
    lock.release_read_lock
  end

  thread do
    sleep 1
    lock.acquire_write_lock
    message ||= "thread 2"
    lock.release_write_lock
  end

  sleep 3
  lock.with_read_lock do
    message
  end
  `

  expected := "thread 1"

  v := initTestVM()
  evaluated := v.testEval(t, code, getFilename())
  testStringObject(t, i, evaluated, expected)
  v.checkCFP(t, i, 0)
  v.checkSP(t, i, 1)
}

func TestRWLockWithReadLockReadBlocksWriteNoRaceDetection(t *testing.T) {
	skipRWLockTestIfRaceDetectionEnabled(t)

	code := `
	require 'concurrent/rw_lock'

	lock = Concurrent::RWLock.new
	message = nil

	thread do
	  lock.with_read_lock do
	    sleep 2
	    message ||= "thread 1"
	  end
	end

	thread do
	  sleep 1
	  lock.with_write_lock do
	    message ||= "thread 2"
	  end
	end

	sleep 3
	lock.with_read_lock do
		message
	end
	`

	expected := "thread 1"

	v := initTestVM()
	evaluated := v.testEval(t, code, getFilename())
	testStringObject(t, i, evaluated, expected)
	v.checkCFP(t, i, 0)
	v.checkSP(t, i, 1)
}

func skipRWLockTestIfRaceDetectionEnabled(t *testing.T) {
	if os.Getenv("NO_RACE_DETECTION") == "" {
		t.Skip("skipping RW lock related tests")
	}
}
<|endoftext|>


<commit_before>package psimgo

import (
	"testing"
	"fmt"
	"math/rand"
)

func TestMessagePassing(t *testing.T) {
	comm := PSim{
		P: 5,
		Topology: SWITCH,
	}

	runTest := func (rank int, comm PSim) {
		if rank == 0 {
			fmt.Printf("start test\n")
		}

		if rank == 2 {
			comm.Send(rank, 3, 11)
		} else if rank == 3 {
			c := comm.RecvInt(rank, 2)
			d := c + 1
			fmt.Printf("%d\n", d)
		}

		var f int
		a := ToIntArray(comm.All2all_broadcast(rank, rank))

		for _, e := range a {
			f += e
		}

		fmt.Printf("%d\n", f)

		comm.Barrier(rank)

		op := func(a, b interface {}) interface {} {
			if x, ok := a.(int); ok {
				if y, ok := b.(int); ok {
					return x + y
				}
			}
			return 0
		}

		b := comm.All2all_reduce(rank, rank, op)

		fmt.Printf("%d\n", b)

		if f!=10 || f!=b {
			t.Error(fmt.Sprintf("from process %d\n", rank))
		}

		if rank==0 {
			fmt.Printf("test passed\n")
		}
	}

	comm.Run(runTest)
}

func TestMergeSort(t *testing.T) {

	comm := PSim{
		P: 2,
		Topology: SWITCH,
	}

	p_mergesort_test := func(rank int, comm PSim) {
			data := make([]float64, 16, 16)
		if rank == 0 {
			for i := range data {
				data[i] = rand.Float64() * 10
			}
			mid := int(16/2)
			comm.Send(rank, 1, data[mid+1:])
			mergesort(data, 0, mid)
			second := comm.RecvFloatArray(rank, 1)

			for k := range second {
				data[k+mid+1] = second[k]
			}
			fmt.Printf("%v\n", data)
			merge(data, 0, mid+1, 15)
			fmt.Printf("%v\n", data)

			for j := range data {
				if j < len(data)-1 && data[j+1] < data[j] {
					t.Errorf("Data not sorted correctly")
				}
			}
		} else {
			data2 := comm.RecvFloatArray(rank, 0)

			//		reflect.ValueOf(data2)
			mergesort(data2, 0, len(data2)-1)
			comm.Send(rank, 0, data2)
		}
	}

	comm.Run(p_mergesort_test)
}

func mergesort(A []float64, p, r int) {
	if p < r {
		q := int((p + r) / 2)
		mergesort(A, p, q)
		mergesort(A, q+1, r)
		merge(A, p, q+1, r)
	}
}

func merge(A []float64, p, q, r int) {
	B := make([]float64, 0)
	//	fmt.Printf("%d %d %d\n", p, q, r)
	i := p
	j := q
	for {
		if A[i] <= A[j] {
			B = append(B, A[i])
			i = i+1
		} else {
			B = append(B, A[j])
			j = j+1
		}

		if i == q {
			for j<=r {
				B = append(B, A[j])
				j = j+1
			}
			break
		}
		if j == r+1 {
			for i<q {
				B = append(B, A[i])
				i = i+1
			}
			break
		}
	}

	//	fmt.Printf("%v\n", B)

	for k := range B {
		A[p+k] = B[k]
	}
}

func mergesort_test() {
	data := make([]float64, 16, 16)
	for i := range data {
		data[i] = rand.Float64() * 10
	}
	fmt.Printf("%v\n", data)
	mergesort(data, 0, 15)
	fmt.Printf("%v\n", data)
}

<commit_msg>Added additional check in TestMessagePassing<commit_after>package psimgo

import (
	"testing"
	"fmt"
	"math/rand"
)

func TestMessagePassing(t *testing.T) {
	comm := PSim{
		P: 5,
		Topology: SWITCH,
	}

	runTest := func (rank int, comm PSim) {
		if rank == 0 {
			fmt.Printf("start test\n")
		}

		if rank == 2 {
			comm.Send(rank, 3, 11)
		} else if rank == 3 {
			c := comm.RecvInt(rank, 2)
			d := c + 1
			if d != 12 {
				t.Errorf("Wrong number received or number not received as int")
			}
		}

		var f int
		a := ToIntArray(comm.All2all_broadcast(rank, rank))

		for _, e := range a {
			f += e
		}

		fmt.Printf("%d\n", f)

		comm.Barrier(rank)

		op := func(a, b interface {}) interface {} {
			if x, ok := a.(int); ok {
				if y, ok := b.(int); ok {
					return x + y
				}
			}
			return 0
		}

		b := comm.All2all_reduce(rank, rank, op)

		fmt.Printf("%d\n", b)

		if f!=10 || f!=b {
			t.Error(fmt.Sprintf("from process %d\n", rank))
		}

		if rank==0 {
			fmt.Printf("test passed\n")
		}
	}

	comm.Run(runTest)
}

func TestMergeSort(t *testing.T) {

	comm := PSim{
		P: 2,
		Topology: SWITCH,
	}

	p_mergesort_test := func(rank int, comm PSim) {
			data := make([]float64, 16, 16)
		if rank == 0 {
			for i := range data {
				data[i] = rand.Float64() * 10
			}
			mid := int(16/2)
			comm.Send(rank, 1, data[mid+1:])
			mergesort(data, 0, mid)
			second := comm.RecvFloatArray(rank, 1)

			for k := range second {
				data[k+mid+1] = second[k]
			}
			fmt.Printf("%v\n", data)
			merge(data, 0, mid+1, 15)
			fmt.Printf("%v\n", data)

			for j := range data {
				if j < len(data)-1 && data[j+1] < data[j] {
					t.Errorf("Data not sorted correctly")
				}
			}
		} else {
			data2 := comm.RecvFloatArray(rank, 0)

			//		reflect.ValueOf(data2)
			mergesort(data2, 0, len(data2)-1)
			comm.Send(rank, 0, data2)
		}
	}

	comm.Run(p_mergesort_test)
}

func mergesort(A []float64, p, r int) {
	if p < r {
		q := int((p + r) / 2)
		mergesort(A, p, q)
		mergesort(A, q+1, r)
		merge(A, p, q+1, r)
	}
}

func merge(A []float64, p, q, r int) {
	B := make([]float64, 0)
	//	fmt.Printf("%d %d %d\n", p, q, r)
	i := p
	j := q
	for {
		if A[i] <= A[j] {
			B = append(B, A[i])
			i = i+1
		} else {
			B = append(B, A[j])
			j = j+1
		}

		if i == q {
			for j<=r {
				B = append(B, A[j])
				j = j+1
			}
			break
		}
		if j == r+1 {
			for i<q {
				B = append(B, A[i])
				i = i+1
			}
			break
		}
	}

	for k := range B {
		A[p+k] = B[k]
	}
}

func mergesort_test() {
	data := make([]float64, 16, 16)
	for i := range data {
		data[i] = rand.Float64() * 10
	}
	fmt.Printf("%v\n", data)
	mergesort(data, 0, 15)
	fmt.Printf("%v\n", data)
}

<|endoftext|>


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

package samples

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"time"

	"github.com/jacobsa/fuse"
	"github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
	"golang.org/x/net/context"
)

// A struct that implements common behavior needed by tests in the samples/
// directory. Use it as an embedded field in your test fixture, calling its
// SetUp method from your SetUp method after setting the Server field.
type SampleTest struct {
	// The server under test and the configuration with which it should be
	// mounted. These must be set by the user of this type before calling SetUp;
	// all the other fields below are set by SetUp itself.
	Server      fuse.Server
	MountConfig fuse.MountConfig

	// A context object that can be used for long-running operations.
	Ctx context.Context

	// A clock with a fixed initial time. The test's set up method may use this
	// to wire the server with a clock, if desired.
	Clock timeutil.SimulatedClock

	// The directory at which the file system is mounted.
	Dir string

	// Anothing non-nil in this slice will be closed by TearDown. The test will
	// fail if closing fails.
	ToClose []io.Closer

	mfs *fuse.MountedFileSystem
}

// Mount t.Server and initialize the other exported fields of the struct.
// Panics on error.
//
// REQUIRES: t.Server has been set.
func (t *SampleTest) SetUp(ti *ogletest.TestInfo) {
	err := t.initialize(ti.Ctx, t.Server, &t.MountConfig)
	if err != nil {
		panic(err)
	}
}

// Like SetUp, but doens't panic.
func (t *SampleTest) initialize(
	ctx context.Context,
	server fuse.Server,
	config *fuse.MountConfig) (err error) {
	// Initialize the context used by the test.
	t.Ctx = ctx

	// Make the server share that context, if the test hasn't already set some
	// other one.
	if config.OpContext == nil {
		config.OpContext = ctx
	}

	// Initialize the clock.
	t.Clock.SetTime(time.Date(2012, 8, 15, 22, 56, 0, 0, time.Local))

	// Set up a temporary directory.
	t.Dir, err = ioutil.TempDir("", "sample_test")
	if err != nil {
		err = fmt.Errorf("TempDir: %v", err)
		return
	}

	// Mount the file system.
	t.mfs, err = fuse.Mount(t.Dir, server, config)
	if err != nil {
		err = fmt.Errorf("Mount: %v", err)
		return
	}

	return
}

// Unmount the file system and clean up. Panics on error.
func (t *SampleTest) TearDown() {
	err := t.destroy()
	if err != nil {
		panic(err)
	}
}

// Like TearDown, but doesn't panic.
func (t *SampleTest) destroy() (err error) {
	// Close what is necessary.
	for _, c := range t.ToClose {
		if c == nil {
			continue
		}

		ogletest.ExpectEq(nil, c.Close())
	}

	// Was the file system mounted?
	if t.mfs == nil {
		return
	}

	// Unmount the file system.
	err = unmount(t.Dir)
	if err != nil {
		err = fmt.Errorf("unmount: %v", err)
		return
	}

	// Unlink the mount point.
	if err = os.Remove(t.Dir); err != nil {
		err = fmt.Errorf("Unlinking mount point: %v", err)
		return
	}

	// Join the file system.
	err = t.mfs.Join(t.Ctx)
	if err != nil {
		err = fmt.Errorf("mfs.Join: %v", err)
		return
	}

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

package samples

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
	"time"

	"github.com/jacobsa/fuse"
	"github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
	"golang.org/x/net/context"
)

// A struct that implements common behavior needed by tests in the samples/
// directory. Use it as an embedded field in your test fixture, calling its
// SetUp method from your SetUp method after setting the Server field.
type SampleTest struct {
	// The server under test and the configuration with which it should be
	// mounted. These must be set by the user of this type before calling SetUp;
	// all the other fields below are set by SetUp itself.
	Server      fuse.Server
	MountConfig fuse.MountConfig

	// A context object that can be used for long-running operations.
	Ctx context.Context

	// A clock with a fixed initial time. The test's set up method may use this
	// to wire the server with a clock, if desired.
	Clock timeutil.SimulatedClock

	// The directory at which the file system is mounted.
	Dir string

	// Anothing non-nil in this slice will be closed by TearDown. The test will
	// fail if closing fails.
	ToClose []io.Closer

	mfs *fuse.MountedFileSystem
}

// Mount t.Server and initialize the other exported fields of the struct.
// Panics on error.
//
// REQUIRES: t.Server has been set.
func (t *SampleTest) SetUp(ti *ogletest.TestInfo) {
	cfg := t.MountConfig
	if *fDebug {
		cfg.DebugLogger = log.New(os.Stderr, "fuse: ", 0)
	}

	err := t.initialize(ti.Ctx, t.Server, &cfg)
	if err != nil {
		panic(err)
	}
}

// Like SetUp, but doens't panic.
func (t *SampleTest) initialize(
	ctx context.Context,
	server fuse.Server,
	config *fuse.MountConfig) (err error) {
	// Initialize the context used by the test.
	t.Ctx = ctx

	// Make the server share that context, if the test hasn't already set some
	// other one.
	if config.OpContext == nil {
		config.OpContext = ctx
	}

	// Initialize the clock.
	t.Clock.SetTime(time.Date(2012, 8, 15, 22, 56, 0, 0, time.Local))

	// Set up a temporary directory.
	t.Dir, err = ioutil.TempDir("", "sample_test")
	if err != nil {
		err = fmt.Errorf("TempDir: %v", err)
		return
	}

	// Mount the file system.
	t.mfs, err = fuse.Mount(t.Dir, server, config)
	if err != nil {
		err = fmt.Errorf("Mount: %v", err)
		return
	}

	return
}

// Unmount the file system and clean up. Panics on error.
func (t *SampleTest) TearDown() {
	err := t.destroy()
	if err != nil {
		panic(err)
	}
}

// Like TearDown, but doesn't panic.
func (t *SampleTest) destroy() (err error) {
	// Close what is necessary.
	for _, c := range t.ToClose {
		if c == nil {
			continue
		}

		ogletest.ExpectEq(nil, c.Close())
	}

	// Was the file system mounted?
	if t.mfs == nil {
		return
	}

	// Unmount the file system.
	err = unmount(t.Dir)
	if err != nil {
		err = fmt.Errorf("unmount: %v", err)
		return
	}

	// Unlink the mount point.
	if err = os.Remove(t.Dir); err != nil {
		err = fmt.Errorf("Unlinking mount point: %v", err)
		return
	}

	// Join the file system.
	err = t.mfs.Join(t.Ctx)
	if err != nil {
		err = fmt.Errorf("mfs.Join: %v", err)
		return
	}

	return
}
<|endoftext|>


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

package usb

import "io"

type transferIntf interface {
	submit() error
	cancel() error
	wait() (int, error)
	free() error
	data() []byte
}

type stream struct {
	// a fifo of USB transfers.
	transfers chan transferIntf
	// current holds the last transfer to return.
	current transferIntf
	// total/used are the number of all/used bytes in the current transfer.
	total, used int
	// delayedErr is the delayed error, returned to the user after all
	// remaining data was read.
	delayedErr error
}

func (s *stream) setDelayedErr(err error) {
	if s.delayedErr == nil {
		s.delayedErr = err
		close(s.transfers)
	}
}

// ReadStream is a buffer that tries to prefetch data from the IN endpoint,
// reducing the latency between subsequent Read()s.
// ReadStream keeps prefetching data until Close() is called or until
// an error is encountered. After Close(), the buffer might still have
// data left from transfers that were initiated before Close. Read()ing
// from the ReadStream will keep returning available data. When no more
// data is left, io.EOF is returned.
type ReadStream struct {
	s *stream
}

// Read reads data from the transfer stream.
// The data will come from at most a single transfer, so the returned number
// might be smaller than the length of p.
// After a non-nil error is returned, all subsequent attempts to read will
// return io.ErrClosedPipe.
func (r ReadStream) Read(p []byte) (int, error) {
	s := r.s
	if s.transfers == nil {
		return 0, io.ErrClosedPipe
	}
	if s.current == nil {
		t, ok := <-s.transfers
		if !ok {
			// no more transfers in flight
			s.transfers = nil
			return 0, s.delayedErr
		}
		n, err := t.wait()
		if err != nil {
			// wait error aborts immediately, all remaining data is invalid.
			t.free()
			if s.delayedErr == nil {
				close(s.transfers)
			}
			for t := range s.transfers {
				t.cancel()
				t.wait()
				t.free()
			}
			s.transfers = nil
			return n, err
		}
		s.current = t
		s.total = n
		s.used = 0
	}
	use := s.total - s.used
	if use > len(p) {
		use = len(p)
	}
	copy(p, s.current.data()[s.used:s.used+use])
	s.used += use
	if s.used == s.total {
		if s.delayedErr == nil {
			if err := s.current.submit(); err == nil {
				// guaranteed to not block, len(transfers) == number of allocated transfers
				s.transfers <- s.current
			} else {
				s.setDelayedErr(err)
			}
		}
		if s.delayedErr != nil {
			s.current.free()
		}
		s.current = nil
	}
	return use, nil
}

// Close signals that the transfer should stop. After Close is called,
// subsequent Read()s will return data from all transfers that were already
// in progress before returning an io.EOF error, unless another error
// was encountered earlier.
func (r ReadStream) Close() {
	r.s.setDelayedErr(io.EOF)
}

// WriteStream is a buffer that will send data asynchronously, reducing
// the latency between subsequent Write()s.
type WriteStream struct {
	s *stream
}

// Write sends the data to the endpoint. Write returning a nil error doesn't
// mean that data was written to the device, only that it was written to the
// buffer. Only a call to Flush() that returns nil error guarantees that
// all transfers have succeeded.
func (w WriteStream) Write(p []byte) (int, error) {
	s := w.s
	written := 0
	all := len(p)
	for written < all {
		if s.current == nil {
			s.current = <-s.transfers
			s.total = len(s.current.data())
			s.used = 0
		}
		use := all - written
		if use > s.total {
			use = s.total
		}
		copy(s.current.data()[s.used:], p[written:written+use])
	}
	return 0, nil
}

func (w WriteStream) Flush() error {
	return nil
}

func newStream(tt []transferIntf, submit bool) *stream {
	s := &stream{
		transfers: make(chan transferIntf, len(tt)),
	}
	for _, t := range tt {
		if submit {
			if err := t.submit(); err != nil {
				t.free()
				s.setDelayedErr(err)
				break
			}
		}
		s.transfers <- t
	}
	return s
}
<commit_msg>Disable Write streams for now.<commit_after>// Copyright 2017 the gousb Authors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package usb

import "io"

type transferIntf interface {
	submit() error
	cancel() error
	wait() (int, error)
	free() error
	data() []byte
}

type stream struct {
	// a fifo of USB transfers.
	transfers chan transferIntf
	// current holds the last transfer to return.
	current transferIntf
	// total/used are the number of all/used bytes in the current transfer.
	total, used int
	// delayedErr is the delayed error, returned to the user after all
	// remaining data was read.
	delayedErr error
}

func (s *stream) setDelayedErr(err error) {
	if s.delayedErr == nil {
		s.delayedErr = err
		close(s.transfers)
	}
}

// ReadStream is a buffer that tries to prefetch data from the IN endpoint,
// reducing the latency between subsequent Read()s.
// ReadStream keeps prefetching data until Close() is called or until
// an error is encountered. After Close(), the buffer might still have
// data left from transfers that were initiated before Close. Read()ing
// from the ReadStream will keep returning available data. When no more
// data is left, io.EOF is returned.
type ReadStream struct {
	s *stream
}

// Read reads data from the transfer stream.
// The data will come from at most a single transfer, so the returned number
// might be smaller than the length of p.
// After a non-nil error is returned, all subsequent attempts to read will
// return io.ErrClosedPipe.
func (r ReadStream) Read(p []byte) (int, error) {
	s := r.s
	if s.transfers == nil {
		return 0, io.ErrClosedPipe
	}
	if s.current == nil {
		t, ok := <-s.transfers
		if !ok {
			// no more transfers in flight
			s.transfers = nil
			return 0, s.delayedErr
		}
		n, err := t.wait()
		if err != nil {
			// wait error aborts immediately, all remaining data is invalid.
			t.free()
			if s.delayedErr == nil {
				close(s.transfers)
			}
			for t := range s.transfers {
				t.cancel()
				t.wait()
				t.free()
			}
			s.transfers = nil
			return n, err
		}
		s.current = t
		s.total = n
		s.used = 0
	}
	use := s.total - s.used
	if use > len(p) {
		use = len(p)
	}
	copy(p, s.current.data()[s.used:s.used+use])
	s.used += use
	if s.used == s.total {
		if s.delayedErr == nil {
			if err := s.current.submit(); err == nil {
				// guaranteed to not block, len(transfers) == number of allocated transfers
				s.transfers <- s.current
			} else {
				s.setDelayedErr(err)
			}
		}
		if s.delayedErr != nil {
			s.current.free()
		}
		s.current = nil
	}
	return use, nil
}

// Close signals that the transfer should stop. After Close is called,
// subsequent Read()s will return data from all transfers that were already
// in progress before returning an io.EOF error, unless another error
// was encountered earlier.
func (r ReadStream) Close() {
	r.s.setDelayedErr(io.EOF)
}

// WriteStream is a buffer that will send data asynchronously, reducing
// the latency between subsequent Write()s.
type WriteStream struct {
	s *stream
}

// Write sends the data to the endpoint. Write returning a nil error doesn't
// mean that data was written to the device, only that it was written to the
// buffer. Only a call to Flush() that returns nil error guarantees that
// all transfers have succeeded.
// TODO(sebek): not implemented and tested yet
/*
func (w WriteStream) Write(p []byte) (int, error) {
	s := w.s
	written := 0
	all := len(p)
	for written < all {
		if s.current == nil {
			s.current = <-s.transfers
			s.total = len(s.current.data())
			s.used = 0
		}
		use := all - written
		if use > s.total {
			use = s.total
		}
		copy(s.current.data()[s.used:], p[written:written+use])
	}
	return 0, nil
}

func (w WriteStream) Flush() error {
	return nil
}
*/

func newStream(tt []transferIntf, submit bool) *stream {
	s := &stream{
		transfers: make(chan transferIntf, len(tt)),
	}
	for _, t := range tt {
		if submit {
			if err := t.submit(); err != nil {
				t.free()
				s.setDelayedErr(err)
				break
			}
		}
		s.transfers <- t
	}
	return s
}
<|endoftext|>