Example #1
0
func lookupFunc(instruction byte, buf *bytes.Buffer) instruction {
	const high_2_bits = 0xc0
	var restore bool

	// Special case the 3 opcodes that have their argument encoded in the opcode itself.
	switch instruction & high_2_bits {
	case DW_CFA_advance_loc:
		instruction = DW_CFA_advance_loc
		restore = true

	case DW_CFA_offset:
		instruction = DW_CFA_offset
		restore = true

	case DW_CFA_restore:
		instruction = DW_CFA_restore
		restore = true
	}

	if restore {
		// Restore the last byte as it actually contains the argument for the opcode.
		err := buf.UnreadByte()
		if err != nil {
			panic("Could not unread byte")
		}
	}

	fn, ok := fnlookup[instruction]
	if !ok {
		panic(fmt.Sprintf("Encountered an unexpected DWARF CFA opcode: %#v", instruction))
	}

	return fn
}
Example #2
0
File: pdf.go Project: flowlo/quali
func parse(r io.Reader) (*Match, error) {
	cmd := exec.Command("pdftotext", "-q", "-enc", "UTF-8", "-eol", "unix", "-layout", "-", "-")
	cmd.Stdin = r
	stdout := new(bytes.Buffer)
	cmd.Stdout = stdout
	stderr := new(bytes.Buffer)
	cmd.Stderr = stderr
	err := cmd.Run()

	if err != nil {
		return nil, err
	}

	m := new(Match)
	m.Results = make(map[Division][]Result)

	for {
		if err := parsePage(stdout, m); err != nil {
			return nil, err
		}

		if _, err := stdout.ReadByte(); err == io.EOF {
			return m, nil
		} else {
			stdout.UnreadByte()
		}
	}
}
Example #3
0
func decodeNextFrom(buffer *bytes.Buffer) (Bencodable, error) {
	nextByte, err := buffer.ReadByte()
	if err != nil {
		return nil, err
	}
	buffer.UnreadByte()

	var result Bencodable

	switch nextByte {
	case 'i':
		result, err = decodeNextIntFrom(buffer)
	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
		result, err = decodeNextStringFrom(buffer)
	case 'l':
		result, err = decodeNextListFrom(buffer)
	case 'd':
		result, err = decodeNextDictFrom(buffer)
	default:
		err = errors.New(fmt.Sprintf(
			"Unexpected initial byte in bencoded data: %v",
			strconv.Quote(string(nextByte))))
	}

	if err != nil {
		return nil, err
	}

	return result, nil
}
Example #4
0
func decodeNextDictFrom(buffer *bytes.Buffer) (Dict, error) {
	initial, err := buffer.ReadByte()
	if initial != 'd' || err != nil {
		panic("How is this not a dictionary?")
	}

	result := make(Dict, 0)

AccumulateItems:
	for {
		nextByte, err := buffer.ReadByte()
		switch {
		case err != nil:
			return nil, err
		case nextByte == 'e':
			break AccumulateItems
		default:
			buffer.UnreadByte()

			key, err := decodeNextStringFrom(buffer)
			if err != nil {
				return nil, err
			}

			value, err := decodeNextFrom(buffer)
			if err != nil {
				return nil, err
			}

			result[key] = value
		}
	}

	return result, nil
}
Example #5
0
func decodeNextListFrom(buffer *bytes.Buffer) (List, error) {
	initial, err := buffer.ReadByte()
	if initial != 'l' || err != nil {
		panic("How is this not a list?")
	}

	result := make(List, 0)

AccumulateItems:
	for {
		nextByte, err := buffer.ReadByte()
		switch {
		case err != nil:
			return nil, err
		case nextByte == 'e':
			break AccumulateItems
		default:
			buffer.UnreadByte()
			value, err := decodeNextFrom(buffer)
			if err != nil {
				return nil, err
			}

			result = append(result, value)
		}
	}

	return result, nil
}
Example #6
0
func consume(r *bytes.Buffer, b byte) bool {
	got, err := r.ReadByte()
	if err != nil {
		return false
	}
	if got != b {
		r.UnreadByte()
		return false
	}

	return true
}
Example #7
0
File: lex.go Project: albrow/calc
func readNumber(buf *bytes.Buffer) (token.Token, error) {
	value := []byte{}
	for {
		b, err := buf.ReadByte()
		if err != nil {
			if err == io.EOF {
				return newNumberToken(string(value)), nil
			}
			return token.Token{}, err
		}
		switch b {
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			value = append(value, b)
		default:
			buf.UnreadByte()
			return newNumberToken(string(value)), nil
		}
	}
}
Example #8
0
File: pdf.go Project: flowlo/quali
func parsePage(r *bytes.Buffer, m *Match) error {
	ds, err := r.ReadString(byte(' '))
	if err != nil {
		return nil
	}
	ds = strings.ToLower(ds[0 : len(ds)-1])
	var d Division
	switch ds {
	case "classic":
		d = Classic
	case "standard":
		d = Standard
	case "production":
		d = Production
	case "open":
		d = Open
	case "revolver":
		d = Revolver
	default:
		_, err := r.ReadBytes(ff) // Skip page
		return err
	}

	// TODO(flowlo): Maybe match for those lines,
	// to make sure we're dealing with a nice file.
	r.ReadBytes(lf) // Skip rest of first line, usually "-- Overall Match Results"
	r.ReadBytes(lf) // Skip line, usually name of the Match
	r.ReadBytes(lf) // Skip line, usually print timestamp of the PDF
	r.ReadBytes(lf) // Skip empty line
	r.ReadBytes(lf) // Skip line, usually a descriptive headline
	r.ReadBytes(lf) // Skip empty line

	buf := new(bytes.Buffer)

	c := 1
	for {
		b, err := r.ReadByte()
		if err != nil {
			return err
		}
		r.UnreadByte()
		if b == byte('\n') {
			break
		}

		l, err := r.ReadBytes(byte('\n'))
		if err != nil {
			return err
		}

		buf.Reset()
		buf.Write(l)
		sc := bufio.NewScanner(buf)
		sc.Split(bufio.ScanWords)

		res := Result{}

		// Read rank.
		if !sc.Scan() {
			return ErrNoToken
		}

		i, err := strconv.Atoi(sc.Text())
		if err != nil {
			return err
		}
		if i != len(m.Results[d])+1 {
			return fmt.Errorf("expected rank %d but got %d", len(m.Results[d]), i)
		}

		// Read percentage.
		if !sc.Scan() {
			return ErrNoToken
		}

		dotted := strings.Replace(sc.Text(), ",", ".", 1)
		f, err := strconv.ParseFloat(dotted, 64)
		if err != nil {
			return err
		}
		res.Percent = f

		// Read points.
		if !sc.Scan() {
			return ErrNoToken
		}

		dotted = strings.Replace(sc.Text(), ",", ".", 1)
		f, err = strconv.ParseFloat(dotted, 64)
		if err != nil {
			return err
		}
		res.Points = f

		// Read MOS number.
		if !sc.Scan() {
			return ErrNoToken
		}

		i, err = strconv.Atoi(sc.Text())
		if err != nil {
			return err
		}
		res.MosNumber = i

		// Read name.
		sc.Split(scanThreeSpaces)
		if !sc.Scan() {
			return ErrNoToken
		}
		res.Name = sc.Text()

		sc.Split(bufio.ScanWords)
		if !sc.Scan() {
			return ErrNoToken
		}

		res.Flags = sc.Text()
		res.CountryCode = ""
		if len(res.Flags) > 2 {
			i := sort.SearchStrings(countryCodes[:], res.Flags)
			if i < len(countryCodes) && countryCodes[i] == res.Flags {
				res.CountryCode = res.Flags
				res.Flags = ""
				goto finish
			}
		}

		if !sc.Scan() {
			if res.CountryCode == "" {
				return ErrNoToken
			}
		} else {
			res.CountryCode = sc.Text()
		}

	finish:
		c++
		fmt.Printf("%+v\n", res)
		m.Results[d] = append(m.Results[d], res)
	}

	for {
		s, err := r.ReadString(lf) // Skip empty line
		if err != nil {
			return err
		}
		if len(s) == 0 {
			continue
		}
		if strings.Contains(s, "used") {
			_, err := r.ReadBytes(ff) // Skip footer
			return err
		}
	}

	return nil
}
Example #9
0
func decodeNextStringFrom(buffer *bytes.Buffer) (String, error) {
	firstByte, err := buffer.ReadByte()
	if err != nil {
		return "", err
	}

	if firstByte == '0' {
		// must be null string
		lastByte, err := buffer.ReadByte()
		switch {
		case err != nil:
			return "", err
		case lastByte != ':':
			return "", errors.New("Unexpected leading zero in non-{empty string}.")
		default:
			return "", nil
		}
	}

	buffer.UnreadByte()

	digits := []byte{}

AccumulatingDigits:
	for {
		nextByte, err := buffer.ReadByte()
		if err != nil {
			return "", err
		}
		switch nextByte {
		case ':':
			break AccumulatingDigits
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			digits = append(digits, nextByte)
		default:
			return "", errors.New(fmt.Sprintf(
				"Unexpected byte in integer value: %v",
				strconv.Quote(string(nextByte))))
		}
	}

	strLen, err := strconv.ParseInt(string(digits), 10, 64)

	if err != nil {
		return "", err
	}

	if strLen <= 0 {
		panic("strLen should not be able to be <= 0 here.")
	}

	contents := make([]byte, strLen)

	n, err := buffer.Read(contents)

	if err != nil {
		return "", err
	}
	if int64(n) != strLen {
		return "", errors.New("Declared string length greater than remaining input.")
	}

	return String(contents), nil
}
Example #10
0
func decodeNextIntFrom(buffer *bytes.Buffer) (Int, error) {
	initial, err := buffer.ReadByte()
	if initial != 'i' || err != nil {
		panic("How is this not an integer?")
	}

	firstByte, err := buffer.ReadByte()
	if err != nil {
		return -1, err
	}

	isNegative := false

InterpretingInitial:
	for {
		switch firstByte {
		case '-':
			if !isNegative {
				isNegative = true
				firstByte, err = buffer.ReadByte()
				if err != nil {
					return -1, err
				}
				continue InterpretingInitial
			} else {
				return -1, errors.New("Unexpected \"--\" in integer value.")
			}
		case '0':
			// Leading zero is only allowed for value "i0e".
			if isNegative {
				return -1, errors.New("Unexpected \"-0\" in integer value.")
			}
			remainingByte, err := buffer.ReadByte()
			if err != nil {
				return -1, err
			}
			if remainingByte != byte('e') {
				return -1, errors.New("Unexpected leading zero in integer value.")
			}
			return 0, nil
		default:
			buffer.UnreadByte()
			break InterpretingInitial
		}
	}

	digits := []byte{}

AccumulatingDigits:
	for {
		nextByte, err := buffer.ReadByte()
		if err != nil {
			return -1, err
		}
		switch nextByte {
		case 'e':
			break AccumulatingDigits
		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
			digits = append(digits, nextByte)
		default:
			return -1, errors.New(fmt.Sprintf(
				"Unexpected byte in integer value: %v", nextByte))
		}
	}

	digitValue, err := strconv.ParseInt(string(digits), 10, 64)

	if err != nil {
		return -1, err
	}

	if digitValue <= 0 {
		panic("digitValue should not be able to be <= 0 here.")
	}

	if !isNegative {
		return Int(digitValue), nil
	} else {
		return Int(-digitValue), nil
	}

}