⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbian.cpp

📁 OggPlay for Symbian 是symbian上的一个媒体播放程序的源码。它支持ogg,wav等等多媒体格式。
💻 CPP
字号:
/*
 *  Copyright (c) 2005 S. Fisher
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <f32file.h>
#include "iVorbisFile.h"

// C interface to Symbian OS file system and User functions
extern "C"
{
char* _ogg_strstr(const char* str1, const char* str2)
{
	const char *resStr, *str2b;
	char chr1, chr2;
	if ((str1 == NULL) || (str2 == NULL))
		return (char *) str1;

	chr2 = *str2;
	if (chr2 == 0)
		return (char*) str1;

	chr1 = *str1;
	while (chr1)
	{
		if (chr1 == chr2)
		{
			resStr = str1;
			str2b = str2;
			do
			{
				str2b++;
				chr2 = *str2b;
				if (chr2 == 0)
					return (char *) resStr;

				str1++;
				chr1 = *str1;
			} while (chr1 == chr2);

			chr2 = *str2;
		}
		else
		{
			str1++;
			chr1 = *str1;
		}
	}

	return NULL;
}

int _ogg_strncmp(const char* str1, const char* str2, size_t num)
{
	size_t i;
	char chr1 = 0, chr2 = 0;
	if ((str1 == NULL) || (str2 == NULL))
		return 0;

	for (i = 0 ; i<num ; i++)
		{
		chr1 = str1[i];
		chr2 = str2[i];
		if ((chr1 != chr2) || !chr1)
			break;
		}

	return chr1-chr2;
}

char *_ogg_strcat(char *aDst, const char *aSrc)
{
	// Check args
	if ((aDst == NULL) || (aSrc == NULL))
		return aDst;

	// Save the return ptr
	char* retPtr = aDst;

	// Scan to the end of the dst
	while(*aDst)
		aDst++;

	// Copy the source
	while((*aDst++ = *aSrc++) != 0);
	return retPtr;
}

int _ogg_toupper(int c)
{
	if ((c >= 'a') && ( c <= 'z'))
		return 'A' + (c - 'a');

	return  c;
}

void _ogg_sort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
{
	// Implement an efficient quick sort
	// (based upon the version in Numrical Recipies in Pascal)
	const TInt insertionNum = width * 11;
	TInt8* arrayStack[64];
	TInt stackIndex;
	TInt halfWidth = width >> 1;

	TInt8* iElement;
	TInt8* jElement;
	TInt8* kElement;
	TInt8* leftElement;
	TInt8* rightElement;
	TInt8* elementVal = (TInt8*) User::Alloc(width);

	stackIndex = 0;
	leftElement = (TInt8 *) base;
	rightElement = leftElement + width*(num-1);
	for ( ; ; )
	{
		if ((rightElement-leftElement)<insertionNum)
		{
			// Insertion sort the sub-array
			for (jElement = leftElement+width ; jElement<=rightElement ; jElement += width)
			{
				Mem::Copy(elementVal, jElement, width);
				for (iElement = leftElement ; iElement<jElement ; iElement += width)
				{
					if (compare(jElement, iElement) < 0)
					{
						Mem::Copy(iElement+width, iElement, jElement-iElement);
						Mem::Copy(iElement, elementVal, width);
						break;
					}
				}
			}

			// Pop the stack
			if (!stackIndex)
				break; // Job done

			leftElement = arrayStack[--stackIndex];
			rightElement = arrayStack[--stackIndex];
		}
		else
		{
			// Choose partitioning element
			// (median of left, middle and right elements of the current subarray)
			iElement = leftElement + width;
			jElement = rightElement;
			kElement = (TInt8 *) ((((TInt) leftElement) + ((TInt) rightElement)) >> 1);
			if (((TInt) (kElement - leftElement)) % width)
				kElement -= halfWidth;

			// Move the middle element to be after the left element
			Mem::Swap(iElement, kElement, width);

			// Arrange the three values in the correct order
			if (compare(leftElement, rightElement) > 0)
				Mem::Swap(leftElement, rightElement, width);

			if (compare(iElement, rightElement) > 0)
				Mem::Swap(iElement, rightElement, width);

			if (compare(leftElement, iElement) > 0)
				Mem::Swap(leftElement, iElement, width);

			// Do the partitioning
			kElement = iElement;
			for ( ; ; )
			{
				do
				{
					iElement += width;
				} while (compare(iElement, kElement) < 0);

				do
				{
					jElement -= width;
				} while (compare(jElement, kElement) > 0);

				if (jElement<iElement)
					break; // Partitioning done

				Mem::Swap(iElement, jElement, width);
			}

			// Move the partitioning element to it's correct place
			Mem::Swap(kElement, jElement, width);

			// Push the larger of the subarrays, process the other one
			if ((rightElement - (iElement+width)) > (jElement - leftElement))
			{
				arrayStack[stackIndex++] = rightElement;
				arrayStack[stackIndex++] = iElement;
				rightElement = jElement - width;
			}
			else
			{
				arrayStack[stackIndex++] = jElement - width;
				arrayStack[stackIndex++] = leftElement;
				leftElement = iElement;
			}
		}
	}

	User::Free(elementVal);
}

void _ogg_aligned_sort(void *base, size_t num, int (*compare)(const void *, const void *))
{
	// Implement an efficient quick sort
	// (based upon the version in Numrical Recipies in Pascal)
	const TInt insertionNum = 11;
	TInt* arrayStack[64];
	TInt stackIndex;

	TInt* iElement;
	TInt* jElement;
	TInt* kElement;
	TInt* leftElement;
	TInt* rightElement;
	TInt elementVal;

	stackIndex = 0;
	leftElement = (TInt *) base;
	rightElement = leftElement + (num-1);
	for ( ; ; )
	{
		if ((rightElement-leftElement)<insertionNum)
		{
			// Insertion sort the sub-array
			for (jElement = leftElement+1 ; jElement<=rightElement ; jElement++)
			{
				elementVal = *jElement;
				for (iElement = leftElement ; iElement<jElement ; iElement++)
				{
					if (compare(jElement, iElement) < 0)
					{
						Mem::Move(iElement+1, iElement, 4*(jElement-iElement));
						*iElement = elementVal;
						break;
					}
				}
			}

			// Pop the stack
			if (!stackIndex)
				break; // Job done

			leftElement = arrayStack[--stackIndex];
			rightElement = arrayStack[--stackIndex];
		}
		else
		{
			// Choose partitioning element
			// (median of left, middle and right elements of the current subarray)
			iElement = leftElement + 1;
			jElement = rightElement;
			kElement = (TInt *) (((((TInt) leftElement) + ((TInt) rightElement)) >> 1) & 0xFFFFFFF0);

			// Move the middle element to be after the left element
			elementVal = *kElement;
			*kElement = *iElement;
			*iElement = elementVal;

			// Arrange the three values in the correct order
			if (compare(leftElement, rightElement) > 0)
			{
				elementVal = *leftElement;
				*leftElement = *rightElement;
				*rightElement = elementVal;
			}

			if (compare(iElement, rightElement) > 0)
			{
				elementVal = *iElement;
				*iElement = *rightElement;
				*rightElement = elementVal;
			}

			if (compare(leftElement, iElement) > 0)
			{
				elementVal = *leftElement;
				*leftElement = *iElement;
				*iElement = elementVal;
			}

			// Do the partitioning
			kElement = iElement;
			for ( ; ; )
			{
				do
				{
					iElement++;
				} while (compare(iElement, kElement) < 0);

				do
				{
					jElement--;
				} while (compare(jElement, kElement) > 0);

				if (jElement<iElement)
					break; // Partitioning done

				elementVal = *iElement;
				*iElement = *jElement;
				*jElement = elementVal;
			}

			// Move the partitioning element to it's correct place
			elementVal = *kElement;
			*kElement = *jElement;
			*jElement = elementVal;

			// Push the larger of the subarrays, process the other one
			if ((rightElement - (iElement+1)) > (jElement - leftElement))
			{
				arrayStack[stackIndex++] = rightElement;
				arrayStack[stackIndex++] = iElement;
				rightElement = jElement - 1;
			}
			else
			{
				arrayStack[stackIndex++] = jElement - 1;
				arrayStack[stackIndex++] = leftElement;
				leftElement = iElement;
			}
		}
	}
}

void _ogg_qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
{ 
	if (num == 0)
		return;

	if ((width == 4) && !(((TInt) base) & 0x03)) // likely
		_ogg_aligned_sort(base, num, compare);
	else
		_ogg_sort(base, num, width, compare);
}

int _ogg_memcmp(const void* aBuf1, const void* aBuf2, size_t aNumBytes)
{
	return Mem::Compare((TUint8* ) aBuf1, aNumBytes, (TUint8 *) aBuf2, aNumBytes);
}

void* _ogg_memcpy(void *aDst, const void *aSrc, size_t aNumBytes)
{
	return Mem::Copy(aDst, aSrc, aNumBytes);
}

char* _ogg_strcpy(char *aDst, const char *aSrc)
{
	if ((aDst == NULL) || (aSrc == NULL))
		return aDst;

	char* retPtr = aDst;
	char srcChar = *aSrc;
	while(srcChar)
	{
		*aDst = srcChar;
		aSrc++ ; aDst++;

		srcChar = *aSrc;
	}

	*aDst = 0;
	return retPtr;
}

size_t _ogg_strlen(const char* aStr)
{
	if (aStr == NULL)
		return 0;

	const char* strBase = aStr;
	while(*aStr)
		aStr++;

	return aStr - strBase;
}

void _ogg_exit(int aVal)
{
	User::Exit(aVal);
}

long _ogg_labs(long aVal)
{
	return (aVal<0) ? -aVal : aVal;
}

int _ogg_abs(int aVal)
{
	return (aVal<0) ? -aVal : aVal; 
}

void* _ogg_memset(void* aPtr, int aVal, size_t aNumBytes)
{
	Mem::Fill(aPtr, aNumBytes, aVal);
	return aPtr;
}

void* _ogg_memchr(const void *aBuf, int aChr, size_t aNumBytes)
{
	const TUint8* ptr = (const TUint8*) aBuf;
	TUint8 chr8 = (TUint8) aChr;
	if ((ptr == NULL) || !aNumBytes)
		return NULL;

	for (TUint i = 0 ; i<aNumBytes ; i++, ptr++)
	{
		if (*ptr == chr8)
			return (void *) ptr;
	}

	return NULL;
}

size_t _ogg_read(void* aBufPtr, size_t aReadSize, void* aFilePtr)
{
	RFile* file = (RFile *) aFilePtr;

	TPtr8 buf((TUint8 *) aBufPtr, 0, aReadSize);
	TInt err = file->Read(buf, aReadSize);

	return (err == KErrNone) ? buf.Length() : err;
}

int _ogg_seek(void* filePtr, long aOffset, int aSeekOrigin)
{
	RFile* file = (RFile *) filePtr;
	TInt offset = aOffset;

	switch (aSeekOrigin)
	{
		case SEEK_SET:
			return file->Seek(ESeekStart, offset);

		case SEEK_CUR:
			return file->Seek(ESeekCurrent, offset);

		case SEEK_END:
			return file->Seek(ESeekEnd, offset);

		default:
			return -1;
	}

}

int _ogg_tell(void* filePtr)
{
	RFile* file = (RFile *) filePtr;
	TInt pos = 0;

	TInt err = file->Seek(ESeekCurrent, pos);
	return (err == KErrNone) ? pos : -1;
}

int _ogg_close(void* filePtr)
{
	RFile* file = (RFile *) filePtr;
	
	file->Close();
	return 0;
}

void* _ogg_malloc(size_t aNumBytes)
{
	return User::Alloc(aNumBytes);
}

void* _ogg_calloc(size_t aNumItems, size_t aItemSize)
{
	TInt numBytes = aNumItems*aItemSize;
	void *ptr = User::Alloc(numBytes);
	if (ptr)
		Mem::FillZ(ptr, numBytes);

	return ptr;
}

void* _ogg_realloc(void* aPtr, size_t aNumBytes)
{
	return User::ReAlloc(aPtr, aNumBytes);
}

void _ogg_free(void* aPtr)
{
	User::Free(aPtr);
}
} // Extern "C"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -