Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagecpp
private func parsePublication(at url: URL) -> PubBox? {
    do {
      guard let (pubBox, parsingCallback) = try Publication.parse(at: url) else {
        return nil
      }
      let (publication, container) = pubBox
      // TODO: SIMPLY-2840
      // Parse .ncx document to update TOC and page list if publication doesn't contain TOC
      // -- the code below should be removed as described in SIMPLY-2840 --

      if publication.tableOfContents.isEmpty {
        publication.otherCollections.append(contentsOf: parseNCXDocument(in: container, links: publication.links))
      }
      // -- end of cleanup --

      items[url.lastPathComponent] = (container, parsingCallback)
      return (publication, container)
    } catch {
      log(.error, "Error parsing publication at '\(url.absoluteString)': \(error.localizedDescription)")
      return nil
    }
  }
}

  private func parsePublication(at url: URL) -> PubBox? {

    do {

      guard let (pubBox, parsingCallback) = try Publication.parse(at: url) else {

        return nil

      }

      let (publication, container) = pubBox

      // TODO: SIMPLY-2840

      // Parse .ncx document to update TOC and page list if publication doesn't contain TOC

      // -- the code below should be removed as described in SIMPLY-2840 --

      if publication.tableOfContents.isEmpty {

        publication.otherCollections.append(contentsOf: parseNCXDocument(in: container, links: publication.links))

      }

      // -- end of cleanup --

      items[url.lastPathComponent] = (container, parsingCallback)

      return (publication, container)

    } catch {

      log(.error, "Error parsing publication at '\(url.absoluteString)': \(error.localizedDescription)")

      return nil

    }

  }

}


And parseNCXDocument(from container: Container, to publication: inout Publication) function was added in an extension to LibraryService. 

The way Readium 2 creates Publication and Container objects may change in the future, the idea is to decrypt ncxDocumentData as shown below:

Original code:  private func


Code Block
languagecpp
private func parseNCXDocument(in container: Container, links: [Link]) -> [PublicationCollection]

...

 {
      // Get the link in the readingOrder pointing to the NCX document.

...


      guard let ncxLink = links.first(withType: .ncx),

...


          let ncxDocumentData = try? container.data(relativePath: ncxLink.href)

...

      {

          return []

      }

...

 else
      {
          return []
      }
      let ncx = NCXParser(data: ncxDocumentData, at: ncxLink.href)

...


      func makeCollection(_ type: NCXParser.NavType, role: String)

...

 -> PublicationCollection? {
          let links = ncx.links(for: type)

...


          guard !links.isEmpty else

...

              return nil

          }

...

 {
              return nil
          }
          return PublicationCollection(role: role, links: links)

...

      }

      return [

...


      }
      return [
          makeCollection(.tableOfContents, role: "toc"),

...


          makeCollection(.pageList, role: "pageList")

...


      ].compactMap { $0 }
  }


  }Modified code decrypts ncx data (in bold):  private func


Code Block
languagecpp
private func parseNCXDocument(in container: Container, links: [Link]) -> [PublicationCollection

...

] {

      // Get the link in the readingOrder pointing to the NCX document.

...


      guard let ncxLink = links.first(withType: .ncx),

...


          let ncxDocumentData = try? container.data(relativePath: ncxLink.href)

...

      {

          return []

      }

      // this part is added to decrypt ncx data

      var data = ncxDocumentData

      let license = AdobeDRMLicense(for: container)

...

 else
      {
          return []
      }
      // this part is added to decrypt ncx data
      var data = ncxDocumentData
      let license = AdobeDRMLicense(for: container)
      if let optionalDecipheredData = try? license.decipher(ncxDocumentData),

...

          let decipheredData = optionalDecipheredData {

          data = decipheredData

      }

      // NCXParser here parses data instead of ncxDocumentData

      let ncx = NCXParser(data: data, at: ncxLink.href)

      func makeCollection(_ type: NCXParser.NavType, role: String) -> PublicationCollection? {

...


          let decipheredData = optionalDecipheredData {
          data = decipheredData
      }
      // NCXParser here parses data instead of ncxDocumentData
      let ncx = NCXParser(data: data, at: ncxLink.href)
      func makeCollection(_ type: NCXParser.NavType, role: String) -> PublicationCollection? {
          let links = ncx.links(for: type)

...

          guard !links.isEmpty else {

              return nil

          }

...


          guard !links.isEmpty else {
              return nil
          }
          return PublicationCollection(role: role, links:

...

      }

      return [

...

 links)
      }
      return [
          makeCollection(.tableOfContents, role: "toc"),

...


          makeCollection(.pageList, role: "pageList")

...


      ].compactMap { $0 }

...


  }


  }

 

This workaround is temporary, the version of Readium 2 that supports multiple DRM services won’t need additional parsing of the navigation document, and this workaround should be removed.

...