Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@ -0,0 +1,410 @@
#include "circlebuffer.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* memory copy */
#include "duck_mem.h"
/* this is just a debugging trick so that we can "see" the free space */
void* circleread_memcpy(void* dst, void* src, int64_t count);
void* circleread_memcpy(void* dst, void* src, int64_t count)
{
return duck_memcpy64(dst, src, count);
}
void CircleReport(const CircleBuffer_t* cb, const char* title)
{
printf("-----(%s)------\n", title);
printf("max Size cb = %ld\n", cb->bufSize);
printf("fills at = %ld\n", cb->bufSize * cb->percent / 100 );
printf("Current amount = %ld, level = %ld\n", cb->count, cb->count * 100 / cb->bufSize);
}
int ForwardBuffer(CircleBuffer_t* cb, int64_t len)
{
if (len >= (int64_t)cb->count)
return -1;
if ( (cb->head + len) < cb->bufSize )
cb->head += (int)len;
else
cb->head = (int)len - (cb->bufSize - cb->head);
cb->count -= (int)len;
return 0;
}
int RewindBuffer(CircleBuffer_t* cb, int64_t len)
{
if (len >= (int64_t)(cb->bufSize - cb->count) )
return -1; /* not enough history in buffer ! */
if (cb->head <= (size_t)len)
{
if (cb->wrapped == 0)
return -1;
cb->head = cb->bufSize - ((int)len - cb->head);
cb->count += (int)len;
return 0;
}
else
{
cb->head -= (int)len;
cb->count += (int)len;
}
return 0;
}
void destroyCircleBuffer(CircleBuffer_t* cb)
{
assert(cb);
if (cb->buffer)
free(cb->buffer);
if (cb->maxChunk)
free(cb->maxChunk);
}
int resetCircleBuffer(CircleBuffer_t* cb)
{
cb->count = 0;
cb->bytesConsumed = 0;
cb->wrapped = 0;
cb->starvedBytes = 0;
cb->starvedRequests = 0;
return 0;
}
int initCircleBuffer(
CircleBuffer_t* cb,
size_t countRecords,
int percent,
size_t maxChunk,
FuncLock_t lock,
FuncLock_t unlock
)
{
assert(cb);
cb->buffer = (unsigned char * ) calloc(1, countRecords);
cb->maxChunk = (unsigned char *) calloc(1, maxChunk);
cb->maxChunkLen = maxChunk;
if (cb->buffer)
{
cb->head = cb->count = 0;
cb->balance = 0;
cb->bufSize = countRecords;
cb->bytesConsumed = 0;
cb->muted = false;
cb->percent = percent;
cb->wrapped = 0;
cb->lock = lock;
cb->unlock = unlock;
return 0;
}
else
{
return -1; /* error */
}
}
/* return zero if plenty of room and success */
/*-------------------------------------------*/
/* free space nested in the middle of the buffer is consider endSpace */
/* and when free space nested in middle, startSpace is considered to be zero */
/*---------------------------------------------------------------------------*/
int addToCircleBuffer(CircleBuffer_t* cb, void* data, size_t requestSpace)
{
int64_t freeSpace; /* count total free space in buffer */
int64_t head = cb->head; /* offset start of valid data */
int64_t tail = (cb->head + cb->count) % cb->bufSize; /* offest first free byte after valid data */
int64_t endSpace;
freeSpace = cb->bufSize - cb->count;
/* if not enough room to do the add */
/*----------------------------------*/
if (requestSpace > freeSpace)
{
assert(0);
return CB_FULL;
}
endSpace = cb->bufSize - tail;
if (tail >= head && requestSpace > endSpace) /* additional data write will wrap */
{
duck_memcpy64(&cb->buffer[tail], data, endSpace);
duck_memcpy64(
cb->buffer,
(unsigned char *)data+endSpace,
requestSpace - endSpace);
}
else /* existing data wrapped around from end of buffer through beginning of buffer. */
{
memcpy(&cb->buffer[tail], data, requestSpace);
}
cb->count += requestSpace;
cb->balance += 1;
return 0; /* -1 will mean error,m zero is OK */
}
/* get info need so we can write direct as in memcpy into the circle buffer */
/*--------------------------------------------------------------------------*/
void FreeWrapless(const CircleBuffer_t* cb, void* handle, int64_t* sizeWrapless)
{
int64_t tail = (cb->head + cb->count) % cb->bufSize;
if ((cb->head + cb->count) < cb->bufSize)
{
*((void **) handle) = &cb->buffer[tail];
*sizeWrapless = (cb->bufSize -(cb->head + cb->count));
}
else
{
*((void **) handle) = &cb->buffer[tail];
*sizeWrapless = (cb->bufSize - cb->count);
}
}
/* Please clone this sucker from readFromCircleBuffer */
int accessCircleBuffer(CircleBuffer_t* cb, void* handle1, size_t requestSize)
{
int64_t head = cb->head;
int64_t tail = (cb->head + cb->count) % cb->bufSize;
void** handle = (void **) handle1;
void* dest = *handle;
if (requestSize <= 0)
{
return requestSize;
}
if (cb->count < requestSize)
{
return -1;
}
if (tail > head) /* the data does not wrap ! */
{
*handle = &cb->buffer[head];
}
else /* the current data does wrap */
{
/* but our read does not wrap */
if (head + requestSize < cb->bufSize)
{
*handle = &cb->buffer[head];
}
else if (head + requestSize == cb->bufSize)
{
*handle = &cb->buffer[head];
}
else /* our read will wrap ! */
{
int64_t temp = cb->bufSize - head;
dest = cb->maxChunk;
assert(cb->maxChunkLen >= requestSize);
circleread_memcpy(
dest,
&cb->buffer[head],
temp);
circleread_memcpy(
((unsigned char *) dest) + temp,
cb->buffer,
requestSize - temp);
*handle = dest;
}
}
cb->head = (cb->head + requestSize) % cb->bufSize;
cb->count -= requestSize;
cb->bytesConsumed += requestSize;
cb->balance -= 1;
return requestSize; /* records (16 bit or maybe other in future) */
}
/* return count read , or -1 if not enough data */
/*----------------------------------------------*/
int readFromCircleBuffer(CircleBuffer_t* cb, void* dest, size_t requestSize)
{
int64_t head = cb->head;
int64_t tail = (cb->head + cb->count) % cb->bufSize;
if (cb->count < requestSize)
{
requestSize = cb->count; /* Give them what we have */
}
if (requestSize <= 0)
{
return (int)requestSize;
}
if (tail > head) /* the data does not wrap ! */
{
circleread_memcpy(dest, &cb->buffer[head], requestSize);
}
else /* the current data does wrap */
{
/* but our read does not wrap */
if (head + requestSize < cb->bufSize)
{
circleread_memcpy(dest, &cb->buffer[head], requestSize);
}
else if (head + requestSize == cb->bufSize)
{
circleread_memcpy(dest, &cb->buffer[head], requestSize);
memset(&cb->buffer[head], 0, (size_t)requestSize); /* optional, debug */
}
else /* our read will wrap ! */
{
int64_t temp = cb->bufSize - head;
circleread_memcpy(
dest,
&cb->buffer[head],
temp);
circleread_memcpy(
((unsigned char *) dest) + temp,
cb->buffer,
requestSize - temp);
}
}
cb->head = (cb->head + requestSize) % cb->bufSize;
cb->count -= requestSize;
cb->bytesConsumed += requestSize;
cb->balance -= 1;
return (int)requestSize; /* records (16 bit or maybe other in future) */
}
void testCircleBuffer()
{
CircleBuffer_t temp;
size_t bufSize = 256;
const size_t maxInput = 256*3;
size_t count = 0;
size_t t;
int i;
const int maxRandom = 32;
size_t chunkOut = 30;
CircleRecord_t data[256*3];
initCircleBuffer(&temp, bufSize, 75, 256, 0, 0);
/* who cares ... take the default seed value. */
while (count < maxInput || temp.count > chunkOut)
{
t = rand();
/* for whatever reason this seems to be a 16 bit random number */
t = t / ( 2 << (16 - 7) ) ;
for(i = 0; i < (int)t; i++)
{
data[i] = (unsigned char ) ( count + i );
}
if (
((temp.bufSize - temp.count) >= t*sizeof(short)+1) &&
(count < (maxInput - maxRandom))
) /* add 1 to keep buffer being completely filled */
{
int64_t tail = (temp.head + temp.count) % temp.bufSize;
addToCircleBuffer(&temp, data, t);
printf("Add to buffer count = %ld. head = %ld, tail = %ld\n", t, temp.head, tail);
count += t;
}
else /* not enough space in buffer, try to empty some out */
{
int r;
r = readFromCircleBuffer(&temp, data, chunkOut);
if (r >= 0)
{
int64_t tail = (temp.head + temp.count) % temp.bufSize;
for(i = 0; i < r; i++)
printf("%ld ", data[i]);
printf("\nRead from buffer. head = %ld, tail = %ld\n", temp.head, tail);
}
}
} /* while we have not accumulated a large eough test ... */
}
int CirclePercent(CircleBuffer_t* cb)
{
return (int)(cb->count * 100 / cb->bufSize);
}
int CircleAtLevel(CircleBuffer_t* cb)
{
return (int)(cb->count * 100 / cb->bufSize) >= cb->percent;
}
int CircleOverLevel(CircleBuffer_t* cb)
{
return (int)(cb->count * 100 / cb->bufSize) > cb->percent;
}

View File

@ -0,0 +1,99 @@
#if !defined(_circlebuffer_h)
#define _circlebuffer_h
#include <stdlib.h>
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(_WIN32)
typedef __int64 int64_t;
#elif defined(__POWERPC) || defined(__APPLE)
#include <ppc/types.h>
#else
typedef long long int64_t;
#endif
#if !defined(_WIN32)
#pragma bool on
#endif
typedef unsigned char CircleRecord_t;
typedef void (*FuncLock_t)() ;
/* assume that assert, alerts, messages to go off before this ever is allowed to fill */
/*------------------------------------------------------------------------------------*/
typedef struct CircleBuf_tt
{
size_t head; /* points to start of usable data in buffer */
size_t count;
size_t bufSize;
int64_t bytesConsumed;
size_t recordSize;
size_t userData; /* might store actual recordsize */
int balance;
CircleRecord_t* buffer; /* 10 seconds of 16 bit stereo nice quality */
unsigned char* maxChunk;
size_t maxChunkLen;
int percent; /* level where buffer considered stable */
int wrapped; /* non-zero if data has wrapped at least once */
int muted;
FuncLock_t lock; /* in case there could be competition for any members */
FuncLock_t unlock; /* in case there could be competition for any members */
int starvedBytes; /* how many bytes we had to "conjure up" because we were empty (debug) */
int starvedRequests; /* how many request we honored when we have been in a starved state (debug) */
} CircleBuffer_t;
void testCircleBuffer(void);
void destroyCircleBuffer(CircleBuffer_t* cb);
int initCircleBuffer(CircleBuffer_t* cb, size_t size, int percent, size_t maxChunk, FuncLock_t lock, FuncLock_t unlock);
int addToCircleBuffer(CircleBuffer_t* cb, void* data, size_t count);
int readFromCircleBuffer(CircleBuffer_t* cb, void* dest, size_t count);
int accessCircleBuffer(CircleBuffer_t* cb, void* dest, size_t count);
void FreeWrapless(const CircleBuffer_t* cb, void* handle, size_t* sizeWrapless);
int resetCircleBuffer(CircleBuffer_t* cb);
int RewindBuffer(CircleBuffer_t* cb, int64_t len);
int ForwardBuffer(CircleBuffer_t* cb, int64_t len);
void CircleReport(const CircleBuffer_t* cb, const char* title);
int CirclePercent(CircleBuffer_t* cb);
int CircleAtLevel(CircleBuffer_t* cb);
int CircleOverLevel(CircleBuffer_t* cb);
typedef enum {
CB_NOERR = 0, /* OK */
CB_FULL = -1, /* Buffer overflow */
CB_MAX_LEVEL = -2, /* Buffer is over target full level (percent) */
CB_MIN_LEVEL = -3, /* Buffer is under target min level (percent) */
CB_EMPTY = -4 /* Buffer is empty */
} CB_Err_t;
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,130 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "duck_io.h"
#include "duck_io_http.h"
#include "duck_io_file.h"
#include "duck_hfb.h"
#include <assert.h>
#define MAKE_FOUR_CC(b1, b2, b3, b4 ) \
((b4 << 24) | (b3 << 16) | (b2 << 8) | (b1 << 0))
int duck_readFinished(int han, int flag)
{
(void)han;
(void)flag;
return 1;
}
bool g_isHttp = false;
int duck_open(const char *name, unsigned long userData)
{
if (strstr(name, "http://"))
return duck_open_http(name, userData);
else
return duck_open_file(name, userData);
}
void duck_close(int handle)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
duck_close_http(handle);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
duck_close_file(handle);
else
assert(0);
}
int duck_read(int handle,unsigned char *buffer,int bytes)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_read_http(handle, buffer, bytes);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_read_file(handle, buffer, bytes);
else
{
assert(0);
return -1;
}
}
int duck_read_blocking(int handle,unsigned char *buffer,int bytes)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_read_blocking_http(handle, buffer, bytes);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_read_file(handle, buffer, bytes);
else
{
assert(0);
return -1;
}
}
int64_t duck_seek(int handle,int64_t offset,int origin)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_seek_http(handle, offset, origin);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_seek_file(handle, offset, origin);
else
{
assert(0);
return -1;
}
}
int duck_name(int handle, char name[], size_t maxLen)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_name_http(handle, name, maxLen);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_name_file(handle, name, maxLen);
else
{
assert(0);
return -1;
}
}
int64_t duck_available_data(int handle)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_available_data_http(handle);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_available_data_file(handle);
else
{
assert(0);
return -1;
}
}

View File

@ -0,0 +1,224 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#if defined(_WIN32)
#include <io.h>
#endif
#include "duck_io_file.h"
#include "duck_hfb.h"
#include "duck_io.h"
#include "duck_mem.h"
#include <assert.h>
#if defined (__cplusplus)
extern "C" {
#endif
#if defined (__cplusplus)
}
#endif
//int read_count;
#define MAKE_FOUR_CC(b1, b2, b3, b4 ) \
((b4 << 24) | (b3 << 16) | (b2 << 8) | (b1 << 0))
typedef struct
{
unsigned long scheme; /* contains FILE */
#if defined(_WIN32)
int fileDescriptor; /* used to be the handle */
#else
FILE* fileDescriptor; /* used to be the handle */
#endif
char fname[512];
int64_t fileLength;
char errorString[256];
SAL_ERR lastErrorCode;
} FileScheme_t;
/* Add the decoration to avoid name collisions in the case where we want to include */
/* a forking version of duck_io that calls duck_io_file or duck_io_http */
/* The user of this service should not need to compile and link all three files */
/* duck_io (abstract forker) duck_io_file and duck_io_http. */
#define DECORATE(x) x##_file
/* Sets an error code and message */
static int SetError(int handle, SAL_ERR code, const char* appendMsg)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
const char* decode = SalErrText(code);
if (decode)
{
strcpy(fileObj->errorString, decode);
fileObj->lastErrorCode = code;
if (appendMsg)
{
strcat(fileObj->errorString, " : ");
strcat(fileObj->errorString, appendMsg);
}
return code;
}
return SAL_ERROR; // DEFAULT ERROR
}
int DECORATE(duck_open)(const char *name, unsigned long userData)
{
FileScheme_t* const fileObj = (FileScheme_t *) duck_calloc(1,sizeof(FileScheme_t), DMEM_GENERAL);
const ReOpen_t* const openData = (ReOpen_t*) userData;
fileObj->scheme = MAKE_FOUR_CC('f','i','l','e');
assert(name);
assert(strlen(name) < sizeof(fileObj->fname));
strcpy(fileObj->fname,name);
#if defined(_WIN32)
fileObj->fileDescriptor = _open(name, _O_RDONLY | _O_BINARY);
if(fileObj->fileDescriptor == -1)
return SetError((int)fileObj, SAL_ERR_FILE_OPEN_FAILED, 0);
#else
fileObj->fileDescriptor = fopen(name, "rb");
if(fileObj->fileDescriptor == 0)
return SetError((int)fileObj, SAL_ERR_FILE_OPEN_FAILED, 0);;
#endif
fileObj->fileLength = duck_seek((int) fileObj, 0, SEEK_END);
duck_seek((int) fileObj, 0, SEEK_SET);
if(openData)
duck_seek_file((int) fileObj, openData->offset, SEEK_SET);
return (int)fileObj;
}
void DECORATE(duck_close)(int handle)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
#if defined(_WIN32)
_close(fileObj->fileDescriptor);
#else
fclose(fileObj->fileDescriptor);
#endif
if (fileObj)
{
duck_free(fileObj);
fileObj = 0;
}
}
int DECORATE(duck_read_blocking)(int handle,unsigned char *buffer,int bytes)
{
return DECORATE(duck_read)(handle, buffer, bytes);
}
int DECORATE(duck_read)(int handle,unsigned char *buffer,int bytes)
{
int x;
FileScheme_t* fileObj = (FileScheme_t *) handle;
if (buffer == NULL){
duck_seek_file((int ) fileObj->fileDescriptor,bytes,SEEK_CUR);
return bytes;
}
if (bytes == 0)
return 0;
#if defined(_WIN32)
x = _read(fileObj->fileDescriptor, buffer, (unsigned int) bytes);
if (x == -1L)
{
assert(0);
}
#else
x = fread(buffer, sizeof(char) , (size_t) bytes, fileObj->fileDescriptor);
if (x < bytes)
{
assert(x == bytes);
}
#endif
return x ;
}
int64_t DECORATE(duck_seek)(int handle, int64_t offset, int origin)
{
#if defined(_WIN32)
int64_t tellNo = 0;
FileScheme_t* fileObj = (FileScheme_t *) handle;
_lseeki64(fileObj->fileDescriptor,offset,origin);
tellNo = _telli64(fileObj->fileDescriptor);
return tellNo ;
#else
int64_t tellNo = 0;
FileScheme_t* fileObj = 0;
assert(sizeof(off_t) == sizeof(int64_t));
fileObj = (FileScheme_t *) handle;
fseeko(fileObj->fileDescriptor,(off_t) offset,origin);
tellNo = (int64_t) ftello(fileObj->fileDescriptor);
return tellNo ;
#endif
}
int DECORATE(duck_name)(int handle, char fname[], size_t maxLen)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
if (strlen(fileObj->fname) < maxLen)
strcpy(fname, fileObj->fname);
else
return -1;
return 0;
}
int64_t DECORATE(duck_available_data)(int handle)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
#if defined(_WIN32)
return fileObj->fileLength - _telli64(fileObj->fileDescriptor);
#else
return fileObj->fileLength - (int64_t) ftello(fileObj->fileDescriptor);
#endif
}

View File

@ -0,0 +1,902 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#ifdef _WIN32
#pragma warning(push,3)
#endif
#include "duck_io_http.h"
#include "duck_mem.h"
#include "on2_timer.h"
#include "circlebuffer.h"
#include "duck_io.h"
#include <errno.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
extern "C" {
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
}
#endif
#include <sstream>
#include <limits.h>
#define DEFAULT_CBSIZE 512 * 1024
#define DECORATE(x) x##_http
int duck_sal_fill(void * handle, bool blocking, size_t maxFill);
//#include "debug.h" // This can be removed
#ifdef _WIN32
#pragma warning(pop)
#pragma warning(disable:4706) /* assignment in conditional expression */
#pragma warning(disable:4514) /* matt made me do it */
const char i64Fmt[] = "%I64d";
#else
const char i64Fmt[] = "%lld";
int WSAGetLastError()
{
return -1;
}
#endif
#define MAKE_FOUR_CC(b1, b2, b3, b4 ) \
((b4 << 24) | (b3 << 16) | (b2 << 8) | (b1 << 0))
typedef struct _DuckHttp_temp
{
unsigned long scheme;
std::string url;
std::string urlExtended;
#if defined(_WIN32)
SOCKET socket;
#else
int socket;
#endif
SAL_ERR lastErrorCode;
std::ostringstream errorString;
/* milliseconds to wait before disconnecting from server */
unsigned int timeOut;
/* Assuming 2k is the max size of an http header */
char httpHeader[2 * 1024];
int64_t contentLen; // Size of the movie
int headerSize; // Size of the http header
int xtraData; // Amout of movie data recv'd from the http header recv
int64_t totalRead; // Position in file
CircleBuffer_t cBuffer;
int cbSize; // Circular buffer size
} DuckHttp_t;
/* Returns size of movie as parsed from the http header */
int64_t duck_content_len(void* handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
if (httpObj == 0)
return -1;
return httpObj->contentLen;
}
void* duck_get_buffer(void *handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return (void *) &httpObj->cBuffer;
}
/* Checks to see if any errors occured in recv */
int isDataAvailable(int bytesReceived)
{
(void ) bytesReceived; // for warning supression
#ifdef WIN32
if (WSAGetLastError() == 10035) // No data is available right now, try again later
return 0;
#else
int x = errno;
if(x == EAGAIN)
{
return 0;
}
else if (x == 0)
{
assert(bytesReceived != -1);
return 1;
}
else
{
assert(0);
}
#endif
return 1;
}
/* Sets an error code and message */
static int SetError(DuckHttp_t* httpObj, SAL_ERR code, const char* appendMsg)
{
const char* decode = SalErrText(code);
if (decode)
{
httpObj->errorString.str("");
httpObj->errorString << decode;
httpObj->lastErrorCode = code;
if (appendMsg)
httpObj->errorString << " : " << appendMsg;
return code;
}
return SAL_ERROR; // Default error
}
static int64_t http_atoi(const char* str)
{
int64_t temp = 0;
size_t len = 0;
while(str[len] >= '0' && str[len] <= '9')
len++;
for(size_t i = 0; i < len; i++)
temp = temp * 10 + (str[i] - '0');
return temp;
}
/* Parses url for a parameter */
inline bool get_url_parameter(const std::string url, std::string& parameter)
{
std::string temp = url;
size_t strPos;
strPos = temp.find(parameter.c_str());
if (strPos == std::string::npos)
{
return false;
}
else
{
temp = temp.substr(strPos + parameter.length() + 1);
size_t i = 0;
for(i = 0; i < temp.length(); i++)
{
if (temp[i] == '&')
temp[i] = '\0';
}
parameter = temp.c_str();
return true;
}
}
#if !defined(__cplusplus)
#error
#endif
char* duck_init_http(char *url)
{
std::string strTime = "timeout";
std::string strBuff = "buffer";
DuckHttp_t* httpObj = new (DuckHttp_t);
assert(httpObj);
httpObj->scheme = MAKE_FOUR_CC('h','t','t','p');
httpObj->urlExtended = url;
if (get_url_parameter(url, strTime))
sscanf(strTime.c_str(),"%d", &httpObj->timeOut);
else
httpObj->timeOut = INT_MAX; // Wait "forever" is default
if (get_url_parameter(url, strBuff))
{
sscanf(strBuff.c_str(), "%d", &httpObj->cbSize);
// Convert kilobytes into bytes
httpObj->cbSize *= 1024;
}
else
httpObj->cbSize = DEFAULT_CBSIZE;
for(size_t i = 0; i < strlen(url); i++)
{
if (url[i] == '?')
url[i] = '\0';
}
httpObj->url = url;
httpObj->contentLen = 0;
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData))
{
std::ostringstream temp;
temp << " : " << WSAGetLastError();
SetError(httpObj,SAL_ERR_WSASTARTUP,temp.str().c_str());
return 0;
}
#endif
return (char *) httpObj;
}
/* Might need to reduce timeout after initial buffering */
/*------------------------------------------------------*/
void duck_http_timeout(int handle, unsigned long milliseconds)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
httpObj->timeOut = milliseconds;
}
int DECORATE(duck_open)(const char* src, unsigned long userData)
{
struct sockaddr_in sa_in;
struct sockaddr* const psa = (struct sockaddr*)&sa_in;
struct hostent* host;
std::ostringstream buf1;
unsigned short port = 0;
int input;
char* endOfHttpHeader = "\r\n\r\n";
char* strContentLen = "Content-Length: ";
char* strPos;
on2Timer start;
(void) userData;
unsigned long block = 1;
DuckHttp_t* httpObj;
ReOpen_t* reOpenData = (ReOpen_t*) userData;
if(reOpenData == 0 || reOpenData->blocking || reOpenData->offset == 0)
httpObj = (DuckHttp_t *) duck_init_http((char *) src);
else
httpObj = (DuckHttp_t *) src;
if(!reOpenData) // if we're not doing a re-open
httpObj->totalRead = 0;
else
httpObj->totalRead = reOpenData->offset;
std::stringbuf path;
std::stringbuf server;
std::istringstream is(httpObj->url);
is.ignore(strlen("http://"), '\0');
// Check if a port is specified
for(size_t i = strlen("http://"); i < httpObj->url.length(); i++)
{
if(httpObj->url[i] == ':')
{
port = 1;
break;
} else if(httpObj->url[i] == '/') break;
}
if(port)
{
std::stringbuf strPort;
is.get(server,':');/* get the server */
is.ignore(1, '\0');
is.get(strPort, '/');
port = (unsigned short)http_atoi(strPort.str().c_str());
}
else
{
is.get(server,'/');/* get the server */
port = 80; // default http port
}
assert(server.str().length() > 0);
is.ignore(1, '\0'); /* get the path */
is.get(path, '\0');
/* Wrap up the send message */
buf1 << "GET " << "/" << path.str() << " HTTP/1.1 " << "\r\n";
buf1 << "Host:" << server.str().c_str() << "\r\n" ;
if (reOpenData)
{
char number[64];
sprintf(number, i64Fmt, reOpenData->offset);
buf1 << "Range: bytes=" << number << "-" ;
buf1 << " \r\n" ;
}
buf1 << "\r\n";
if ((httpObj->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "duck_open: SAL_ERR_SOCKET_CREATE\n");
SetError(httpObj,SAL_ERR_SOCKET_CREATE, 0);
duck_exit_http((int)httpObj);
return SAL_ERR_SOCKET_CREATE;
}
sa_in.sin_family = AF_INET;
sa_in.sin_port = htons(port);
if (!(host = gethostbyname(server.str().c_str())))
{
fprintf(stderr, "duck_open: SAL_ERR_RESOLVING_HOSTNAME\n");
SetError(httpObj,SAL_ERR_RESOLVING_HOSTNAME,0);
duck_exit_http((int)httpObj);
return SAL_ERR_RESOLVING_HOSTNAME;
}
duck_memcpy(&sa_in.sin_addr, host->h_addr_list[0], sizeof(struct in_addr));
if (connect(httpObj->socket, psa, sizeof(sa_in) ) != 0)
{
fprintf(stderr, "duck_open: SAL_ERR_SERVER_CONNECTION\n");
SetError(httpObj,SAL_ERR_SERVER_CONNECTION,0);
duck_exit_http((int)httpObj);
return SAL_ERR_SERVER_CONNECTION;
}
/* connected */
if (send(httpObj->socket, buf1.str().c_str(), strlen(buf1.str().c_str()), 0) < 0)
{
fprintf(stderr, "duck_open: SAL_ERR_SENDING_DATA\n");
SetError(httpObj,SAL_ERR_SENDING_DATA,0);
duck_exit_http((int)httpObj);
return SAL_ERR_SENDING_DATA;
}
on2Timer_Init(&start);
on2Timer_Start(&start);
duck_memset(httpObj->httpHeader, 0, sizeof(httpObj->httpHeader));
/* Get the HTTP header EMH 2-14-03 */
/* Assuming we get all the header info in the 1st good recv */
do
{
unsigned long delta = on2Timer_GetCurrentElapsedMilli(&start);
if (delta > httpObj->timeOut)
{
return SetError(httpObj,SAL_ERR_CONNECTION_TIMEOUT,0);
}
input = recv(httpObj->socket, httpObj->httpHeader, sizeof(httpObj->httpHeader), 0);
} while (!strstr(httpObj->httpHeader, endOfHttpHeader));
#ifdef _WIN32
ioctlsocket(httpObj->socket, FIONBIO, &block); /* Set the socket to non-blocking */
#else
if (ioctl(httpObj->socket, FIONBIO, &block)) /* Set the socket to non-blocking */
{
assert(0);
}
#endif
strPos = strstr(httpObj->httpHeader, endOfHttpHeader);
strPos += strlen(endOfHttpHeader);
httpObj->headerSize = (int)strPos - (int)httpObj->httpHeader;
httpObj->xtraData = input - httpObj->headerSize; // Amount of GOOD data grabbed with the HTTP header
if (strstr(httpObj->httpHeader, "404") && strstr(httpObj->httpHeader, "Not Found"))
{
fprintf(stderr, "duck_open: SAL_ERR_404_FILE_NOT_FOUND\n");
SetError(httpObj,SAL_ERR_404_FILE_NOT_FOUND,0);
duck_exit_http((int)httpObj);
return SAL_ERR_404_FILE_NOT_FOUND;
}
strPos = strstr(httpObj->httpHeader, strContentLen);
if (!strPos)
{
fprintf(stderr, "duck_open: SAL_ERR_PARSING_HTTP_HEADER\n");
SetError(httpObj,SAL_ERR_PARSING_HTTP_HEADER,0);
duck_exit_http((int)httpObj);
return SAL_ERR_PARSING_HTTP_HEADER;
}
strPos += strlen(strContentLen);
if((*strPos >= '0') && (*strPos <= '9'))
{
httpObj->contentLen = http_atoi(strPos);
}
else
{
fprintf(stderr, "duck_open: SAL_ERR_PARSING_CONTENT_LEN\n");
SetError(httpObj,SAL_ERR_PARSING_CONTENT_LEN,0);
duck_exit_http((int)httpObj);
return SAL_ERR_PARSING_CONTENT_LEN;
}
int rv;
rv = initCircleBuffer(&httpObj->cBuffer, httpObj->cbSize, 75,
httpObj->cbSize/4, /* max chunk */ 0, 0);
if (rv < 0)
assert(0);
addToCircleBuffer(&httpObj->cBuffer,
httpObj->httpHeader + httpObj->headerSize,
(size_t) httpObj->xtraData);
bool blocking = true;
/*
// Block only if we're not doing a re-open
userData ? blocking = false : blocking = true;
*/
if(reOpenData)
blocking = (reOpenData->blocking != 0);
if (duck_sal_fill((void *) httpObj, blocking, 0) < 0)
{
fprintf(stderr, "duck_open: SAL_ERR_RECEIVING_DATA\n");
duck_close_http((int)httpObj);
return -1;
}
return (int) httpObj;
}
void DECORATE(duck_close)(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
#if defined(_WIN32)
closesocket(httpObj->socket); // Close the old socket
#else
close(httpObj->socket);
#endif
destroyCircleBuffer(&httpObj->cBuffer);
duck_exit_http(handle);
}
void duck_exit_http(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
//delete httpObj->cBuffer;
delete httpObj;
#ifdef _WIN32
WSACleanup();
#endif
}
/* Read data off of the socket directly into the circular buffer */
inline int recv_circular (void* handle, size_t maxBytes)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
int bytesRead = 0;
int totalRead = 0;
size_t tail = (httpObj->cBuffer.head + httpObj->cBuffer.count) % httpObj->cBuffer.bufSize;
size_t head = httpObj->cBuffer.head;
size_t freeSpace = httpObj->cBuffer.bufSize - httpObj->cBuffer.count;
size_t endSpace = httpObj->cBuffer.bufSize - tail;
size_t least;
if (tail >= head && maxBytes > endSpace) /* additional data write will wrap */
{
/* try to fill to end of buffer */
bytesRead = recv(httpObj->socket, (char*)httpObj->cBuffer.buffer + tail, (int)endSpace, 0);
if (bytesRead < 0)
{
if (isDataAvailable((int)bytesRead) == 0)
return 0; // Try again later...
else
return (int)bytesRead; // Error
}
totalRead += bytesRead;
httpObj->cBuffer.count += bytesRead;
maxBytes -= bytesRead;
freeSpace = httpObj->cBuffer.bufSize - httpObj->cBuffer.count;
if((size_t)bytesRead < maxBytes && (size_t)bytesRead == endSpace) /* filled to end and more to read */
{
httpObj->cBuffer.wrapped = 1;
least = (maxBytes < freeSpace) ? maxBytes : freeSpace;
bytesRead = recv(httpObj->socket, (char *)httpObj->cBuffer.buffer, (int)least, 0);
if (bytesRead < 0)
{
if (isDataAvailable((int)bytesRead) == 0)
return 0; // Try again later...
else
return (int)bytesRead; // Error
}
totalRead += bytesRead;
httpObj->cBuffer.count += bytesRead;
}
}
else /* existing data wrapped around from end of buffer through beginning of buffer. */
{
if (tail < head)
httpObj->cBuffer.wrapped = 1;
least = (maxBytes < freeSpace) ? maxBytes : freeSpace;
bytesRead = recv(httpObj->socket, (char*)httpObj->cBuffer.buffer + tail, (int)least, 0);
if (bytesRead < 0)
{
if (isDataAvailable((int)bytesRead) == 0)
return 0; // Try again later...
else
return (int)bytesRead; // Error
}
totalRead += bytesRead;
httpObj->cBuffer.count += bytesRead;
}
return (int)totalRead;
}
/* Re-charge the circular buffer */
int duck_sal_fill(void * handle, bool blocking, size_t maxFill)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
on2Timer start;
int bytesRead = 0;
int totalRead = 0;
int fillLevel = httpObj->cBuffer.bufSize * httpObj->cBuffer.percent / 100;
int fillSpace = fillLevel - httpObj->cBuffer.count;
if(maxFill)
{
// Charge twice as much as was read
maxFill *=2;
// Take the lesser of the two
fillSpace = ((int)maxFill < fillSpace) ? maxFill : fillSpace;
}
on2Timer_Init ( &start );
on2Timer_Start ( &start );
while ((httpObj->cBuffer.count < (size_t)fillLevel) && ((int)httpObj->cBuffer.count < httpObj->contentLen))
{
unsigned long delta = on2Timer_GetCurrentElapsedMilli(&start);
if (delta > httpObj->timeOut)
{
std::ostringstream temp;
temp << "Bytes received = " << totalRead;
//return -1;
return SetError(httpObj, SAL_ERR_CONNECTION_TIMEOUT, temp.str().c_str());
}
bytesRead = recv_circular(handle, fillSpace);
#if defined(__APPLE__) || defined(__POWERPC__)
if (bytesRead == 0 && blocking) /* please give some time to the SOCKET thread / OS . */
usleep(1000*2);
#endif
if (bytesRead < 0)
{
std::ostringstream temp;
temp << " : WSAGetLastError = " << WSAGetLastError();
SetError(httpObj,SAL_ERR_SERVER_CONNECTION,temp.str().c_str());
return bytesRead;
}
totalRead += bytesRead;
if (blocking == 0) /* we only want one recv done */
return totalRead;
}
return totalRead;
}
int DECORATE(duck_read)(int handle,unsigned char *buffer, int bytes)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
int input;
if (bytes < 0)
return -1;
assert(httpObj);
assert(buffer);
input = readFromCircleBuffer(&httpObj->cBuffer, buffer, bytes);
if (input >= 1)
{
httpObj->totalRead += input;
}
bool blocking = false;
if (duck_sal_fill((void *)handle, blocking, bytes) < 0)
{
return -1; // The socket probably disconnected
}
return input;
}
int DECORATE(duck_read_blocking)(int handle,unsigned char *buffer, int bytes)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
int input;
int amountRead = 0;
if (bytes < 0)
return -1;
assert(httpObj);
assert(buffer);
while (amountRead < bytes)
{
input = readFromCircleBuffer(
&httpObj->cBuffer,
buffer + amountRead,
bytes - amountRead);
if (input < 0)
return input;
else
{
amountRead += input;
httpObj->totalRead += input;
}
bool blocking = false;
if (duck_sal_fill((void *)handle, blocking, bytes) < 0)
{
return -1; // The socket probably disconnected
}
}
return amountRead;
}
int64_t DECORATE(duck_seek)(int handle, int64_t offset,int origin)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
//printf("seeking to offset = %ld, origin = %ld\n", offset, origin);
if (offset < 0)
{
fprintf(stderr, "Trying to seek backwards with offset = %d\n", offset);
assert(0);
}
if (origin == SEEK_END)
{
fprintf(stderr, "SEEK_END is not supported\n", offset);
assert(0);
}
if (origin == SEEK_SET)
{
if ( offset > httpObj->totalRead &&
ForwardBuffer(&httpObj->cBuffer, (offset - httpObj->totalRead)) == 0
) /* forward small jump */
{
// We've eaten away at the buffer so re-charge it.
duck_sal_fill((void *)handle, false, (int)(offset - httpObj->totalRead));
httpObj->totalRead = offset;
return httpObj->totalRead;
}
else if ( offset < httpObj->totalRead &&
RewindBuffer(&httpObj->cBuffer, (httpObj->totalRead - offset)) == 0
) /* backwards small jump */
{
httpObj->totalRead = offset;
return httpObj->totalRead;
}
else
httpObj->totalRead = offset;
}
if (origin == SEEK_CUR)
{
if (!offset) // They just want the current pos
return httpObj->totalRead;
httpObj->totalRead += offset;
if(ForwardBuffer(&httpObj->cBuffer, offset) == 0)
{
duck_sal_fill((void *)handle, false, (size_t)offset); // We've eaten away at the buffer so re-charge it.
return httpObj->totalRead;
}
}
#if defined(_WIN32)
closesocket(httpObj->socket); // Close the old socket
#else
close(httpObj->socket);
#endif
destroyCircleBuffer(&httpObj->cBuffer);
ReOpen_t openData;
openData.offset = httpObj->totalRead;
openData.blocking = 0;
// Reconnect to http server
if( duck_open_http((char* )handle, (unsigned long)&openData) < 0)
{
char err[256];
SAL_ERR errCode;
duck_sal_error_http((void*)handle, &errCode, err, sizeof(err));
assert(0);
return -1;
}
return httpObj->totalRead;
}
int64_t duck_tell(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return httpObj->totalRead;
}
/* Return the amount of data in the circular buffer */
int duck_sal_buff_percent(void* handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return 100 * httpObj->cBuffer.count / httpObj->cBuffer.bufSize;
}
int64_t DECORATE(duck_available_data)(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return httpObj->cBuffer.count;
}
/* Checks the last error */
int DECORATE(duck_sal_error)(void* handle, SAL_ERR* lastErrorCode, char buffer[], size_t maxLen)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
*lastErrorCode = httpObj->lastErrorCode;
if (httpObj->errorString.str().length() <= maxLen)
{
strcpy(buffer, httpObj->errorString.str().c_str());
return 0;
}
else
return -1;
}
int DECORATE(duck_name)(int handle, char url[], size_t maxLen)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
if (httpObj->urlExtended.length() <= maxLen)
strcpy(url, httpObj->urlExtended.c_str());
else
return -1;
return 0;
}

View File

@ -0,0 +1,110 @@
#include "on2_timer.h"
#if defined(WIN32)
#include <windows.h>
#include <mmsystem.h>
#else
#include <sys/time.h>
#endif
#if defined( WIN32 )
const unsigned long MAX_BEFORE_ROLLOVER = (1000 * 60 * 60 * 24);
#else
const unsigned long MAX_BEFORE_ROLLOVER = 0xFFFFFFFF;
#endif
// full day in milliseconds
const unsigned long kDuckFullDayMilli = 86400000;
void
on2Timer_Init ( on2Timer* pTimer )
{
pTimer->elapsedMilli = 0;
pTimer->baseMilli = 0;
}
/* The DeInit function was in danger of trying to free statically allocated timers goofy */
unsigned long
on2Timer_Start ( on2Timer* pTimer )
{
pTimer->baseMilli = on2Timer_GetCurrentTimeMilli();
pTimer->elapsedMilli = 0;
return pTimer->baseMilli;
}
unsigned long
on2Timer_Stop ( on2Timer* pTimer )
{
unsigned long currentMilli = on2Timer_GetCurrentTimeMilli();
if(currentMilli >= pTimer->baseMilli)
{
pTimer->elapsedMilli = currentMilli - pTimer->baseMilli;
return pTimer->elapsedMilli;
}
// rollover condition, get milli before rollover, add to current milli
// I think if there is a rollover during timing on win32 this will cause a crash
// when the addition of currentMilli and rollMilli results in overflowing the size of
// and unsigned long int
else
{
unsigned long rollMilli = MAX_BEFORE_ROLLOVER - pTimer->baseMilli;
pTimer->elapsedMilli = currentMilli + rollMilli;
return pTimer->elapsedMilli;
}
}
unsigned long
on2Timer_GetCurrentElapsedMilli ( on2Timer* pTimer )
{
unsigned long currentMilli = on2Timer_GetCurrentTimeMilli();
if(currentMilli >= pTimer->baseMilli)
{
return ( currentMilli - pTimer->baseMilli );
}
// rollover condition, get milli before rollover, add to current milli
else
{
unsigned long rollMilli = MAX_BEFORE_ROLLOVER - pTimer->baseMilli;
return ( currentMilli + rollMilli );
}
}
unsigned long
on2Timer_GetCurrentTimeSeconds ()
{
unsigned long currentMilli = on2Timer_GetCurrentTimeMilli();
return currentMilli / 1000;
}
unsigned long
on2Timer_GetCurrentTimeMilli ()
{
#if !defined(WIN32)
unsigned long currentMilli;
struct timeval tv;
struct timezone tz;
gettimeofday ( &tv, &tz );
currentMilli = (tv.tv_sec * 1000) + (tv.tv_usec/1000);
return currentMilli;
#else
return timeGetTime();
#endif
}
int
on2Timer_Sleep( int msec )
{
#ifdef _WIN32
Sleep( msec );
#endif
return 0;
}

View File

@ -0,0 +1,85 @@
#ifndef _ON2_TIMER_H_
#define _ON2_TIMER_H_
/************************************************************************/
/* on2Timer: cross-platform timer, works on win32 and linux so far */
/* started: August 14, 2001 */
/* codemonkey: TJF */
/************************************************************************/
#include <stdio.h>
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct on2Timer_ {
unsigned long baseMilli;
unsigned long elapsedMilli;
} on2Timer;
/****************************************************************/
/* void on2Timer_Init ( on2Timer* pTimer ) */
/* initialize an allocated timer's members to 0 */
/****************************************************************/
void on2Timer_Init ( on2Timer* pTimer );
/****************************************************************/
/* unsigned long on2Timer_Start ( on2Timer* pTimer ) */
/* start a timer: sets baseTime to currentTime in milliseconds */
/****************************************************************/
unsigned long on2Timer_Start ( on2Timer* pTimer );
/****************************************************************/
/* unsigned long on2Timer_Stop ( on2Timer* pTimer ) */
/* stop a timer: sets elapsed time and accounts for rollover */
/****************************************************************/
unsigned long on2Timer_Stop ( on2Timer* pTimer );
/********************************************************************************/
/* unsigned long on2Timer_GetCurrentElapsedMilli ( on2Timer* pTimer ) */
/* get current elapsed time: returns elapsed time and accounts for rollover */
/********************************************************************************/
unsigned long on2Timer_GetCurrentElapsedMilli ( on2Timer* pTimer );
/********************************************************************************/
/* unsigned long on2Timer_GetMilliBeforeRollover ( unsigned long baseMilli ) */
/* returns milliseconds elapsed since rollover occurred */
/********************************************************************************/
unsigned long on2Timer_GetMilliBeforeRollover ( unsigned long baseMilli );
/****************************************************************/
/* unsigned long on2Timer_GetCurrentTimeSeconds ( void ) */
/* returns seconds since midnight */
/****************************************************************/
unsigned long on2Timer_GetCurrentTimeSeconds ( void );
/****************************************************************/
/* unsigned long on2Timer_GetCurrentTimeMilli ( void ) */
/* returns milliseconds since midnight */
/****************************************************************/
unsigned long on2Timer_GetCurrentTimeMilli ( void );
/****************************************************************/
/* void on2Timer_DeInit ( on2Timer* pTimer ); */
/* on2_free's a pointer to a on2Timer struct, for the lazy ;-) */
/****************************************************************/
void on2Timer_DeInit ( on2Timer* pTimer );
/****************************************************************/
/* void on2Timer_Sleep ( int msec ); */
/* Sleeps for the passed in number of milliseconds */
/****************************************************************/
int on2Timer_Sleep( int msec );
#if defined(__cplusplus)
}
#endif
#endif /* #ifndef _ON2_TIMER_H_ */

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="sal"
ProjectGUID="{7C45701D-CD78-4C6A-A551-C62952E163A6}"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\include,..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\..\..\..\ObjectCode\sal\Release/sal.pch"
AssemblerListingLocation="..\..\..\ObjectCode\sal\Release/"
ObjectFile="..\..\..\ObjectCode\sal\Release/"
ProgramDataBaseFileName="..\..\..\ObjectCode\sal\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\include,..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\..\..\..\ObjectCode\sal\debug/sal.pch"
AssemblerListingLocation="..\..\..\ObjectCode\sal\debug/"
ObjectFile="..\..\..\ObjectCode\sal\debug/"
ProgramDataBaseFileName="..\..\..\ObjectCode\sal\debug/"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="win32"
>
<File
RelativePath="win32\duck_io32.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="win32\duck_mem.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="generic"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,106 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include "duck_io.h"
#include "duck_hfb.h"
#include <assert.h>
int read_count;
int duck_readFinished(int han, int flag)
{
return 1;
}
int duck_open(const char *name, unsigned long userData)
{
int f;
FILE *fp;
unsigned long x;
read_count = 0;
fp = fopen(name, "rb");
if (!fp)
assert(0);
x = (unsigned long ) fp;
/* high bit is set, the cast is a bad idea ! */
if (x & 0x90000000)
assert(0);
f = (int ) x;
return f;
}
void duck_close(int handle)
{
fclose((FILE *) handle);
}
static long totalRead = 0;
static long tellNo = 0;
long duck_read(int handle,unsigned char *buffer,long bytes)
{
int x;
if (buffer == NULL){
duck_seek(handle,bytes,SEEK_CUR);
return bytes;
}
tellNo = ftell((FILE *) handle);
if (bytes == 0)
return 0;
x = fread(buffer,sizeof(char) ,bytes, (FILE *) handle);
if (feof((FILE *) handle) && (x != (int ) bytes))
return -1;
totalRead += x;
if (x == -1L)
assert(0);
return x ;
}
long duck_seek(int handle,long offset,int origin)
{
long x = fseek((FILE *) handle,offset,origin);
tellNo = ftell((FILE *) handle);
return tellNo ;
}

View File

@ -0,0 +1,70 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include "duck_io.h"
int duck_open(const char *name, unsigned long userData)
{
char filename[255];
(void) userData;
if(name[strlen(name)-4] != '.') { /*no extension, try .AVI */
sprintf(filename,"%s.AVI",name);
//f = open(filename,O_BINARY|O_RDONLY);
//return(f);
}else
strcpy(filename,name);
//return(open(filename,O_BINARY|O_RDONLY));
return (int)CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL);
}
void duck_close(int handle)
{
//close(handle);
CloseHandle((void *)handle);
}
long duck_read(int handle,unsigned char *buffer,long bytes)
{
DWORD bytesRead;
if (buffer == NULL){
duck_seek(handle,bytes,SEEK_CUR);
return bytes;
}
ReadFile((void *)handle,buffer,bytes,&bytesRead,NULL);
//return(read(handle,buffer,bytes));
return bytesRead;
}
int64_t duck_seek(int handle,int64_t offset,int origin)
{
//return(lseek(handle,offset,origin));
return(SetFilePointer((HANDLE) handle,(LONG)offset,NULL,origin));
}
int duck_readFinished(int han, int flag)
{
(void)han; // not used;
(void)flag; // not used;
return 1;
}
void set_iofuncs()
{
// HFB_Setopen(duck_open);
// HFB_Setclose(duck_close);
// HFB_Setread(duck_read);
// HFB_Setseek(duck_seek);
}

View File

@ -0,0 +1,132 @@
/***********************************************\
??? duck_mem.c
\***********************************************/
#pragma warning(disable:4786)
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <time.h>
#include <malloc.h>
#include "duck_mem.h"
#include "duck_io.h"
//#include "duck_hfb.h"
#include "duck_dxl.h"
//#define CHECK_MEM
#ifdef CHECK_MEM
#include <map>
#include "debug.h"
#endif
#ifdef CHECK_MEM
struct comp
{
bool operator()(void* v1, void* v2) const
{
return v1 < v2;
}
};
#endif
#ifdef CHECK_MEM
std::map<void*, size_t, struct comp> pointers;
int g_allocs = 0;
int g_frees = 0;
#endif
void *duck_memmove( void *dst, const void *src, size_t length )
{
return memmove(dst, src, length);
}
void *duck_malloc(size_t size, dmemType foo)
{
void *temp = malloc(size);
#ifdef CHECK_MEM
g_allocs++;
TRACE("a=%d\t%d\n", g_allocs, (int)temp);
pointers[temp] = size;
#endif
return temp;
}
void *duck_memset( void *dest, int c, size_t count )
{
return((void *) memset(dest, c, count));
}
void *duck_calloc(size_t n,size_t size, dmemType foo)
{
void *temp = calloc(n, size);
#ifdef CHECK_MEM
g_allocs++;
TRACE("a=%d\t%d\n", g_allocs, (int)temp);
pointers[temp] = size;
#endif
return temp;
}
void duck_free(void *old_blk)
{
#ifdef CHECK_MEM
g_frees++;
TRACE("f=%d\t%d\n", g_frees, (int)old_blk);
if(!pointers.erase(old_blk))
assert(0);
#endif
free(old_blk);
}
void* duck_realloc(void *src, size_t newSize, size_t oldSize)
{
void *temp;
if(newSize <= oldSize)
return src;
#ifdef CHECK_MEM
temp = duck_malloc(newSize, DMEM_GENERAL);
duck_memcpy(temp, src, oldSize);
duck_free(src);
#else
temp = realloc(src, newSize);
#endif
return temp;
}
void *duck_memcpy(void *dest, const void *source, size_t length)
{
return memcpy(dest,source,length);
}
void *duck_memcpy64(void *dest, const void *source, int64_t length)
{
/* Not fully 64 bit compliant */
return memcpy(dest,source,(size_t)length);
}
int duck_strcmp(const char *one, const char *two)
{
return strcmp(one, two);
}
void set_memfuncs()
{
#if defined(DXV_DLL)
DXV_Setmalloc(malloc);
DXV_Setcalloc(calloc);
DXV_Setfree(free);
#endif
#if defined(HFB_DLL)
HFB_Setmalloc(malloc);
HFB_Setcalloc(calloc);
HFB_Setfree(free);
#endif
}

View File

@ -0,0 +1,19 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include "duck_io.h"
#include "duck_hfb.h"
int duck_strcmp(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}