Example #1
0
"""Contains routines for printing protocol messages in text format."""

import cStringIO
import re

from google.net.proto2.python.internal import type_checkers
from google.net.proto2.python.public import descriptor
from google.net.proto2.python.public import text_encoding

__all__ = [
    'MessageToString', 'PrintMessage', 'PrintField', 'PrintFieldValue', 'Merge'
]

_INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(),
                     type_checkers.Int32ValueChecker(),
                     type_checkers.Uint64ValueChecker(),
                     type_checkers.Int64ValueChecker())
_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?', re.IGNORECASE)
_FLOAT_NAN = re.compile('nanf?', re.IGNORECASE)
_FLOAT_TYPES = frozenset([
    descriptor.FieldDescriptor.CPPTYPE_FLOAT,
    descriptor.FieldDescriptor.CPPTYPE_DOUBLE
])


class Error(Exception):
    """Top-level module error for text_format."""


class ParseError(Error):
    """Thrown in case of ASCII parsing error."""
Example #2
0
class _Tokenizer(object):
    """Protocol buffer ASCII representation tokenizer.

  This class handles the lower level string parsing by splitting it into
  meaningful tokens.

  It was directly ported from the Java protocol buffer API.
  """

    _WHITESPACE = re.compile('(\\s|(#.*$))+', re.MULTILINE)
    _TOKEN = re.compile('[a-zA-Z_][0-9a-zA-Z_+-]*|'
                        '[0-9+-][0-9a-zA-Z_.+-]*|'
                        '\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|'
                        '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)')
    _IDENTIFIER = re.compile('\w+')
    _INTEGER_CHECKERS = [
        type_checkers.Uint32ValueChecker(),
        type_checkers.Int32ValueChecker(),
        type_checkers.Uint64ValueChecker(),
        type_checkers.Int64ValueChecker()
    ]
    _FLOAT_INFINITY = re.compile('-?inf(inity)?f?', re.IGNORECASE)
    _FLOAT_NAN = re.compile("nanf?", re.IGNORECASE)

    def __init__(self, text_message):
        self._text_message = text_message

        self._position = 0
        self._line = -1
        self._column = 0
        self._token_start = None
        self.token = ''
        self._lines = deque(text_message.split('\n'))
        self._current_line = ''
        self._previous_line = 0
        self._previous_column = 0
        self._SkipWhitespace()
        self.NextToken()

    def AtEnd(self):
        """Checks the end of the text was reached.

    Returns:
      True iff the end was reached.
    """
        return self.token == ''

    def _PopLine(self):
        while len(self._current_line) <= self._column:
            if not self._lines:
                self._current_line = ''
                return
            self._line += 1
            self._column = 0
            self._current_line = self._lines.popleft()

    def _SkipWhitespace(self):
        while True:
            self._PopLine()
            match = self._WHITESPACE.match(self._current_line, self._column)
            if not match:
                break
            length = len(match.group(0))
            self._column += length

    def TryConsume(self, token):
        """Tries to consume a given piece of text.

    Args:
      token: Text to consume.

    Returns:
      True iff the text was consumed.
    """
        if self.token == token:
            self.NextToken()
            return True
        return False

    def Consume(self, token):
        """Consumes a piece of text.

    Args:
      token: Text to consume.

    Raises:
      ParseError: If the text couldn't be consumed.
    """
        if not self.TryConsume(token):
            raise self._ParseError('Expected "%s".' % token)

    def LookingAtInteger(self):
        """Checks if the current token is an integer.

    Returns:
      True iff the current token is an integer.
    """
        if not self.token:
            return False
        c = self.token[0]
        return (c >= '0' and c <= '9') or c == '-' or c == '+'

    def ConsumeIdentifier(self):
        """Consumes protocol message field identifier.

    Returns:
      Identifier string.

    Raises:
      ParseError: If an identifier couldn't be consumed.
    """
        result = self.token
        if not self._IDENTIFIER.match(result):
            raise self._ParseError('Expected identifier.')
        self.NextToken()
        return result

    def ConsumeInt32(self):
        """Consumes a signed 32bit integer number.

    Returns:
      The integer parsed.

    Raises:
      ParseError: If a signed 32bit integer couldn't be consumed.
    """
        try:
            result = self._ParseInteger(self.token,
                                        is_signed=True,
                                        is_long=False)
        except ValueError, e:
            raise self._IntegerParseError(e)
        self.NextToken()
        return result