Blame src/lib/MSPUBDocument.cpp

rpm-build 9243a4
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
rpm-build 9243a4
/*
rpm-build 9243a4
 * This file is part of the libmspub project.
rpm-build 9243a4
 *
rpm-build 9243a4
 * This Source Code Form is subject to the terms of the Mozilla Public
rpm-build 9243a4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
rpm-build 9243a4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
rpm-build 9243a4
 */
rpm-build 9243a4
rpm-build 9243a4
#include <libmspub/libmspub.h>
rpm-build 9243a4
rpm-build 9243a4
#include <memory>
rpm-build 9243a4
rpm-build 9243a4
#include "MSPUBCollector.h"
rpm-build 9243a4
#include "MSPUBParser.h"
rpm-build 9243a4
#include "MSPUBParser2k.h"
rpm-build 9243a4
#include "MSPUBParser97.h"
rpm-build 9243a4
#include "libmspub_utils.h"
rpm-build 9243a4
rpm-build 9243a4
namespace libmspub
rpm-build 9243a4
{
rpm-build 9243a4
rpm-build 9243a4
namespace
rpm-build 9243a4
{
rpm-build 9243a4
rpm-build 9243a4
enum MSPUBVersion
rpm-build 9243a4
{
rpm-build 9243a4
  MSPUB_UNKNOWN_VERSION = 0,
rpm-build 9243a4
  MSPUB_2K,
rpm-build 9243a4
  MSPUB_2K2
rpm-build 9243a4
};
rpm-build 9243a4
rpm-build 9243a4
MSPUBVersion getVersion(librevenge::RVNGInputStream *input)
rpm-build 9243a4
{
rpm-build 9243a4
  try
rpm-build 9243a4
  {
rpm-build 9243a4
    if (!input->isStructured())
rpm-build 9243a4
      return MSPUB_UNKNOWN_VERSION;
rpm-build 9243a4
rpm-build 9243a4
    std::unique_ptr<librevenge::RVNGInputStream> contentsStream(input->getSubStreamByName("Contents"));
rpm-build 9243a4
    if (!contentsStream)
rpm-build 9243a4
      return MSPUB_UNKNOWN_VERSION;
rpm-build 9243a4
rpm-build 9243a4
    if (0xe8 != readU8(contentsStream.get()) || 0xac != readU8(contentsStream.get()))
rpm-build 9243a4
      return MSPUB_UNKNOWN_VERSION;
rpm-build 9243a4
rpm-build 9243a4
    unsigned char magicVersionByte = readU8(contentsStream.get());
rpm-build 9243a4
rpm-build 9243a4
    if (0x00 != readU8(contentsStream.get()))
rpm-build 9243a4
      return MSPUB_UNKNOWN_VERSION;
rpm-build 9243a4
rpm-build 9243a4
    MSPUBVersion version = MSPUB_UNKNOWN_VERSION;
rpm-build 9243a4
    switch (magicVersionByte)
rpm-build 9243a4
    {
rpm-build 9243a4
    case 0x2C:
rpm-build 9243a4
      version = MSPUB_2K2;
rpm-build 9243a4
      break;
rpm-build 9243a4
    case 0x22:
rpm-build 9243a4
      version =  MSPUB_2K;
rpm-build 9243a4
      break;
rpm-build 9243a4
    default:
rpm-build 9243a4
      break;
rpm-build 9243a4
    }
rpm-build 9243a4
    return version;
rpm-build 9243a4
  }
rpm-build 9243a4
  catch (...)
rpm-build 9243a4
  {
rpm-build 9243a4
    return MSPUB_UNKNOWN_VERSION;
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
} // anonymous namespace
rpm-build 9243a4
rpm-build 9243a4
rpm-build 9243a4
rpm-build 9243a4
/**
rpm-build 9243a4
Analyzes the content of an input stream to see if it can be parsed
rpm-build 9243a4
\param input The input stream
rpm-build 9243a4
\return A value that indicates whether the content from the input
rpm-build 9243a4
stream is a Microsoft Publisher Document that libmspub is able to parse
rpm-build 9243a4
*/
rpm-build 9243a4
PUBAPI bool MSPUBDocument::isSupported(librevenge::RVNGInputStream *input)
rpm-build 9243a4
{
rpm-build 9243a4
  if (!input)
rpm-build 9243a4
    return false;
rpm-build 9243a4
rpm-build 9243a4
  try
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUBVersion version = getVersion(input);
rpm-build 9243a4
    if (version == MSPUB_UNKNOWN_VERSION)
rpm-build 9243a4
      return false;
rpm-build 9243a4
rpm-build 9243a4
    if (version == MSPUB_2K2)
rpm-build 9243a4
    {
rpm-build 9243a4
      std::unique_ptr<librevenge::RVNGInputStream> escherStream(input->getSubStreamByName("Escher/EscherStm"));
rpm-build 9243a4
      if (!escherStream)
rpm-build 9243a4
        return false;
rpm-build 9243a4
      std::unique_ptr<librevenge::RVNGInputStream> quillStream(input->getSubStreamByName("Quill/QuillSub/CONTENTS"));
rpm-build 9243a4
      if (!quillStream)
rpm-build 9243a4
        return false;
rpm-build 9243a4
    }
rpm-build 9243a4
    return true;
rpm-build 9243a4
  }
rpm-build 9243a4
  catch (...)
rpm-build 9243a4
  {
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
/**
rpm-build 9243a4
Parses the input stream content. It will make callbacks to the functions provided by a
rpm-build 9243a4
RVNGDrawingInterface class implementation when needed. This is often commonly called the
rpm-build 9243a4
'main parsing routine'.
rpm-build 9243a4
\param input The input stream
rpm-build 9243a4
\param painter A MSPUBPainterInterface implementation
rpm-build 9243a4
\return A value that indicates whether the parsing was successful
rpm-build 9243a4
*/
rpm-build 9243a4
PUBAPI bool MSPUBDocument::parse(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter)
rpm-build 9243a4
{
rpm-build 9243a4
  if (!input || !painter)
rpm-build 9243a4
    return false;
rpm-build 9243a4
rpm-build 9243a4
  try
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUBCollector collector(painter);
rpm-build 9243a4
    input->seek(0, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    std::unique_ptr<MSPUBParser> parser;
rpm-build 9243a4
    switch (getVersion(input))
rpm-build 9243a4
    {
rpm-build 9243a4
    case MSPUB_2K:
rpm-build 9243a4
    {
rpm-build 9243a4
      std::unique_ptr<librevenge::RVNGInputStream> quillStream(input->getSubStreamByName("Quill/QuillSub/CONTENTS"));
rpm-build 9243a4
      if (!quillStream)
rpm-build 9243a4
        parser.reset(new MSPUBParser97(input, &collector));
rpm-build 9243a4
      else
rpm-build 9243a4
        parser.reset(new MSPUBParser2k(input, &collector));
rpm-build 9243a4
      break;
rpm-build 9243a4
    }
rpm-build 9243a4
    case MSPUB_2K2:
rpm-build 9243a4
    {
rpm-build 9243a4
      parser.reset(new MSPUBParser(input, &collector));
rpm-build 9243a4
      break;
rpm-build 9243a4
    }
rpm-build 9243a4
    default:
rpm-build 9243a4
      return false;
rpm-build 9243a4
    }
rpm-build 9243a4
    if (parser)
rpm-build 9243a4
    {
rpm-build 9243a4
      return parser->parse();
rpm-build 9243a4
    }
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
  catch (...)
rpm-build 9243a4
  {
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */