예제 #1
0
    /**
     * Build the segment array by parsing the path. when the path is modified,
     * the existing map is invalidated and needs to be remapped.
     */
    void parse()
    {
        // Already been here?
        if (segmentCount > 0) return;

        segmentCount = 0;
        extraSegments.clear();

        if (path.isEmpty())
        {
            // There always has to be at least one segment.
            allocSegment(&emptyPath);

            DENG2_ASSERT(segmentCount > 0);
            return;
        }

        QChar const *segBegin = path.constData();
        QChar const *segEnd   = path.constData() + path.length() - 1;

        // Skip over any trailing delimiters.
        for (int i = path.length();
            segEnd->unicode() && *segEnd == separator && i-- > 0;
            --segEnd) {}

        // Scan the path for segments, in reverse order.
        QChar const *from;
        forever
        {
            if (segEnd < segBegin) break; // E.g., path is "/"

            // Find the start of the next segment.
            for (from = segEnd; from > segBegin && !(*from == separator); from--)
            {}

            int startIndex = (*from == separator? from + 1 : from) - path.constData();
            int length = (segEnd - path.constData()) - startIndex + 1;
            allocSegment(QStringRef(&path, startIndex, length));

            // Are there no more parent directories?
            if (from == segBegin) break;

            // So far so good. Move one directory level upwards.
            // The next name ends here.
            segEnd = from - 1;
        }

        // Unix style zero-length root name?
        if (*segBegin == separator)
        {
            allocSegment(&emptyPath);
        }

        DENG2_ASSERT(segmentCount > 0);
    }
예제 #2
0
void Stream::putSegment(int length, const char *ptr, bool copy)
{
#ifdef ENGINE
	ASSERT (length >= 0);
#endif
	if (length == 0)
		return;

	const char *address = ptr;
	totalLength += length;

	if (!segments)
	{
		if (copyFlag = copy)
		{
			allocSegment (MAX (length, minSegment));
			current->length = length;
			memcpy (current->address, address, length);
		}
		else
		{
			//copyFlag = copy;
			current = segments = &first;
			current->length = length;
			current->address = (char*) address;
			current->next = NULL;
		}
	}
	else if (copyFlag)
	{
		int l = currentLength - current->length;
		if (l > 0)
		{
			const int l2 = MIN (l, length);
			memcpy (current->address + current->length, address, l2);
			current->length += l2;
			length -= l2;
			address += l2;
		}
		if (length)
		{
			allocSegment (MAX (length, minSegment));
			current->length = length;
			memcpy (current->address, address, length);
		}
	}
	else
	{
		allocSegment (0);
		current->address = (char*) address;
		current->length = length;
	}
}
예제 #3
0
void Stream::compress(int length, const void * address)
{
	//printShorts ("Original data", (length + 1) / 2, (short*) address);
	Segment *segment = allocSegment (length + 5);
	short *q = (short*) segment->address;
	const short *p = (short*) address;
	const short* const end = p + (length + 1) / 2;
	const short* const yellow = end - 2;
	*q++ = length;

	while (p < end)
	{
		short *start = ++q;
		while (p < end && (p >= yellow || p[0] != p[1] || p[1] != p[2]))
			*q++ = *p++;
		int n = q - start;
		if (n)
			start [-1] = -n;
		else
			--q;
		if (p >= end)
			break;
		const short* start2 = p++;
		while (p < end && *p == *start2)
			++p;
		n = p - start2;
		*q++ = n;
		*q++ = *start2;
	}

	totalLength = segment->length = (char*) q - segment->address;
}
예제 #4
0
void Stream::putCharacter(char c)
{
	if (!segments || current->length >= currentLength)
		allocSegment (MAX (100, minSegment));

	current->address [current->length] = c;
	++current->length;
	++totalLength;
}
예제 #5
0
void Stream::putSegment(int length, const unsigned short *chars)
{
	if (length == 0)
		return;

	totalLength += length;
	const unsigned short *wc = chars;

	if (!segments)
	{
		allocSegment (MAX (length, minSegment));
		current->length = length;
	}
	else
	{
		int l = currentLength - current->length;
		if (l > 0)
		{
			const int l2 = MIN (l, length);
			char *p = current->address + current->length;
			for (int n = 0; n < l2; ++n)
				*p++ = (char) *wc++;
			//memcpy (current->address + current->length, address, l2);
			current->length += l2;
			length -= l2;
			//address += l2;
		}
		if (length)
		{
			allocSegment (MAX (length, minSegment));
			current->length = length;
			//memcpy (current->address, address, length);
		}
	}

	char *p = current->address;

	for (int n = 0; n < length; ++n)
		*p++ = (char) *wc++;

}
예제 #6
0
char* Stream::alloc(int length)
{
	totalLength += length;

	if (!current || length > currentLength - current->length)
		allocSegment (length);

	char* const p = current->tail + current->length;
	current->length += length;

	return p;
}