MCPcopy Create free account
hub / github.com/claroty/access_parser / AccessTable

Class AccessTable

access_parser/access_parser.py:202–591  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

200
201
202class AccessTable(object):
203 def __init__(self, table, version, page_size, data_pages, table_defs, props=None):
204 self.version = version
205 self.props = props
206 self.page_size = page_size
207 self._data_pages = data_pages
208 self._table_defs = table_defs
209 self.table = table
210 self.parsed_table = defaultdict(list)
211 self.columns, self.primary_keys, self.table_header = self._get_table_columns()
212
213 def create_empty_table(self):
214 parsed_table = defaultdict(list)
215 columns, *_ = self._get_table_columns()
216 for i, column in columns.items():
217 parsed_table[column.col_name_str] = ""
218 return parsed_table
219
220 def parse(self):
221 """
222 This is the main table parsing function. We go through all of the data pages linked to the table, separate each
223 data page to rows(records) and parse each record.
224 :return defaultdict(list) with the parsed data -- table[column][row_index]
225 """
226 if not self.table.linked_pages:
227 return self.create_empty_table()
228 for data_chunk in self.table.linked_pages:
229 original_data = data_chunk
230 parsed_data = parse_data_page_header(original_data, version=self.version)
231
232 last_offset = None
233 for rec_offset in parsed_data.record_offsets:
234 # Deleted row - Just skip it
235 if rec_offset & 0x8000:
236 last_offset = rec_offset & 0xfff
237 continue
238 # Overflow page
239 if rec_offset & 0x4000:
240 # overflow ptr is 4 bits flags, 12 bits ptr
241 rec_ptr_offset = rec_offset & 0xfff
242 # update last pointer to pointer without flags
243 last_offset = rec_ptr_offset
244 # The ptr is the offset in the current data page. we get a 4 byte record_pointer from that
245 overflow_rec_ptr = original_data[rec_ptr_offset:rec_ptr_offset + 4]
246 overflow_rec_ptr = struct.unpack("<I", overflow_rec_ptr)[0]
247 record = self._get_overflow_record(overflow_rec_ptr)
248 if record:
249 self._parse_row(record)
250 continue
251 # First record is actually the last one - from offset until the end of the data
252 if not last_offset:
253 record = original_data[rec_offset:]
254 else:
255 record = original_data[rec_offset:last_offset]
256 last_offset = rec_offset
257 if record:
258 self._parse_row(record)
259 return self.parsed_table

Callers 2

_parse_catalogMethod · 0.85
get_tableMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected