예제 #1
0
/**
 * Sets the type of an ASTNode based on the given MathML <ci> element.
 * Errors will be logged in the stream's SBMLErrorLog object.
 */
static void
setTypeCI (ASTNode& node, const XMLToken& element, XMLInputStream& stream)
{
  if (element.getName() == "csymbol")
  {
    string url;
    element.getAttributes().readInto("definitionURL", url);

    if ( url == URL_DELAY ) node.setType(AST_FUNCTION_DELAY);
    else if ( url == URL_TIME  ) node.setType(AST_NAME_TIME);
    else if ( url == URL_AVOGADRO  ) node.setType(AST_NAME_AVOGADRO);
    else 
    {
      static_cast <SBMLErrorLog*>
	        (stream.getErrorLog())->logError(BadCsymbolDefinitionURLValue,
          stream.getSBMLNamespaces()->getLevel(), 
          stream.getSBMLNamespaces()->getVersion());
    }
  }
  else if (element.getName() == "ci")
  {
    node.setDefinitionURL(element.getAttributes());
  }

  const string name = trim( stream.next().getCharacters() );
  node.setName( name.c_str() );
}
예제 #2
0
bool
XMLTokenizer::containsChild(bool & valid, 
                            const std::string& qualifier, 
                            const std::string& container)
{
  valid = false;
  //unsigned int numQualifiers = 0;
  

  size_t size = mTokens.size();
  if (size < 2)
  {
    return false;
  }

  unsigned int index = 0;
  //unsigned int depth = 0;
  std::string name;
  
  XMLToken next = mTokens.at(index);
  name = next.getName();

  while (index < size-2)
  {
    // skip any text elements
    while(next.isText() == true && index < size-1)
    {
      index++;
      next = mTokens.at(index);
    }

    if (next.getName() == qualifier)
    {
      valid = true;
      return true;
    }

    index++;
    if (index < size)
    {
      next = mTokens.at(index);
    }
  }  

  // we might have hit the end of the loop and the end of the correct tag
  if (valid == false && index >= size-2)
  {
    valid = true;
  }

  return false;
}
예제 #3
0
bool 
ArraysASTPlugin::readMatrixRow(XMLInputStream& stream, const std::string& reqd_prefix,
                        const XMLToken& currentElement)
{
  bool read = false;
  
  stream.skipText();
  const XMLToken nextElement = stream.peek();
  const string&  nextName = nextElement.getName();
  
  unsigned int numChildren = determineNumChildren(stream, "matrixrow");
    
  mVector = new ASTArraysVectorFunctionNode(AST_LINEAR_ALGEBRA_MATRIXROW_CONSTRUCTOR);
  
  mVector->setExpectedNumChildren(numChildren);
  
  // read attributes on this element here since we have already consumed
  // the element
  ExpectedAttributes expectedAttributes;
  mVector->addExpectedAttributes(expectedAttributes, stream);
  read = mVector->ASTBase::readAttributes(currentElement.getAttributes(), 
                                expectedAttributes, stream, currentElement);
  if (read == false)
  {
    mVector = NULL;
  }
  else
  {  
    read = mVector->read(stream, reqd_prefix);
  }

  return read;
}
예제 #4
0
bool
ArraysASTPlugin::read(XMLInputStream& stream, const std::string& reqd_prefix, 
                                             const XMLToken& currentElement)
{
  bool read = false;
  
  stream.skipText();
  
  const string&  currentName = currentElement.getName();

  //ASTBase::checkPrefix(stream, reqd_prefix, currentElement);
  
  // create appropriate sub class
  if (currentName == "vector")
  {
    read = readVector(stream, reqd_prefix, currentElement);
  }
#if (0)
  else if (currentName == "matrix")
  {
    read = readMatrix(stream, reqd_prefix, currentElement);
  }
  else if (currentName == "matrixrow")
  {
    read = readMatrixRow(stream, reqd_prefix, currentElement);
  }
#endif
 
  return read;
}
bool
ASTCiNumberNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  const XMLToken element = stream.next ();
  const string&  nameE = element.getName();

  ASTBase::checkPrefix(stream, reqd_prefix, element);

  if (nameE != "ci")
  {
#if 0
    cout << "HELP\n";
#endif
    return read;
  }

  ExpectedAttributes expectedAttributes;
  addExpectedAttributes(expectedAttributes, stream);
  read = readAttributes(element.getAttributes(), expectedAttributes,
                        stream, element);

  const string name = trim( stream.next().getCharacters() );
    
  setName((name));
  ASTBase::setType(AST_NAME);

  if (read == true)
    stream.skipPastEnd(element);

  return read;
}
예제 #6
0
bool
ASTUnaryFunctionNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  ASTBase * child = NULL;
  const XMLToken element = stream.peek ();

  ASTBase::checkPrefix(stream, reqd_prefix, element);

  const char*      name = element.getName().c_str();

  setType(getTypeFromName(name));
  ASTBase::read(stream, reqd_prefix);

  unsigned int numChildrenAdded = 0;

  if (getExpectedNumChildren() > 0)
  {
    while (stream.isGood() && numChildrenAdded < getExpectedNumChildren())
    {
      stream.skipText();

      name = stream.peek().getName().c_str();

      if (representsNumber(ASTBase::getTypeFromName(name)) == true)
      {
        child = new ASTNumber();
      }
      else 
      {
        child = new ASTFunction();
      }

      read = child->read(stream, reqd_prefix);

      stream.skipText();

      if (read == true && addChild(child) == LIBSBML_OPERATION_SUCCESS)
      {
        numChildrenAdded++;
      }
      else
      {
        delete child;
        child = NULL;
        read = false;
        break;
      }
    }
  }
  else
  {
    stream.skipPastEnd(element);
    read = true;
  }

  return read;
}
예제 #7
0
/*
 * @return @c true if this XMLToken is an XML end element for the given XML
 * start element, false otherwise.
 */
bool
XMLToken::isEndFor (const XMLToken& element) const
{
  return
    isEnd()                        &&
    !isStart()                     &&
    element.isStart()              &&
    element.getName() == getName() &&
    element.getURI () == getURI ();
}
예제 #8
0
void
ASTBase::checkPrefix(XMLInputStream &stream, const std::string& reqd_prefix, 
                     const XMLToken& element)
{
  if (!reqd_prefix.empty())
  {
    std::string prefix = element.getPrefix();
    if (prefix != reqd_prefix)
    {
      const string message = "Element <" + element.getName() 
        + "> should have prefix \"" + reqd_prefix + "\".";

      logError(stream, element, InvalidMathElement, message);
      
    }
  }
}
예제 #9
0
bool
ASTCnRealNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  const XMLToken element = stream.peek ();
  const string&  name = element.getName();

  ASTBase::checkPrefix(stream, reqd_prefix, element);

  if (name != "cn")
  {
#if 0
    cout << "HELP\n";
#endif
    return read;
  }

  ASTCnBase::read(stream, reqd_prefix);

  std::string type = "real";
  element.getAttributes().readInto("type", type);

  if (type == "real")
  {
    double value = 0;
    istringstream isreal;
    isreal.str( stream.next().getCharacters() );
    isreal >> value;

    setReal(value);
    ASTBase::setType(AST_REAL);

    if (isreal.fail() 
      || (util_isInf(getValue()) > 0)
      || (util_isInf(getValue()) < 0)
      )
    {
      logError(stream, element, FailedMathMLReadOfDouble);      
    }

    read = true;
  }
예제 #10
0
/*
 * Copy constructor; creates a copy of this XMLToken.
 */
XMLToken::XMLToken(const XMLToken& orig)
 : mTriple()
 , mAttributes()
 , mNamespaces()
 , mChars (orig.mChars)
 , mIsStart (orig.mIsStart)
 , mIsEnd (orig.mIsEnd)
 , mIsText (orig.mIsText)
 , mLine (orig.mLine)
 , mColumn (orig.mColumn)
{
  if (!orig.mTriple.isEmpty())
    mTriple = XMLTriple(orig.getName(), orig.getURI(), orig.getPrefix());
  
  if (!orig.mAttributes.isEmpty())
    mAttributes = XMLAttributes(orig.getAttributes());
  
  if (!orig.mNamespaces.isEmpty())
    mNamespaces = XMLNamespaces(orig.getNamespaces());

}
예제 #11
0
bool
ASTCnIntegerNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  const XMLToken element = stream.peek ();
  const string&  name = element.getName();

  ASTBase::checkPrefix(stream, reqd_prefix, element);

  if (name != "cn")
  {
    cout << "HELP\n";
    return read;
  }

  ASTCnBase::read(stream, reqd_prefix);

  std::string type;
  element.getAttributes().readInto("type", type);

  if (type == "integer")
  {
    int value = 0;
    istringstream isint;
    isint.str( stream.next().getCharacters() );
    isint >> value;

    if (isint.fail())
    {
      logError(stream, element, FailedMathMLReadOfInteger);      
    }
    else if ( sizeof(int) > 4 && ( (value > SBML_INT_MAX) || (value < SBML_INT_MIN) ) )
    {
      logError(stream, element, FailedMathMLReadOfInteger);      
    }

    setInteger(value);
    ASTBase::setType(AST_INTEGER);
    read = true;
  }
bool
ASTCnExponentialNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  const XMLToken element = stream.peek ();
  const string&  name = element.getName();

  ASTBase::checkPrefix(stream, reqd_prefix, element);

  if (name != "cn")
  {
#if 0
    cout << "HELP\n";
#endif
    return read;
  }

  ASTCnBase::read(stream, reqd_prefix);

  std::string type;
  element.getAttributes().readInto("type", type);

  if (type == "e-notation")
  {
    double mantissa = 0;
    long   exponent = 0;
    istringstream ismantissa;
    istringstream isexponent;
    ismantissa.str( stream.next().getCharacters() );
    ismantissa >> mantissa;

    if (stream.peek().getName() == "sep")
    {
      stream.next();
      isexponent.str( stream.next().getCharacters() );
      isexponent >> exponent;
    }
예제 #13
0
unsigned int
XMLTokenizer::determineNumSpecificChildren(bool & valid, 
                                           const std::string& qualifier, 
                                        const std::string& container)
{
  valid = false;
  unsigned int numQualifiers = 0;

  size_t size = mTokens.size();
  if (size < 2)
  {
    return numQualifiers;
  }

  unsigned int depth = 0;
  unsigned int index = 0;
  std::string name;
  std::string prevName = "";
  std::string rogueTag = "";
  
  XMLToken next = mTokens.at(index);
  name = next.getName();
  if (next.isStart() == true && next.isEnd() == true && 
    name == qualifier && index < size)
  {
    numQualifiers++;
    index++;
    next = mTokens.at(index);
  }
  bool cleanBreak = false;

  while (index < size-2)
  {
    // skip any text elements
    while(next.isText() == true && index < size-1)
    {
      index++;
      next = mTokens.at(index);
    }

    if (next.isEnd() == true)
    {
      if (next.getName() == container)
      {
        valid = true;
        break;
      }
      //else if (!rogueTag.empty() && next.getName() == rogueTag)
      //{
      //  index++;
      //  next = mTokens.at(index);
      //  break;
      //}
    }
    // iterate to first start element
    while (next.isStart() == false && index < size-1)
    {
      index++;
      next = mTokens.at(index);
    }

    if (next.isStart() == true && next.isEnd() == true)
    {
      if (qualifier.empty() == true)
      {
        // if we are not looking for a specifc element then
        // we may have a child that is a start and end
        // such as <true/>
        numQualifiers++;
      }
      index++;
      if (index < size)
      {
        next = mTokens.at(index);
        continue;
      }
    }
    // check we have not reached the end
    // this would be a bad place if we have so set num children to zero
    if (index == size)
    {
      numQualifiers = 0;
      break;
    }

    // record the name of the start element
    name = next.getName();

    // need to deal with the weird situation where someone has used a tag
    // after the piece but before the next correct element
    //if (container == "piecewise")
    //{
    //  if (prevName == "piece")
    //  {
    //    if (name != "piece" && name != "otherwise")
    //    {
    //      rogueTag = name;
    //      index++;
    //      next = mTokens.at(index);
    //      continue;
    //    }
    //  }
    //}
    if (qualifier.empty() == true || name == qualifier)
    {
      numQualifiers++;
    }

//    index++;
    // check we have not reached the end
    if (index+1 == size)
    {
      numQualifiers = 0;
      break;
    }
    else
    {
      index++;
      next = mTokens.at(index);
    }

    // iterate to the end of </name>
    // checking that we have not got a nested element <name></name>
    cleanBreak = false;
    while (index < size-1)
    {
      if (next.isStart() == true && next.getName() == name)
      {
        depth++;
      }

      if (next.isEnd() == true && next.getName() == name)
      {
        if (depth == 0)
        {
          cleanBreak = true;
          break;
        }
        else
        {
          depth--;
        }
      }

      index++;
      if (index < size)
      {
        next = mTokens.at(index);
      }
    }

    prevName = name;
    index++;
    if (index < size)
    {
      next = mTokens.at(index);
    }
  }  

  // we might have hit the end of the loop and the end of the correct tag
  if (valid == false && cleanBreak == true)
  {
    if (index >= size-2 && next.isEnd() == true && next.getName() == container)
    {
        valid = true;
    }
  }

  return numQualifiers;
}
bool
ASTCSymbolDelayNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  XMLToken element = stream.peek ();
  const string&  nameE = element.getName();

  if (nameE != "csymbol")
  {
#if 0
    cout << "HELP\n";
#endif
    return read;
  }

  ASTBase::read(stream, reqd_prefix);

  const string nameDelay = trim( stream.next().getCharacters() );
    
  setName((nameDelay));
  ASTBase::setType(AST_FUNCTION_DELAY);

  stream.skipPastEnd(element);
  
  const char * name;
  ASTBase * child = NULL;

  unsigned int numChildrenAdded = 0;
  // catch if we do not have two children
  if (getExpectedNumChildren() > 0)
  {
    while (stream.isGood() && numChildrenAdded < getExpectedNumChildren())
    {
      stream.skipText();

      name = stream.peek().getName().c_str();

      if (representsNumber(ASTBase::getTypeFromName(name)) == true)
      {
        child = new ASTNumber();
      }
      else 
      {
        child = new ASTFunction();
      }

      read = child->read(stream, reqd_prefix);

      stream.skipText();

      if (read == true && addChild(child) == LIBSBML_OPERATION_SUCCESS)
      {
        numChildrenAdded++;
      }
      else
      {
        read = false;
        break;
      }
    }
  }
  else
  {
    stream.skipPastEnd(element);
    read = true;
  }

  return read;
}
예제 #15
0
bool 
ASTBase::readAttributes(const XMLAttributes& attributes,
                       const ExpectedAttributes& expectedAttributes,
                               XMLInputStream& stream, const XMLToken& element)
{
  bool read = true;

  //
  // check that all attributes are expected
  //
  for (int i = 0; i < attributes.getLength(); i++)
  {
    std::string name   = attributes.getName(i);
    std::string uri    = attributes.getURI(i);
    std::string prefix = attributes.getPrefix(i);

    //
    // To allow prefixed attribute whose namespace doesn't belong to
    // core or extension package.
    //
    // (e.g. xsi:type attribute in Curve element in layout extension)
    //
    if (!prefix.empty())
    {
      if ( expectedAttributes.hasAttribute(prefix + ":" + name) ) continue;
    }

    if (!expectedAttributes.hasAttribute(name))
    {
      std::string message = "The attribute '" + name + "' is not permitted" +
        " on a <" + element.getName() + "> element.";
      if (name == "type")
      {
        logError(stream, element, DisallowedMathTypeAttributeUse, message);    
      }
      else if (name == "encoding")
      {
        logError(stream, element, DisallowedMathMLEncodingUse, message);    
      }
      else if (name == "definitionURL")
      {
        logError(stream, element, DisallowedDefinitionURLUse, message);    
      }
      else if (name == "units")
      {
        if (stream.getSBMLNamespaces() != NULL
          && stream.getSBMLNamespaces()->getLevel() > 2)
        {
          logError(stream, element, DisallowedMathUnitsUse, message);   
        }
        else
        {
          message = "The 'units' attribute was introduced in SBML Level 3.";
          logError(stream, element, InvalidMathMLAttribute, message);  
        }

      }
      else
      {
        logError(stream, element, InvalidMathElement, message);
      }

      // not sufficient to make the read bad
      //return false;
    }
  }


  
  string id; 
  string className;
  string style;

  attributes.readInto( "id"           , id        );
  attributes.readInto( "class"        , className );
  attributes.readInto( "style"        , style     );

  if (!id.empty())
  {
	  if (setId(id) != LIBSBML_OPERATION_SUCCESS)
    {
      read = false;
    }
  }

  if (!className.empty())
  {
	  if (setClass(className) != LIBSBML_OPERATION_SUCCESS)
    {
      read = false;
    }
  }

  if (!style.empty())
  {
	  if (setStyle(style) != LIBSBML_OPERATION_SUCCESS)
    {
      read = false;
    }
  }

  unsigned int i = 0;
  while (read == true && i < getNumPlugins())
  {
    read = getPlugin(i)->readAttributes(attributes, expectedAttributes, 
                                        stream, element, getExtendedType());
    i++;
  }


  return read;
}
bool
ASTNaryFunctionNode::read(XMLInputStream& stream, const std::string& reqd_prefix)
{
  bool read = false;
  ASTBase * child = NULL;
  const XMLToken element = stream.peek ();

  ASTBase::checkPrefix(stream, reqd_prefix, element);

  const char*      name = element.getName().c_str();

  int type = getTypeFromName(name);
  setType(type);
  ASTBase::read(stream, reqd_prefix);

  unsigned int numChildrenAdded = 0;

  if (getExpectedNumChildren() > 0)
  {
    while (stream.isGood() && numChildrenAdded < getExpectedNumChildren())
    {
      stream.skipText();

      name = stream.peek().getName().c_str();

      if (representsNumber(ASTBase::getTypeFromName(name)) == true)
      {
        child = new ASTNumber();
      }
      else 
      {
        child = new ASTFunction();
      }

      read = child->read(stream, reqd_prefix);

      stream.skipText();

      if (read == true && addChild(child) == LIBSBML_OPERATION_SUCCESS)
      {
        numChildrenAdded++;
      }
      else
      {
        delete child;
        child = NULL;
        read = false;
        break;
      }
    }
  }
  else
  {
    stream.skipPastEnd(element);
    read = true;
  }

  if (read == true && type == AST_FUNCTION_ROOT 
    && getExpectedNumChildren() == 1 
    && ASTFunctionBase::getChild(0)->getType() != AST_QUALIFIER_DEGREE)
  {
    /* HACK TO REPLICATE OLD BEHAVIOUR */
    /* we need to add the qualifier child for the degree 2 */
    ASTFunction * degree = new ASTFunction(AST_QUALIFIER_DEGREE);
    ASTNumber * int2 = new ASTNumber(AST_INTEGER);
    int2->setInteger(2);
    degree->addChild(int2->deepCopy());
    this->prependChild(degree->deepCopy());
    delete int2;
    delete degree;

  }

  //if (read == false)
  //{
  //  stream.skipPastEnd(element);
  //}

  return read;
}
예제 #17
0
unsigned int
XMLTokenizer::determineNumberChildren(bool & valid, const std::string element)
{
  valid = false;
  unsigned int numChildren = 0;
  std::string closingTag = element;
  bool forcedElement = true;
  if (closingTag.empty() == true) 
  {
    closingTag = "apply";
    forcedElement = false;
  }

  // if there is only one token there cannot be any children 
  size_t size = mTokens.size();
  if (size < 2)
  {
    return numChildren;
  }

  // we assume that the first unread token is a 
  // function and that at some point in the
  // list of tokens we will hit the end of the 
  // element for that function
  // need to count the number of starts

  unsigned int index = 0;
  XMLToken firstUnread = mTokens.at(index);
  while (firstUnread.isText() && index < size - 1)
  {
    // skip any text
    index++;
    firstUnread = mTokens.at(index);
  }


  // if we have an apply the firstToken should be a function
  // that is both a start and an end
  // unless we are reading a user function
  // or a csymbol
  // if the tag is not a start and an end this is an error
  // we want to exit
  // but be happy that the read is ok
  // and the error gets logged elsewhere
  if (closingTag == "apply")
  {
    std::string firstName = firstUnread.getName();

    if (firstName != "ci" && firstName != "csymbol")
    {
      if (firstUnread.isStart() != true 
        || (firstUnread.isStart() == true &&  firstUnread.isEnd() != true))
      {
        valid = true;
        return numChildren;
      }
    }
  }

  index = 1;
  if (forcedElement == true)
  {
    index = 0;
  }

  unsigned int depth = 0;
  std::string name;
  bool cleanBreak = false;
  XMLToken next = mTokens.at(index);
  while (index < size-2)
  {
    // skip any text elements
    while(next.isText() == true && index < size-1)
    {
      index++;
      next = mTokens.at(index);
    }
    if (next.isEnd() == true && next.getName() == closingTag)
    {
      valid = true;
      break;
    }
    // iterate to first start element
    while (next.isStart() == false && index < size-1)
    {
      index++;
      next = mTokens.at(index);
    }

    // check we have not reached the end
    // this would be a bad place if we have so set num children to zero
    if (index == size)
    {
      numChildren = 0;
      break;
    }

    // record the name of the start element
    name = next.getName();
    numChildren++;

 //   index++;
    // check we have not reached the end
    if (index + 1 == size)
    {
      numChildren = 0;
      break;
    }
    else if (next.isEnd() == false)
    {
      index++;
      if (index < size)
      {
        next = mTokens.at(index);
      }
      else
      {
        break;
      }
    }

    // iterate to the end of </name>
    // checking that we have not got a nested element <name></name>
    cleanBreak = false;
    while (index < size-1)
    {
      if (next.isStart() == true && next.isEnd() == false && next.getName() == name)
      {
        depth++;
      }

      if (next.isEnd() == true && next.getName() == name)
      {
        if (depth == 0)
        {
          cleanBreak = true;
          break;
        }
        else
        {
          depth--;
        }
      }

      index++;
      next = mTokens.at(index);
    }

    index++;
    if (index < size)
    {
      next = mTokens.at(index);
    }
  } 

  // we might have hit the end of the loop and the end of the correct tag
  // but the loop hits before it can record that it was valid
  if (valid == false && cleanBreak == true)
  {
  if (index >= size-2 && next.isEnd() == true && next.getName() == closingTag)
  {
      valid = true;
  }
  }

  return numChildren;
}