Ejemplo n.º 1
0
bool RtfReader::parseDocument() {
    enum {
        READ_NORMAL_DATA,
        READ_BINARY_DATA,
        READ_HEX_SYMBOL,
        READ_KEYWORD,
        READ_KEYWORD_PARAMETER
    } parserState = READ_NORMAL_DATA;

    std::string keyword;
    std::string parameterString;
    std::string hexString;
    int imageStartOffset = -1;

    while (!myIsInterrupted) {
        const char *ptr = myStreamBuffer;
        const char *end = myStreamBuffer + myStream->read(myStreamBuffer, rtfStreamBufferSize);
        if (ptr == end) {
            break;
        }
        const char *dataStart = ptr;
        bool readNextChar = true;
        while (ptr != end) {
            switch (parserState) {
            case READ_BINARY_DATA:
                // TODO: optimize
                processCharData(ptr, 1);
                --myBinaryDataSize;
                if (myBinaryDataSize == 0) {
                    parserState = READ_NORMAL_DATA;
                }
                break;
            case READ_NORMAL_DATA:
                switch (*ptr) {
                case '{':
                    if (ptr > dataStart) {
                        processCharData(dataStart, ptr - dataStart);
                    }
                    dataStart = ptr + 1;
                    myStateStack.push(myState);
                    myState.ReadDataAsHex = false;
                    break;
                case '}':
                {
                    if (ptr > dataStart) {
                        processCharData(dataStart, ptr - dataStart);
                    }
                    dataStart = ptr + 1;

                    if (imageStartOffset >= 0) {
                        int imageSize = myStream->offset() + (ptr - end) - imageStartOffset;
                        insertImage(myNextImageMimeType, myFileName, imageStartOffset, imageSize);
                        imageStartOffset = -1;
                    }

                    if (myStateStack.empty()) {
                        return false;
                    }

                    if (myState.Destination != myStateStack.top().Destination) {
                        switchDestination(myState.Destination, false);
                        switchDestination(myStateStack.top().Destination, true);
                    }

                    bool oldItalic = myState.Italic;
                    bool oldBold = myState.Bold;
                    bool oldUnderlined = myState.Underlined;
                    ZLTextAlignmentType oldAlignment = myState.Alignment;
                    myState = myStateStack.top();
                    myStateStack.pop();

                    if (myState.Italic != oldItalic) {
                        setFontProperty(RtfReader::FONT_ITALIC);
                    }
                    if (myState.Bold != oldBold) {
                        setFontProperty(RtfReader::FONT_BOLD);
                    }
                    if (myState.Underlined != oldUnderlined) {
                        setFontProperty(RtfReader::FONT_UNDERLINED);
                    }
                    if (myState.Alignment != oldAlignment) {
                        setAlignment();
                    }

                    break;
                }
                case '\\':
                    if (ptr > dataStart) {
                        processCharData(dataStart, ptr - dataStart);
                    }
                    dataStart = ptr + 1;
                    keyword.erase();
                    parserState = READ_KEYWORD;
                    break;
                case 0x0d:
                case 0x0a:			// cr and lf are noise characters...
                    if (ptr > dataStart) {
                        processCharData(dataStart, ptr - dataStart);
                    }
                    dataStart = ptr + 1;
                    break;
                default:
                    if (myState.ReadDataAsHex) {
                        if (imageStartOffset == -1) {
                            imageStartOffset = myStream->offset() + (ptr - end);
                        }
                    }
                    break;
                }
                break;
            case READ_HEX_SYMBOL:
                hexString += *ptr;
                if (hexString.size() == 2) {
                    char ch = strtol(hexString.c_str(), 0, 16);
                    hexString.erase();
                    processCharData(&ch, 1);
                    parserState = READ_NORMAL_DATA;
                    dataStart = ptr + 1;
                }
                break;
            case READ_KEYWORD:
                if (!isalpha(*ptr)) {
                    if ((ptr == dataStart) && (keyword.empty())) {
                        if (*ptr == '\'') {
                            parserState = READ_HEX_SYMBOL;
                        } else {
                            keyword = *ptr;
                            processKeyword(keyword);
                            parserState = READ_NORMAL_DATA;
                        }
                        dataStart = ptr + 1;
                    } else {
                        keyword.append(dataStart, ptr - dataStart);
                        if ((*ptr == '-') || isdigit(*ptr)) {
                            dataStart = ptr;
                            parserState = READ_KEYWORD_PARAMETER;
                        } else {
                            readNextChar = *ptr == ' ';
                            processKeyword(keyword);
                            parserState = READ_NORMAL_DATA;
                            dataStart = readNextChar ? ptr + 1 : ptr;
                        }
                    }
                }
                break;
            case READ_KEYWORD_PARAMETER:
                if (!isdigit(*ptr)) {
                    parameterString.append(dataStart, ptr - dataStart);
                    int parameter = atoi(parameterString.c_str());
                    parameterString.erase();
                    readNextChar = *ptr == ' ';
                    if ((keyword == "bin") && (parameter > 0)) {
                        myBinaryDataSize = parameter;
                        parserState = READ_BINARY_DATA;
                    } else {
                        processKeyword(keyword, &parameter);
                        parserState = READ_NORMAL_DATA;
                    }
                    dataStart = readNextChar ? ptr + 1 : ptr;
                }
                break;
            }
            if (readNextChar) {
                ++ptr;
            } else {
                readNextChar = true;
            }
        }
        if (dataStart < end) {
            switch (parserState) {
            case READ_NORMAL_DATA:
                processCharData(dataStart, end - dataStart);
            case READ_KEYWORD:
                keyword.append(dataStart, end - dataStart);
                break;
            case READ_KEYWORD_PARAMETER:
                parameterString.append(dataStart, end - dataStart);
                break;
            default:
                break;
            }
        }
    }

    return myIsInterrupted || myStateStack.empty();
}
Ejemplo n.º 2
0
Table::Table(const std::vector<std::string>& fieldsList)
: fieldsList(fieldsList)
{
    processKeyword();
}
Ejemplo n.º 3
0
Drop::Drop(const std::string& table, const bool& ifExists, DropType typeOfDropOrCreate)
: table(table), ifExists(ifExists), typeOfDropOrCreate(typeOfDropOrCreate)
{
    processKeyword();
}
Ejemplo n.º 4
0
Having::Having(const std::vector<std::string>& havingList)
: havingList(havingList)
{
    processKeyword();
}
Ejemplo n.º 5
0
InsertInto::InsertInto(const std::string& table)
: table(table)
{
    processKeyword();
}