예제 #1
0
파일: uctricks.go 프로젝트: rjw57/unifun
// initialise the mappings from vanilla runes -> flipped
func initFlipped() {
	const (
		VANILLA = "zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA0987654321&_?!\"'.,;"
		FLIPPED = "zʎxʍʌnʇsɹbdouɯlʞɾıɥɓɟǝpɔqɐZ⅄XMΛ∩⊥SᴚΌԀONW˥⋊ſIH⅁ℲƎ◖Ɔ𐐒∀068ㄥ9ގㄣƐᄅ⇂⅋‾¿¡„,˙'؛"
	)

	var (
		vanillaIdx int
		runeMap    map[int]int
	)

	vanilla := utf8.NewString(VANILLA)

	vanillaIdx = 0
	runeMap = make(map[int]int)
	for _, r := range FLIPPED {
		runeMap[vanilla.At(vanillaIdx)] = r
		vanillaIdx++
	}

	// a function to reverse the runes in a string
	reverse := func(s string) string {
		us := utf8.NewString(s)
		out := ""
		for i := us.RuneCount() - 1; i >= 0; i-- {
			out += fmt.Sprintf("%c", us.At(i))
		}
		return out
	}

	fonts["flipped"] = Font{runeMap, reverse}
}
예제 #2
0
func MakeACGenEdit(Gp [][]string, c []float64) func(string, string) float64 {
	Proot := MakeLinkedGoto(Gp[0])
	MakeLinkedFail(Proot)
	Troot := MakeLinkedGoto(Gp[1])
	MakeLinkedFail(Troot)
	G := make([][]*utf8.String, len(Gp))
	for i, _ := range G {
		G[i] = make([]*utf8.String, len(Gp[i]))
		for j, _ := range G[i] {
			G[i][j] = utf8.NewString(Gp[i][j])
		}
	}

	return func(pattern string, text string) float64 {
		P := utf8.NewString(pattern + " ")
		PLen := P.RuneCount() - 1
		T := utf8.NewString(text + " ")
		TLen := T.RuneCount() - 1
		d := makeMatrix(TLen+1, PLen+1)
		p := NewBitArray(len(Gp[0]))

		Pstate := Proot
		Tstate := Troot

		for x := 0; x <= PLen; x++ {
			Tstate = Troot
			for y := 0; y <= TLen; y++ {
				if x == 0 && y == 0 {
					d[y][x] = 0
				} else {
					d[y][x] = math.Inf(1)
					if x > 0 && y > 0 && Pstate.symbol == Tstate.symbol {
						d[y][x] = d[y-1][x-1]
					}
					if len(Pstate.output) > 0 && len(Tstate.output) > 0 {
						p = p.Intersection(Pstate.output, Tstate.output)
						p.ForEach(func(i int) {
							a := x - G[0][i].RuneCount()
							b := y - G[1][i].RuneCount()
							d[y][x] = math.Fmin(d[y][x], d[b][a]+c[i])
						})
					}
				}
				Tstate = Tstate.Push(T.At(y))
			}
			Pstate = Pstate.Push(P.At(x))
		}

		return d[TLen][PLen]
	}
}
예제 #3
0
파일: uctricks.go 프로젝트: rjw57/unifun
// initialise the mappings from vanilla runes -> blackletter
func initBlackLetter() {
	const (
		VANILLA          = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
		BLACKLETTER      = "𝔄𝔅ℭ𝔇𝔈𝔉𝔊ℌℑ𝔍𝔎𝔏𝔐𝔑𝔒𝔓𝔔ℜ𝔖𝔗𝔘𝔙𝔚𝔛𝔜ℨ𝔞𝔟𝔠𝔡𝔢𝔣𝔤𝔥𝔦𝔧𝔨𝔩𝔪𝔫𝔬𝔭𝔮𝔯𝔰𝔱𝔲𝔳𝔴𝔵𝔶𝔷"
		BLACKLETTER_BOLD = "𝕬𝕭𝕮𝕯𝕰𝕱𝕲𝕳𝕴𝕵𝕶𝕷𝕸𝕹𝕺𝕻𝕼𝕽𝕾𝕿𝖀𝖁𝖂𝖃𝖄𝖅𝖆𝖇𝖈𝖉𝖊𝖋𝖌𝖍𝖎𝖏𝖐𝖑𝖒𝖓𝖔𝖕𝖖𝖗𝖘𝖙𝖚𝖛𝖜𝖝𝖞𝖟"
	)

	var (
		vanillaIdx int
		runeMap    map[int]int
	)

	vanilla := utf8.NewString(VANILLA)

	vanillaIdx = 0
	runeMap = make(map[int]int)
	for _, r := range BLACKLETTER {
		runeMap[vanilla.At(vanillaIdx)] = r
		vanillaIdx++
	}
	fonts["blackletter"] = Font{runeMap, nil}

	vanillaIdx = 0
	runeMap = make(map[int]int)
	for _, r := range BLACKLETTER_BOLD {
		runeMap[vanilla.At(vanillaIdx)] = r
		vanillaIdx++
	}
	fonts["blackletterbold"] = Font{runeMap, nil}
}
예제 #4
0
func Literal(s string, result interface{}) Parser {
	match := utf8.NewString(s)
	if len(s) == 0 {
		return Return(result)
	}
	return Sequence_(literalRune(match.At(0)), Literal(match.Slice(1, match.RuneCount()), result))
}
예제 #5
0
func frame(data string, json bool) string {
	utf8str := utf8.NewString(data)
	if json {
		return fmt.Sprintf("~m~%d~m~~j~%s", 3+utf8str.RuneCount(), data)
	}
	return fmt.Sprintf("~m~%d~m~%s", utf8str.RuneCount(), data)
}
예제 #6
0
파일: singlemover.go 프로젝트: newblue/gorf
func (this *SingleMover) CollectUnexportedObjs() {
	this.unexportedObjs = make(map[*ast.Object]bool)
	for node, obj := range this.moveNodes {
		//printer.Fprint(os.Stdout, token.NewFileSet(), node)
		//fmt.Printf("\n%v %T\n", obj, node)

		if !unicode.IsUpper(utf8.NewString(obj.Name).At(0)) {
			this.unexportedObjs[obj] = true
		}

		if ts, ok := node.(*ast.TypeSpec); ok {
			if st, ok := ts.Type.(*ast.StructType); ok {
				for _, field := range st.Fields.List {
					for _, name := range field.Names {
						if !name.IsExported() {
							obj, _ := types.ExprType(name, LocalImporter)
							this.unexportedObjs[obj] = true
						}
					}
				}
			}
		}
	}
	return
}
예제 #7
0
func RandomString(alpha string, min int, max int) string {
	alphabet := utf8.NewString(alpha)
	runes := make([]int, rand.Intn(max-(min-1))+min)
	for i, _ := range runes {
		p := rand.Intn(alphabet.RuneCount())
		runes[i] = alphabet.At(p)
	}
	return string(runes)
}
예제 #8
0
func Substrings(str string) []string {
	s := utf8.NewString(str)
	n := s.RuneCount()
	substrings := make([]string, 0, (n*(n+1))/2)
	for start := 0; start < n; start++ {
		for end := start + 1; end <= n; end++ {
			substrings = append(substrings, s.Slice(start, end))
		}
	}
	return substrings
}
예제 #9
0
func ParseSumma(s string) int64 {
	S := utf8.NewString(s)
	var i int
	for i = 0; i < S.RuneCount(); i++ {
		if unicode.IsSpace(S.At(i)) { // конец даты
			//DecodeDate(S.Slice(0,i), &lf.curT.date)
			break
		}
	}
	return (0)
}
예제 #10
0
func (doc *Document) AddText(text string, font *drawing.Font, color drawing.Color, preferredSize drawing.Size, format drawing.DrawTextFormat) os.Error {
	item := &simpleTextItem{
		text:          utf8.NewString(text),
		font:          font,
		color:         color,
		preferredSize: preferredSize,
		format:        format,
		parts:         make([]*simpleTextPart, 0, 1),
	}

	return doc.paginateItem(item)
}
예제 #11
0
파일: util.go 프로젝트: newblue/gorf
func IsLegalIdentifier(s string) bool {
	us := utf8.NewString(s)
	if !unicode.IsLetter(us.At(0)) {
		return false
	}
	for i, c := range s {
		if !unicode.IsLetter(c) && (i == 0 || !unicode.IsDigit(c)) {
			return false
		}
	}
	return true
}
예제 #12
0
func MakeBasicGenEdit(G [][]string, c []float64) func(string, string) float64 {
	cost := func(A string, B string, pi int, d [][]float64) float64 {
		a := len(A) - len(G[pi][0])
		b := len(B) - len(G[pi][1])
		if a >= 0 && b >= 0 && A[a:] == G[pi][0] && B[b:] == G[pi][1] {
			return d[b][a] + c[pi]
		}
		return math.Inf(1)
	}

	return func(Ap string, Bp string) float64 {
		A := utf8.NewString(Ap)
		B := utf8.NewString(Bp)
		d := makeMatrix(B.RuneCount()+1, A.RuneCount()+1)

		for x := 0; x <= A.RuneCount(); x++ {
			for y := 0; y <= B.RuneCount(); y++ {
				if x == 0 && y == 0 {
					d[y][x] = 0
				} else {
					min := math.Inf(1)
					if x > 0 && y > 0 && A.At(x-1) == B.At(y-1) {
						min = d[y-1][x-1]
					}
					for pi, _ := range G {
						min = math.Fmin(min,
							cost(A.Slice(0, x),
								B.Slice(0, y),
								pi,
								d))
					}

					d[y][x] = min
				}
			}
		}

		return d[B.RuneCount()][A.RuneCount()]
	}
}
예제 #13
0
파일: cmd-google.go 프로젝트: raylu/rbot
func translate(sourcelang, targetlang, text string) string {
	uri := fmt.Sprintf("http://translate.google.com/translate_a/t?client=t&hl=%s&sl=%s&tl=en-US&text=%s",
		targetlang, sourcelang, url.QueryEscape(text))

	b, err := getUserAgent(uri)
	if err != nil {
		return "Error while requesting translation"
	}

	result := strings.SplitN(string(b), `"`, 11)
	if len(result) < 11 {
		return "Error while parsing translation"
	}

	if sourcelang == "auto" {
		return result[9]
	}

	source := utf8.NewString(result[1])
	romanized := utf8.NewString(result[5])
	if romanized.RuneCount() > 0 {
		if sourcelang == "en" && !strings.Contains(text, " ") {
			// Google duplicates when there is only one source word
			source_left := source.Slice(0, source.RuneCount()/2)
			source_right := source.Slice(source.RuneCount()/2, source.RuneCount())
			romanized_left := romanized.Slice(0, romanized.RuneCount()/2)
			romanized_right := romanized.Slice(romanized.RuneCount()/2, romanized.RuneCount())
			if source_left == source_right &&
				strings.ToLower(romanized_left) == strings.ToLower(romanized_right) {
				return fmt.Sprintf("%s: %s", source_left, romanized_left)
			}
		}
		return fmt.Sprintf("%s: %s", source, romanized)
	}
	return source.String()
}
예제 #14
0
func frame(data string, typ int, json bool) string {
	utf8str := utf8.NewString(data)
	switch typ {
	case 0:
		return "0:0:,"

	case 2, 3:
		return fmt.Sprintf("%d:%d:%s,", typ, utf8str.RuneCount(), data)
	}

	if json {
		return fmt.Sprintf("%d:%d:j\n:%s,", typ, 3+utf8str.RuneCount(), data)
	}
	return fmt.Sprintf("%d:%d::%s,", typ, 1+utf8str.RuneCount(), data)
}
예제 #15
0
// Returns all available methods
func (this *JsonRPC) GetMethods() (m []Method) {
	m = make([]Method, this.object.NumMethod())
	j := 0
	for i := 0; i < this.object.NumMethod(); i++ {
		method := this.object.Type().Method(i)
		// Is this a public method?
		if unicode.IsUpper(utf8.NewString(method.Name).At(0)) {
			m[j].Name = method.Name
			// first parameter is the receiver object
			// which is provided by us, not the remote caller
			m[j].NumParams = this.object.Method(i).Type().NumIn() - 1
			j++
		}
	}
	return m[0:j]
}
예제 #16
0
파일: cmd-google.go 프로젝트: raylu/rbot
func roman(conn *irc.Conn, nick *irc.Nick, args, target string) {
	if args == "" {
		return
	}

	var sourcelang, targetlang string
	if utf8.NewString(args).IsASCII() {
		sourcelang = "en"
	} else {
		sourcelang = "ja"
	}
	targetlang, _ = conf.String(conn.Network, "roman")
	if targetlang == "" {
		targetlang = "ja"
	}
	say(conn, target, translate(sourcelang, targetlang, args))
}
예제 #17
0
func (lf *t_ledger_file) ParseTran(s string) *t_ledger_tran {
	lf.curT = new(t_ledger_tran)
	lf.curT.items = make([]*t_ledger_item, 0)
	lf.curT.date.Year = lf.curY
	lf.curT.date.Month = lf.curM
	S := utf8.NewString(s)
	var i int
	for i = 0; i < S.RuneCount(); i++ {
		if unicode.IsSpace(S.At(i)) { // конец даты
			DecodeDate(S.Slice(0, i), &lf.curT.date)
			break
		}
	}
	lf.curT.description = S.Slice(i, S.RuneCount())
	print("add tran: ", lf.curT.date.String(), lf.curT.description)
	lf.Tran = append(lf.Tran, lf.curT)
	return (lf.curT)
}
예제 #18
0
파일: parser.go 프로젝트: machinaut/oh
func Parse(r ReadStringer, p func(Cell)) {
	s := new(scanner)

	s.process = p

	s.input = r
	s.line = utf8.NewString("")

	s.state = ssStart
	s.indent = 0

	s.cursor = 0
	s.start = 0

	s.previous = 0
	s.token = 0

	yyParse(s)
}
예제 #19
0
func TestConsume(t *testing.T) {
	s := "package นี้"
	l := new(compiler.Lexer).Init(s)
	if l.GetInput() != "package นี้" {
		t.Fatalf("l.input failed")
	}

	str := utf8.NewString(s)
	for i := 0; i < str.RuneCount(); i++ {
		if l.GetOffset() != i+1 {
			t.Fatalf("l.readOffset failed != " + strconv.Itoa(i+1))
		}
		if l.GetCh() != str.At(i) {
			t.Fatalf("ch " + strconv.Itoa(l.GetCh()) + " != at " + strconv.Itoa(str.At(i)))
		}
		l.Consume()
	}
	if l.GetCh() != compiler.EOF {
		t.Fatalf("EOF not found")
	}
}
예제 #20
0
func DecodeDate(s string, dt *time.Time) int { // cлайс на входе
	S := utf8.NewString(s)
	var err os.Error

	if S.RuneCount() == 2 { // тока день
		dt.Day, err = strconv.Atoi(S.Slice(0, 2))
		if err == os.ERANGE {
			return (-1)
		}
		return (0)
	}
	if S.RuneCount() == 5 { // тока месяц день
		dt.Day, err = strconv.Atoi(S.Slice(3, 5))
		if err == os.ERANGE {
			return (-1)
		}
		dt.Month, err = strconv.Atoi(S.Slice(0, 2))
		if err == os.ERANGE {
			return (-1)
		}
		return (0)
	}
	if S.RuneCount() == 10 { // все
		dt.Year, err = strconv.Atoi64(S.Slice(0, 4))
		if err == os.ERANGE {
			return (-1)
		}
		dt.Month, err = strconv.Atoi(S.Slice(5, 7))
		if err == os.ERANGE {
			return (-1)
		}
		dt.Day, err = strconv.Atoi(S.Slice(8, 10))
		if err == os.ERANGE {
			return (-1)
		}
		return (0)
	}
	return (-10)
}
예제 #21
0
func ledgerParseFile(fileName string) *t_ledger_file {
	f, err := os.Open(fileName, os.O_RDONLY, 0)
	if err != nil {
		return nil
	}
	defer f.Close()
	lf := new(t_ledger_file)
	lf.Tran = make([]*t_ledger_tran, 0)
	lf.Accounts = make(map[string]*t_account, 0)
	var s string
	//var n int = 1
	fr := bufio.NewReader(f)
	s, err = fr.ReadString('\n')
	for s != "" {
		S := utf8.NewString(s)

		if S.At(0) == int(';') {
			println("// ", s)
		}
		if S.At(0) == int('Y') { // текущий год
			lf.curY, err = strconv.Atoi64(S.Slice(1, 5))
		}
		if S.At(0) == int('M') { // текущий месяц
			lf.curM, err = strconv.Atoi(S.Slice(1, 3))
		}

		if unicode.IsDigit(S.At(0)) { // tran begin
			lf.ParseTran(s)
		}
		if unicode.IsSpace(S.At(0)) { // tran item
			lf.ParseTranItem(s)
		}
		s, err = fr.ReadString('\n')
	}

	println(lf.Tran)
	return lf
}
예제 #22
0
//  Some rediculously dumb tests of Config methods, which are very simple.
func TestConfig(T *testing.T) {
	var config = NewConfig()

	// Test comment detection.
	config.CommentPrefix = "//"
	if !config.LooksLikeComment("// This should be a comment.\n") {
		T.Error("Did not correctly identify a // comment")
	}
	if config.LooksLikeComment("/ This, is not, a comment\n") {
		T.Error("Incorrectly labeled something a // comment")
	}

	// Test seperator detection.
	config.Sep = '\t'
	var str = "\t"
	var utf8str = utf8.NewString(str)
	if !config.IsSep(utf8str.At(0)) {
		T.Error("Did not correctly identify a \\t separator")
	}
	if config.IsSep(52) {
		T.Error("Incorrectly labelled 52 a \\t separator")
	}
}
예제 #23
0
파일: singlemover.go 프로젝트: newblue/gorf
func (this *SingleMover) CreateNewSource() (err os.Error) {

	liw := make(ListImportWalker)
	for n := range this.moveNodes {
		ast.Walk(liw, n)
	}
	finalImports := make(map[*ast.ImportSpec]bool)
	for obj, is := range liw {
		if _, ok := this.moveObjs[obj]; !ok {
			finalImports[is] = true
		}
	}

	newfile := &ast.File{
		Name: &ast.Ident{Name: this.pkg.Name},
	}

	if len(finalImports) != 0 {
		for is := range finalImports {
			gdl := &ast.GenDecl{
				Tok:   token.IMPORT,
				Specs: []ast.Spec{is},
			}
			newfile.Decls = append(newfile.Decls, gdl)
		}
	}

	var sortedNodes NodeSorter

	for mn := range this.moveNodes {
		sortedNodes = append(sortedNodes, mn)
	}
	sort.Sort(sortedNodes)

	for _, mn := range sortedNodes {
		switch m := mn.(type) {
		case ast.Decl:
			newfile.Decls = append(newfile.Decls, m)
		case *ast.TypeSpec:
			gdl := &ast.GenDecl{
				Tok:   token.TYPE,
				Specs: []ast.Spec{m},
			}
			newfile.Decls = append(newfile.Decls, gdl)
		}
	}

	npf := ExprParentFinder{
		ExprParents: make(map[ast.Expr]ast.Node),
	}
	for n := range this.moveNodes {
		ast.Walk(&npf, n)
	}

	var pkgfiles []*ast.File
	for _, pkgfile := range this.pkg.Files {
		pkgfiles = append(pkgfiles, pkgfile)
	}
	oldPkgNewName := GetUniqueIdent(pkgfiles, this.pkg.Name)

	needOldImport := false

	this.referenceBack = false

	for expr, parent := range npf.ExprParents {
		obj, _ := types.ExprType(expr, LocalImporter)
		if _, ok := this.moveObjs[obj]; ok {
			continue
		}

		if _, ok := this.allObjs[obj]; !ok {
			continue
		}

		if !unicode.IsUpper(utf8.NewString(obj.Name).At(0)) {
			position := AllSources.Position(expr.Pos())
			fmt.Printf("At %v ", position)
			printer.Fprint(os.Stdout, token.NewFileSet(), expr)
			fmt.Println()
			err = MakeErr("Can't move code that references unexported objects")
			return
		}

		needOldImport = true
		this.referenceBack = true

		getSel := func(idn *ast.Ident) *ast.SelectorExpr {
			return &ast.SelectorExpr{
				X: &ast.Ident{
					Name:    oldPkgNewName,
					NamePos: idn.NamePos,
				},
				Sel: idn,
			}
		}

		switch p := parent.(type) {
		case *ast.CallExpr:
			if idn, ok := expr.(*ast.Ident); ok {
				p.Fun = getSel(idn)
			} else {
				err = MakeErr("CallExpr w/ unexpected type %T\n", expr)
				return
			}
		case *ast.AssignStmt:
			for i, x := range p.Lhs {
				if x == expr {
					if idn, ok := x.(*ast.Ident); ok {
						p.Lhs[i] = getSel(idn)
					}
				}
			}
			for i, x := range p.Rhs {
				if x == expr {
					if idn, ok := x.(*ast.Ident); ok {
						p.Rhs[i] = getSel(idn)
					}
				}
			}
		default:
			err = MakeErr("Unexpected parent %T\n", parent)
			return
		}
	}

	if needOldImport {
		is := &ast.ImportSpec{
			Name: &ast.Ident{Name: oldPkgNewName},
			Path: &ast.BasicLit{Value: QuotePath(this.oldpath)},
		}
		gdl := &ast.GenDecl{
			Tok:   token.IMPORT,
			Specs: []ast.Spec{is},
		}
		newfile.Decls = append([]ast.Decl{gdl}, newfile.Decls...)
	}

	err = os.MkdirAll(this.newpath, 0755)
	if err != nil {
		return
	}
	newSourcePath := filepath.Join(this.newpath, this.pkg.Name+".go")

	containedComments := make(CommentCollector)
	for node := range this.moveNodes {
		ast.Walk(containedComments, node)
	}

	for _, file := range this.pkg.Files {
		for i := len(file.Comments) - 1; i >= 0; i-- {
			cg := file.Comments[i]
			add := func() {
				newfile.Comments = append([]*ast.CommentGroup{cg}, newfile.Comments...)
				file.Comments[i] = file.Comments[len(file.Comments)-1]
				file.Comments = file.Comments[:len(file.Comments)-1]
			}
			if containedComments[cg] {
				add()
			} else {
				for node := range this.moveNodes {
					if node.Pos() <= cg.Pos() && node.End() >= cg.End() {
						add()
						break
					}
				}
			}
		}

	}
	err = NewSource(newSourcePath, newfile)
	if err != nil {
		return
	}

	return
}
예제 #24
0
파일: oppai2.go 프로젝트: kimikato/go_oppai
func encode_utf8(str string) string {
	return utf8.NewString(str).String()
}
예제 #25
0
파일: poker.go 프로젝트: hjfreyer/misc
	"log"
	"os"
	"runtime/pprof"
)

type Card string

func NewCard(rank, suit int) Card {
	return Card(string([]byte{byte(rank), byte(suit)}))
}

const (
	CardNames = "XX23456789TJQKA"
)

var Suits = utf8.NewString("♥♦♠♣")

func (c Card) String() string {

	return fmt.Sprintf("%c%c", CardNames[c.Rank()], Suits.At(c.Suit()))
}

type CardSort []Card

func (c CardSort) Len() int           { return len(c) }
func (c CardSort) Less(i, j int) bool { return c[i] < c[j] }
func (c CardSort) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }

type CardPair string

func NewPair(a, b Card) CardPair {
예제 #26
0
파일: scheme.go 프로젝트: ceving/goscheme
func NewImmutableString(str string) *ImmutableString {
	return (*ImmutableString)(utf8.NewString(str))
}
예제 #27
0
func (dec *sioDecoder) Decode() (messages []Message, err os.Error) {
	messages = make([]Message, 0, 1)
	var c int

L:
	for {
		if dec.state == sioDecodeStateBegin {
			dec.msg = &sioMessage{}
			dec.state = sioDecodeStateHeaderBegin
			dec.buf.Reset()
		}

		c, _, err = dec.src.ReadRune()
		if err != nil {
			break
		}

		switch dec.state {
		case sioDecodeStateHeaderBegin:
			dec.buf.WriteRune(c)
			if dec.buf.Len() == len(sioFrameDelim) {
				if !bytes.Equal(dec.buf.Bytes(), sioFrameDelim) {
					dec.Reset()
					return nil, os.NewError("Malformed header")
				}

				dec.state = sioDecodeStateLength
				dec.buf.Reset()
			}
			continue

		case sioDecodeStateLength:
			if c >= '0' && c <= '9' {
				dec.buf.WriteRune(c)
				continue
			}

			if dec.length, err = strconv.Atoi(dec.buf.String()); err != nil {
				dec.Reset()
				return nil, err
			}

			dec.buf.Reset()
			dec.state = sioDecodeStateHeaderEnd
			fallthrough

		case sioDecodeStateHeaderEnd:
			dec.buf.WriteRune(c)
			if dec.buf.Len() < len(sioFrameDelim) {
				continue
			}

			if !bytes.Equal(dec.buf.Bytes(), sioFrameDelim) {
				dec.Reset()
				return nil, os.NewError("Malformed header")
			}

			dec.state = sioDecodeStateData
			dec.buf.Reset()
			if dec.length > 0 {
				continue
			}
			fallthrough

		case sioDecodeStateData:
			if dec.length > 0 {
				dec.buf.WriteRune(c)
				dec.length--

				utf8str := utf8.NewString(dec.src.String())

				if utf8str.RuneCount() >= dec.length {
					str := utf8str.Slice(0, dec.length)
					dec.buf.WriteString(str)
					dec.src.Next(len(str))
					dec.length = 0
				} else {
					break L
				}
			}

			data := dec.buf.Bytes()
			dec.msg.typ = sioMessageTypeMessage

			if bytes.HasPrefix(data, sioFrameDelimJSON) {
				dec.msg.annotations = make(map[string]string)
				dec.msg.annotations[SIOAnnotationJSON] = ""
				data = data[len(sioFrameDelimJSON):]
			} else if bytes.HasPrefix(data, sioFrameDelimHeartbeat) {
				dec.msg.typ = sioMessageTypeHeartbeat
				data = data[len(sioFrameDelimHeartbeat):]
			}
			dec.msg.data = make([]byte, len(data))
			copy(dec.msg.data, data)

			messages = append(messages, dec.msg)

			dec.state = sioDecodeStateBegin
			dec.buf.Reset()
			continue
		}

		dec.buf.WriteRune(c)
	}

	if err == os.EOF {
		err = nil
	}

	return
}
예제 #28
0
func (dec *sioStreamingDecoder) Decode() (messages []Message, err os.Error) {
	messages = make([]Message, 0, 1)
	var c int
	var typ uint

L:
	for {
		c, _, err = dec.src.ReadRune()
		if err != nil {
			break
		}

		if dec.state == sioStreamingDecodeStateBegin {
			dec.msg = &sioMessage{}
			dec.state = sioStreamingDecodeStateType
			dec.buf.Reset()
		}

		switch dec.state {
		case sioStreamingDecodeStateType:
			if c == ':' {
				if typ, err = strconv.Atoui(dec.buf.String()); err != nil {
					dec.Reset()
					return nil, err
				}
				dec.msg.typ = uint8(typ)
				dec.buf.Reset()
				dec.state = sioStreamingDecodeStateLength
				continue
			}

		case sioStreamingDecodeStateLength:
			if c == ':' {
				if dec.length, err = strconv.Atoi(dec.buf.String()); err != nil {
					dec.Reset()
					return nil, err
				}
				dec.buf.Reset()

				switch dec.msg.typ {
				case sioMessageTypeMessage:
					dec.state = sioStreamingDecodeStateAnnotationKey

				case sioMessageTypeDisconnect:
					dec.state = sioStreamingDecodeStateTrailer

				default:
					dec.state = sioStreamingDecodeStateData
				}

				continue
			}

		case sioStreamingDecodeStateAnnotationKey:
			dec.length--

			switch c {
			case ':':
				if dec.buf.Len() == 0 {
					dec.state = sioStreamingDecodeStateData
				} else {
					dec.key = dec.buf.String()
					dec.buf.Reset()
					dec.state = sioStreamingDecodeStateAnnotationValue
				}

				continue

			case '\n':
				if dec.buf.Len() == 0 {
					dec.Reset()
					return nil, os.NewError("expecting key, but got...")
				}
				dec.key = dec.buf.String()
				if dec.msg.annotations == nil {
					dec.msg.annotations = make(map[string]string)
				}

				dec.msg.annotations[dec.key] = ""
				dec.buf.Reset()

				continue
			}

		case sioStreamingDecodeStateAnnotationValue:
			dec.length--

			if c == '\n' || c == ':' {
				dec.value = dec.buf.String()
				if dec.msg.annotations == nil {
					dec.msg.annotations = make(map[string]string)
				}

				dec.msg.annotations[dec.key] = dec.value
				dec.buf.Reset()

				if c == '\n' {
					dec.state = sioStreamingDecodeStateAnnotationKey
				} else {
					dec.state = sioStreamingDecodeStateData
				}
				continue
			}

		case sioStreamingDecodeStateData:
			if dec.length > 0 {
				dec.buf.WriteRune(c)
				dec.length--

				utf8str := utf8.NewString(dec.src.String())
				if utf8str.RuneCount() >= dec.length {
					str := utf8str.Slice(0, dec.length)
					dec.buf.WriteString(str)
					dec.src.Next(len(str))
					dec.length = 0
					continue
				} else {
					break L
				}
			}

			data := dec.buf.Bytes()
			dec.msg.data = make([]byte, len(data))
			copy(dec.msg.data, data)

			dec.buf.Reset()
			dec.state = sioStreamingDecodeStateTrailer
			fallthrough

		case sioStreamingDecodeStateTrailer:
			if c == ',' {
				messages = append(messages, dec.msg)
				dec.state = sioStreamingDecodeStateBegin
				continue
			} else {
				dec.Reset()
				return nil, os.NewError("Expecting trailer but got... " + string(c))
			}
		}

		dec.buf.WriteRune(c)
	}

	if err == os.EOF {
		err = nil
	}

	return
}
예제 #29
0
// F**k yeah, UTF8 compatible!
func isPublicMethod(method reflect.Method) bool {
	return unicode.IsUpper(utf8.NewString(method.Name).At(0))

}