Ejemplo n.º 1
0
	void blockFromBuffer(KviCString & szBuffer)
	{
		indent(szBuffer);
		szBuffer.prepend("{\n");
		szBuffer.stripRightWhiteSpace();
		szBuffer.ensureLastCharIs('\n');
		szBuffer.append("}\n");
	}
Ejemplo n.º 2
0
bool KviConfigurationFile::load()
{
	// this is really faster than the old version :)

	// open the file
	KviFile f(m_szFileName);
	if(!f.open(QFile::ReadOnly)) return false;

	KviCString tmp;
	KviConfigurationFileGroup * p_group = 0;

	int iLoadBlockSize = LOAD_BLOCK_SIZE;

	char * buffer = (char *)KviMemory::allocate(iLoadBlockSize * sizeof(char));

	int toRead;
	int readedLen;
	int remainingLen = 0;

	char * p = buffer; // start writing to the beginning of the buffer

	do {
		// compute the length to read
		toRead = iLoadBlockSize - remainingLen;
		if(toRead < 1)
		{
			// ops... a string longer than iLoadBlockSize - 1 chars
			iLoadBlockSize += LOAD_BLOCK_SIZE;
			int iOffset = p - buffer;
			buffer = (char *)KviMemory::reallocate(buffer,iLoadBlockSize * sizeof(char));
			p = buffer + iOffset;
			toRead += LOAD_BLOCK_SIZE;
		}

		// do read
		readedLen = f.read(p,toRead);
		if(readedLen < toRead)
		{
			// check for errors
			if(readedLen <= 0)
			{
				if(readedLen < 0)
				{
					// error at all
					f.close();
					KviMemory::free(buffer);
					return true; // nothing more to parse anyway
				} else {
					// just a zero byte read
					if(remainingLen == 0)
					{
						// there was nothing in the buffer
						f.close(); // nothing to parse anyway
						KviMemory::free(buffer);
						return true;
					}
					// there is something in the buffer but we have readed 0 bytes
					// this usually means that the last line in the file has no trailing newline
					// ...we just fake it :)
					*p = '\n';
					readedLen = 1;
				}
			} else {
				// just readed something but less than expected
				// check if the last readed char is a newline
				// if it isn't, fake it
				if(*(p + readedLen - 1) != '\n')
				{
					*(p + readedLen) = '\n';
					readedLen++;
				}
			}
		}
		// compute the end pointer
		char * endp = p + readedLen;

		p = buffer; // start from beginning of the data buffer at all
		// begin of the current string
		char * begin = p;

		// and loop
		while(p < endp)
		{
			// find a newline
			if(*p != '\n')
			{
				p++;
				continue;
			}
			// newline!
			*p = 0;
			// now begin points to the string that terminates in p
			// skip leading whitespace
			while((*begin == '\t') || (*begin == ' '))begin++;

			if(p == begin)
			{
				// empty line
				p++;
				begin = p;
				continue;
			}
			// now p > begin
			// check if there are trailing spaces (include CR so CRLF is trimmed too)
			char * trail = p - 1;

			p++;

			while(trail >= begin)
			{
				if((*trail == '\r') || (*trail == '\t') || (*trail == ' '))*trail = 0;
				else break;
				trail--;
			}

			// yeah, have some data in this line :D
			switch(*begin)
			{
				case 0:
					// empty line
				break;
				case '#':
					// comment: just skip it
				break;
				case '[':
					// group ?
					begin++;
					if(*begin && (*begin != ']'))
					{
						char * z = begin;
#define COMPAT_WITH_OLD_CONFIGS
#ifdef COMPAT_WITH_OLD_CONFIGS
						// run to the end of the string
						while(*z)z++;
						// run back to the trailing ']'
						while((z > begin) && (*z != ']'))z--;
						// if it is not ther just run back to the end of the string
						if(*z != ']')while(*z)z++;
#else
						// new configs have it always encoded properly
						while(*z && (*z != ']'))z++;
#endif
						*z = 0;
						tmp.hexDecode(begin);
						tmp.stripRightWhiteSpace(); // no external spaces in group names

						if(!tmp.isEmpty())
						{
							QString szGroup = m_bLocal8Bit ?
								QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
								QString::fromUtf8(tmp.ptr(),tmp.len());
							p_group = m_pDict->find(szGroup);
							if(!p_group)
							{
								p_group = new KviConfigurationFileGroup(17,false);
								p_group->setAutoDelete(true);
								m_pDict->insert(szGroup,p_group);
							}
						}
					}
				break;
				default:
				{
					// real data ?
					char * z = begin;
					while(*z && (*z != '='))z++;
					if(*z && (z != begin))
					{
						*z = 0;
						tmp.hexDecode(begin);
						tmp.stripRightWhiteSpace(); // No external spaces at all in keys
						if(!tmp.isEmpty())
						{
							QString szKey =  m_bLocal8Bit ?
									QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
									QString::fromUtf8(tmp.ptr(),tmp.len());
							z++;
							while(*z && ((*z == ' ') || (*z == '\t')))z++;
							if(*z)
							{
								tmp.hexDecode(z);
								QString * pVal = new QString( m_bLocal8Bit ?
									QString::fromLocal8Bit(tmp.ptr(),tmp.len()) :
									QString::fromUtf8(tmp.ptr(),tmp.len())
									);
								if(!p_group)
								{
									// ops...we're missing a group
									// use the default one
									p_group = new KviConfigurationFileGroup(17,false);
									p_group->setAutoDelete(true);
									m_pDict->insert(KVI_CONFIG_DEFAULT_GROUP,p_group);
								}
								p_group->replace(szKey,pVal);
							} else {
								// we in fact need this (mercy :D)
								// otherwise the empty options will be treated as non-existing ones
								// and will get the defaults (which is bad)
								QString * pVal = new QString(QString());
								p_group->replace(szKey,pVal);
							}
						}
					}
				}
				break;
			}
			begin = p;
		}
		if(begin != endp)
		{
			// there is data with no trailing newline in the buffer
			remainingLen = endp-begin;
			if(buffer != begin)
			{
				KviMemory::move(buffer,begin,remainingLen);
				p = buffer + remainingLen;
			} // else p remains where it is
		} else {
			p = buffer;
		}
	} while(readedLen == toRead);

	f.close();
	KviMemory::free(buffer);
	return true;
}