tools/binary_size/libsupersize/file_format.py
def _LoadSizeInfoFromFile(file_obj, size_path):
  """Loads a size_info from the given file.

  See _SaveSizeInfoToFile() for details on the .size file format.

  Args:
    file_obj: File to read, should be a GzipFile
  """
  # Split lines on '\n', since '\r' can appear in some lines!
  lines = io.TextIOWrapper(file_obj, newline='\n')
  header_line = _ReadLine(lines).encode('ascii')
  assert header_line == _COMMON_HEADER[:-1], 'was ' + str(header_line)
  header_line = _ReadLine(lines).encode('ascii')
  if header_line == _SIZE_HEADER_SINGLE_CONTAINER[:-1]:
    has_multi_containers = False
  elif header_line == _SIZE_HEADER_MULTI_CONTAINER[:-1]:
    has_multi_containers = True
  else:
    raise ValueError('Version mismatch. Need to write some upgrade code.')

  # JSON header fields
  json_len = int(_ReadLine(lines))
  json_str = lines.read(json_len)

  fields = json.loads(json_str)
  assert ('containers' in fields) == has_multi_containers
  assert ('build_config' in fields) == has_multi_containers
  assert ('containers' in fields) == has_multi_containers
  assert ('metadata' not in fields) == has_multi_containers
  assert ('section_sizes' not in fields) == has_multi_containers

  containers = []
  if has_multi_containers:  # New format.
    build_config = fields['build_config']
    for cfield in fields['containers']:
      c = models.Container(name=cfield['name'],
                           metadata=cfield['metadata'],
                           section_sizes=cfield['section_sizes'])
      containers.append(c)
  else:  # Old format.
    build_config = {}
    metadata = fields.get('metadata')
    if metadata:
      for key in models.BUILD_CONFIG_KEYS:
        if key in metadata:
          build_config[key] = metadata[key]
          del metadata[key]
    section_sizes = fields['section_sizes']
    containers.append(
        models.Container(name='',
                         metadata=metadata,
                         section_sizes=section_sizes))
  models.BaseContainer.AssignShortNames(containers)

  has_components = fields.get('has_components', False)
  has_padding = fields.get('has_padding', False)

  # Eat empty line.
  _ReadLine(lines)

  # Path list.
  num_path_tuples = int(_ReadLine(lines))  # Number of paths in list.
  # Read the path list values and store for later.
  path_tuples = [
      _ReadValuesFromLine(lines, split='\t') for _ in range(num_path_tuples)
  ]

  if num_path_tuples == 0:
    logging.warning('File contains no symbols: %s', size_path)
    return models.SizeInfo(build_config, containers, [], size_path=size_path)

  # Component list.
  if has_components:
    num_components = int(_ReadLine(lines))  # Number of components in list.
    components = [_ReadLine(lines) for _ in range(num_components)]

  # Symbol counts by "segments", defined as (container, section) tuples.
  segment_names = _ReadValuesFromLine(lines, split='\t')
  symbol_counts = [int(c) for c in _ReadValuesFromLine(lines, split='\t')]

  # Addresses, sizes, paddings, path indices, component indices.
  def read_numeric(delta=False):
    """Read numeric values, where each line corresponds to a symbol group.

    The values in each line are space separated.
    If |delta| is True, the numbers are read as a value to add to the sum of the
    prior values in the line, or as the amount to change by.
    """
    ret = []
    delta_multiplier = int(delta)
    for _ in symbol_counts:
      value = 0
      fields = []
      for f in _ReadValuesFromLine(lines, split=' '):
        value = value * delta_multiplier + int(f)
        fields.append(value)
      ret.append(fields)
    return ret

  addresses = read_numeric(delta=True)
  sizes = read_numeric(delta=False)
  if has_padding:
    paddings = read_numeric(delta=False)
  else:
    paddings = [None] * len(segment_names)
  path_indices = read_numeric(delta=True)
  if has_components:
    component_indices = read_numeric(delta=True)
  else:
    component_indices = [None] * len(segment_names)

  raw_symbols = [None] * sum(symbol_counts)
  symbol_idx = 0
  for (cur_segment_name, cur_symbol_count, cur_addresses, cur_sizes,
       cur_paddings, cur_path_indices,
       cur_component_indices) in zip(segment_names, symbol_counts, addresses,
                                     sizes, paddings, path_indices,
                                     component_indices):
    if has_multi_containers:
      # Extract '<cur_container_idx_str>cur_section_name'.
      assert cur_segment_name.startswith('<')
      cur_container_idx_str, cur_section_name = (cur_segment_name[1:].split(
          '>', 1))
      cur_container = containers[int(cur_container_idx_str)]
    else:
      cur_section_name = cur_segment_name
      cur_container = containers[0]
    alias_counter = 0
    for i in range(cur_symbol_count):
      parts = _ReadValuesFromLine(lines, split='\t')
      full_name = parts[0]
      flags_part = None
      aliases_part = None

      # aliases_part or flags_part may have been omitted.
      if len(parts) == 3:
        # full_name  aliases_part  flags_part
        aliases_part = parts[1]
        flags_part = parts[2]
      elif len(parts) == 2:
        if parts[1][0] == '0':
          # full_name  aliases_part
          aliases_part = parts[1]
        else:
          # full_name  flags_part
          flags_part = parts[1]

      # Use a bit less RAM by using the same instance for this common string.
      if full_name == models.STRING_LITERAL_NAME:
        full_name = models.STRING_LITERAL_NAME
      flags = int(flags_part, 16) if flags_part else 0
      num_aliases = int(aliases_part, 16) if aliases_part else 0

      # Skip the constructor to avoid default value checks.
      new_sym = models.Symbol.__new__(models.Symbol)
      new_sym.container = cur_container
      new_sym.section_name = cur_section_name
      new_sym.full_name = full_name
      new_sym.address = cur_addresses[i]
      new_sym.size = cur_sizes[i]
      paths = path_tuples[cur_path_indices[i]]
      new_sym.object_path, new_sym.source_path = paths
      component = components[cur_component_indices[i]] if has_components else ''
      new_sym.component = component
      new_sym.flags = flags
      # Derived.
      if cur_paddings:
        new_sym.padding = cur_paddings[i]
        if not new_sym.IsOverhead():
          new_sym.size += new_sym.padding
      else:
        new_sym.padding = 0  # Computed below.
      new_sym.template_name = ''
      new_sym.name = ''

      if num_aliases:
        assert alias_counter == 0
        new_sym.aliases = [new_sym]
        alias_counter = num_aliases - 1
      elif alias_counter > 0:
        new_sym.aliases = raw_symbols[symbol_idx - 1].aliases
        new_sym.aliases.append(new_sym)
        alias_counter -= 1
      else:
        new_sym.aliases = None

      raw_symbols[symbol_idx] = new_sym
      symbol_idx += 1

  if not has_padding:
    CalculatePadding(raw_symbols)

  return models.SizeInfo(build_config,
                         containers,
                         raw_symbols,
                         size_path=size_path)
Loads a size_info from the given file.

  See _SaveSizeInfoToFile() for details on the .size file format.

  Args:
    file_obj: File to read, should be a GzipFile
  
Loads a size_info from the given file.
See _SaveSizeInfoToFile() for details on the .size file format.
Loads a size_info from the given file . See _SaveSizeInfoToFile () for details on the . size file format .
def _LoadSizeInfoFromFile(file_obj, size_path):
  lines = io.TextIOWrapper(file_obj, newline='\n')
  header_line = _ReadLine(lines).encode('ascii')
  assert header_line == _COMMON_HEADER[:-1], 'was ' + str(header_line)
  header_line = _ReadLine(lines).encode('ascii')
  if header_line == _SIZE_HEADER_SINGLE_CONTAINER[:-1]:
    has_multi_containers = False
  elif header_line == _SIZE_HEADER_MULTI_CONTAINER[:-1]:
    has_multi_containers = True
  else:
    raise ValueError('Version mismatch. Need to write some upgrade code.')
  json_len = int(_ReadLine(lines))
  json_str = lines.read(json_len)
  fields = json.loads(json_str)
  assert ('containers' in fields) == has_multi_containers
  assert ('build_config' in fields) == has_multi_containers
  assert ('containers' in fields) == has_multi_containers
  assert ('metadata' not in fields) == has_multi_containers
  assert ('section_sizes' not in fields) == has_multi_containers
  containers = []
  if has_multi_containers:  
    build_config = fields['build_config']
    for cfield in fields['containers']:
      c = models.Container(name=cfield['name'],
                           metadata=cfield['metadata'],
                           section_sizes=cfield['section_sizes'])
      containers.append(c)
  else:  
    build_config = {}
    metadata = fields.get('metadata')
    if metadata:
      for key in models.BUILD_CONFIG_KEYS:
        if key in metadata:
          build_config[key] = metadata[key]
          del metadata[key]
    section_sizes = fields['section_sizes']
    containers.append(
        models.Container(name='',
                         metadata=metadata,
                         section_sizes=section_sizes))
  models.BaseContainer.AssignShortNames(containers)
  has_components = fields.get('has_components', False)
  has_padding = fields.get('has_padding', False)
  _ReadLine(lines)
  num_path_tuples = int(_ReadLine(lines))  
  path_tuples = [
      _ReadValuesFromLine(lines, split='\t') for _ in range(num_path_tuples)
  ]
  if num_path_tuples == 0:
    logging.warning('File contains no symbols: %s', size_path)
    return models.SizeInfo(build_config, containers, [], size_path=size_path)
  if has_components:
    num_components = int(_ReadLine(lines))  
    components = [_ReadLine(lines) for _ in range(num_components)]
  segment_names = _ReadValuesFromLine(lines, split='\t')
  symbol_counts = [int(c) for c in _ReadValuesFromLine(lines, split='\t')]
  def read_numeric(delta=False):
    ret = []
    delta_multiplier = int(delta)
    for _ in symbol_counts:
      value = 0
      fields = []
      for f in _ReadValuesFromLine(lines, split=' '):
        value = value * delta_multiplier + int(f)
        fields.append(value)
      ret.append(fields)
    return ret
  addresses = read_numeric(delta=True)
  sizes = read_numeric(delta=False)
  if has_padding:
    paddings = read_numeric(delta=False)
  else:
    paddings = [None] * len(segment_names)
  path_indices = read_numeric(delta=True)
  if has_components:
    component_indices = read_numeric(delta=True)
  else:
    component_indices = [None] * len(segment_names)
  raw_symbols = [None] * sum(symbol_counts)
  symbol_idx = 0
  for (cur_segment_name, cur_symbol_count, cur_addresses, cur_sizes,
       cur_paddings, cur_path_indices,
       cur_component_indices) in zip(segment_names, symbol_counts, addresses,
                                     sizes, paddings, path_indices,
                                     component_indices):
    if has_multi_containers:
      assert cur_segment_name.startswith('<')
      cur_container_idx_str, cur_section_name = (cur_segment_name[1:].split(
          '>', 1))
      cur_container = containers[int(cur_container_idx_str)]
    else:
      cur_section_name = cur_segment_name
      cur_container = containers[0]
    alias_counter = 0
    for i in range(cur_symbol_count):
      parts = _ReadValuesFromLine(lines, split='\t')
      full_name = parts[0]
      flags_part = None
      aliases_part = None
      if len(parts) == 3:
        aliases_part = parts[1]
        flags_part = parts[2]
      elif len(parts) == 2:
        if parts[1][0] == '0':
          aliases_part = parts[1]
        else:
          flags_part = parts[1]
      if full_name == models.STRING_LITERAL_NAME:
        full_name = models.STRING_LITERAL_NAME
      flags = int(flags_part, 16) if flags_part else 0
      num_aliases = int(aliases_part, 16) if aliases_part else 0
      new_sym = models.Symbol.__new__(models.Symbol)
      new_sym.container = cur_container
      new_sym.section_name = cur_section_name
      new_sym.full_name = full_name
      new_sym.address = cur_addresses[i]
      new_sym.size = cur_sizes[i]
      paths = path_tuples[cur_path_indices[i]]
      new_sym.object_path, new_sym.source_path = paths
      component = components[cur_component_indices[i]] if has_components else ''
      new_sym.component = component
      new_sym.flags = flags
      if cur_paddings:
        new_sym.padding = cur_paddings[i]
        if not new_sym.IsOverhead():
          new_sym.size += new_sym.padding
      else:
        new_sym.padding = 0  
      new_sym.template_name = ''
      new_sym.name = ''
      if num_aliases:
        assert alias_counter == 0
        new_sym.aliases = [new_sym]
        alias_counter = num_aliases - 1
      elif alias_counter > 0:
        new_sym.aliases = raw_symbols[symbol_idx - 1].aliases
        new_sym.aliases.append(new_sym)
        alias_counter -= 1
      else:
        new_sym.aliases = None
      raw_symbols[symbol_idx] = new_sym
      symbol_idx += 1
  if not has_padding:
    CalculatePadding(raw_symbols)
  return models.SizeInfo(build_config,
                         containers,
                         raw_symbols,
                         size_path=size_path)
def _LoadSizeInfoFromFile ( file_obj , size_path ) : lines = io . TextIOWrapper ( file_obj , newline = '\n' ) header_line = _ReadLine ( lines ) . encode ( 'ascii' ) assert header_line == _COMMON_HEADER [ : - 1 ] , 'was ' + str ( header_line ) header_line = _ReadLine ( lines ) . encode ( 'ascii' ) if header_line == _SIZE_HEADER_SINGLE_CONTAINER [ : - 1 ] : has_multi_containers = False elif header_line == _SIZE_HEADER_MULTI_CONTAINER [ : - 1 ] : has_multi_containers = True else : raise ValueError ( 'Version mismatch. Need to write some upgrade code.' ) json_len = int ( _ReadLine ( lines ) ) json_str = lines . read ( json_len ) fields = json . loads ( json_str ) assert ( 'containers' in fields ) == has_multi_containers assert ( 'build_config' in fields ) == has_multi_containers assert ( 'containers' in fields ) == has_multi_containers assert ( 'metadata' not in fields ) == has_multi_containers assert ( 'section_sizes' not in fields ) == has_multi_containers containers = [ ] if has_multi_containers : build_config = fields [ 'build_config' ] for cfield in fields [ 'containers' ] : c = models . Container ( name = cfield [ 'name' ] , metadata = cfield [ 'metadata' ] , section_sizes = cfield [ 'section_sizes' ] ) containers . append ( c ) else : build_config = { } metadata = fields . get ( 'metadata' ) if metadata : for key in models . BUILD_CONFIG_KEYS : if key in metadata : build_config [ key ] = metadata [ key ] del metadata [ key ] section_sizes = fields [ 'section_sizes' ] containers . append ( models . Container ( name = '' , metadata = metadata , section_sizes = section_sizes ) ) models . BaseContainer . AssignShortNames ( containers ) has_components = fields . get ( 'has_components' , False ) has_padding = fields . get ( 'has_padding' , False ) _ReadLine ( lines ) num_path_tuples = int ( _ReadLine ( lines ) ) path_tuples = [ _ReadValuesFromLine ( lines , split = '\t' ) for _ in range ( num_path_tuples ) ] if num_path_tuples == 0 : logging . warning ( 'File contains no symbols: %s' , size_path ) return models . SizeInfo ( build_config , containers , [ ] , size_path = size_path ) if has_components : num_components = int ( _ReadLine ( lines ) ) components = [ _ReadLine ( lines ) for _ in range ( num_components ) ] segment_names = _ReadValuesFromLine ( lines , split = '\t' ) symbol_counts = [ int ( c ) for c in _ReadValuesFromLine ( lines , split = '\t' ) ] def read_numeric ( delta = False ) : """Read numeric values, where each line corresponds to a symbol group.

    The values in each line are space separated.
    If |delta| is True, the numbers are read as a value to add to the sum of the
    prior values in the line, or as the amount to change by.
    """ ret = [ ] delta_multiplier = int ( delta ) for _ in symbol_counts : value = 0 fields = [ ] for f in _ReadValuesFromLine ( lines , split = ' ' ) : value = value * delta_multiplier + int ( f ) fields . append ( value ) ret . append ( fields ) return ret addresses = read_numeric ( delta = True ) sizes = read_numeric ( delta = False ) if has_padding : paddings = read_numeric ( delta = False ) else : paddings = [ None ] * len ( segment_names ) path_indices = read_numeric ( delta = True ) if has_components : component_indices = read_numeric ( delta = True ) else : component_indices = [ None ] * len ( segment_names ) raw_symbols = [ None ] * sum ( symbol_counts ) symbol_idx = 0 for ( cur_segment_name , cur_symbol_count , cur_addresses , cur_sizes , cur_paddings , cur_path_indices , cur_component_indices ) in zip ( segment_names , symbol_counts , addresses , sizes , paddings , path_indices , component_indices ) : if has_multi_containers : assert cur_segment_name . startswith ( '<' ) cur_container_idx_str , cur_section_name = ( cur_segment_name [ 1 : ] . split ( '>' , 1 ) ) cur_container = containers [ int ( cur_container_idx_str ) ] else : cur_section_name = cur_segment_name cur_container = containers [ 0 ] alias_counter = 0 for i in range ( cur_symbol_count ) : parts = _ReadValuesFromLine ( lines , split = '\t' ) full_name = parts [ 0 ] flags_part = None aliases_part = None if len ( parts ) == 3 : aliases_part = parts [ 1 ] flags_part = parts [ 2 ] elif len ( parts ) == 2 : if parts [ 1 ] [ 0 ] == '0' : aliases_part = parts [ 1 ] else : flags_part = parts [ 1 ] if full_name == models . STRING_LITERAL_NAME : full_name = models . STRING_LITERAL_NAME flags = int ( flags_part , 16 ) if flags_part else 0 num_aliases = int ( aliases_part , 16 ) if aliases_part else 0 new_sym = models . Symbol . __new__ ( models . Symbol ) new_sym . container = cur_container new_sym . section_name = cur_section_name new_sym . full_name = full_name new_sym . address = cur_addresses [ i ] new_sym . size = cur_sizes [ i ] paths = path_tuples [ cur_path_indices [ i ] ] new_sym . object_path , new_sym . source_path = paths component = components [ cur_component_indices [ i ] ] if has_components else '' new_sym . component = component new_sym . flags = flags if cur_paddings : new_sym . padding = cur_paddings [ i ] if not new_sym . IsOverhead ( ) : new_sym . size += new_sym . padding else : new_sym . padding = 0 new_sym . template_name = '' new_sym . name = '' if num_aliases : assert alias_counter == 0 new_sym . aliases = [ new_sym ] alias_counter = num_aliases - 1 elif alias_counter > 0 : new_sym . aliases = raw_symbols [ symbol_idx - 1 ] . aliases new_sym . aliases . append ( new_sym ) alias_counter -= 1 else : new_sym . aliases = None raw_symbols [ symbol_idx ] = new_sym symbol_idx += 1 if not has_padding : CalculatePadding ( raw_symbols ) return models . SizeInfo ( build_config , containers , raw_symbols , size_path = size_path )
Loads a size_info from the given file.
Loads a size_info from the given file .
"""Loads a size_info from the given file.

  See _SaveSizeInfoToFile() for details on the .size file format.

  Args:
    file_obj: File to read, should be a GzipFile
  """ # Split lines on '\n', since '\r' can appear in some lines! # JSON header fields # New format. # Old format. # Eat empty line. # Path list. # Number of paths in list. # Read the path list values and store for later. # Component list. # Number of components in list. # Symbol counts by "segments", defined as (container, section) tuples. # Addresses, sizes, paddings, path indices, component indices. """Read numeric values, where each line corresponds to a symbol group.

    The values in each line are space separated.
    If |delta| is True, the numbers are read as a value to add to the sum of the
    prior values in the line, or as the amount to change by.
    """ # Extract '<cur_container_idx_str>cur_section_name'. # aliases_part or flags_part may have been omitted. # full_name  aliases_part  flags_part # full_name  aliases_part # full_name  flags_part # Use a bit less RAM by using the same instance for this common string. # Skip the constructor to avoid default value checks. # Derived. # Computed below.
file_obj
File to read, should be a GzipFile
File to read should be a GzipFile
size_path