Override this method to support alternative .mo formats.
(self, fp)
| 347 | return (version >> 16, version & 0xffff) |
| 348 | |
| 349 | def _parse(self, fp): |
| 350 | """Override this method to support alternative .mo formats.""" |
| 351 | # Delay struct import for speeding up gettext import when .mo files |
| 352 | # are not used. |
| 353 | from struct import unpack |
| 354 | filename = getattr(fp, 'name', '') |
| 355 | # Parse the .mo file header, which consists of 5 little endian 32 |
| 356 | # bit words. |
| 357 | self._catalog = catalog = {} |
| 358 | self.plural = lambda n: int(n != 1) # germanic plural by default |
| 359 | buf = fp.read() |
| 360 | buflen = len(buf) |
| 361 | # Are we big endian or little endian? |
| 362 | magic = unpack('<I', buf[:4])[0] |
| 363 | if magic == self.LE_MAGIC: |
| 364 | version, msgcount, masteridx, transidx = unpack('<4I', buf[4:20]) |
| 365 | ii = '<II' |
| 366 | elif magic == self.BE_MAGIC: |
| 367 | version, msgcount, masteridx, transidx = unpack('>4I', buf[4:20]) |
| 368 | ii = '>II' |
| 369 | else: |
| 370 | raise OSError(0, 'Bad magic number', filename) |
| 371 | |
| 372 | major_version, minor_version = self._get_versions(version) |
| 373 | |
| 374 | if major_version not in self.VERSIONS: |
| 375 | raise OSError(0, 'Bad version number ' + str(major_version), filename) |
| 376 | |
| 377 | # Now put all messages from the .mo file buffer into the catalog |
| 378 | # dictionary. |
| 379 | for i in range(0, msgcount): |
| 380 | mlen, moff = unpack(ii, buf[masteridx:masteridx+8]) |
| 381 | mend = moff + mlen |
| 382 | tlen, toff = unpack(ii, buf[transidx:transidx+8]) |
| 383 | tend = toff + tlen |
| 384 | if mend < buflen and tend < buflen: |
| 385 | msg = buf[moff:mend] |
| 386 | tmsg = buf[toff:tend] |
| 387 | else: |
| 388 | raise OSError(0, 'File is corrupt', filename) |
| 389 | # See if we're looking at GNU .mo conventions for metadata |
| 390 | if mlen == 0: |
| 391 | # Catalog description |
| 392 | lastk = None |
| 393 | for b_item in tmsg.split(b'\n'): |
| 394 | item = b_item.decode().strip() |
| 395 | if not item: |
| 396 | continue |
| 397 | # Skip over comment lines: |
| 398 | if item.startswith('#-#-#-#-#') and item.endswith('#-#-#-#-#'): |
| 399 | continue |
| 400 | k = v = None |
| 401 | if ':' in item: |
| 402 | k, v = item.split(':', 1) |
| 403 | k = k.strip().lower() |
| 404 | v = v.strip() |
| 405 | self._info[k] = v |
| 406 | lastk = k |
nothing calls this directly
no test coverage detected