@Override public void detectLanguageAndEncoding(Book book) throws BookReadingException { InputStream stream = null; try { stream = book.File.getInputStream(); final PdbHeader header = new PdbHeader(stream); PdbUtil.skip(stream, header.Offsets[0] + 16 - header.length()); if (PdbUtil.readInt(stream) != 0x4D4F4249) /* "MOBI" */ { throw new BookReadingException("unsupportedFileFormat", book.File); } final int length = (int) PdbUtil.readInt(stream); PdbUtil.skip(stream, 4); final int encodingCode = (int) PdbUtil.readInt(stream); final Encoding encoding = supportedEncodings().getEncoding(encodingCode); final String encodingName = encoding != null ? encoding.Name : "utf-8"; book.setEncoding(encodingName); PdbUtil.skip(stream, 52); final int fullNameOffset = (int) PdbUtil.readInt(stream); final int fullNameLength = (int) PdbUtil.readInt(stream); final int languageCode = (int) PdbUtil.readInt(stream); book.setLanguage( ZLLanguageUtil.languageByIntCode(languageCode & 0xFF, (languageCode >> 8) & 0xFF)); } catch (IOException e) { throw new BookReadingException(e, book.File); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { } } } }
@Override public void readMetaInfo(Book book) throws BookReadingException { InputStream stream = null; try { stream = book.File.getInputStream(); final PdbHeader header = new PdbHeader(stream); PdbUtil.skip(stream, header.Offsets[0] + 16 - header.length()); if (PdbUtil.readInt(stream) != 0x4D4F4249) /* "MOBI" */ { throw new BookReadingException("unsupportedFileFormat", book.File); } final int length = (int) PdbUtil.readInt(stream); PdbUtil.skip(stream, 4); final int encodingCode = (int) PdbUtil.readInt(stream); final Encoding encoding = supportedEncodings().getEncoding(encodingCode); final String encodingName = encoding != null ? encoding.Name : "utf-8"; book.setEncoding(encodingName); PdbUtil.skip(stream, 52); final int fullNameOffset = (int) PdbUtil.readInt(stream); final int fullNameLength = (int) PdbUtil.readInt(stream); final int languageCode = (int) PdbUtil.readInt(stream); book.setLanguage( ZLLanguageUtil.languageByIntCode(languageCode & 0xFF, (languageCode >> 8) & 0xFF)); PdbUtil.skip(stream, 32); int offset = 132; if ((PdbUtil.readInt(stream) & 0x40) != 0) { PdbUtil.skip(stream, length - 116); offset = length + 20; if (PdbUtil.readInt(stream) == 0x45585448) /* "EXTH" */ { PdbUtil.skip(stream, 4); final int recordsNumber = (int) PdbUtil.readInt(stream); offset += 8; for (int i = 0; i < recordsNumber; ++i) { final int type = (int) PdbUtil.readInt(stream); final int size = (int) PdbUtil.readInt(stream); offset += size; if (size <= 8) { continue; } switch (type) { default: PdbUtil.skip(stream, size - 8); break; case 100: { final byte[] buffer = new byte[size - 8]; stream.read(buffer); String author = new String(buffer, encodingName); final int index = author.indexOf(','); if (index != -1) { author = author.substring(index + 1).trim() + ' ' + author.substring(0, index).trim(); } else { author = author.trim(); } book.addAuthor(author); break; } case 105: { final byte[] buffer = new byte[size - 8]; stream.read(buffer); book.addTag(new String(buffer, encodingName)); break; } } } } } PdbUtil.skip(stream, fullNameOffset - offset); final byte[] titleBuffer = new byte[fullNameLength]; stream.read(titleBuffer); book.setTitle(new String(titleBuffer, encodingName)); } catch (IOException e) { throw new BookReadingException(e, book.File); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { } } } }