Ejemplo n.º 1
0
bool IniReader::Parse() {
	FILE* f = OpenGameFile(m_filename, "r");
	if(f == NULL)
		return false;

	bool res = true;
	enum ParseState {
		S_DEFAULT, S_IGNORERESTLINE, S_PROPNAME, S_PROPVALUE, S_SECTION };
	ParseState state = S_DEFAULT;
	std::string propname;
	std::string section;
	std::string value;

	while(!feof(f) && !ferror(f)) {
		unsigned char c = 0;
		if(fread(&c, 1, 1, f) == 0) break;

		if(c == '\r') continue; // ignore this

		switch(state) {
		case S_DEFAULT:
			if(c >= 128) break; // just ignore unicode-stuff when we are in this state (UTF8 bytes at beginning are also handled by this)
			else if(isspace(c)) break; // ignore spaces and newlines
			else if(c == '#') { state = S_IGNORERESTLINE; /* this is a comment */ break; }
			else if(c == '[') { state = S_SECTION; section = ""; break; }
			else if(c == '=') {
				warnings << "WARNING: \"=\" is not allowed as the first character in a line of " << m_filename << endl;
				break; /* ignore */ }
			else { state = S_PROPNAME; propname = c; break; }

		case S_SECTION:
			if(c == ']') {
				if( ! OnNewSection(section) )  { res = false; goto parseCleanup; }
				state = S_DEFAULT; NewSection(section); break; }
			else if(c == '\n') {
				warnings << "WARNING: section-name \"" << section << "\" of " << m_filename << " is not closed correctly" << endl;
				state = S_DEFAULT; break; }
			else if(isspace(c)) {
				warnings << "WARNING: section-name \"" << section << "\" of " << m_filename << " contains a space" << endl;
				break; /* ignore */ }
			else { section += c; break; }

		case S_PROPNAME:
			if(c == '\n') {
				warnings << "WARNING: property \"" << propname << "\" of " << m_filename << " incomplete" << endl;
				state = S_DEFAULT; break; }
			else if(isspace(c)) break; // just ignore spaces
			else if(c == '=') { state = S_PROPVALUE; value = ""; break; }
			else { propname += c; break; }

		case S_PROPVALUE:
			if(c == '\n' || c == '#') {
				if( ! OnEntry(section, propname, value) ) { res = false; goto parseCleanup; }
				NewEntryInSection(propname, value);
				if(c == '#') state = S_IGNORERESTLINE; else state = S_DEFAULT;
				break; }
			else if(isspace(c) && value == "") break; // ignore heading spaces
			else { value += c; break; }

		case S_IGNORERESTLINE:
			if(c == '\n') state = S_DEFAULT;
			break; // ignore everything
		}
	}

	// In case the endline is missing at the end of file, finish the parsing of the last line
	if (state == S_PROPVALUE)  {
		if( ! OnEntry(section, propname, value) ) { res = false; goto parseCleanup; }
		NewEntryInSection(propname, value);
	}

	// DEBUG: dump the file
	/*notes << "Dump of " << m_filename << endl;
	for (SectionMap::iterator it = m_sections.begin(); it != m_sections.end(); ++it)  {
		notes << "[" << it->first << "]" << endl;
		for (Section::iterator k = it->second.begin(); k != it->second.end(); ++k)
			notes << k->first << "=" << k->second << endl;
		notes << endl;
	}
	notes << endl;*/

parseCleanup:
	fclose(f);

	return res;
}
    void CSectionDecoder::OnTsPacket(CTsHeader& header, byte* tsPacket)
    {
        try
        {
            if (header.TransportError)
            {
                m_section.Reset(); // Will force us to wait for new PayloadUnitStart
                return;
            }
            if (m_pid >= 0x1fff) return;
            if (header.Pid != m_pid) return;
            if (!header.HasPayload) return;

            int start = header.PayLoadStart;
            int pointer_field = 0;

            if (header.PayloadUnitStart)
            {
                if (start >= 188)
                    return;

                pointer_field = start + tsPacket[start] + 1;
                if (m_section.BufferPos == 0)
                    start += tsPacket[start] + 1;
                else
                    start++;
            }

            int numloops = 0;
            while (start < 188)
            {
                numloops++;
                if (m_section.BufferPos == 0)
                {
                    if (!header.PayloadUnitStart) return;
                    if (tsPacket[start] == 0xFF) return;
                    int section_length = SnapshotSectionLength(tsPacket, start);
                    start = StartNewSection(tsPacket, start, section_length);
                }
                else
                {
                    if (m_section.section_length == -1)
                        m_section.CalcSectionLength(tsPacket, start);
                    if (m_section.section_length == 0)
                    {
                        if (m_bLog)
                            XBMC->Log(LOG_DEBUG, "!!! CSectionDecoder::OnTsPacket got a section with section length: 0 on pid: 0x%X tableid: 0x%X bufferpos: %d start: %d - Discarding whole packet.", header.Pid, m_section.Data[0], m_section.BufferPos, start);
                        m_section.Reset();
                        return;
                    }
                    int len = m_section.section_length - m_section.BufferPos;
                    if (pointer_field != 0 && ((start + len) > pointer_field))
                    {
                        // We have an incomplete section here
                        len = pointer_field - start;
                        start = AppendSection(tsPacket, start, len);
                        m_section.section_length = m_section.BufferPos - 1;
                        start = pointer_field;
                    }
                    else
                        start = AppendSection(tsPacket, start, len);
                }
                if (m_section.SectionComplete() && m_section.section_length > 0)
                {
                    uint32_t crc = 0;

                    // Only long syntax (section_syntax_indicator == 1) has a CRC
                    // Short syntax may have CRC e.g. TOT, but that is part of the specific section
                    if (m_section.section_syntax_indicator == 1)
                        crc = crc32((char*)m_section.Data, m_section.section_length + 3);

                    if (crc == 0 || (m_bCrcCheck == false))
                    {
                        OnNewSection(m_section);
                        if (m_pCallback != NULL)
                            m_pCallback->OnNewSection(header.Pid, m_section.table_id, m_section);
                    }
                    else
                    {
                        // If the section is complete and the CRC fails, then this section is crap!
                        m_section.Reset();
                        return;
                    }

                    m_section.Reset();
                }
                pointer_field = 0;
                if (numloops > 100)
                {
                    XBMC->Log(LOG_DEBUG, "!!! CSectionDecoder::OnTsPacket Entered infinite loop. pid: %X start: %d BufferPos: %d SectionLength: %d - Discarding section and moving to next packet",
                        header.Pid, start, m_section.BufferPos, m_section.section_length);
                    m_section.Reset();
                    return;
                }
            }
        }
        catch (...)
        {
            XBMC->Log(LOG_DEBUG, "exception in CSectionDecoder::OnTsPacket");
        }
    }