Example #1
0
void CastingPlatform<TSubClass, issueError>::issueCastError(const Item &validationError,
                                                            const Item &sourceValue,
                                                            const ReportContext::Ptr &context) const
{
    Q_ASSERT(validationError);
    Q_ASSERT(context);
    Q_ASSERT(validationError.isAtomicValue());
    Q_ASSERT(validationError.template as<AtomicValue>()->hasError());

    const ValidationError::Ptr err(validationError.template as<ValidationError>());
    QString msg(err->message());

    if(msg.isNull())
    {
        msg = QtXmlPatterns::tr("It's not possible to cast the value %1 of type %2 to %3")
                 .arg(formatData(sourceValue.stringValue()))
                 .arg(formatType(context->namePool(), sourceValue.type()))
                 .arg(formatType(context->namePool(), targetType()));
    }
    else
    {
        Q_ASSERT(!msg.isEmpty());
        msg = QtXmlPatterns::tr("Failure when casting from %1 to %2: %3")
                 .arg(formatType(context->namePool(), sourceValue.type()))
                 .arg(formatType(context->namePool(), targetType()))
                 .arg(msg);
    }

    /* If m_errorCode is FORG0001, we assume our sub-classer doesn't have a
     * special wish about error code, so then we use the error object's code.
     */
    context->error(msg, m_errorCode == ReportContext::FORG0001 ? err->errorCode() : m_errorCode,
                   static_cast<const TSubClass*>(this));
}
Example #2
0
AtomicComparator::Ptr ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
fetchComparator(const ItemType::Ptr &t1,
                const ItemType::Ptr &t2,
                const ReportContext::Ptr &context) const
{
    Q_ASSERT(t1);
    Q_ASSERT(t2);

    if(*BuiltinTypes::xsAnyAtomicType == *t1    ||
       *BuiltinTypes::xsAnyAtomicType == *t2    ||
       *BuiltinTypes::item == *t1               ||
       *BuiltinTypes::item == *t2               ||
       *BuiltinTypes::numeric == *t1            ||
       *BuiltinTypes::numeric == *t2            ||
       *CommonSequenceTypes::Empty == *t1       ||
       *CommonSequenceTypes::Empty == *t2)
    {
        /* The static type of(at least) one of the operands could not
         * be narrowed further, so we do the operator
         * lookup at runtime.
         */
        return AtomicComparator::Ptr();
    }

    const AtomicComparatorLocator::Ptr locator
        (static_cast<const AtomicType *>(t1.data())->comparatorLocator());

    if(!locator)
    {
        if(issueError)
        {
            context->error(QtXmlPatterns::tr("No comparisons can be done involving the type %1.")
                                            .arg(formatType(context->namePool(), t1)),
                                       errorCode, static_cast<const TSubClass *>(this)->actualReflection());
        }
        return AtomicComparator::Ptr();
    }

    const AtomicComparator::Ptr comp(static_cast<const AtomicType *>(t2.data())->accept(locator, operatorID(),
                                                                                       static_cast<const TSubClass *>(this)->actualReflection()));

    if(comp)
        return comp;
    else if(issueError)
    {
        context->error(QtXmlPatterns::tr("Operator %1 is not available between atomic values of type %2 and %3.")
                                        .arg(formatKeyword(AtomicComparator::displayName(operatorID(),
                                                                                         comparisonType)),
                                             formatType(context->namePool(), t1),
                                             formatType(context->namePool(), t2)),
                                   errorCode, static_cast<const TSubClass *>(this)->actualReflection());
    }

    return AtomicComparator::Ptr();
}
Example #3
0
        /**
         * Performs the actual tracing.
         */
        Item mapToItem(const Item &item,
                            const DynamicContext::Ptr &context)
        {
            QTextStream out(stderr);
            ++m_position;
            if(m_position == 1)
            {
                if(item)
                {
                    out << qPrintable(m_msg)
                        << " : "
                        << qPrintable(item.stringValue());
                }
                else
                {
                    out << qPrintable(m_msg)
                        << " : ("
                        << qPrintable(formatType(context->namePool(), CommonSequenceTypes::Empty))
                        << ")\n";
                    return Item();
                }
            }
            else
            {
                out << qPrintable(item.stringValue())
                    << '['
                    << m_position
                    << "]\n";
            }

            return item;
        }
Example #4
0
QMap<QString, TLMethod> GeneratorNG::readMethods(const QJsonDocument &document)
{
    const QJsonArray methods = document.object().value("methods").toArray();

    QMap<QString, TLMethod> result;

    for (int i = 0; i < methods.count(); ++i) {
        const QJsonObject obj = methods.at(i).toObject();

        const QString methodName = formatName(obj.value("method").toString());
        const quint32 methodId = obj.value("id").toString().toInt();

        TLMethod tlMethod;
        tlMethod.name = methodName;
        tlMethod.id = methodId;

        const QJsonArray params = obj.value("params").toArray();

        foreach (const QJsonValue &paramValue, params) {
            const QJsonObject &paramObj = paramValue.toObject();
            const QString paramName = formatMember(paramObj.value("name").toString());

            const QString paramType = paramObj.value("type").toString();

            tlMethod.params.append(TLParam(paramName, formatType(paramType)));
        }

        result.insert(methodName, tlMethod);

//        quint32 id = obj.value("id").toString().toInt();
//        qDebug() << name << QString::number(id, 0x10);
    }

    return result;
}
Example #5
0
AtomicCaster::Ptr CastingPlatform<TSubClass, issueError>::locateCaster(const ItemType::Ptr &sourceType,
                                                                       const ReportContext::Ptr &context,
                                                                       bool &castImpossible,
                                                                       const SourceLocationReflection *const location,
                                                                       const ItemType::Ptr &targetType)
{
    Q_ASSERT(sourceType);
    Q_ASSERT(targetType);

    const AtomicCasterLocator::Ptr locator(static_cast<AtomicType *>(
            targetType.data())->casterLocator());
    if(!locator)
    {
        if(issueError)
        {
            context->error(QtXmlPatterns::tr("No casting is possible with %1 as the target type.")
                                        .arg(formatType(context->namePool(), targetType)),
                                       ReportContext::XPTY0004, location);
        }
        else
            castImpossible = true;

        return AtomicCaster::Ptr();
    }

    const AtomicCaster::Ptr caster(static_cast<const AtomicType *>(sourceType.data())->accept(locator, location));
    if(!caster)
    {
        if(issueError)
        {
            context->error(QtXmlPatterns::tr("It is not possible to cast from %1 to %2.")
                                            .arg(formatType(context->namePool(), sourceType))
                                            .arg(formatType(context->namePool(), targetType)),
                                       ReportContext::XPTY0004, location);
        }
        else
            castImpossible = true;

        return AtomicCaster::Ptr();
    }

    return caster;
}
Example #6
0
void ConvertVarType( char *typebuf, char *arraybuf, id_type id, ArrayInfo *array ) {
/***************************************************************************/

    char        *type;

    if( _BaseType( id ) == TY_STRING ) {
        type = "String";
    } else {
        type = convertType( id );
    }
    formatType( typebuf, arraybuf, "", type, _IsRefType( id ), array );
}
Example #7
0
void ConvertParmType( char *buf, char *name, id_type id, ArrayInfo *array ) {
/**************************************************************************/

    char        *type;
    char        arraybuf[30];

    if( _BaseType( id ) == TY_STRING && array == NULL && _IsRefType( id ) ) {
        type = "char";
    } else {
        type = convertType( id );
    }
    formatType( buf, arraybuf, name, type, _IsRefType( id ), array );
    strcat( buf, arraybuf );
}
Example #8
0
QMap<QString, TLType> GeneratorNG::readTypes(const QJsonDocument &document)
{
    const QJsonArray constructors = document.object().value("constructors").toArray();

    QMap<QString, TLType> types;

    for (int i = 0; i < constructors.count(); ++i) {
        const QJsonObject obj = constructors.at(i).toObject();

        const QString predicateName = formatName1stCapital(obj.value("predicate").toString());
        const quint32 predicateId = obj.value("id").toString().toInt();
        const QString typeName = formatType(obj.value("type").toString());

        TLType tlType = types.value(typeName);
        tlType.name = typeName;

        TLSubType tlSubType;
        tlSubType.name = predicateName;
        tlSubType.id = predicateId;

        const QJsonArray params = obj.value("params").toArray();

        foreach (const QJsonValue &paramValue, params) {
            const QJsonObject &paramObj = paramValue.toObject();
            const QString paramName = formatMember(paramObj.value("name").toString());

            const QString paramType = paramObj.value("type").toString();

            tlSubType.members.append(TLParam(paramName, formatType(paramType)));
        }

        tlType.subTypes.append(tlSubType);
        types.insert(typeName, tlType);
    }

    return types;
}
Example #9
0
QString GeneratorNG::formatType(QString type)
{
    if (plainTypes.contains(type)) {
        return nativeTypes.at(plainTypes.indexOf(type));
    } else if (type.startsWith(QLatin1String("Vector<"))) {
        int firstIndex = type.indexOf(QLatin1Char('<')) + 1;
        int lastIndex = type.indexOf(QLatin1Char('>'));
        QString subType = type.mid(firstIndex, lastIndex - firstIndex);
        return QString("%1<%2>").arg(tlVectorType).arg(formatType(subType));
    } else {
        type[0] = type.at(0).toUpper();

        return tlPrefix + formatName(type);
    }
}
Example #10
0
Expression::Ptr
ComparingAggregator<oper, result>::typeCheck(const StaticContext::Ptr &context,
                                             const SequenceType::Ptr &reqType)
{
    Q_ASSERT(oper == AtomicComparator::OperatorGreaterThan ||
             oper == AtomicComparator::OperatorLessThan);
    const Expression::Ptr me(FunctionCall::typeCheck(context, reqType));

    ItemType::Ptr t1(m_operands.first()->staticType()->itemType());

    if(*CommonSequenceTypes::Empty == *t1)
        return EmptySequence::create(this, context);
    else if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
            BuiltinTypes::numeric->xdtTypeMatches(t1))
        return me;
    else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1))
    {
        m_operands.replace(0, Expression::Ptr(new UntypedAtomicConverter(m_operands.first(),
                           BuiltinTypes::xsDouble)));
        t1 = m_operands.first()->staticType()->itemType();
    }
    else if(!BuiltinTypes::xsString->xdtTypeMatches(t1) &&
            !BuiltinTypes::xsAnyURI->xdtTypeMatches(t1) &&
            !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1) &&
            !BuiltinTypes::xsDate->xdtTypeMatches(t1) &&
            !BuiltinTypes::xsTime->xdtTypeMatches(t1) &&
            !BuiltinTypes::xsDateTime->xdtTypeMatches(t1) &&
            !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1))
    {
        context->error(QtXmlPatterns::tr("The first argument to %1 cannot be of type %2.")
                          .arg(QPatternist::formatFunction(context->namePool(), signature()))
                          .arg(formatType(context->namePool(), m_operands.first()->staticType())),
                       ReportContext::FORG0006, this);
        return me;
    }

    if(!m_operands.first()->staticType()->cardinality().allowsMany())
        return m_operands.first();
    
    // explicit scope needed in RVCT
    ComparingAggregator<oper, result>::prepareComparison(fetchComparator(t1, t1, context));

    return me;
}
Example #11
0
void CastingPlatform<TSubClass, issueError>::checkTargetType(const ReportContext::Ptr &context) const
{
    Q_ASSERT(context);

    const ItemType::Ptr tType(targetType());
    Q_ASSERT(tType);
    Q_ASSERT(tType->isAtomicType());
    const AtomicType::Ptr asAtomic(tType);

    /* This catches casting to xs:NOTATION and xs:anyAtomicType. */
    if(asAtomic->isAbstract())
    {
        context->error(QtXmlPatterns::tr("Casting to %1 is not possible because it "
                                     "is an abstract type, and can therefore never be instantiated.")
                                .arg(formatType(context->namePool(), tType)),
                          ReportContext::XPST0080,
                          static_cast<const TSubClass*>(this));
    }
}
Example #12
0
// This method expects a well-formatted string, there is no error checking!
// Since we create those ourselves, we should be pretty safe that nobody does something crappy here.
UiStyle::StyledString UiStyle::styleString(const QString &s_, quint32 baseFormat)
{
    QString s = s_;
    if (s.length() > 65535) {
        qWarning() << QString("String too long to be styled: %1").arg(s);
        return StyledString();
    }
    StyledString result;
    result.formatList.append(qMakePair((quint16)0, baseFormat));
    quint32 curfmt = baseFormat;
    int pos = 0; quint16 length = 0;
    for (;;) {
        pos = s.indexOf('%', pos);
        if (pos < 0) break;
        if (s[pos+1] == '%') { // escaped %, we just remove one and continue
            s.remove(pos, 1);
            pos++;
            continue;
        }
        if (s[pos+1] == 'D' && s[pos+2] == 'c') { // color code
            if (s[pos+3] == '-') { // color off
                curfmt &= 0x003fffff;
                length = 4;
            }
            else {
                int color = 10 * s[pos+4].digitValue() + s[pos+5].digitValue();
                //TODO: use 99 as transparent color (re mirc color "standard")
                color &= 0x0f;
                if (s[pos+3] == 'f') {
                    curfmt &= 0xf0ffffff;
                    curfmt |= (quint32)(color << 24) | 0x00400000;
                }
                else {
                    curfmt &= 0x0fffffff;
                    curfmt |= (quint32)(color << 28) | 0x00800000;
                }
                length = 6;
            }
        }
        else if (s[pos+1] == 'O') { // reset formatting
            curfmt &= 0x000000ff; // we keep message type-specific formatting
            length = 2;
        }
        else if (s[pos+1] == 'R') { // reverse
            // TODO: implement reverse formatting

            length = 2;
        }
        else { // all others are toggles
            QString code = QString("%") + s[pos+1];
            if (s[pos+1] == 'D') code += s[pos+2];
            FormatType ftype = formatType(code);
            if (ftype == Invalid) {
                pos++;
                qWarning() << (QString("Invalid format code in string: %1").arg(s));
                continue;
            }
            curfmt ^= ftype;
            length = code.length();
        }
        s.remove(pos, length);
        if (pos == result.formatList.last().first)
            result.formatList.last().second = curfmt;
        else
            result.formatList.append(qMakePair((quint16)pos, curfmt));
    }
    result.plainText = s;
    return result;
}
Example #13
0
JNIEXPORT jint JNICALL
Java_ipc_java_formatters_formatType (JNIEnv *env, jclass theClass, jlong formatter)
{
  return (jint)(size_t)formatType((FORMAT_PTR)(size_t)formatter);
}
Example #14
0
void AccelTreeBuilder<FromDocument>::attribute(const QXmlName &name, const QStringRef &value)
{
    /* Attributes adds a namespace binding, so lets synthesize one.
     *
     * We optimize by checking whether we have a namespace for which a binding would
     * be generated. Happens relatively rarely. */
    if(name.hasPrefix())
        namespaceBinding(QXmlName(name.namespaceURI(), 0, name.prefix()));

    m_document->basicData.append(AccelTree::BasicNodeData(currentDepth(), currentParent(), QXmlNodeModelIndex::Attribute, 0, name));
    ++m_preNumber;
    ++m_size.top();

    m_isPreviousAtomic = false;

    if(name.namespaceURI() == StandardNamespaces::xml && name.localName() == StandardLocalNames::id)
    {
        const QString normalized(value.toString().simplified());

        if(QXmlUtils::isNCName(normalized))
        {
            const QXmlName::LocalNameCode id = m_namePool->allocateLocalName(normalized);

            const int oldSize = m_document->m_IDs.count();
            m_document->m_IDs.insert(id, currentParent());
            /* We don't run the value through m_attributeCompress here, because
             * the likelyhood of it deing identical to another attribute is
             * very small. */
            m_document->data.insert(m_preNumber, normalized);

            /**
             * In the case that we're called for doc-available(), m_context is
             * null, and we need to flag somehow that we failed to load this
             * document.
             */
            if(oldSize == m_document->m_IDs.count() && m_context) // TODO
            {
                Q_ASSERT(m_context);
                m_context->error(QtXmlPatterns::tr("An %1-attribute with value %2 has already been declared.")
                                                   .arg(formatKeyword("xml:id"),
                                                        formatData(normalized)),
                                 FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091,
                                 this);
            }
        }
        else if(m_context) // TODO
        {
            Q_ASSERT(m_context);

            /* If we're building from an XML Document(e.g, we're fed from QXmlStreamReader, we raise FODC0002,
             * otherwise XQDY0091. */
            m_context->error(QtXmlPatterns::tr("An %1-attribute must have a "
                                               "valid %2 as value, which %3 isn't.").arg(formatKeyword("xml:id"),
                                                                                         formatType(m_namePool, BuiltinTypes::xsNCName),
                                                                                         formatData(value.toString())),
                             FromDocument ? ReportContext::FODC0002 : ReportContext::XQDY0091,
                             this);
        }
    }
    else
        m_document->data.insert(m_preNumber, *m_attributeCompress.insert(value.toString()));
}
Example #15
0
StringBuilder& FormatUtils::vformat(StringBuilder& sb, const char* fmt, va_list ap) noexcept {
  const char kFormatChar = '%';

  const char* p = fmt;
  const char* mark = fmt;

  for (;;) {
    uint32_t c = static_cast<unsigned char>(*p);
    if (c == '\0')
      break;
    p++;

    // Don't continue if the character is not a formatting mark. In most cases
    // this branch should be taken as most of the string should be just a text.
    if (c != kFormatChar)
      continue;

    // NULL terminator after a formatting mark. It's safe to just break here.
    // The trailing mark will be appended to the string as well. However, this
    // is basically handling of an invalid `fmt` string.
    c = static_cast<unsigned char>(*p);
    if (c == '\0')
      break;

    // Handle a double-escaped formatting mark "%%", which produces "%".
    bool isEscape = (c == kFormatChar);
    sb.appendString(mark, (size_t)(p - mark) - 1 + isEscape);

    // Guess a new mark position, which is exactly two characters after the
    // initial mark when simple or a double-escaped mark formatting has been
    // used. MPSL formatting extensions will adjust the mark again.
    mark = ++p;
    if (isEscape)
      continue;

    if (c == '{') {
      // ----------------------------------------------------------------------
      // [MPSL Formatting Extensions - '%{...}']
      // ----------------------------------------------------------------------

      do {
        c = static_cast<unsigned char>(*p);
        // Invalid formatting, bail out.
        if (c == '\0') {
          mark -= 2;
          goto _Done;
        }
        p++;
      } while (c != '}');

      StringRef ext(mark, (size_t)(p - mark) - 1);
      mark = p;

      // Handle '%{StringRef}' passed as 'const StringRef*'.
      if (ext.eq("StringRef", 9)) {
        const StringRef* value = va_arg(ap, StringRef*);

        sb.appendString(value->getData(), value->getLength());
        continue;
      }

      // Handle '%{Type}' passed as 'unsigned int'.
      if (ext.eq("Type", 4)) {
        unsigned int type = va_arg(ap, unsigned int);

        formatType(sb, type);
        continue;
      }

      // Handle '%{Value}' passed as 'unsigned int, const Value*'.
      if (ext.eq("Value", 5)) {
        unsigned int type = va_arg(ap, unsigned int);
        const Value* value = va_arg(ap, const Value*);

        formatValue(sb, type, value);
        continue;
      }

      // Handle '%{SymbolType}' passed as 'unsigned int'.
      if (ext.eq("SymbolType", 10)) {
        unsigned int value = va_arg(ap, unsigned int);

        sb.appendString(mpAstSymbolType[value].name);
        continue;
      }
/*static*/ StructureParser::StringVec::const_iterator StructureParser::matchCppType (StringVec::const_iterator begin, StringVec::const_iterator end, bool * result, CppType * type) {
	int tDepth = 0;			  // template depth
	bool modifierPart = true; // currently at left side where modifiers are
	StringVec::const_iterator i = begin;
	StringVec::const_iterator j = i == end ? end : i + 1;
	StringVec::const_iterator typeBegin = end;
	bool awaitNext = false;
	for (; i != end; i++){
		j = i + 1;
		if (modifierPart){
			if (*i == "static"){
				if (type->static_){	// static can be there only once
					*result = false;
					return end;
				}
				type->static_ = true;
				continue;
			}
			if (*i == "const"){
				if (type->const_){ // const can be there only once
					*result = false;
					return end;
				}
				type->const_ = true;
				continue;
			}
			if (*i == "mutable"){
				if (type->mutable_){ // mutable can be there only once
					*result = false;
					return end;
				}
				type->mutable_ = true;
				continue;
			}

			// ignoring struct class forward definitions (hack?)
			if (*i == "struct" || *i == "class"){
				*result = false;
				return end;
			}
			// ignoring typedef
			if (*i == "typedef"){
				*result = false;
				return end;
			}

			modifierPart = false;
			typeBegin = i;
		}
		if (*i == "<") {
			tDepth++;
			continue;
		}
		if (*i == ">") {
			tDepth--;
			continue;
		}
		if (*i == "&" || *i == "*"){
			continue;
		}
		if ((j != end && *j == "::") || *i == "::" ){
			awaitNext = true;
			continue;
		}
		if (tDepth == 0 && i != typeBegin && !awaitNext){
			// ready
			break;
		}
		awaitNext = false;
	}
	if (tDepth > 0) {
		*result = false;
		return end;
	}
	if (typeBegin == end){
		*result = false;
		return end;
	}

	type->name = formatType (typeBegin, i);
	*result = true;
	return i;
}
/*static*/ bool StructureParser::matchLine (char finishing) {
	// Case 1. Namespace definition
	if (mIncomingLine.size() == 2 && mIncomingLine[0] == "namespace" && finishing == '{'){
		NamespaceElement * element = new NamespaceElement();
		element->name = mIncomingLine[1];
		push (element);
		return true;
	}
	// Case 2. Enum definition
	if (mIncomingLine.size() == 2 && mIncomingLine[0] == "enum" && finishing == '{'){
		EnumElement * element = new EnumElement;
		element->name = mIncomingLine[1];
		push (element);
		return true;
	}
	// Case 3. Simple Structure/Class Definition
	if (mIncomingLine.size() == 2 && (mIncomingLine[0] == "struct" || mIncomingLine[0] == "class") && finishing == '{'){
		ClassElement * element = new ClassElement;
		element->name = mIncomingLine[1];
		element->isStruct = (mIncomingLine[0] == "struct");
		element->currentVisibility = element->isStruct ? Public : Private;
		push (element);
		return true;
	}
	// Case 4. Structure/Class derived from some other type
	if (mIncomingLine.size() > 3 && (mIncomingLine[0] == "struct" || mIncomingLine[0] == "class") && mIncomingLine[2] == ":"){
		ClassElement * element = new ClassElement;
		element->name = mIncomingLine[1];
		element->isStruct = (mIncomingLine[0] == "struct");
		element->currentVisibility = element->isStruct ? Public : Private;
		StringVec::const_iterator i = mIncomingLine.begin() + 3;
		while (i != mIncomingLine.end()){
			Visibility v = element->currentVisibility;
			if (*i == "public")   { v = Public; i++; }
			if (*i == "private")  { v = Private; i++; }
			if (*i == "protected"){ v = Protected; i++;}
			bool suc;
			StringVec::const_iterator end = matchTypeName (i, mIncomingLine.end(), &suc);
			if (!suc) {
				fprintf (stderr, "Error: could not match a typename\n");
				delete element;
				return false;
			}
			ClassElement::Parent p;
			p.first  = v;
			p.second = formatType (i,end);
			element->parents.push_back (p);
			i = end;
			if (i == mIncomingLine.end()) break;
			if (*i == ",") { i++; continue; }
			fprintf (stderr, "Error: Invalid character: %s\n", i->c_str());
			delete element;
			return false;
		}
		push (element);
		return true;
	}
	// Case 5. Member Variable
	if (finishing == ';'){
		VariableDefinition definition;
		bool result = matchVariableDefinition (mIncomingLine.begin(), mIncomingLine.end(), &definition);
		if (result) {
			if (mDebug) printf ("Matched variable definition: %s\n", sf::toJSON(definition).c_str());
			StackElement * element = mStack.top();
			if (element->type == StackElement::Class){
				ClassElement * celement = static_cast<ClassElement*> (element);
				celement->memberVariables.push_back (std::make_pair(celement->currentVisibility,definition));
				return true;
			}
		}
	}
	// Case 6a: Handling of SF_AUTOREFLECT_COMMAND;
	if (finishing == ';'){
		size_t size =  mIncomingLine.size();
		if (size >= 1){
			const std::string & x (mIncomingLine.back());
			size_t prefix = beginsWidth (x, mCommandPrefix);
			if (prefix != x.npos){
				std::string cmd = x.substr (prefix, x.npos);
				assert (!mStack.empty());
				StackElement * element = mStack.top ();
				element->commands.insert (cmd);
				mIncomingLine.pop_back ();
				return true;
			}
		}
	}
	// Case 6b: handling of SF_AUTOREFLECT_COMMAND(element-name)
	if (finishing == ';'){
		size_t size = mIncomingLine.size();
		if (size >= 4){
			const std::string & x (mIncomingLine.front());
			size_t prefix = beginsWidth (x, mCommandPrefix);
			if (prefix != x.npos && mIncomingLine[1] == "(" && mIncomingLine[size-1] == ")"){
				std::string cmd = x.substr (prefix, x.npos);
				StringVec::iterator beginType = mIncomingLine.begin() + 2;
				StringVec::iterator endType   = mIncomingLine.end() - 1;
				bool suc;
				StringVec::const_iterator foundEnd = matchTypeName (beginType, endType, &suc);
				if (!suc) {
					fprintf (stderr, "Could not match a type name in %s command", cmd.c_str());
					return false;
				}
				std::string elementName = formatType (beginType, foundEnd);
				StackElement * parent = mStack.top ();
				StackElement * child = parent->findChild (elementName);
				if (child){
					child->commands.insert (cmd);
					mIncomingLine.erase(mIncomingLine.end() - 4, mIncomingLine.end());
					return true;
				} else {
					fprintf (stderr, "Did not found a element with name %s as child of element of name %s, for command %s\n", elementName.c_str(), sf::toJSON(parent).c_str(), cmd.c_str());
					return false;
				}

			}
		}
	}
	// Case 7 Function declaration
	if (finishing == ';' || finishing == '{') {
		FunctionDeclarationElement * declaration = new FunctionDeclarationElement();
		bool result = matchFunctionDeclaration (mIncomingLine.begin(), mIncomingLine.end(), declaration);
		if (result) {
			if (mDebug) printf ("Matched function declaration %s\n", sf::toJSON (declaration).c_str());
			StackElement * element = mStack.top();
			if (element->type == StackElement::Class)
				declaration->visibility = (static_cast<ClassElement*> (element))->currentVisibility;

			if (
					(element->type == StackElement::Class)
				 || (element->type == StackElement::Root)
				 || (element->type == StackElement::Namespace)){
				element->children.push_back (declaration);
			} else {
				// May happen. Regular functions are similar to be parsed like functions
				// E.g. int bla () { X x ();} // must not declare x but can also declare an instance of (struct/class) X, called x.
				// fprintf (stderr, "Matched a function declaration %s outside a class/root/namespace element, parent=%s\n", sf::toJSON (declaration).c_str(), sf::toJSON (*element).c_str());
				delete declaration;
				if (finishing != '{') // otherwise there is still a block
					return true;
			}
		}
		if (finishing != '{') // otherwise there is still a block
			return true;
	}

	// Unknown block, starting
	if (finishing == '{'){
		if (mDebug){
			printf ("Unknown block start: ");
			for (StringVec::const_iterator i = mIncomingLine.begin(); i != mIncomingLine.end(); i++){
				printf ("%s ", i->c_str());
			}
			printf ("<stop>\n");
		}

		UnknownBlock * element = new UnknownBlock ();
		push (element);
		return true;
	}
	// End of a block, ending
	if (finishing == '}'){
		bool ret = pop ();
		return ret;
	}
	// Command, ending
	if (finishing == ';'){
		if (mDebug){
			printf ("Unknown command: ");
			for (StringVec::const_iterator i = mIncomingLine.begin(); i != mIncomingLine.end(); i++){
				printf ("%s ", i->c_str());
			}
			printf ("<stop>\n");
		}
		return true;
	}
	return true;
}
Example #18
0
gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
                                       const gl::Rectangle &area,
                                       GLenum format,
                                       GLenum type,
                                       size_t outputPitch,
                                       const gl::PixelPackState &pack,
                                       uint8_t *pixels)
{
    const gl::FramebufferAttachment *colorbuffer = mState.getColorAttachment(0);
    ASSERT(colorbuffer);

    RenderTarget9 *renderTarget = nullptr;
    ANGLE_TRY(colorbuffer->getRenderTarget(context, &renderTarget));
    ASSERT(renderTarget);

    IDirect3DSurface9 *surface = renderTarget->getSurface();
    ASSERT(surface);

    D3DSURFACE_DESC desc;
    surface->GetDesc(&desc);

    if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
    {
        UNIMPLEMENTED();   // FIXME: Requires resolve using StretchRect into non-multisampled render target
        SafeRelease(surface);
        return gl::OutOfMemory()
               << "ReadPixels is unimplemented for multisampled framebuffer attachments.";
    }

    IDirect3DDevice9 *device = mRenderer->getDevice();
    ASSERT(device);

    HRESULT result;
    IDirect3DSurface9 *systemSurface = nullptr;
    bool directToPixels = !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() &&
                          area.x == 0 && area.y == 0 &&
                          static_cast<UINT>(area.width) == desc.Width && static_cast<UINT>(area.height) == desc.Height &&
                          desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
    if (directToPixels)
    {
        // Use the pixels ptr as a shared handle to write directly into client's memory
        result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
                                                     D3DPOOL_SYSTEMMEM, &systemSurface, reinterpret_cast<void**>(&pixels));
        if (FAILED(result))
        {
            // Try again without the shared handle
            directToPixels = false;
        }
    }

    if (!directToPixels)
    {
        result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
                                                     D3DPOOL_SYSTEMMEM, &systemSurface, nullptr);
        if (FAILED(result))
        {
            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
            SafeRelease(surface);
            return gl::OutOfMemory() << "Failed to allocate internal texture for ReadPixels.";
        }
    }

    result = device->GetRenderTargetData(surface, systemSurface);
    SafeRelease(surface);

    if (FAILED(result))
    {
        SafeRelease(systemSurface);

        // It turns out that D3D will sometimes produce more error
        // codes than those documented.
        if (d3d9::isDeviceLostError(result))
        {
            mRenderer->notifyDeviceLost();
        }
        else
        {
            UNREACHABLE();
        }

        return gl::OutOfMemory() << "Failed to read internal render target data.";
    }

    if (directToPixels)
    {
        SafeRelease(systemSurface);
        return gl::NoError();
    }

    RECT rect;
    rect.left = gl::clamp(area.x, 0L, static_cast<LONG>(desc.Width));
    rect.top = gl::clamp(area.y, 0L, static_cast<LONG>(desc.Height));
    rect.right = gl::clamp(area.x + area.width, 0L, static_cast<LONG>(desc.Width));
    rect.bottom = gl::clamp(area.y + area.height, 0L, static_cast<LONG>(desc.Height));

    D3DLOCKED_RECT lock;
    result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);

    if (FAILED(result))
    {
        UNREACHABLE();
        SafeRelease(systemSurface);

        return gl::OutOfMemory() << "Failed to lock internal render target.";
    }

    uint8_t *source = reinterpret_cast<uint8_t *>(lock.pBits);
    int inputPitch  = lock.Pitch;

    const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
    gl::FormatType formatType(format, type);

    PackPixelsParams packParams;
    packParams.area.x      = rect.left;
    packParams.area.y      = rect.top;
    packParams.area.width  = rect.right - rect.left;
    packParams.area.height = rect.bottom - rect.top;
    packParams.format      = format;
    packParams.type        = type;
    packParams.outputPitch = static_cast<GLuint>(outputPitch);
    packParams.pack        = pack;

    PackPixels(packParams, d3dFormatInfo.info(), inputPitch, source, pixels);

    systemSurface->UnlockRect();
    SafeRelease(systemSurface);

    return gl::NoError();
}
Example #19
0
void PackPixels(const PackPixelsParams &params,
                const angle::Format &sourceFormat,
                int inputPitchIn,
                const uint8_t *sourceIn,
                uint8_t *destWithoutOffset)
{
    uint8_t *destWithOffset = destWithoutOffset + params.offset;

    const uint8_t *source = sourceIn;
    int inputPitch        = inputPitchIn;

    if (params.pack.reverseRowOrder)
    {
        source += inputPitch * (params.area.height - 1);
        inputPitch = -inputPitch;
    }

    const auto &sourceGLInfo = gl::GetSizedInternalFormatInfo(sourceFormat.glInternalFormat);

    if (sourceGLInfo.format == params.format && sourceGLInfo.type == params.type)
    {
        // Direct copy possible
        for (int y = 0; y < params.area.height; ++y)
        {
            memcpy(destWithOffset + y * params.outputPitch, source + y * inputPitch,
                   params.area.width * sourceGLInfo.pixelBytes);
        }
        return;
    }

    ASSERT(sourceGLInfo.sized);

    gl::FormatType formatType(params.format, params.type);
    ColorCopyFunction fastCopyFunc =
        GetFastCopyFunction(sourceFormat.fastCopyFunctions, formatType);
    const auto &destFormatInfo = gl::GetInternalFormatInfo(formatType.format, formatType.type);

    if (fastCopyFunc)
    {
        // Fast copy is possible through some special function
        for (int y = 0; y < params.area.height; ++y)
        {
            for (int x = 0; x < params.area.width; ++x)
            {
                uint8_t *dest =
                    destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
                const uint8_t *src = source + y * inputPitch + x * sourceGLInfo.pixelBytes;

                fastCopyFunc(src, dest);
            }
        }
        return;
    }

    ColorWriteFunction colorWriteFunction = GetColorWriteFunction(formatType);

    // Maximum size of any Color<T> type used.
    uint8_t temp[16];
    static_assert(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) &&
                      sizeof(temp) >= sizeof(gl::ColorI),
                  "Unexpected size of gl::Color struct.");

    const auto &colorReadFunction = sourceFormat.colorReadFunction;

    for (int y = 0; y < params.area.height; ++y)
    {
        for (int x = 0; x < params.area.width; ++x)
        {
            uint8_t *dest      = destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes;
            const uint8_t *src = source + y * inputPitch + x * sourceGLInfo.pixelBytes;

            // readFunc and writeFunc will be using the same type of color, CopyTexImage
            // will not allow the copy otherwise.
            colorReadFunction(src, temp);
            colorWriteFunction(temp, dest);
        }
    }
}