Darwin-Streaming-Server/CommonUtilitiesLib/OSFileSource.h
Darren VanBuren 849723c9cf Add even more of the source
This should be about everything needed to build so far?
2017-03-07 17:14:16 -08:00

234 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_