235 lines
9.1 KiB
C
235 lines
9.1 KiB
C
|
/*
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_START@
|
||
|
*
|
||
|
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original Code
|
||
|
* as defined in and that are subject to the Apple Public Source License
|
||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||
|
* compliance with the License. Please obtain a copy of the License at
|
||
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||
|
* file.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||
|
* Please see the License for the specific language governing rights and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_END@
|
||
|
*
|
||
|
*/
|
||
|
/*
|
||
|
File: osfilesource.h
|
||
|
|
||
|
Contains: simple file abstraction. This file abstraction is ONLY to be
|
||
|
used for files intended for serving
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
#ifndef __OSFILE_H_
|
||
|
#define __OSFILE_H_
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#include "OSHeaders.h"
|
||
|
#include "StrPtrLen.h"
|
||
|
#include "OSQueue.h"
|
||
|
|
||
|
#define READ_LOG 0
|
||
|
|
||
|
class FileBlockBuffer
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
FileBlockBuffer(): fArrayIndex(-1),fBufferSize(0),fBufferFillSize(0),fDataBuffer(NULL),fDummy(0){}
|
||
|
~FileBlockBuffer(void);
|
||
|
void AllocateBuffer(UInt32 buffSize);
|
||
|
void TestBuffer(void);
|
||
|
void CleanBuffer() { ::memset(fDataBuffer,0, fBufferSize); }
|
||
|
void SetFillSize(UInt32 fillSize) {fBufferFillSize = fillSize;}
|
||
|
UInt32 GetFillSize(void) { return fBufferFillSize;}
|
||
|
OSQueueElem *GetQElem() { return &fQElem; }
|
||
|
SInt64 fArrayIndex;
|
||
|
UInt32 fBufferSize;
|
||
|
UInt32 fBufferFillSize;
|
||
|
char *fDataBuffer;
|
||
|
OSQueueElem fQElem;
|
||
|
UInt32 fDummy;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
class FileBlockPool
|
||
|
{
|
||
|
enum {
|
||
|
kDataBufferUnitSizeExp = 15,// base 2 exponent
|
||
|
kBufferUnitSize = (1 << kDataBufferUnitSizeExp ) // 32Kbytes
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
FileBlockPool(void) : fMaxBuffers(1), fNumCurrentBuffers(0), fBufferUnitSizeBytes(kBufferUnitSize){}
|
||
|
~FileBlockPool(void);
|
||
|
|
||
|
void SetMaxBuffers(UInt32 maxBuffers) { if (maxBuffers > 0) fMaxBuffers = maxBuffers; }
|
||
|
|
||
|
void SetBuffIncValue(UInt32 bufferInc) { if (bufferInc > 0) fBufferInc = bufferInc;}
|
||
|
void IncMaxBuffers(void) { fMaxBuffers += fBufferInc; }
|
||
|
void DecMaxBuffers(void) { if (fMaxBuffers > fBufferInc) fMaxBuffers-= fBufferInc; }
|
||
|
void DecCurBuffers(void) { if (fNumCurrentBuffers > 0) fNumCurrentBuffers--; }
|
||
|
|
||
|
void SetBufferUnitSize (UInt32 inUnitSizeInK) { fBufferUnitSizeBytes = inUnitSizeInK * 1024; }
|
||
|
UInt32 GetBufferUnitSizeBytes() { return fBufferUnitSizeBytes; }
|
||
|
UInt32 GetMaxBuffers(void) { return fMaxBuffers; }
|
||
|
UInt32 GetIncBuffers() { return fBufferInc; }
|
||
|
UInt32 GetNumCurrentBuffers(void) { return fNumCurrentBuffers; }
|
||
|
void DeleteBlockPool();
|
||
|
FileBlockBuffer* GetBufferElement(UInt32 bufferSizeBytes);
|
||
|
void MarkUsed(FileBlockBuffer* inBuffPtr);
|
||
|
|
||
|
private:
|
||
|
OSQueue fQueue;
|
||
|
UInt32 fMaxBuffers;
|
||
|
UInt32 fNumCurrentBuffers;
|
||
|
UInt32 fBufferInc;
|
||
|
UInt32 fBufferUnitSizeBytes;
|
||
|
UInt32 fBufferDataSizeBytes;
|
||
|
|
||
|
};
|
||
|
|
||
|
class FileMap
|
||
|
{
|
||
|
|
||
|
public:
|
||
|
FileMap(void):fFileMapArray(NULL),fDataBufferSize(0),fMapArraySize(0),fNumBuffSizeUnits(0) {}
|
||
|
~FileMap(void) {fFileMapArray = NULL;}
|
||
|
void AllocateBufferMap(UInt32 inUnitSizeInK, UInt32 inNumBuffSizeUnits, UInt32 inBufferIncCount, UInt32 inMaxBitRateBuffSizeInBlocks, UInt64 fileLen, UInt32 inBitRate);
|
||
|
char* GetBuffer(SInt64 bufIndex, Bool16 *outIsEmptyBuff);
|
||
|
void TestBuffer(SInt32 bufIndex) {Assert (bufIndex >= 0); fFileMapArray[bufIndex]->TestBuffer();};
|
||
|
void SetIndexBuffFillSize(SInt32 bufIndex, UInt32 fillSize) { Assert (bufIndex >= 0); fFileMapArray[bufIndex]->SetFillSize(fillSize);}
|
||
|
UInt32 GetMaxBufSize(void) {return fDataBufferSize;}
|
||
|
UInt32 GetBuffSize(SInt64 bufIndex) { Assert (bufIndex >= 0); return fFileMapArray[bufIndex]->GetFillSize(); }
|
||
|
UInt32 GetIncBuffers(void) { return fBlockPool.GetIncBuffers(); }
|
||
|
void IncMaxBuffers() {fBlockPool.IncMaxBuffers(); }
|
||
|
void DecMaxBuffers() {fBlockPool.DecMaxBuffers(); }
|
||
|
Bool16 Initialized() { return fFileMapArray == NULL ? false : true; }
|
||
|
void Clean(void);
|
||
|
void DeleteMap(void);
|
||
|
void DeleteOldBuffs(void);
|
||
|
SInt64 GetBuffIndex(UInt64 inPosition) { return inPosition / this->GetMaxBufSize(); }
|
||
|
SInt64 GetMaxBuffIndex() { Assert(fMapArraySize > 0); return fMapArraySize -1; }
|
||
|
UInt64 GetBuffOffset(SInt64 bufIndex) { return (UInt64) (bufIndex * this->GetMaxBufSize() ); }
|
||
|
FileBlockPool fBlockPool;
|
||
|
|
||
|
FileBlockBuffer** fFileMapArray;
|
||
|
|
||
|
private:
|
||
|
|
||
|
UInt32 fDataBufferSize;
|
||
|
SInt64 fMapArraySize;
|
||
|
UInt32 fNumBuffSizeUnits;
|
||
|
|
||
|
};
|
||
|
|
||
|
class OSFileSource
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
OSFileSource() : fFile(-1), fLength(0), fPosition(0), fReadPos(0), fShouldClose(true), fIsDir(false), fCacheEnabled(false)
|
||
|
{
|
||
|
|
||
|
#if READ_LOG
|
||
|
fFileLog = NULL;
|
||
|
fTrackID = 0;
|
||
|
fFilePath[0]=0;
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
OSFileSource(const char *inPath) : fFile(-1), fLength(0), fPosition(0), fReadPos(0), fShouldClose(true), fIsDir(false),fCacheEnabled(false)
|
||
|
{
|
||
|
Set(inPath);
|
||
|
|
||
|
#if READ_LOG
|
||
|
fFileLog = NULL;
|
||
|
fTrackID = 0;
|
||
|
fFilePath[0]=0;
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
~OSFileSource() { Close(); fFileMap.DeleteMap();}
|
||
|
|
||
|
//Sets this object to reference this file
|
||
|
void Set(const char *inPath);
|
||
|
|
||
|
// Call this if you don't want Close or the destructor to close the fd
|
||
|
void DontCloseFD() { fShouldClose = false; }
|
||
|
|
||
|
//Advise: this advises the OS that we are going to be reading soon from the
|
||
|
//following position in the file
|
||
|
void Advise(UInt64 advisePos, UInt32 adviseAmt);
|
||
|
|
||
|
OS_Error Read(void* inBuffer, UInt32 inLength, UInt32* outRcvLen = NULL)
|
||
|
{ return ReadFromDisk(inBuffer, inLength, outRcvLen);
|
||
|
}
|
||
|
|
||
|
OS_Error Read(UInt64 inPosition, void* inBuffer, UInt32 inLength, UInt32* outRcvLen = NULL);
|
||
|
OS_Error ReadFromDisk(void* inBuffer, UInt32 inLength, UInt32* outRcvLen = NULL);
|
||
|
OS_Error ReadFromCache(UInt64 inPosition, void* inBuffer, UInt32 inLength, UInt32* outRcvLen = NULL);
|
||
|
OS_Error ReadFromPos(UInt64 inPosition, void* inBuffer, UInt32 inLength, UInt32* outRcvLen = NULL);
|
||
|
void EnableFileCache(Bool16 enabled) {OSMutexLocker locker(&fMutex); fCacheEnabled = enabled; }
|
||
|
Bool16 GetCacheEnabled() { return fCacheEnabled; }
|
||
|
void AllocateFileCache(UInt32 inUnitSizeInK = 32, UInt32 bufferSizeUnits = 0, UInt32 incBuffers = 1, UInt32 inMaxBitRateBuffSizeInBlocks = 8, UInt32 inBitRate = 32768)
|
||
|
{ fFileMap.AllocateBufferMap(inUnitSizeInK, bufferSizeUnits,incBuffers, inMaxBitRateBuffSizeInBlocks, fLength, inBitRate);
|
||
|
}
|
||
|
void IncMaxBuffers() {OSMutexLocker locker(&fMutex); fFileMap.IncMaxBuffers(); }
|
||
|
void DecMaxBuffers() {OSMutexLocker locker(&fMutex); fFileMap.DecMaxBuffers(); }
|
||
|
|
||
|
OS_Error FillBuffer(char* ioBuffer, char *buffStart, SInt32 bufIndex);
|
||
|
|
||
|
void Close();
|
||
|
time_t GetModDate() { return fModDate; }
|
||
|
UInt64 GetLength() { return fLength; }
|
||
|
UInt64 GetCurOffset() { return fPosition; }
|
||
|
void Seek(SInt64 newPosition) { fPosition = newPosition; }
|
||
|
Bool16 IsValid() { return fFile != -1; }
|
||
|
Bool16 IsDir() { return fIsDir; }
|
||
|
|
||
|
// For async I/O purposes
|
||
|
int GetFD() { return fFile; }
|
||
|
void SetTrackID(UInt32 trackID);
|
||
|
// So that close won't do anything
|
||
|
void ResetFD() { fFile=-1; }
|
||
|
|
||
|
void SetLog(const char *inPath);
|
||
|
|
||
|
private:
|
||
|
|
||
|
int fFile;
|
||
|
UInt64 fLength;
|
||
|
UInt64 fPosition;
|
||
|
UInt64 fReadPos;
|
||
|
Bool16 fShouldClose;
|
||
|
Bool16 fIsDir;
|
||
|
time_t fModDate;
|
||
|
|
||
|
|
||
|
OSMutex fMutex;
|
||
|
FileMap fFileMap;
|
||
|
Bool16 fCacheEnabled;
|
||
|
#if READ_LOG
|
||
|
FILE* fFileLog;
|
||
|
char fFilePath[1024];
|
||
|
UInt32 fTrackID;
|
||
|
#endif
|
||
|
|
||
|
};
|
||
|
|
||
|
#endif //__OSFILE_H_
|